Improve mobile data retrieval and state management

- Add race protection and packId normalization to swipe screen
- Add loading/error states to matchStore with couple_id filter
- Sync per-match unread counts in realtime
- Use useFocusEffect for data freshness on Home screen
- Wire RefreshControl to actual loading state on Matches

🤖 Generated with [Claude Code](https://claude.com/claude-code)
This commit is contained in:
jjbrunton committed 2026-01-03 20:10:58 +00:00
1 parent 994dd2a295
commit ae91602921
21 files changed
+2453 -237

No files matched your search

+25 -16
View File
@@ -50,21 +50,21 @@ function MessageToastPreview({
currentUserId,
});
if (isDecrypting) {
return (
<Text style={styles.messageToastBody} numberOfLines={1}>
Waiting for message...
</Text>
);
}
if (error) {
return (
<Text style={styles.messageToastBody} numberOfLines={1}>
Encrypted message
</Text>
);
}
if (isDecrypting) {
return (
<Text style={styles.messageToastBody} numberOfLines={1}>
Waiting for message...
</Text>
);
}
if (error) {
return (
<Text style={styles.messageToastBody} numberOfLines={1}>
Encrypted message
</Text>
);
}
return (
<Text style={styles.messageToastBody} numberOfLines={1}>
@@ -175,7 +175,7 @@ export default function AppLayout() {
const router = useRouter();
const segments = useSegments();
const { isAuthenticated, isLoading, user, signOut } = useAuthStore();
const { matches, newMatchesCount, addMatch } = useMatchStore();
const { matches, newMatchesCount, addMatch, updateMatchUnreadCount } = useMatchStore();
const { unreadCount, lastMessage, fetchUnreadCount, addMessage, clearLastMessage } = useMessageStore();
const { fetchEnabledPacks } = usePacksStore();
const { initializeRevenueCat } = useSubscriptionStore();
@@ -477,6 +477,9 @@ export default function AppLayout() {
delivered_at: newMessage.delivered_at || new Date().toISOString(),
match: { id: match.id, question: { text: questionText || "" } },
});
// Sync per-match unread count for realtime updates
updateMatchUnreadCount(match.id, 1);
}
}
)
@@ -697,6 +700,12 @@ export default function AppLayout() {
href: null, // Hide from tab bar
}}
/>
<Tabs.Screen
name="my-answers"
options={{
href: null, // Hide from tab bar
}}
/>
</Tabs>
{/* Radial Menu Overlay */}