Files
paseo/packages/app/src/hooks/use-load-older-agent-history.ts
T
chyendongnhanh338andGitHub 08ebe5e7e1 Complete client UI i18n migration
Adds client-side i18n support, language settings, translated UI copy, and locale parity coverage.
2026-06-11 14:15:35 +08:00

116 lines
3.3 KiB
TypeScript

import { useCallback } from "react";
import { useTranslation } from "react-i18next";
import type { ToastApi } from "@/components/toast-host";
import { i18n } from "@/i18n/i18next";
import { useSessionStore, type AgentTimelineCursorState } from "@/stores/session-store";
import { planTimelineOlderFetch } from "@/timeline/timeline-sync-plan";
export interface LoadOlderAgentHistoryClient {
fetchAgentTimeline: (
agentId: string,
request: {
direction: "before";
cursor: { epoch: string; seq: number };
limit: number;
projection: "projected";
},
) => Promise<unknown>;
}
export interface LoadOlderAgentHistoryLogger {
warn: (...args: unknown[]) => void;
}
export interface LoadOlderAgentHistoryDeps {
client: LoadOlderAgentHistoryClient | null;
cursor: AgentTimelineCursorState | undefined;
hasOlder: boolean;
isLoadingOlder: boolean;
setInFlight: (value: boolean) => void;
toast?: ToastApi | null;
logger?: LoadOlderAgentHistoryLogger;
failedMessage?: string;
}
export async function loadOlderAgentHistory(
agentId: string,
deps: LoadOlderAgentHistoryDeps,
): Promise<void> {
const { client, cursor, hasOlder, isLoadingOlder, setInFlight, toast, logger, failedMessage } =
deps;
if (!client || !cursor || !hasOlder || isLoadingOlder) {
return;
}
setInFlight(true);
try {
await client.fetchAgentTimeline(
agentId,
planTimelineOlderFetch({ epoch: cursor.epoch, seq: cursor.startSeq }),
);
} catch (error) {
(logger ?? console).warn("[Timeline] failed to load older agent history", agentId, error);
toast?.show(failedMessage ?? i18n.t("loadOlderHistory.failed"), {
durationMs: 2200,
testID: "agent-load-older-history-toast",
});
} finally {
setInFlight(false);
}
}
export function useLoadOlderAgentHistory({
serverId,
agentId,
toast,
}: {
serverId: string;
agentId: string;
toast?: ToastApi | null;
}) {
const { t } = useTranslation();
const hasOlder =
useSessionStore((state) => state.sessions[serverId]?.agentTimelineHasOlder.get(agentId)) ===
true;
const isLoadingOlder =
useSessionStore((state) =>
state.sessions[serverId]?.agentTimelineOlderFetchInFlight.get(agentId),
) === true;
const setOlderFetchInFlight = useSessionStore(
(state) => state.setAgentTimelineOlderFetchInFlight,
);
const setInFlight = useCallback(
(value: boolean) => {
setOlderFetchInFlight(serverId, (prev) => {
if (prev.get(agentId) === value) {
return prev;
}
const next = new Map(prev);
next.set(agentId, value);
return next;
});
},
[agentId, serverId, setOlderFetchInFlight],
);
const loadOlder = useCallback(() => {
const session = useSessionStore.getState().sessions[serverId];
void loadOlderAgentHistory(agentId, {
client: (session?.client ?? null) as LoadOlderAgentHistoryClient | null,
cursor: session?.agentTimelineCursor.get(agentId),
hasOlder: session?.agentTimelineHasOlder.get(agentId) === true,
isLoadingOlder: session?.agentTimelineOlderFetchInFlight.get(agentId) === true,
setInFlight,
toast,
failedMessage: t("loadOlderHistory.failed"),
});
}, [agentId, serverId, setInFlight, toast, t]);
return {
isLoadingOlder,
hasOlder,
loadOlder,
};
}