import { login as loginMasto } from 'masto' import type { ServerInfo, UserLogin } from '~/types' const ServerInfoTTL = 60 * 60 * 1000 * 12 // 12 hour function createClientState() { const { server, token } = useAppCookies() const accounts = useLocalStorage('nuxtodon-accounts', [], { deep: true }) const currentId = useLocalStorage('nuxtodon-current-user', '') const currentUser = computed(() => { let user: UserLogin | undefined if (currentId.value) { user = accounts.value.find(user => user.account?.id === currentId.value) if (user) return user } // Fallback to the first account return accounts.value[0] }) async function login(user: UserLogin) { const existing = accounts.value.findIndex(u => u.server === user.server && u.token === user.token) if (existing !== -1) { if (currentId.value === accounts.value[existing].account?.id) return null currentId.value = user.account?.id server.value = user.server token.value = user.token return true } const masto = await loginMasto({ url: `https://${user.server}`, accessToken: user.token, }) const me = await masto.accounts.verifyCredentials() user.account = me accounts.value.push(user) currentId.value = me.id server.value = user.server token.value = user.token return true } const serverInfos = useLocalStorage>('nuxtodon-server-info', {}) async function fetchServerInfo(server: string) { if (!serverInfos.value[server]) { // @ts-expect-error init serverInfos.value[server] = { timeUpdated: 0, server, } } if (serverInfos.value[server].timeUpdated + ServerInfoTTL < Date.now()) { const masto = await useMasto() await Promise.allSettled([ masto.instances.fetch().then((r) => { Object.assign(serverInfos.value[server], r) }), masto.customEmojis.fetchAll().then((r) => { serverInfos.value[server].customEmojis = Object.fromEntries(r.map(i => [i.shortcode, i])) }), ]) } return serverInfos.value[server] } if (server.value) fetchServerInfo(server.value) return { currentUser, accounts, login, serverInfos, fetchServerInfo, } } export type ClientState = ReturnType export default defineNuxtPlugin((nuxt) => { nuxt.$clientState = createClientState() })