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

82 lines
2.1 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import type { LoginStatus } from "@/data/dto/auth";
import { loadSplashLatestMessagePreview } from "@/lib/chat/splash_latest_message";
import { useSplashLatestMessageCache } from "@/providers/splash-latest-message-provider";
import { Logger, Result } from "@/utils";
const log = new Logger("SplashLatestMessage");
export interface UseSplashLatestMessageInput {
hasInitialized: boolean;
isAuthLoading: boolean;
loginStatus: LoginStatus;
}
export interface UseSplashLatestMessageOutput {
message: string | null;
isLoading: boolean;
}
interface SplashLatestMessageState {
key: string;
loaded: boolean;
message: string | null;
}
export function useSplashLatestMessage({
hasInitialized,
isAuthLoading,
loginStatus,
}: UseSplashLatestMessageInput): UseSplashLatestMessageOutput {
const cache = useSplashLatestMessageCache();
const [state, setState] = useState<SplashLatestMessageState>({
key: "",
loaded: false,
message: null,
});
const shouldLoad =
hasInitialized && !isAuthLoading && loginStatus !== "notLoggedIn";
const requestKey = shouldLoad ? loginStatus : "";
useEffect(() => {
if (!shouldLoad) return;
let cancelled = false;
const loadLatestMessage = async () => {
const result = await loadSplashLatestMessagePreview({ cache });
if (cancelled) return;
if (Result.isErr(result)) {
log.warn(
{ err: result.error.message },
"[splash] latest message history request failed",
);
setState({ key: requestKey, loaded: true, message: null });
return;
}
setState({
key: requestKey,
loaded: true,
message: result.data,
});
};
void loadLatestMessage();
return () => {
cancelled = true;
};
}, [cache, requestKey, shouldLoad]);
if (!shouldLoad) return { message: null, isLoading: false };
if (state.key !== requestKey || !state.loaded) {
return { message: null, isLoading: true };
}
return { message: state.message, isLoading: false };
}