feat(chat): sync multi-role backend APIs

This commit is contained in:
2026-07-20 11:29:54 +08:00
parent 16b5c16e76
commit b6fdc912ae
84 changed files with 1488 additions and 439 deletions
+45 -1
View File
@@ -13,6 +13,9 @@ import {
useActiveCharacter,
useActiveCharacterRoutes,
} from "@/providers/character-provider";
import { useCharacterCatalog } from "@/providers/character-catalog-provider";
import { clearPendingChatNavigation } from "@/lib/navigation/chat_unlock_session";
import { getCharacterRoutes } from "@/router/routes";
import { MobileShell } from "@/app/_components/core";
@@ -50,6 +53,9 @@ const chatShellStyle = {
export function ChatScreen() {
const router = useRouter();
const character = useActiveCharacter();
const characterCatalog = useCharacterCatalog();
const refreshCharacterCatalog = characterCatalog.refresh;
const defaultCharacterSlug = characterCatalog.defaultCharacter.slug;
const characterRoutes = useActiveCharacterRoutes();
const searchParams = useSearchParams();
const state = useChatState();
@@ -133,6 +139,42 @@ export function ChatScreen() {
state.historyLoaded,
]);
useEffect(() => {
const errorCode = state.characterErrorCode;
if (errorCode === "CHARACTER_MISMATCH") {
chatDispatch({ type: "ChatHistoryRefreshRequested" });
return;
}
if (
errorCode !== "CHARACTER_DISABLED" &&
errorCode !== "CHARACTER_NOT_FOUND"
) {
return;
}
let cancelled = false;
void (async () => {
if (errorCode === "CHARACTER_NOT_FOUND") {
await clearPendingChatNavigation();
}
await refreshCharacterCatalog();
if (!cancelled) {
router.replace(
getCharacterRoutes(defaultCharacterSlug).splash,
);
}
})();
return () => {
cancelled = true;
};
}, [
chatDispatch,
defaultCharacterSlug,
refreshCharacterCatalog,
router,
state.characterErrorCode,
]);
function handleUnlockPrivateMessage(messageId: string): void {
unlockCoordinator.requestMessageUnlock(messageId, "private");
}
@@ -223,7 +265,9 @@ export function ChatScreen() {
onUnlock={messageLimitBanner.unlock}
/>
) : (
<ChatInputBar disabled={!state.historyLoaded} />
<ChatInputBar
disabled={!state.historyLoaded || !state.canSendMessage}
/>
)}
</div>