kopia lustrzana https://github.com/elk-zone/elk
				
				
				
			
		
			
				
	
	
		
			112 wiersze
		
	
	
		
			3.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
			
		
		
	
	
			112 wiersze
		
	
	
		
			3.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
| import { useAsyncIDBKeyval } from '~/composables/idb'
 | |
| import { STORAGE_KEY_USERS } from '~/constants'
 | |
| import type { UserLogin } from '~/types'
 | |
| 
 | |
| const mock = process.mock
 | |
| 
 | |
| export default defineNuxtPlugin({
 | |
|   enforce: 'pre',
 | |
|   parallel: import.meta.server,
 | |
|   async setup() {
 | |
|     const users = useUsers()
 | |
| 
 | |
|     let defaultUsers = mock ? [mock.user] : []
 | |
| 
 | |
|     // Backward compatibility with localStorage
 | |
|     let removeUsersOnLocalStorage = false
 | |
|     if (globalThis?.localStorage) {
 | |
|       const usersOnLocalStorageString = globalThis.localStorage.getItem(STORAGE_KEY_USERS)
 | |
|       if (usersOnLocalStorageString) {
 | |
|         defaultUsers = JSON.parse(usersOnLocalStorageString)
 | |
|         removeUsersOnLocalStorage = true
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     if (import.meta.server) {
 | |
|       users.value = defaultUsers
 | |
|     }
 | |
| 
 | |
|     if (removeUsersOnLocalStorage)
 | |
|       globalThis.localStorage.removeItem(STORAGE_KEY_USERS)
 | |
| 
 | |
|     let callback = noop
 | |
| 
 | |
|     // when multiple tabs: we need to reload window when sign in, switch account or sign out
 | |
|     if (import.meta.client) {
 | |
|       // prevent reloading on the first visit
 | |
|       const initialLoad = ref(true)
 | |
| 
 | |
|       callback = () => (initialLoad.value = false)
 | |
| 
 | |
|       const { readIDB } = await useAsyncIDBKeyval<UserLogin[]>(STORAGE_KEY_USERS, defaultUsers, users)
 | |
| 
 | |
|       function reload() {
 | |
|         setTimeout(() => {
 | |
|           window.location.reload()
 | |
|         }, 0)
 | |
|       }
 | |
| 
 | |
|       debouncedWatch(
 | |
|         () => [currentUserHandle.value, users.value.length] as const,
 | |
|         async ([handle, currentUsers], old) => {
 | |
|           if (initialLoad.value) {
 | |
|             return
 | |
|           }
 | |
| 
 | |
|           const oldHandle = old?.[0]
 | |
| 
 | |
|           // read database users: it is not reactive
 | |
|           const dbUsers = await readIDB()
 | |
| 
 | |
|           const numberOfUsers = dbUsers?.length || 0
 | |
| 
 | |
|           // sign in or sign out
 | |
|           if (currentUsers !== numberOfUsers) {
 | |
|             reload()
 | |
|             return
 | |
|           }
 | |
| 
 | |
|           let sameAcct: boolean
 | |
|           // 1. detect account switching
 | |
|           if (oldHandle) {
 | |
|             sameAcct = handle === oldHandle
 | |
|           }
 | |
|           else {
 | |
|             const acct = currentUser.value?.account?.acct
 | |
|             // 2. detect sign-in?
 | |
|             sameAcct = !acct || acct === handle
 | |
|           }
 | |
| 
 | |
|           if (!sameAcct) {
 | |
|             reload()
 | |
|           }
 | |
|         },
 | |
|         { debounce: 450, flush: 'post', immediate: true },
 | |
|       )
 | |
|     }
 | |
| 
 | |
|     const { params, query } = useRoute()
 | |
| 
 | |
|     publicServer.value = params.server as string || useRuntimeConfig().public.defaultServer
 | |
| 
 | |
|     const masto = createMasto()
 | |
|     const user = (typeof query.server === 'string' && typeof query.token === 'string')
 | |
|       ? {
 | |
|           server: query.server,
 | |
|           token: query.token,
 | |
|           vapidKey: typeof query.vapid_key === 'string' ? query.vapid_key : undefined,
 | |
|         }
 | |
|       : (currentUser.value || { server: publicServer.value })
 | |
| 
 | |
|     if (import.meta.client) {
 | |
|       loginTo(masto, user).finally(callback)
 | |
|     }
 | |
| 
 | |
|     return {
 | |
|       provide: {
 | |
|         masto,
 | |
|       },
 | |
|     }
 | |
|   },
 | |
| })
 |