fix(chat): hide the load-older button once history is confirmed complete
The button's visibility mixed the sync meta with the prefetch-cache hint; a stale prefetch entry (cursor recorded at the initial page) could keep the affordance alive after the user had already loaded to the top. Sync now exposes an explicit isComplete (positive confirmation from a fetch, distinct from !hasMore on unpopulated meta) and it overrides the prefetch hint, which stays in effect only before the meta knows anything.
This commit is contained in:
@@ -522,10 +522,17 @@ export const ChatContainer: React.FC<ChatContainerProps> = ({ autoOpenDraft = tr
|
||||
// History metadata — use sync's hasMore/isLoading
|
||||
const historyMeta = React.useMemo(() => {
|
||||
if (!currentSessionId) return null;
|
||||
const prefetchHasMore = Boolean(sessionPrefetchInfo?.cursor) && sessionPrefetchInfo?.complete !== true;
|
||||
// Sync's meta is authoritative once a fetch has confirmed the history
|
||||
// is fully loaded — a stale prefetch-cache entry (cursor recorded at
|
||||
// the initial page) must not keep the "load older" affordance alive
|
||||
// after the user has already reached the top.
|
||||
const syncComplete = sync.isComplete(currentSessionId);
|
||||
const prefetchHasMore = !syncComplete
|
||||
&& Boolean(sessionPrefetchInfo?.cursor)
|
||||
&& sessionPrefetchInfo?.complete !== true;
|
||||
return {
|
||||
limit: sessionMessages.length,
|
||||
complete: !(sync.hasMore(currentSessionId) || prefetchHasMore),
|
||||
complete: syncComplete || !(sync.hasMore(currentSessionId) || prefetchHasMore),
|
||||
loading: sync.isLoading(currentSessionId),
|
||||
};
|
||||
}, [currentSessionId, sessionMessages.length, sessionPrefetchInfo, sync]);
|
||||
|
||||
@@ -555,6 +555,14 @@ export function useSync() {
|
||||
[getMetaFor],
|
||||
)
|
||||
|
||||
// True only when a fetch has positively confirmed the history is fully
|
||||
// loaded (no next cursor). Distinct from !hasMore(), which is also true for
|
||||
// sessions whose meta simply hasn't been populated yet.
|
||||
const isComplete = useCallback(
|
||||
(sessionID: string) => getMetaFor(sessionID).complete,
|
||||
[getMetaFor],
|
||||
)
|
||||
|
||||
// Optimistic add (for prompt submission)
|
||||
const optimisticAdd = useCallback(
|
||||
(input: { sessionID: string; directory?: string | null; message: Message; parts: Part[] }) => {
|
||||
@@ -610,11 +618,12 @@ export function useSync() {
|
||||
loadMore,
|
||||
hasMore,
|
||||
isLoading,
|
||||
isComplete,
|
||||
optimistic: {
|
||||
add: optimisticAdd,
|
||||
remove: optimisticRemove,
|
||||
},
|
||||
}),
|
||||
[syncSession, loadMore, hasMore, isLoading, optimisticAdd, optimisticRemove],
|
||||
[syncSession, loadMore, hasMore, isLoading, isComplete, optimisticAdd, optimisticRemove],
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user