Files
cozsweet-frontend-nextjs/src/app/chat/hooks/use-splash-latest-message-sync.ts
T

57 lines
1.6 KiB
TypeScript

"use client";
import { useEffect, useRef } from "react";
import type { LoginStatus } from "@/data/dto/auth";
import type { UiMessage } from "@/data/dto/chat";
import { resolveSplashLatestMessageCacheIdentity } from "@/lib/chat/splash_latest_message";
import { getLatestSplashMessagePreview } from "@/lib/chat/splash_latest_message_preview";
import { useSplashLatestMessageCache } from "@/providers/splash-latest-message-provider";
export interface UseSplashLatestMessageSyncInput {
characterId: string;
historyLoaded: boolean;
loginStatus: LoginStatus;
messages: readonly UiMessage[];
}
export function useSplashLatestMessageSync({
characterId,
historyLoaded,
loginStatus,
messages,
}: UseSplashLatestMessageSyncInput): void {
const cache = useSplashLatestMessageCache();
const hasObservedInitialSnapshotRef = useRef(false);
const identityPromiseRef = useRef<Promise<string | null> | null>(null);
useEffect(() => {
hasObservedInitialSnapshotRef.current = false;
identityPromiseRef.current = null;
}, [characterId, loginStatus]);
useEffect(() => {
if (!historyLoaded) return;
if (!hasObservedInitialSnapshotRef.current) {
hasObservedInitialSnapshotRef.current = true;
return;
}
const preview = getLatestSplashMessagePreview(messages);
let cancelled = false;
identityPromiseRef.current ??=
resolveSplashLatestMessageCacheIdentity(characterId);
void identityPromiseRef.current.then((identity) => {
if (!cancelled && identity) {
cache.set(identity, preview);
}
});
return () => {
cancelled = true;
};
}, [cache, characterId, historyLoaded, messages]);
}