diff --git a/src/features/modes/game/components/GameConversationView.tsx b/src/features/modes/game/components/GameConversationView.tsx
index d3a408ed6..84b3326cc 100644
--- a/src/features/modes/game/components/GameConversationView.tsx
+++ b/src/features/modes/game/components/GameConversationView.tsx
@@ -1,4 +1,5 @@
import { useEffect } from "react";
+import { RefreshCw } from "lucide-react";
import type { Chat as EngineChat } from "../../../../engine/contracts/types/chat";
import { useUIStore } from "../../../../shared/stores/ui.store";
import {
@@ -15,6 +16,46 @@ interface GameConversationViewProps {
activeChatId: string;
}
+function GameChatHydrationState({
+ status,
+ onRetry,
+}: {
+ status: "loading" | "error";
+ onRetry?: () => void;
+}) {
+ return (
+
+
+ {status === "loading" ? (
+
+ ) : (
+
+ )}
+
+
+ {status === "loading" ? "Loading game chat..." : "Game chat could not load"}
+
+
+ {status === "loading"
+ ? "Restoring the saved game surface."
+ : "Retry loading the chat before leaving the game surface."}
+
+
+ {status === "error" && onRetry && (
+
+ )}
+
+
+ );
+}
+
export function GameConversationView({ activeChatId }: GameConversationViewProps) {
const messagesPerPage = useUIStore((state) => state.messagesPerPage);
const data = useChatSurfaceData({
@@ -46,7 +87,12 @@ export function GameConversationView({ activeChatId }: GameConversationViewProps
void fetchNextPage();
}, [fetchNextPage, hasNextPage, isFetchingNextPage, loadedMessageCount, totalMessageCount]);
- if (!data.chat) return ;
+ if (!data.chat) {
+ if (data.chatError) {
+ return void data.refetchChat()} />;
+ }
+ return ;
+ }
return (
<>
diff --git a/src/features/modes/shared/chat-ui/hooks/use-chat-surface-data.ts b/src/features/modes/shared/chat-ui/hooks/use-chat-surface-data.ts
index 913c0e7a3..4dca1d985 100644
--- a/src/features/modes/shared/chat-ui/hooks/use-chat-surface-data.ts
+++ b/src/features/modes/shared/chat-ui/hooks/use-chat-surface-data.ts
@@ -162,7 +162,13 @@ export function useChatSurfaceData({
const resolvedMessagePageSize =
Number.isFinite(messagePageSize) && messagePageSize > 0 ? Math.floor(messagePageSize) : DEFAULT_MESSAGE_PAGE_SIZE;
const setActiveChatId = useChatStore((state) => state.setActiveChatId);
- const { data: chat, error: chatError } = useChat(activeChatId);
+ const {
+ data: chat,
+ error: chatError,
+ isLoading: isChatLoading,
+ isFetching: isChatFetching,
+ refetch: refetchChat,
+ } = useChat(activeChatId);
const {
data: msgData,
isLoading,
@@ -323,6 +329,10 @@ export function useChatSurfaceData({
return {
chat,
+ chatError,
+ isChatLoading,
+ isChatFetching,
+ refetchChat,
chatMode,
chatMeta,
messages,