mirror of
https://github.com/R0m1k3/FlowReader.git
synced 2026-10-20 13:48:10 +02:00
fix(focus): solve double swipe skip by stabilizing deck state
This commit is contained in:
1 parent
679722cc13
commit
d11068b3df
1 file changed
+15
-6
@@ -19,11 +19,21 @@ export function FocusPage({ onExit }: FocusPageProps) {
|
|||||||
staleTime: 0, // Always fresh for focus mode
|
staleTime: 0, // Always fresh for focus mode
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Stable deck state to prevent UI jumping when articles are marked read
|
||||||
|
const [deck, setDeck] = useState<typeof articles>([]);
|
||||||
|
|
||||||
|
// Initialize/Append deck when data arrives
|
||||||
|
if (articles && (!deck || deck.length === 0)) {
|
||||||
|
setDeck(articles);
|
||||||
|
}
|
||||||
|
// Note: A more robust implementation would append new unique items if we implemented pagination/infinite scroll,
|
||||||
|
// but for now, snapshotting the initial load is sufficient for the "Focus Session" concept.
|
||||||
|
|
||||||
// Mutation to mark read
|
// Mutation to mark read
|
||||||
const markReadMutation = useMutation({
|
const markReadMutation = useMutation({
|
||||||
mutationFn: (id: string) => articlesApi.markRead(id),
|
mutationFn: (id: string) => articlesApi.markRead(id),
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
// Invalidate main lists to sync up when returning
|
// Invalidate main lists to sync up sidebar, but our local 'deck' state won't change
|
||||||
queryClient.invalidateQueries({ queryKey: ['articles'] });
|
queryClient.invalidateQueries({ queryKey: ['articles'] });
|
||||||
queryClient.invalidateQueries({ queryKey: ['feeds'] });
|
queryClient.invalidateQueries({ queryKey: ['feeds'] });
|
||||||
},
|
},
|
||||||
@@ -35,11 +45,10 @@ export function FocusPage({ onExit }: FocusPageProps) {
|
|||||||
|
|
||||||
const handleKeep = (id: string) => {
|
const handleKeep = (id: string) => {
|
||||||
// Do nothing api-wise, just skip.
|
// Do nothing api-wise, just skip.
|
||||||
// Or strictly speaking, we could have a "skipped" list, but for now just don't mark read.
|
|
||||||
console.log('Skipped:', id);
|
console.log('Skipped:', id);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading && (!deck || deck.length === 0)) {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center justify-center h-full bg-carbon/50 backdrop-blur-xl">
|
<div className="flex items-center justify-center h-full bg-carbon/50 backdrop-blur-xl">
|
||||||
<div className="w-16 h-16 border-4 border-nature border-t-transparent rounded-full animate-spin" />
|
<div className="w-16 h-16 border-4 border-nature border-t-transparent rounded-full animate-spin" />
|
||||||
@@ -48,8 +57,8 @@ export function FocusPage({ onExit }: FocusPageProps) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Filter out locally read? No, we handle that in stack index.
|
// Filter out locally read? No, we handle that in stack index.
|
||||||
// But if API returns empty:
|
// If deck is empty
|
||||||
if (!articles || articles.length === 0) {
|
if (!deck || deck.length === 0) {
|
||||||
return <FocusEmptyState onBack={onExit} />;
|
return <FocusEmptyState onBack={onExit} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +88,7 @@ export function FocusPage({ onExit }: FocusPageProps) {
|
|||||||
{/* Main Deck Area */}
|
{/* Main Deck Area */}
|
||||||
<main className="flex-1 flex items-center justify-center p-4">
|
<main className="flex-1 flex items-center justify-center p-4">
|
||||||
<FocusCardStack
|
<FocusCardStack
|
||||||
articles={articles}
|
articles={deck}
|
||||||
onMarkRead={handleMarkRead}
|
onMarkRead={handleMarkRead}
|
||||||
onKeep={handleKeep}
|
onKeep={handleKeep}
|
||||||
onEmpty={() => setIsComplete(true)}
|
onEmpty={() => setIsComplete(true)}
|
||||||
|
|||||||
Reference in new issue
Block a user