feat : add profile page

This commit is contained in:
2026-08-06 22:46:47 +07:00 Unverified
parent e5a6ad3e04
commit c1c015ef78
26 changed files with 1169 additions and 310 deletions
+58
View File
@@ -0,0 +1,58 @@
import { describe, expect, test } from "bun:test";
import {
startRealtimeRefresh,
type RealtimeRefreshHandlers,
} from "@/lib/realtime/realtime-refresh";
function waitForRefresh() {
return new Promise((resolve) => setTimeout(resolve, 5));
}
describe("profile realtime refresh", () => {
test("refreshes for both XP and voice events", async () => {
let handlers: RealtimeRefreshHandlers | undefined;
let refreshes = 0;
const clean = startRealtimeRefresh({
filter: { kind: "profile" },
debounceMs: 0,
refresh: () => { refreshes += 1; },
subscribe: (nextHandlers) => {
handlers = nextHandlers;
return { clean() {} };
},
});
handlers?.onXp();
await waitForRefresh();
handlers?.onVc({ channelId: "1234567890" });
await waitForRefresh();
expect(refreshes).toBe(2);
clean();
});
test("debounces profile event bursts and refreshes after reconnect", async () => {
let handlers: RealtimeRefreshHandlers | undefined;
let refreshes = 0;
const clean = startRealtimeRefresh({
filter: { kind: "profile" },
debounceMs: 1,
refresh: () => { refreshes += 1; },
subscribe: (nextHandlers) => {
handlers = nextHandlers;
return { clean() {} };
},
});
handlers?.onXp();
handlers?.onVc({ channelId: "1234567890" });
await waitForRefresh();
expect(refreshes).toBe(1);
handlers?.onOpen();
handlers?.onOpen();
await waitForRefresh();
expect(refreshes).toBe(2);
clean();
});
});
+7 -3
View File
@@ -1,6 +1,7 @@
export type RealtimeRefreshFilter =
| { kind: "form"; formId?: string }
| { kind: "uploads" }
| { kind: "profile" }
| { kind: "xp" }
| { kind: "vc"; channelId?: string };
@@ -50,15 +51,18 @@ export function startRealtimeRefresh({
}
},
onXp() {
if (filter.kind === "xp") scheduleRefresh();
if (filter.kind === "xp" || filter.kind === "profile") scheduleRefresh();
},
onUpload() {
if (filter.kind === "uploads") scheduleRefresh();
},
onVc(event) {
if (
filter.kind === "vc"
&& (!filter.channelId || event.channelId === filter.channelId)
filter.kind === "profile"
|| (
filter.kind === "vc"
&& (!filter.channelId || event.channelId === filter.channelId)
)
) {
scheduleRefresh();
}