1+ import React , { useCallback , useEffect , useMemo , useRef , useState } from 'react' ;
2+ import { ActivityIndicator , Alert , Animated , FlatList , Keyboard , Pressable , RefreshControl , StyleSheet , Text , TouchableOpacity , View } from 'react-native' ;
3+
4+ import { useUser } from '@clerk/clerk-expo' ;
15import { Ionicons } from '@expo/vector-icons' ;
2- import { BottomSheetBackdrop , BottomSheetBackdropProps , BottomSheetModal , BottomSheetTextInput , BottomSheetView } from '@gorhom/bottom-sheet' ;
3- import AsyncStorage from '@react-native-async-storage/async-storage' ;
6+ import {
7+ BottomSheetBackdrop ,
8+ BottomSheetBackdropProps ,
9+ BottomSheetModal ,
10+ BottomSheetTextInput ,
11+ BottomSheetView ,
12+ } from '@gorhom/bottom-sheet' ;
413import { useFocusEffect } from '@react-navigation/native' ;
5- import { useUser } from '@clerk/clerk-expo ' ;
14+ import AsyncStorage from '@react-native-async-storage/async-storage ' ;
615import * as Haptics from 'expo-haptics' ;
7- import React , { useCallback , useEffect , useMemo , useRef , useState } from 'react' ;
8- import { ActivityIndicator , Alert , Animated , FlatList , Keyboard , Pressable , RefreshControl , StyleSheet , Text , TouchableOpacity , useWindowDimensions , View } from 'react-native' ;
916
10- import { FOLDER_CARD , FOLDER_COLORS , NOTE_CARD , SECTION } from '../constants/ui' ;
11- import { type Folder , type FolderCounts , type Note , useApiService } from '../services/api' ;
12- import { decryptNote , isNoteEncrypted } from '../services/api/encryption' ;
17+ import { FOLDER_CARD , FOLDER_COLORS , NOTE_CARD , SECTION } from '../constants/ui' ;
18+ import { type Folder , type FolderCounts , type Note , useApiService } from '../services/api' ;
19+ import { decryptNote } from '../services/api/encryption' ;
1320import { useTheme } from '../theme' ;
1421
1522interface RouteParams {
@@ -62,7 +69,6 @@ export default function NotesListScreen({ navigation, route, renderHeader, scrol
6269 const api = useApiService ( ) ;
6370 const { user } = useUser ( ) ;
6471 const { folderId, viewType, searchQuery } = route ?. params || { } ;
65- const { height : windowHeight } = useWindowDimensions ( ) ;
6672
6773 const [ notes , setNotes ] = useState < Note [ ] > ( [ ] ) ;
6874 const [ subfolders , setSubfolders ] = useState < Folder [ ] > ( [ ] ) ;
@@ -71,6 +77,10 @@ export default function NotesListScreen({ navigation, route, renderHeader, scrol
7177 const [ showLoading , setShowLoading ] = useState ( false ) ;
7278 const [ refreshing , setRefreshing ] = useState ( false ) ;
7379
80+ // Track if notes have been loaded to prevent unnecessary refetch on navigation back
81+ const hasLoadedRef = useRef ( false ) ;
82+ const currentParamsRef = useRef < { folderId ?: string ; viewType ?: string ; searchQuery ?: string } | null > ( null ) ;
83+
7484 // Performance tracking
7585 const screenFocusTime = useRef < number > ( 0 ) ;
7686 const notesLoadedTime = useRef < number > ( 0 ) ;
@@ -169,10 +179,29 @@ export default function NotesListScreen({ navigation, route, renderHeader, scrol
169179 // Load notes when screen focuses or params change
170180 useFocusEffect (
171181 React . useCallback ( ( ) => {
172- loadNotes ( ) ;
173- loadViewMode ( ) ;
174- // Reset scroll position when screen comes into focus
175- if ( flatListRef . current ) {
182+ // Check if params have changed
183+ const paramsChanged =
184+ ! currentParamsRef . current ||
185+ currentParamsRef . current . folderId !== folderId ||
186+ currentParamsRef . current . viewType !== viewType ||
187+ currentParamsRef . current . searchQuery !== searchQuery ;
188+
189+ // Determine if this is the first load
190+ const isFirstLoad = ! hasLoadedRef . current ;
191+
192+ // Always reload when screen comes into focus
193+ // Use refresh mode if not first load to avoid showing spinner
194+ if ( isFirstLoad || paramsChanged ) {
195+ loadNotes ( ) ; // Full load with spinner on first load or param change
196+ loadViewMode ( ) ;
197+ currentParamsRef . current = { folderId, viewType, searchQuery } ;
198+ } else {
199+ // Silent refresh without spinner for subsequent focuses
200+ loadNotes ( true ) ; // Pass true for isRefresh to skip loading state
201+ }
202+
203+ // Reset scroll position when screen comes into focus (only if params changed)
204+ if ( paramsChanged && flatListRef . current ) {
176205 flatListRef . current . scrollToOffset ( { offset : 0 , animated : false } ) ;
177206 }
178207 // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -298,6 +327,9 @@ export default function NotesListScreen({ navigation, route, renderHeader, scrol
298327 setLoading ( false ) ;
299328 }
300329
330+ // Mark that notes have been loaded
331+ hasLoadedRef . current = true ;
332+
301333 // Decrypt remaining notes in background
302334 if ( remaining . length > 0 ) {
303335 const encryptedRemaining = remaining . filter ( note =>
@@ -331,6 +363,8 @@ export default function NotesListScreen({ navigation, route, renderHeader, scrol
331363 if ( ! isRefresh ) {
332364 setLoading ( false ) ;
333365 }
366+ // Mark that notes have been loaded
367+ hasLoadedRef . current = true ;
334368 }
335369
336370 // Load subfolders and their counts in background (non-blocking)
@@ -383,6 +417,8 @@ export default function NotesListScreen({ navigation, route, renderHeader, scrol
383417 if ( ! isRefresh ) {
384418 setLoading ( false ) ;
385419 }
420+ // Mark as loaded even on error to prevent reload loop
421+ hasLoadedRef . current = true ;
386422 }
387423 } ;
388424
@@ -470,10 +506,7 @@ export default function NotesListScreen({ navigation, route, renderHeader, scrol
470506 if ( filterConfig . showStarredOnly && ! note . starred ) {
471507 return false ;
472508 }
473- if ( filterConfig . showHiddenOnly && ! note . hidden ) {
474- return false ;
475- }
476- return true ;
509+ return ! filterConfig . showHiddenOnly || note . hidden ;
477510 } ) ;
478511
479512 // Sort notes
@@ -883,7 +916,7 @@ export default function NotesListScreen({ navigation, route, renderHeader, scrol
883916 </ View >
884917 </ >
885918 ) ;
886- } , [ loading , renderHeader , viewType , subfolders , theme . colors , viewMode , filteredNotes . length , notes . length , hasActiveFilters , handleEmptyTrash , navigation , route ?. params ?. folderId ] ) ;
919+ } , [ loading , renderHeader , viewType , subfolders , theme . colors , theme . isDark , viewMode , filteredNotes . length , notes . length , hasActiveFilters , handleEmptyTrash , navigation , route ?. params ?. folderId ] ) ;
887920
888921 // Render empty state
889922 const renderEmptyComponent = useCallback ( ( ) => {
@@ -1413,7 +1446,7 @@ const styles = StyleSheet.create({
14131446 fontWeight : '400' ,
14141447 } ,
14151448 noteListDivider : {
1416- height : StyleSheet . hairlineWidth ,
1449+ height : 1 ,
14171450 marginLeft : 0 ,
14181451 } ,
14191452 // Bottom sheet styles
0 commit comments