fix: change page reload and account switch logic (#2975)

This commit is contained in:
Joaquín Sánchez 2024-09-25 17:55:32 +02:00 committed by GitHub
parent 54344acf4b
commit 44074ff1a3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 328 additions and 253 deletions

View file

@ -5,6 +5,7 @@ import { STORAGE_KEY_USERS } from '~/constants'
const mock = process.mock
export default defineNuxtPlugin({
enforce: 'pre',
parallel: import.meta.server,
async setup() {
const users = useUsers()
@ -24,11 +25,87 @@ export default defineNuxtPlugin({
if (import.meta.server) {
users.value = defaultUsers
}
if (import.meta.client) {
await useAsyncIDBKeyval<UserLogin[]>(STORAGE_KEY_USERS, defaultUsers, { deep: true }, users)
}
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,
},
}
},
})