Skip to content

Commit 9570c4d

Browse files
committed
fix(mobile): cache invalidation, startup refresh, and autocorrect
1 parent 87afb39 commit 9570c4d

File tree

3 files changed

+33
-10
lines changed

3 files changed

+33
-10
lines changed

apps/mobile/v1/src/components/AppWrapper.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { ActivityIndicator,View } from 'react-native';
55
import { useMasterPassword } from '../hooks/useMasterPassword';
66
import { logger } from '../lib/logger';
77
import AuthScreen from '../screens/AuthScreen';
8+
import { apiCache } from '../services/api/cache';
89
import { useSyncOnReconnect } from '../services/sync/useSyncOnReconnect';
910
import { useTheme } from '../theme';
1011
import { MasterPasswordScreen } from './MasterPasswordDialog';
@@ -34,6 +35,14 @@ export const AppWrapper: React.FC<AppWrapperProps> = ({ children }) => {
3435
// Automatically sync pending mutations when device comes back online
3536
useSyncOnReconnect();
3637

38+
// Clear API cache on app mount to prevent stale data from previous session
39+
useEffect(() => {
40+
apiCache.clearAll();
41+
if (__DEV__) {
42+
console.log('[AppWrapper] Cleared API cache on app startup');
43+
}
44+
}, []);
45+
3746
// Detect userId change SYNCHRONOUSLY in render
3847
if (userId !== lastUserIdRef.current) {
3948
lastUserIdRef.current = userId;

apps/mobile/v1/src/screens/FoldersScreen.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ export default function FoldersScreen() {
113113
// Check if screen is focused
114114
const isFocused = useIsFocused();
115115
const loadTimerRef = useRef<NodeJS.Timeout | null>(null);
116+
const isFirstMountRef = useRef(true);
116117

117118
// Load folders data
118119
const loadFoldersData = useCallback(async (isRefresh = false, forceRefresh = false) => {
@@ -191,8 +192,14 @@ export default function FoldersScreen() {
191192
clearTimeout(loadTimerRef.current);
192193
}
193194

194-
// Load immediately
195-
loadFoldersData();
195+
// Force refresh on first mount to ensure fresh data (prevents stale counts on app reload)
196+
const shouldForceRefresh = isFirstMountRef.current;
197+
if (isFirstMountRef.current) {
198+
isFirstMountRef.current = false;
199+
}
200+
201+
// Load immediately with force refresh on first mount
202+
loadFoldersData(false, shouldForceRefresh);
196203
}
197204

198205
return () => {

apps/mobile/v1/src/services/api/notes.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -186,19 +186,23 @@ export function createNotesApi(getToken: AuthTokenGetter, getUserId: () => strin
186186

187187
// If offline, calculate from database with short-lived cache
188188
if (!online) {
189-
// Check short-lived cache to avoid recalculation on rapid re-renders
190189
const cacheKey = CACHE_KEYS.COUNTS(folderId);
191-
const cached = apiCache.get<NoteCounts>(cacheKey);
192-
if (cached) {
193-
if (__DEV__) {
194-
console.log('[API] Returning cached offline counts');
190+
191+
// Check short-lived cache to avoid recalculation on rapid re-renders
192+
// Skip cache if forceRefresh is true (e.g., on app startup to avoid stale data)
193+
if (!forceRefresh) {
194+
const cached = apiCache.get<NoteCounts>(cacheKey);
195+
if (cached) {
196+
if (__DEV__) {
197+
console.log('[API] Returning cached offline counts');
198+
}
199+
return cached;
195200
}
196-
return cached;
197201
}
198202

199203
// Calculate counts from local SQLite cache
200204
if (__DEV__) {
201-
console.log('[API] Device offline - calculating counts from local cache');
205+
console.log('[API] Device offline - calculating counts from local cache', { forceRefresh });
202206
}
203207

204208
try {
@@ -207,7 +211,10 @@ export function createNotesApi(getToken: AuthTokenGetter, getUserId: () => strin
207211

208212
// Cache for only 2 seconds - offline counts are "best effort" and may be stale
209213
// This prevents stale counts from persisting when network comes back online
210-
apiCache.set(cacheKey, counts, 2_000); // 2s TTL (reduced from 10s)
214+
// Don't cache if forceRefresh is true to ensure next call gets fresh data
215+
if (!forceRefresh) {
216+
apiCache.set(cacheKey, counts, 2_000); // 2s TTL (reduced from 10s)
217+
}
211218

212219
return counts;
213220
} catch (error) {

0 commit comments

Comments
 (0)