mirror of
https://github.com/mudabbir-ahmad/Media-Aggregation-and-Sorting-System.git
synced 2026-10-08 03:40:20 +00:00
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:
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 |
@@ -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
@@ -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' },
|
||||||
|
|||||||
@@ -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',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -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!');
|
||||||
|
|||||||
Reference in new issue
Block a user