feat(frontend): my message menu shows when it was read or listened, group readers open in a right panel
This commit is contained in:
1 parent
f03d7c2890
commit
bb38e23f29
14 files changed
+543
-10
No files matched your search
@@ -0,0 +1,77 @@
|
||||
import { getJob, getReadInfo, refreshReadInfo } from "#lib/api/endpoints.js";
|
||||
import type { ReadInfo } from "#lib/api/types.js";
|
||||
import { accounts } from "#lib/stores/accounts.svelte.js";
|
||||
|
||||
const POLL_INTERVAL = 1000;
|
||||
const POLL_MAX = 20;
|
||||
|
||||
export interface ReadEntry {
|
||||
fetching: boolean;
|
||||
info: ReadInfo;
|
||||
}
|
||||
|
||||
function delay(ms: number): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(resolve, ms);
|
||||
});
|
||||
}
|
||||
|
||||
async function waitForJob(jobId: number) {
|
||||
for (let attempt = 0; attempt < POLL_MAX; attempt += 1) {
|
||||
// biome-ignore lint/performance/noAwaitInLoops: polling waits between tries on purpose
|
||||
await delay(POLL_INTERVAL);
|
||||
const job = await getJob(jobId);
|
||||
if (job.status !== "pending" && job.status !== "running") {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createReads() {
|
||||
let entries = $state<Record<string, ReadEntry>>({});
|
||||
const inflight = new Set<string>();
|
||||
|
||||
function key(chatId: number, messageId: number): string {
|
||||
return `${accounts.selectedId}:${chatId}:${messageId}`;
|
||||
}
|
||||
|
||||
async function load(entryKey: string, chatId: number, messageId: number) {
|
||||
const info = await getReadInfo(chatId, messageId);
|
||||
entries[entryKey] = { fetching: info.can_fetch, info };
|
||||
if (!info.can_fetch) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const { job_id } = await refreshReadInfo(chatId, messageId);
|
||||
if (job_id !== null) {
|
||||
await waitForJob(job_id);
|
||||
}
|
||||
entries[entryKey] = {
|
||||
fetching: false,
|
||||
info: await getReadInfo(chatId, messageId),
|
||||
};
|
||||
} finally {
|
||||
entries[entryKey].fetching = false;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
get(chatId: number, messageId: number): ReadEntry | undefined {
|
||||
return entries[key(chatId, messageId)];
|
||||
},
|
||||
open(chatId: number, messageId: number) {
|
||||
const entryKey = key(chatId, messageId);
|
||||
if (accounts.selectedId === null || inflight.has(entryKey)) {
|
||||
return;
|
||||
}
|
||||
inflight.add(entryKey);
|
||||
load(entryKey, chatId, messageId)
|
||||
.catch(() => undefined)
|
||||
.finally(() => {
|
||||
inflight.delete(entryKey);
|
||||
});
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export const reads = createReads();
|
||||
Reference in new issue
Block a user