added new icons :> and updating the home screen and other pages to use the media collected from the OAUTH login :<<<

This commit is contained in:
bobbert committed 2026-02-23 01:06:03 +00:00
1 parent 4af7893838
commit 969bdfa987
6 files changed
+68 -14

No files matched your search

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 27 KiB

+5
View File
@@ -14,6 +14,8 @@ const PhotoGrid = ({
refreshControl, refreshControl,
ListHeaderComponent, ListHeaderComponent,
ListEmptyComponent, ListEmptyComponent,
ListFooterComponent,
onEndReached,
}) => { }) => {
const { theme } = useTheme(); const { theme } = useTheme();
const itemSize = (width - GRID_GAP * (columns + 1)) / columns; const itemSize = (width - GRID_GAP * (columns + 1)) / columns;
@@ -55,6 +57,9 @@ const PhotoGrid = ({
refreshControl={refreshControl} refreshControl={refreshControl}
ListHeaderComponent={ListHeaderComponent} ListHeaderComponent={ListHeaderComponent}
ListEmptyComponent={ListEmptyComponent} ListEmptyComponent={ListEmptyComponent}
ListFooterComponent={ListFooterComponent}
onEndReached={onEndReached}
onEndReachedThreshold={0.5}
/> />
); );
}; };
+61 -14
View File
@@ -24,6 +24,8 @@ const HomeScreen = ({ navigation, route }) => {
const [refreshing, setRefreshing] = useState(false); const [refreshing, setRefreshing] = useState(false);
const [selectedMedia, setSelectedMedia] = useState(null); const [selectedMedia, setSelectedMedia] = useState(null);
const [viewerVisible, setViewerVisible] = useState(false); const [viewerVisible, setViewerVisible] = useState(false);
const [googleNextPage, setGoogleNextPage] = useState(null);
const [loadingMore, setLoadingMore] = useState(false);
useFocusEffect( useFocusEffect(
useCallback(() => { useCallback(() => {
@@ -54,29 +56,39 @@ const HomeScreen = ({ navigation, route }) => {
const mediaFromDb = await DatabaseService.getMediaByUser(userId); const mediaFromDb = await DatabaseService.getMediaByUser(userId);
const newMedia = []; const newMedia = [];
// Google Photos fetch // Google Photos — restore tokens from the linked account and fetch
const googleAccount = linkedAccounts.find((a) => a.service_type === 'GOOGLE_PHOTOS'); const googleAccount = linkedAccounts.find((a) => a.service_type === 'GOOGLE_PHOTOS');
if (googleAccount) { if (googleAccount) {
try { try {
const data = googleAccount.account_data || {};
const googleAuth = new GoogleAUTH(); const googleAuth = new GoogleAUTH();
googleAuth.accessToken = googleAccount.account_data?.accessToken; googleAuth.accessToken = data.accessToken || null;
googleAuth.refreshToken = googleAccount.account_data?.refreshToken; googleAuth.refreshToken = data.refreshToken || null;
googleAuth.expiresAt = Date.now() + 3600000; // Set expiresAt to 0 so getAccessToken() will refresh if needed
const photos = await googleAuth.getPhotos(50); googleAuth.expiresAt = data.expiresAt || 0;
const photos = await googleAuth.getPhotos(100);
if (photos?.mediaItems?.length) newMedia.push(...photos.mediaItems); if (photos?.mediaItems?.length) newMedia.push(...photos.mediaItems);
setGoogleNextPage(photos?.nextPageToken || null);
// Persist refreshed tokens back to DB if they changed
if (googleAuth.accessToken && googleAuth.accessToken !== data.accessToken) {
await DatabaseService.linkAccount(userId, 'GOOGLE_PHOTOS', {
accessToken: googleAuth.accessToken,
refreshToken: googleAuth.refreshToken || data.refreshToken,
expiresAt: googleAuth.expiresAt,
email: data.email || 'google-user',
});
}
} catch (err) { } catch (err) {
console.error('Google Photos fetch error:', err); console.error('Google Photos fetch error:', err);
} }
} }
// iCloud fetch (placeholder) // iCloud (placeholder)
const iosAccount = linkedAccounts.find((a) => a.service_type === 'ICLOUD_PHOTOS'); const iosAccount = linkedAccounts.find((a) => a.service_type === 'ICLOUD_PHOTOS');
if (iosAccount) { if (iosAccount) {
try { console.log('iCloud: placeholder — would fetch photos here');
console.log('iCloud: placeholder - would fetch photos here');
} catch (err) {
console.error('iCloud fetch error:', err);
}
} }
// NAS fetch // NAS fetch
@@ -114,6 +126,34 @@ const HomeScreen = ({ navigation, route }) => {
setFilteredMedia(filtered); setFilteredMedia(filtered);
}; };
const loadMorePhotos = async () => {
if (loadingMore || !googleNextPage) return;
setLoadingMore(true);
try {
const googleAccount = linkedAccounts.find((a) => a.service_type === 'GOOGLE_PHOTOS');
if (googleAccount) {
const data = googleAccount.account_data || {};
const googleAuth = new GoogleAUTH();
googleAuth.accessToken = data.accessToken || null;
googleAuth.refreshToken = data.refreshToken || null;
googleAuth.expiresAt = data.expiresAt || 0;
const photos = await googleAuth.getPhotos(100, googleNextPage);
if (photos?.mediaItems?.length) {
setAllMedia((prev) => {
const combined = [...prev, ...photos.mediaItems];
return Array.from(new Map(combined.map((m) => [m.source_id || m.id || m.path, m])).values());
});
}
setGoogleNextPage(photos?.nextPageToken || null);
}
} catch (err) {
console.error('Error loading more photos:', err);
} finally {
setLoadingMore(false);
}
};
const getServiceIcon = (type) => ({ GOOGLE_PHOTOS: '📷', ICLOUD_PHOTOS: '🍎', NAS: '💾' }[type] || '📱'); const getServiceIcon = (type) => ({ GOOGLE_PHOTOS: '📷', ICLOUD_PHOTOS: '🍎', NAS: '💾' }[type] || '📱');
const getServiceName = (type) => ({ GOOGLE_PHOTOS: 'Google Photos', ICLOUD_PHOTOS: 'iCloud', NAS: 'NAS' }[type] || type); const getServiceName = (type) => ({ GOOGLE_PHOTOS: 'Google Photos', ICLOUD_PHOTOS: 'iCloud', NAS: 'NAS' }[type] || type);
@@ -127,7 +167,7 @@ const HomeScreen = ({ navigation, route }) => {
} }
const FilterChips = () => ( const FilterChips = () => (
<ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={styles.filterRow}> <ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={styles.filterRow} style={styles.filterContainer}>
<TouchableOpacity <TouchableOpacity
style={[styles.chip, { backgroundColor: selectedFilter === 'all' ? theme.chipActiveBg : theme.chipBg }]} style={[styles.chip, { backgroundColor: selectedFilter === 'all' ? theme.chipActiveBg : theme.chipBg }]}
onPress={() => setSelectedFilter('all')} onPress={() => setSelectedFilter('all')}
@@ -178,9 +218,15 @@ const HomeScreen = ({ navigation, route }) => {
<PhotoGrid <PhotoGrid
data={filteredMedia} data={filteredMedia}
onItemPress={(item) => { setSelectedMedia(item); setViewerVisible(true); }} onItemPress={(item) => { setSelectedMedia(item); setViewerVisible(true); }}
onEndReached={loadMorePhotos}
refreshControl={ refreshControl={
<RefreshControl refreshing={refreshing} onRefresh={() => { setRefreshing(true); loadAllMedia(); }} /> <RefreshControl refreshing={refreshing} onRefresh={() => { setRefreshing(true); loadAllMedia(); }} />
} }
ListFooterComponent={loadingMore ? (
<View style={{ padding: 16, alignItems: 'center' }}>
<ActivityIndicator size="small" color={theme.primary} />
</View>
) : null}
/> />
)} )}
@@ -199,10 +245,11 @@ const styles = StyleSheet.create({
centerContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', paddingHorizontal: 24 }, centerContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', paddingHorizontal: 24 },
loadingText: { marginTop: 12, fontSize: 14 }, loadingText: { marginTop: 12, fontSize: 14 },
// Filter chips // Filter chips
filterRow: { paddingHorizontal: 12, paddingVertical: 6, gap: 6 }, filterContainer: { maxHeight: 40 },
filterRow: { paddingHorizontal: 12, paddingVertical: 6, gap: 6, alignItems: 'center' },
chip: { chip: {
flexDirection: 'row', alignItems: 'center', paddingHorizontal: 10, paddingVertical: 4, flexDirection: 'row', alignItems: 'center', paddingHorizontal: 10, paddingVertical: 4,
borderRadius: 12, gap: 4, borderRadius: 16, gap: 4, height: 28,
}, },
chipIcon: { fontSize: 11 }, chipIcon: { fontSize: 11 },
chipText: { fontSize: 12, fontWeight: '500', color: '#3c4043' }, chipText: { fontSize: 12, fontWeight: '500', color: '#3c4043' },
+1
View File
@@ -65,6 +65,7 @@ const OnboardingScreen = ({ navigation, route }) => {
await DatabaseService.linkAccount(userId, 'GOOGLE_PHOTOS', { await DatabaseService.linkAccount(userId, 'GOOGLE_PHOTOS', {
accessToken: result.accessToken, accessToken: result.accessToken,
refreshToken: result.refreshToken || null, refreshToken: result.refreshToken || null,
expiresAt: googleAuth.expiresAt || Date.now() + 3600000,
email: result.email || 'google-user', email: result.email || 'google-user',
}); });
+1
View File
@@ -153,6 +153,7 @@ const SettingsScreen = ({ navigation, route }) => {
await DatabaseService.linkAccount(userId, 'GOOGLE_PHOTOS', { await DatabaseService.linkAccount(userId, 'GOOGLE_PHOTOS', {
accessToken: result.accessToken, accessToken: result.accessToken,
refreshToken: result.refreshToken || null, refreshToken: result.refreshToken || null,
expiresAt: gAuth.expiresAt || Date.now() + 3600000,
email: result.email || 'google-user', email: result.email || 'google-user',
}); });
Alert.alert('Success', 'Google Photos re-authenticated!'); Alert.alert('Success', 'Google Photos re-authenticated!');