Files
beavergram/frontend/src/lib/stores/accounts.svelte.ts
T

87 lines
1.9 KiB
TypeScript

import {
listAccounts,
logoutAccount,
renameAccountDevice,
} from "#lib/api/endpoints.js";
import type { Account } from "#lib/api/types.js";
import { browser } from "$app/env";
const STORAGE_KEY = "bg.account";
function readSelected(): number | null {
if (!browser) {
return null;
}
const stored = localStorage.getItem(STORAGE_KEY);
return stored === null ? null : Number(stored);
}
function createAccounts() {
let list = $state<Account[]>([]);
let selectedId = $state<number | null>(readSelected());
let loaded = $state(false);
const selected = $derived(
list.find((account) => account.account_id === selectedId) ?? null
);
function persist(id: number | null) {
if (!browser) {
return;
}
if (id === null) {
localStorage.removeItem(STORAGE_KEY);
} else {
localStorage.setItem(STORAGE_KEY, String(id));
}
}
function select(id: number | null) {
selectedId = id;
persist(id);
}
async function load() {
list = await listAccounts();
loaded = true;
const exists = list.some((account) => account.account_id === selectedId);
if (!exists) {
const fallback =
list.find((account) => account.is_active) ?? list.at(0) ?? null;
select(fallback ? fallback.account_id : null);
}
}
return {
get list() {
return list;
},
load,
get loaded() {
return loaded;
},
async logout(id: number) {
await logoutAccount(id);
if (id === selectedId) {
select(null);
}
await load();
},
async renameDevice(id: number, deviceModel: string) {
const updated = await renameAccountDevice(id, deviceModel);
list = list.map((account) =>
account.account_id === id ? updated : account
);
},
select,
get selected() {
return selected;
},
get selectedId() {
return selectedId;
},
};
}
export const accounts = createAccounts();