2026-07-26 16:55:20 +07:00
|
|
|
import { useEffect } from "react";
|
2026-08-01 09:19:39 +07:00
|
|
|
import useSWR, { useSWRConfig } from "swr";
|
|
|
|
|
import { useAction } from "@/hooks/use-action";
|
2026-07-26 16:14:32 +07:00
|
|
|
import { recordingsApi } from "@/lib/api";
|
2026-08-26 17:05:41 +07:00
|
|
|
import type { PaginatedRecordings, VoiceRecording } from "@/lib/types";
|
2026-07-27 21:54:31 +07:00
|
|
|
import type { WsHook } from "@/lib/ws-hook";
|
2026-07-26 16:14:32 +07:00
|
|
|
|
2026-08-01 09:19:39 +07:00
|
|
|
const RECORDINGS_KEY = ["recordings"] as const;
|
|
|
|
|
|
2026-08-26 17:05:41 +07:00
|
|
|
export function useRecordingsPage(initialPage?: PaginatedRecordings) {
|
|
|
|
|
return useSWR<PaginatedRecordings>(
|
2026-08-07 10:44:03 +07:00
|
|
|
RECORDINGS_KEY,
|
2026-08-26 17:05:41 +07:00
|
|
|
() => recordingsApi.list(50),
|
|
|
|
|
{ fallbackData: initialPage },
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function useRecordings(initialPage?: PaginatedRecordings) {
|
|
|
|
|
const page = useRecordingsPage(initialPage);
|
|
|
|
|
return {
|
|
|
|
|
...page,
|
|
|
|
|
data: page.data?.items,
|
|
|
|
|
nextCursor: page.data?.nextCursor ?? null,
|
|
|
|
|
hasMore: page.data?.hasMore ?? false,
|
|
|
|
|
refetch: () => page.mutate(),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function useLoadMoreRecordings() {
|
|
|
|
|
const { mutate } = useSWRConfig();
|
|
|
|
|
return useAction(
|
|
|
|
|
async ({
|
|
|
|
|
channelId,
|
|
|
|
|
userId,
|
|
|
|
|
cursor,
|
|
|
|
|
}: {
|
|
|
|
|
channelId?: string;
|
|
|
|
|
userId?: string;
|
|
|
|
|
cursor: string;
|
|
|
|
|
}) => {
|
|
|
|
|
const result = await recordingsApi.list(50, channelId, userId, cursor);
|
|
|
|
|
await mutate(
|
|
|
|
|
RECORDINGS_KEY,
|
|
|
|
|
(old: PaginatedRecordings | undefined): PaginatedRecordings => {
|
|
|
|
|
if (!old) return result;
|
|
|
|
|
const existingIds = new Set(old.items.map((r) => r.id));
|
|
|
|
|
const newUnique = result.items.filter((r) => !existingIds.has(r.id));
|
|
|
|
|
return {
|
|
|
|
|
items: [...old.items, ...newUnique],
|
|
|
|
|
nextCursor: result.nextCursor,
|
|
|
|
|
hasMore: result.hasMore,
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
{ revalidate: false },
|
|
|
|
|
);
|
|
|
|
|
return result;
|
2026-08-07 10:44:03 +07:00
|
|
|
},
|
|
|
|
|
);
|
2026-07-26 16:14:32 +07:00
|
|
|
}
|
|
|
|
|
|
2026-07-26 16:55:20 +07:00
|
|
|
export function useDeleteRecording() {
|
2026-08-01 09:19:39 +07:00
|
|
|
const { mutate } = useSWRConfig();
|
|
|
|
|
return useAction((id: string) => recordingsApi.delete(id), {
|
2026-08-26 17:05:41 +07:00
|
|
|
onSuccess: (_, id) => {
|
|
|
|
|
void mutate(
|
|
|
|
|
RECORDINGS_KEY,
|
|
|
|
|
(
|
|
|
|
|
old: PaginatedRecordings | undefined,
|
|
|
|
|
): PaginatedRecordings | undefined => {
|
|
|
|
|
if (!old) return old;
|
|
|
|
|
return {
|
|
|
|
|
...old,
|
|
|
|
|
items: old.items.filter((r) => r.id !== id),
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
{ revalidate: false },
|
|
|
|
|
);
|
2026-08-01 09:19:39 +07:00
|
|
|
},
|
2026-07-26 16:55:20 +07:00
|
|
|
});
|
|
|
|
|
}
|
2026-07-26 16:14:32 +07:00
|
|
|
|
2026-07-26 16:55:20 +07:00
|
|
|
export function useRecordingsWsSync(ws: WsHook) {
|
2026-08-01 09:19:39 +07:00
|
|
|
const { mutate } = useSWRConfig();
|
2026-07-26 16:46:53 +07:00
|
|
|
useEffect(() => {
|
2026-07-26 16:55:20 +07:00
|
|
|
const unsub = ws.on("voice_recording_uploaded", (data) => {
|
|
|
|
|
const rec = data as VoiceRecording;
|
2026-08-01 09:19:39 +07:00
|
|
|
void mutate(
|
|
|
|
|
RECORDINGS_KEY,
|
2026-08-26 17:05:41 +07:00
|
|
|
(old: PaginatedRecordings | undefined): PaginatedRecordings => {
|
|
|
|
|
if (!old) return { items: [rec], nextCursor: null, hasMore: false };
|
|
|
|
|
if (old.items.some((r) => r.id === rec.id)) return old;
|
|
|
|
|
return {
|
|
|
|
|
...old,
|
|
|
|
|
items: [rec, ...old.items],
|
|
|
|
|
};
|
|
|
|
|
},
|
2026-08-01 09:19:39 +07:00
|
|
|
{ revalidate: false },
|
2026-07-26 16:55:20 +07:00
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
return unsub;
|
2026-08-01 09:19:39 +07:00
|
|
|
}, [ws, mutate]);
|
2026-07-26 16:14:32 +07:00
|
|
|
}
|