mirror of
https://github.com/mudabbir-ahmad/Media-Aggregation-and-Sorting-System.git
synced 2026-10-07 19:40:20 +00:00
121 lines
4.3 KiB
JavaScript
121 lines
4.3 KiB
JavaScript
import React, { useState, useEffect } from 'react';
|
|
import {
|
|
StyleSheet, View, Text, TextInput, TouchableOpacity, ActivityIndicator,
|
|
} from 'react-native';
|
|
import { useTheme } from '../services/ThemeContext';
|
|
import DatabaseService from '../services/DatabaseService';
|
|
import PhotoGrid from '../components/PhotoGrid';
|
|
import MediaViewer from '../components/MediaViewer';
|
|
import SearchIcon from '../../assets/icons/search.svg';
|
|
|
|
const SearchScreen = ({ route }) => {
|
|
const userId = route?.params?.userId;
|
|
const { theme } = useTheme();
|
|
const [query, setQuery] = useState('');
|
|
const [results, setResults] = useState([]);
|
|
const [searching, setSearching] = useState(false);
|
|
const [selectedMedia, setSelectedMedia] = useState(null);
|
|
const [viewerVisible, setViewerVisible] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const timer = setTimeout(() => {
|
|
if (query.trim().length > 0) performSearch();
|
|
else setResults([]);
|
|
}, 300);
|
|
return () => clearTimeout(timer);
|
|
}, [query]);
|
|
|
|
const performSearch = async () => {
|
|
if (!userId) return;
|
|
setSearching(true);
|
|
try {
|
|
const media = await DatabaseService.searchMedia(userId, query.trim());
|
|
setResults(media);
|
|
} catch (err) {
|
|
console.error('Search error:', err);
|
|
} finally {
|
|
setSearching(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<View style={[styles.container, { backgroundColor: theme.background }]}>
|
|
<View style={[styles.searchBar, { backgroundColor: theme.searchBg }]}>
|
|
<SearchIcon width={16} height={16} color={theme.textSecondary} />
|
|
<TextInput
|
|
style={[styles.searchInput, { color: theme.text }]}
|
|
placeholder="Search photos and videos"
|
|
placeholderTextColor={theme.textTertiary}
|
|
value={query}
|
|
onChangeText={setQuery}
|
|
autoFocus
|
|
autoCapitalize="none"
|
|
autoCorrect={false}
|
|
/>
|
|
{query.length > 0 && (
|
|
<TouchableOpacity onPress={() => setQuery('')}>
|
|
<Text style={[styles.clearButton, { color: theme.textSecondary }]}>✕</Text>
|
|
</TouchableOpacity>
|
|
)}
|
|
</View>
|
|
|
|
{searching && (
|
|
<View style={styles.loadingContainer}>
|
|
<ActivityIndicator size="small" color={theme.primary} />
|
|
</View>
|
|
)}
|
|
|
|
{!searching && query.length > 0 && results.length === 0 && (
|
|
<View style={styles.emptyContainer}>
|
|
<SearchIcon width={48} height={48} color={theme.textTertiary} />
|
|
<Text style={[styles.emptyTitle, { color: theme.text }]}>No results</Text>
|
|
<Text style={[styles.emptyText, { color: theme.textSecondary }]}>Try different keywords</Text>
|
|
</View>
|
|
)}
|
|
|
|
{query.length === 0 && (
|
|
<View style={styles.emptyContainer}>
|
|
<SearchIcon width={48} height={48} color={theme.textTertiary} />
|
|
<Text style={[styles.emptyTitle, { color: theme.text }]}>Search your photos</Text>
|
|
<Text style={[styles.emptyText, { color: theme.textSecondary }]}>
|
|
Search by filename and indexed metadata
|
|
</Text>
|
|
</View>
|
|
)}
|
|
|
|
{results.length > 0 && (
|
|
<>
|
|
<Text style={[styles.resultCount, { color: theme.textSecondary }]}>
|
|
{results.length} result{results.length !== 1 ? 's' : ''}
|
|
</Text>
|
|
<PhotoGrid
|
|
data={results}
|
|
onItemPress={(item) => { setSelectedMedia(item); setViewerVisible(true); }}
|
|
/>
|
|
</>
|
|
)}
|
|
|
|
<MediaViewer visible={viewerVisible} media={selectedMedia} allMedia={results} onClose={() => setViewerVisible(false)} />
|
|
</View>
|
|
);
|
|
};
|
|
|
|
const styles = StyleSheet.create({
|
|
container: { flex: 1 },
|
|
searchBar: {
|
|
flexDirection: 'row', alignItems: 'center', marginHorizontal: 12,
|
|
marginTop: 48, marginBottom: 8, borderRadius: 24,
|
|
paddingHorizontal: 14, paddingVertical: 10, gap: 8,
|
|
},
|
|
searchInput: { flex: 1, fontSize: 15, padding: 0 },
|
|
clearButton: { fontSize: 16, padding: 4 },
|
|
loadingContainer: { padding: 20, alignItems: 'center' },
|
|
emptyContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', paddingHorizontal: 24 },
|
|
emptyTitle: { fontSize: 18, fontWeight: '600', marginBottom: 6 },
|
|
emptyText: { fontSize: 13, textAlign: 'center' },
|
|
resultCount: { paddingHorizontal: 16, paddingVertical: 8, fontSize: 13 },
|
|
});
|
|
|
|
export default SearchScreen;
|
|
|