import { Image } from 'expo-image'; import { Platform, Pressable, RefreshControl, ScrollView, StyleSheet, TouchableOpacity, useColorScheme, View, ViewToken } from 'react-native'; import { HelloWave } from '@/components/HelloWave'; import ParallaxScrollView from '@/components/ParallaxScrollView'; import { ThemedText } from '@/components/ThemedText'; import { ThemedView } from '@/components/ThemedView'; import { ActivityIndicator, Card, FAB, IconButton, List, Surface, Text, TouchableRipple, useTheme } from 'react-native-paper'; import { useCallback, useEffect, useState } from 'react'; import AsyncStorage from '@react-native-async-storage/async-storage'; import { DATA_DIRECTORY_URI_KEY } from '@/constants/Settings'; import { useNavigation } from 'expo-router'; import { SafeAreaView } from 'react-native-safe-area-context'; import { useFileSystem, prettyName } from '@/hooks/useFilesystem'; import { format } from 'date-fns'; import { StorageAccessFramework } from 'expo-file-system'; import { FlatList } from 'react-native-gesture-handler'; import Markdown from 'react-native-markdown-display'; export default function HomeScreen() { const navigation = useNavigation(); const theme = useTheme(); const styles = StyleSheet.create({ fab: { position: 'absolute', margin: 16, right: 0, bottom: 0, backgroundColor: theme.colors.primary, // Use your theme's primary color }, container: { backgroundColor: theme.colors.primary, position: 'absolute', top: 0, left: 0, right: 0, height: 100, zIndex: 1000, }, safeArea: { flex: 1, marginTop: 100, backgroundColor: theme.colors.surface, // padding: 10 }, entryCard: { backgroundColor: theme.colors.surface, height: 150 , alignItems: 'center', }, }); const { dataDirectoryUri, loadFiles, files, directorySize } = useFileSystem(); const [refreshing, setRefreshing] = useState(false); const [loadedContents, setLoadedContents] = useState>(new Map()); const [lastViewableItems, setLastViewableItems] = useState([]); const onRefresh = async () => { setRefreshing(true); setLoadedContents(new Map()); // Clear cached content await loadFiles(); // Reload content for currently visible items lastViewableItems.forEach(({ item }) => { loadFileContent(item.uri, true); // Force reload }); setRefreshing(false); }; const loadFileContent = async (fileUri: string, forceReload = false) => { if (loadedContents.has(fileUri) && !forceReload) return; // Already loaded try { // Replace with your actual file reading logic const content = await StorageAccessFramework.readAsStringAsync(fileUri); setLoadedContents(prev => new Map(prev).set(fileUri, content)); } catch (error) { console.error('Error loading file content:', error); } }; const onViewableItemsChanged = useCallback(({ viewableItems }: { viewableItems: ViewToken[] }) => { setLastViewableItems(viewableItems); // Track visible items viewableItems.forEach(({ item }) => { loadFileContent(item.uri); }); }, []); const renderFileItem = ({ item: f }: { item: typeof files[0] }) => ( { navigation.navigate('Editor', { fileUri: f.uri, fileDatetime: f.datetime }, ); }} > {format(f.datetime, "hh:mm aaa")} {loadedContents.has(f.uri) && ( {loadedContents.get(f.uri) || } )} ); return ( item.uri} onViewableItemsChanged={onViewableItemsChanged} viewabilityConfig={{ itemVisiblePercentThreshold: 50 }} refreshControl={ } ListHeaderComponent={ {prettyName(dataDirectoryUri, { pathContext: 'full' })}: {' '}{files.length} {files.length == 1 ? "entry" : "entries"}, {directorySize} bytes } /> { navigation.navigate('Editor' as never); }} /> ); }