github.com/resonatecoop/id@v1.1.0-43/frontend/src/index.js (about)

     1  const choo = require('choo')
     2  const nanochoo = require('nanochoo')
     3  const initialState = window.initialState
     4    ? Object.assign({}, window.initialState)
     5    : {}
     6  const app = choo({ href: false }) // disable choo href routing
     7  window.initialState = initialState // hack to bring back initial state (should be deleted again by nanochoo)
     8  
     9  const { isBrowser } = require('browser-or-node')
    10  const setTitle = require('./lib/title')
    11  const { getAPIServiceClientWithAuth } = require('@resonate/api-service')({
    12    apiHost: process.env.APP_HOST,
    13    base: process.env.API_BASE || '/api/v3'
    14  })
    15  
    16  const SearchOuter = require('./components/header')
    17  const UserMenu = require('./components/user-menu')
    18  
    19  if (isBrowser) {
    20    require('web-animations-js/web-animations.min')
    21  
    22    window.localStorage.DISABLE_NANOTIMING = process.env.DISABLE_NANOTIMING === 'yes'
    23    window.localStorage.logLevel = process.env.LOG_LEVEL
    24  
    25    if (process.env.NODE_ENV !== 'production') {
    26      app.use(require('choo-devtools')())
    27    }
    28  
    29    if ('Notification' in window) {
    30      app.use(require('choo-notification')())
    31    }
    32  }
    33  
    34  app.use(require('choo-meta')())
    35  
    36  // main app store
    37  app.use((state, emitter) => {
    38    state.profile = state.profile || {
    39      displayName: '',
    40      member: false
    41    }
    42  
    43    state.profile.avatar = state.profile.avatar || {}
    44  
    45    state.clients = state.clients || [
    46      {
    47        connectUrl: 'https://stream.resonate.coop/api/user/connect/resonate',
    48        name: 'Player',
    49        description: 'stream.resonate.coop'
    50      },
    51      {
    52        connectUrl: 'https://dash.resonate.coop/api/user/connect/resonate',
    53        name: 'Dashboard',
    54        description: 'dash.resonate.coop'
    55      }
    56    ]
    57  
    58    emitter.on(state.events.DOMCONTENTLOADED, () => {
    59      emitter.emit(`route:${state.route}`)
    60      setMeta()
    61    })
    62  
    63    emitter.on('route:account', () => {
    64      getUserProfile()
    65    })
    66  
    67    emitter.on('route:profile', () => {
    68      getUserProfile()
    69    })
    70  
    71    emitter.on(state.events.NAVIGATE, () => {
    72      emitter.emit(`route:${state.route}`)
    73      setMeta()
    74    })
    75  
    76    async function getUserProfile () {
    77      try {
    78        // get v2 api profile for legacy values (old nickname, avatar)
    79        const getClient = getAPIServiceClientWithAuth(state.token)
    80        const client = await getClient('profile')
    81        const result = await client.getUserProfile()
    82  
    83        const { body: response } = result
    84        const { data: userData } = response
    85  
    86        state.profile.nickname = userData.nickname
    87        state.profile.avatar = userData.avatar || {}
    88  
    89        emitter.emit(state.events.RENDER)
    90      } catch (err) {
    91        console.log(err.message)
    92        console.log(err)
    93      }
    94    }
    95  
    96    function setMeta () {
    97      const title = {
    98        '*': 'Page not found',
    99        '/': 'Apps',
   100        login: 'Log In',
   101        authorize: 'Authorize',
   102        profile: 'Create your profile',
   103        account: 'Update your account',
   104        'password-reset': 'Password reset',
   105        join: 'Join'
   106      }[state.route]
   107  
   108      if (!title) return
   109  
   110      state.shortTitle = title
   111  
   112      const fullTitle = setTitle(title)
   113  
   114      emitter.emit('meta', {
   115        title: fullTitle
   116      })
   117    }
   118  })
   119  
   120  app.use(require('./plugins/notifications')())
   121  
   122  require('./routes')(app)
   123  
   124  /*
   125   * Append search component to header (outside of main choo app)
   126   */
   127  async function searchApp (initialState) {
   128    window.initialState = initialState
   129  
   130    const search = nanochoo()
   131  
   132    search.use((state, emitter, app) => {
   133      state.search = state.search || {
   134        q: ''
   135      }
   136  
   137      state.user = {
   138        token: state.token
   139      }
   140      state.params = {} // nanochoo does not have a router
   141  
   142      emitter.on('search', (q) => {
   143        const bang = q.startsWith('#')
   144        const pathname = bang ? '/tag' : '/search'
   145        const url = new URL(pathname, process.env.APP_HOST || 'http://localhost')
   146        const params = bang ? { term: q.split('#')[1] } : { q }
   147        url.search = new URLSearchParams(params)
   148        return window.open(url.href, '_blank')
   149      })
   150    })
   151  
   152    search.view((state, emit) => {
   153      // component id needs to be header to work correctly
   154      return state.cache(SearchOuter, 'header').render()
   155    })
   156  
   157    search.mount('#search-host')
   158  
   159    return Promise.resolve()
   160  }
   161  
   162  /*
   163   * Append usermenu app
   164   */
   165  async function userMenuApp (initialState) {
   166    if (!document.getElementById('usermenu')) return
   167  
   168    window.initialState = initialState
   169  
   170    const usermenu = nanochoo()
   171  
   172    usermenu.use((state, emitter, app) => {
   173      state.params = {} // nanochoo does not have a router
   174    })
   175  
   176    usermenu.view((state, emit) => {
   177      return state.cache(UserMenu, 'usermenu').render({
   178        displayName: state.profile.displayName
   179      })
   180    })
   181  
   182    usermenu.mount('#usermenu')
   183  
   184    return Promise.resolve()
   185  }
   186  
   187  searchApp(initialState).then(() => {
   188    console.log('Loaded search app')
   189  })
   190  
   191  userMenuApp(initialState).then(() => {
   192    console.log('Loaded user menu')
   193  })
   194  
   195  module.exports = app.mount('#app')