style(frontend): apply ultracite 7.12 formatting and lint rules
This commit is contained in:
1 parent
fc4758aa0b
commit
c8e5cff871
109 files changed
+845
-817
No files matched your search
@@ -56,23 +56,10 @@ function createAccounts() {
|
||||
get list() {
|
||||
return list;
|
||||
},
|
||||
get selectedId() {
|
||||
return selectedId;
|
||||
},
|
||||
get selected() {
|
||||
return selected;
|
||||
},
|
||||
load,
|
||||
get loaded() {
|
||||
return loaded;
|
||||
},
|
||||
load,
|
||||
select,
|
||||
async renameDevice(id: number, deviceModel: string) {
|
||||
const updated = await renameAccountDevice(id, deviceModel);
|
||||
list = list.map((account) =>
|
||||
account.account_id === id ? updated : account
|
||||
);
|
||||
},
|
||||
async logout(id: number) {
|
||||
await logoutAccount(id);
|
||||
if (id === selectedId) {
|
||||
@@ -80,6 +67,19 @@ function createAccounts() {
|
||||
}
|
||||
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;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -13,9 +13,6 @@ function createAuth() {
|
||||
let token = $state<string | null>(readToken());
|
||||
|
||||
return {
|
||||
get token() {
|
||||
return token;
|
||||
},
|
||||
get isAuthenticated() {
|
||||
return token !== null && token.length > 0;
|
||||
},
|
||||
@@ -31,6 +28,9 @@ function createAuth() {
|
||||
localStorage.removeItem(STORAGE_KEY);
|
||||
}
|
||||
},
|
||||
get token() {
|
||||
return token;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,8 @@ export function createChatPicker() {
|
||||
return results;
|
||||
},
|
||||
search(query: string) {
|
||||
const current = ++seq;
|
||||
seq += 1;
|
||||
const current = seq;
|
||||
if (timer !== null) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ interface Bucket {
|
||||
}
|
||||
|
||||
function createBucket(): Bucket {
|
||||
return { list: [], loaded: false, loading: false, hasMore: true };
|
||||
return { hasMore: true, list: [], loaded: false, loading: false };
|
||||
}
|
||||
|
||||
function bucketKey(folderId: number | null): string {
|
||||
@@ -63,9 +63,9 @@ function createChats() {
|
||||
|
||||
async function fetchPage(key: string, offset: number): Promise<Chat[]> {
|
||||
return await listChats({
|
||||
folder_id: folderQuery(key),
|
||||
limit: PAGE_SIZE,
|
||||
offset,
|
||||
folder_id: folderQuery(key),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -160,8 +160,8 @@ function createChats() {
|
||||
if (event.type !== "message") {
|
||||
return;
|
||||
}
|
||||
const message = event.message;
|
||||
let known = false;
|
||||
const { message } = event;
|
||||
let seenChat = false;
|
||||
for (const bucket of Object.values(buckets)) {
|
||||
const existing = bucket.list.find(
|
||||
(chat) => chat.chat_id === message.chat_id
|
||||
@@ -169,20 +169,21 @@ function createChats() {
|
||||
if (existing === undefined) {
|
||||
continue;
|
||||
}
|
||||
known = true;
|
||||
seenChat = true;
|
||||
existing.last_date = message.date;
|
||||
existing.last_sender_id = message.sender_id;
|
||||
existing.last_text = message.text;
|
||||
existing.message_count++;
|
||||
existing.message_count += 1;
|
||||
hoist(bucket, existing);
|
||||
}
|
||||
if (!known && buckets[ALL]?.loaded) {
|
||||
if (!seenChat && buckets[ALL]?.loaded) {
|
||||
insertUnknown(message.chat_id).catch(() => undefined);
|
||||
}
|
||||
}
|
||||
|
||||
async function waitForJob(jobId: number) {
|
||||
for (let attempt = 0; attempt < POLL_MAX; attempt++) {
|
||||
for (let attempt = 0; attempt < POLL_MAX; attempt += 1) {
|
||||
// biome-ignore lint/performance/noAwaitInLoops: polling waits between tries on purpose
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, POLL_INTERVAL);
|
||||
});
|
||||
@@ -215,19 +216,6 @@ function createChats() {
|
||||
});
|
||||
|
||||
return {
|
||||
get list(): Chat[] {
|
||||
return active()?.list ?? EMPTY;
|
||||
},
|
||||
get loaded(): boolean {
|
||||
return active()?.loaded ?? false;
|
||||
},
|
||||
get loading(): boolean {
|
||||
return active()?.loading ?? false;
|
||||
},
|
||||
get hasMore(): boolean {
|
||||
return active()?.hasMore ?? false;
|
||||
},
|
||||
loadMore,
|
||||
byId(id: number): Chat | undefined {
|
||||
for (const bucket of Object.values(buckets)) {
|
||||
const found = bucket.list.find((chat) => chat.chat_id === id);
|
||||
@@ -237,6 +225,23 @@ function createChats() {
|
||||
}
|
||||
return extra[id];
|
||||
},
|
||||
async enrich(chatId: number) {
|
||||
syncAccount();
|
||||
if (account === null || enriched.has(chatId)) {
|
||||
return;
|
||||
}
|
||||
enriched.add(chatId);
|
||||
try {
|
||||
const { job_id } = await enrichChat(chatId);
|
||||
await waitForJob(job_id);
|
||||
const chat = await getChat(chatId);
|
||||
if (chat !== null) {
|
||||
replaceEverywhere(chat);
|
||||
}
|
||||
} catch {
|
||||
enriched.delete(chatId);
|
||||
}
|
||||
},
|
||||
ensure(id: number) {
|
||||
syncAccount();
|
||||
if (account === null || resolving.has(id) || known(id)) {
|
||||
@@ -277,29 +282,25 @@ function createChats() {
|
||||
}
|
||||
});
|
||||
},
|
||||
get hasMore(): boolean {
|
||||
return active()?.hasMore ?? false;
|
||||
},
|
||||
get list(): Chat[] {
|
||||
return active()?.list ?? EMPTY;
|
||||
},
|
||||
load(folderId: number | null = folders.selectedId) {
|
||||
return load(folderId, false);
|
||||
},
|
||||
get loaded(): boolean {
|
||||
return active()?.loaded ?? false;
|
||||
},
|
||||
get loading(): boolean {
|
||||
return active()?.loading ?? false;
|
||||
},
|
||||
loadMore,
|
||||
refresh(folderId: number | null = folders.selectedId) {
|
||||
return load(folderId, true);
|
||||
},
|
||||
async enrich(chatId: number) {
|
||||
syncAccount();
|
||||
if (account === null || enriched.has(chatId)) {
|
||||
return;
|
||||
}
|
||||
enriched.add(chatId);
|
||||
try {
|
||||
const { job_id } = await enrichChat(chatId);
|
||||
await waitForJob(job_id);
|
||||
const chat = await getChat(chatId);
|
||||
if (chat !== null) {
|
||||
replaceEverywhere(chat);
|
||||
}
|
||||
} catch {
|
||||
enriched.delete(chatId);
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -16,12 +16,6 @@ function createDiscover() {
|
||||
}
|
||||
|
||||
return {
|
||||
get(chatId: number): DiscoverItem | undefined {
|
||||
return items[chatId];
|
||||
},
|
||||
set(item: DiscoverItem) {
|
||||
items = { ...items, [item.chat_id]: item };
|
||||
},
|
||||
async ensure(chatId: number) {
|
||||
syncAccount();
|
||||
if (account === null || items[chatId] || pending.has(chatId)) {
|
||||
@@ -35,6 +29,12 @@ function createDiscover() {
|
||||
pending.delete(chatId);
|
||||
}
|
||||
},
|
||||
get(chatId: number): DiscoverItem | undefined {
|
||||
return items[chatId];
|
||||
},
|
||||
set(item: DiscoverItem) {
|
||||
items = { ...items, [item.chat_id]: item };
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ function createEvents() {
|
||||
if (!response.body) {
|
||||
return;
|
||||
}
|
||||
epoch++;
|
||||
epoch += 1;
|
||||
lastFrameAt = Date.now();
|
||||
for (const listener of reconnectListeners) {
|
||||
listener();
|
||||
@@ -79,6 +79,7 @@ function createEvents() {
|
||||
const decoder = new TextDecoder();
|
||||
let buffer = "";
|
||||
while (!signal.aborted) {
|
||||
// biome-ignore lint/performance/noAwaitInLoops: stream is read frame by frame
|
||||
const result = await readWithTimeout(reader);
|
||||
if (result === STALLED) {
|
||||
await reader.cancel().catch(() => undefined);
|
||||
@@ -95,6 +96,7 @@ function createEvents() {
|
||||
async function run(accountId: number, signal: AbortSignal) {
|
||||
while (!signal.aborted) {
|
||||
try {
|
||||
// biome-ignore lint/performance/noAwaitInLoops: reconnect attempts are sequential by design
|
||||
const response = await fetch(`${BASE}/events?account_id=${accountId}`, {
|
||||
headers: auth.token ? { Authorization: `Bearer ${auth.token}` } : {},
|
||||
signal,
|
||||
@@ -141,10 +143,6 @@ function createEvents() {
|
||||
get epoch(): number {
|
||||
return epoch;
|
||||
},
|
||||
subscribe(listener: Listener): () => void {
|
||||
listeners.add(listener);
|
||||
return () => listeners.delete(listener);
|
||||
},
|
||||
onReconnect(listener: () => void): () => void {
|
||||
reconnectListeners.add(listener);
|
||||
return () => reconnectListeners.delete(listener);
|
||||
@@ -160,6 +158,10 @@ function createEvents() {
|
||||
}
|
||||
start(accountId);
|
||||
},
|
||||
subscribe(listener: Listener): () => void {
|
||||
listeners.add(listener);
|
||||
return () => listeners.delete(listener);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -43,31 +43,31 @@ function createFolders() {
|
||||
}
|
||||
|
||||
return {
|
||||
get list(): Folder[] {
|
||||
return list;
|
||||
},
|
||||
get loading(): boolean {
|
||||
return loading;
|
||||
},
|
||||
get selectedId(): number | null {
|
||||
return selectedId;
|
||||
},
|
||||
get selected(): Folder | null {
|
||||
return list.find((folder) => folder.folder_id === selectedId) ?? null;
|
||||
},
|
||||
get activeIndex(): number {
|
||||
return indexOf(selectedId);
|
||||
},
|
||||
get direction(): number {
|
||||
return direction;
|
||||
},
|
||||
get list(): Folder[] {
|
||||
return list;
|
||||
},
|
||||
load() {
|
||||
return load();
|
||||
},
|
||||
get loading(): boolean {
|
||||
return loading;
|
||||
},
|
||||
select(id: number | null) {
|
||||
direction = indexOf(id) >= indexOf(selectedId) ? 1 : -1;
|
||||
selectedId = id;
|
||||
},
|
||||
get selected(): Folder | null {
|
||||
return list.find((folder) => folder.folder_id === selectedId) ?? null;
|
||||
},
|
||||
get selectedId(): number | null {
|
||||
return selectedId;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -29,9 +29,9 @@ function createPeers() {
|
||||
return;
|
||||
}
|
||||
getPeers(ids)
|
||||
.then((peers) => {
|
||||
.then((rows) => {
|
||||
const next = { ...map };
|
||||
for (const peer of peers) {
|
||||
for (const peer of rows) {
|
||||
next[peer.peer_id] = peer;
|
||||
}
|
||||
map = next;
|
||||
@@ -44,10 +44,6 @@ function createPeers() {
|
||||
}
|
||||
|
||||
return {
|
||||
reset,
|
||||
get(id: number): PeerView | undefined {
|
||||
return map[id];
|
||||
},
|
||||
ensure(ids: Iterable<number>) {
|
||||
if (accounts.selectedId !== account) {
|
||||
account = accounts.selectedId;
|
||||
@@ -64,6 +60,10 @@ function createPeers() {
|
||||
timer = setTimeout(flush, BATCH_DELAY);
|
||||
}
|
||||
},
|
||||
get(id: number): PeerView | undefined {
|
||||
return map[id];
|
||||
},
|
||||
reset,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,8 @@ function createSearch() {
|
||||
function schedule() {
|
||||
clearTimers();
|
||||
const value = trimmed;
|
||||
const current = ++seq;
|
||||
seq += 1;
|
||||
const current = seq;
|
||||
if (value.length < MIN_LENGTH) {
|
||||
messageHits = [];
|
||||
chatHits = [];
|
||||
@@ -100,31 +101,9 @@ function createSearch() {
|
||||
get active() {
|
||||
return active;
|
||||
},
|
||||
get query() {
|
||||
return query;
|
||||
},
|
||||
get trimmed() {
|
||||
return trimmed;
|
||||
},
|
||||
get loading() {
|
||||
return loading;
|
||||
},
|
||||
get messageHits() {
|
||||
return messageHits;
|
||||
},
|
||||
get chatHits() {
|
||||
return chatHits;
|
||||
},
|
||||
get peerHits() {
|
||||
return peerHits;
|
||||
},
|
||||
open() {
|
||||
active = true;
|
||||
},
|
||||
setQuery(value: string) {
|
||||
query = value;
|
||||
schedule();
|
||||
},
|
||||
close() {
|
||||
active = false;
|
||||
query = "";
|
||||
@@ -132,9 +111,31 @@ function createSearch() {
|
||||
chatHits = [];
|
||||
peerResults = [];
|
||||
loading = false;
|
||||
seq++;
|
||||
seq += 1;
|
||||
clearTimers();
|
||||
},
|
||||
get loading() {
|
||||
return loading;
|
||||
},
|
||||
get messageHits() {
|
||||
return messageHits;
|
||||
},
|
||||
open() {
|
||||
active = true;
|
||||
},
|
||||
get peerHits() {
|
||||
return peerHits;
|
||||
},
|
||||
get query() {
|
||||
return query;
|
||||
},
|
||||
setQuery(value: string) {
|
||||
query = value;
|
||||
schedule();
|
||||
},
|
||||
get trimmed() {
|
||||
return trimmed;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -7,18 +7,15 @@ function createShareUi() {
|
||||
let revision = $state(0);
|
||||
|
||||
return {
|
||||
get label() {
|
||||
return label;
|
||||
},
|
||||
get open() {
|
||||
return open;
|
||||
},
|
||||
set open(value: boolean) {
|
||||
open = value;
|
||||
},
|
||||
get subject() {
|
||||
return subject;
|
||||
},
|
||||
get label() {
|
||||
return label;
|
||||
},
|
||||
get revision() {
|
||||
return revision;
|
||||
},
|
||||
@@ -27,6 +24,9 @@ function createShareUi() {
|
||||
label = name;
|
||||
open = true;
|
||||
},
|
||||
get subject() {
|
||||
return subject;
|
||||
},
|
||||
touch() {
|
||||
revision += 1;
|
||||
},
|
||||
|
||||
@@ -21,8 +21,9 @@ function createToasts() {
|
||||
type: ToastType = "info",
|
||||
timeout = DEFAULT_TIMEOUT
|
||||
) {
|
||||
const id = nextId++;
|
||||
items = [...items, { id, type, message }];
|
||||
nextId += 1;
|
||||
const id = nextId;
|
||||
items = [...items, { id, message, type }];
|
||||
if (timeout > 0) {
|
||||
setTimeout(() => dismiss(id), timeout);
|
||||
}
|
||||
@@ -30,17 +31,17 @@ function createToasts() {
|
||||
}
|
||||
|
||||
return {
|
||||
dismiss,
|
||||
error(message: string) {
|
||||
return show(message, "error");
|
||||
},
|
||||
get items() {
|
||||
return items;
|
||||
},
|
||||
show,
|
||||
error(message: string) {
|
||||
return show(message, "error");
|
||||
},
|
||||
success(message: string) {
|
||||
return show(message, "success");
|
||||
},
|
||||
dismiss,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -31,11 +31,18 @@ function createUi() {
|
||||
let jumpTarget = $state<JumpTarget | null>(null);
|
||||
|
||||
return {
|
||||
get rightPanel() {
|
||||
return rightPanel;
|
||||
clearJump() {
|
||||
jumpTarget = null;
|
||||
},
|
||||
get panelMessageId() {
|
||||
return panelMessageId;
|
||||
closePanel() {
|
||||
rightPanel = null;
|
||||
panelMessageId = null;
|
||||
},
|
||||
closeSettings() {
|
||||
leftView = "main";
|
||||
},
|
||||
get jumpTarget() {
|
||||
return jumpTarget;
|
||||
},
|
||||
get leftColumnOpen() {
|
||||
return leftColumnOpen;
|
||||
@@ -43,39 +50,32 @@ function createUi() {
|
||||
get leftView() {
|
||||
return leftView;
|
||||
},
|
||||
get jumpTarget() {
|
||||
return jumpTarget;
|
||||
},
|
||||
openSettings() {
|
||||
leftView = "settings";
|
||||
},
|
||||
closeSettings() {
|
||||
leftView = "main";
|
||||
},
|
||||
requestJump(chatId: number, messageId: number) {
|
||||
jumpTarget = { chatId, messageId };
|
||||
},
|
||||
clearJump() {
|
||||
jumpTarget = null;
|
||||
openMessagePanel(panel: RightPanel, messageId: number) {
|
||||
rightPanel = panel;
|
||||
panelMessageId = messageId;
|
||||
},
|
||||
openPanel(panel: RightPanel) {
|
||||
rightPanel = panel;
|
||||
panelMessageId = null;
|
||||
},
|
||||
openMessagePanel(panel: RightPanel, messageId: number) {
|
||||
rightPanel = panel;
|
||||
panelMessageId = messageId;
|
||||
openSettings() {
|
||||
leftView = "settings";
|
||||
},
|
||||
closePanel() {
|
||||
rightPanel = null;
|
||||
panelMessageId = null;
|
||||
get panelMessageId() {
|
||||
return panelMessageId;
|
||||
},
|
||||
toggleLeftColumn() {
|
||||
leftColumnOpen = !leftColumnOpen;
|
||||
requestJump(chatId: number, messageId: number) {
|
||||
jumpTarget = { chatId, messageId };
|
||||
},
|
||||
get rightPanel() {
|
||||
return rightPanel;
|
||||
},
|
||||
setLeftColumn(open: boolean) {
|
||||
leftColumnOpen = open;
|
||||
},
|
||||
toggleLeftColumn() {
|
||||
leftColumnOpen = !leftColumnOpen;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user