/* SPDX-FileCopyrightText: © 2025 Hornwitser SPDX-License-Identifier: AGPL-3.0-or-later */ import { Info } from "~/shared/utils/luxon"; import { defineStore } from 'pinia' interface SyncOperation { controller: AbortController, promise: Promise>>, } export const useUsersStore = defineStore("users", () => { const accountStore = useAccountStore(); const state = { fetched: ref(false), pendingSync: ref(), users: ref>(new ClientMap(ClientUser, new Map(), new Map())), } const getters = { } const actions = { async fetch() { if (!accountStore.isCrew || state.fetched.value) { return state.users; } const pending = state.pendingSync.value; if (pending) { return pending.promise; } const requestFetch = useRequestFetch(); const controller = new AbortController(); const zone = Info.normalizeZone(accountStore.activeTimezone); const locale = accountStore.activeLocale; const promise = (async () => { try { const apiUsers = await requestFetch("/api/users", { signal: controller.signal }); state.users.value.apiUpdate(apiUsers, { zone, locale }); state.pendingSync.value = undefined; state.fetched.value = true; return state.users; } catch (err: any) { if (err.name !== "AbortError") state.pendingSync.value = undefined; throw err; } })(); state.pendingSync.value = { controller, promise, }; return promise; }, async resync(id: number) { const pending = state.pendingSync.value; if (pending) { pending.controller.abort(); } state.pendingSync.value = undefined; state.fetched.value = false; await actions.fetch(); }, } appEventSource?.addEventListener("update", (event) => { if (event.data.type !== "user-update") { return; } console.log("appyling", event.data) const zone = Info.normalizeZone(accountStore.activeTimezone); const locale = accountStore.activeLocale; state.users.value.apiUpdate([event.data.data], { zone, locale }); }); return { ...state, ...getters, ...actions, }; })