const ComponentFunction = function() { // @section:imports @depends:[] const React = require('react'); const { useState, useEffect, useContext, useMemo, useCallback } = React; const { View, Text, StyleSheet, ScrollView, TouchableOpacity, TextInput, Modal, Alert, Platform, StatusBar, ActivityIndicator, KeyboardAvoidingView, FlatList, Image } = require('react-native'); const { MaterialIcons } = require('@expo/vector-icons'); const { createBottomTabNavigator } = require('@react-navigation/bottom-tabs'); const { useSafeAreaInsets } = require('react-native-safe-area-context'); const { useQuery, useMutation } = require('platform-hooks'); // @end:imports // @section:constants @depends:[] var TAB_BAR_HEIGHT = Platform.OS === 'web' ? 56 : 49; var SCROLL_EXTRA_PADDING = 16; var WEB_TAB_BAR_PADDING = 90; var FAB_SPACING = 16; // @end:constants // @section:theme @depends:[] const storageStrategy = 'all-local'; const primaryColor = '#FF6B35'; const accentColor = '#FF8C42'; const backgroundColor = '#FFFFFF'; const cardColor = '#F8F9FA'; const textPrimary = '#1A1A1A'; const textSecondary = '#6B7280'; const designStyle = 'modern'; // @end:theme // @section:navigation-setup @depends:[] const Tab = createBottomTabNavigator(); // @end:navigation-setup // @section:ThemeContext @depends:[theme] const ThemeContext = React.createContext(); const ThemeProvider = function(props) { const darkModeState = useState(false); const darkMode = darkModeState[0]; const setDarkMode = darkModeState[1]; const lightTheme = useMemo(function() { return { colors: { primary: primaryColor, accent: accentColor, background: backgroundColor, card: cardColor, textPrimary: textPrimary, textSecondary: textSecondary, border: '#E5E7EB', success: '#10B981', error: '#EF4444', warning: '#F59E0B' } }; }, []); const darkTheme = useMemo(function() { return { colors: { primary: primaryColor, accent: accentColor, background: '#1F2937', card: '#374151', textPrimary: '#F9FAFB', textSecondary: '#D1D5DB', border: '#4B5563', success: '#10B981', error: '#EF4444', warning: '#F59E0B' } }; }, []); const theme = darkMode ? darkTheme : lightTheme; const toggleDarkMode = useCallback(function() { setDarkMode(function(prev) { return !prev; }); }, []); const value = useMemo(function() { return { theme: theme, darkMode: darkMode, toggleDarkMode: toggleDarkMode, designStyle: designStyle }; }, [theme, darkMode, toggleDarkMode]); return React.createElement(ThemeContext.Provider, { value: value }, props.children); }; const useTheme = function() { return useContext(ThemeContext); }; // @end:ThemeContext // @section:HomeScreen-state @depends:[ThemeContext] const useHomeScreenState = function() { const themeContext = useTheme(); const theme = themeContext.theme; const { data: videos, loading: videosLoading, refetch: refetchVideos } = useQuery('videos', {}, { column: 'createdAt', ascending: false }); const { data: collections, loading: collectionsLoading, refetch: refetchCollections } = useQuery('collections'); const showAddModalState = useState(false); const showAddModal = showAddModalState[0]; const setShowAddModal = showAddModalState[1]; const searchQueryState = useState(''); const searchQuery = searchQueryState[0]; const setSearchQuery = searchQueryState[1]; const selectedCollectionState = useState(null); const selectedCollection = selectedCollectionState[0]; const setSelectedCollection = selectedCollectionState[1]; const filteredVideos = useMemo(function() { if (!videos) return []; var filtered = videos; if (searchQuery) { filtered = filtered.filter(function(video) { return video.title && video.title.toLowerCase().indexOf(searchQuery.toLowerCase()) !== -1; }); } if (selectedCollection) { filtered = filtered.filter(function(video) { return video.collection_id === selectedCollection; }); } return filtered; }, [videos, searchQuery, selectedCollection]); return { theme: theme, videos: videos || [], collections: collections || [], filteredVideos: filteredVideos, videosLoading: videosLoading, collectionsLoading: collectionsLoading, showAddModal: showAddModal, setShowAddModal: setShowAddModal, searchQuery: searchQuery, setSearchQuery: setSearchQuery, selectedCollection: selectedCollection, setSelectedCollection: setSelectedCollection, refetchVideos: refetchVideos, refetchCollections: refetchCollections }; }; // @end:HomeScreen-state // @section:HomeScreen-handlers @depends:[HomeScreen-state] const homeScreenHandlers = { clearFilters: function(state) { state.setSearchQuery(''); state.setSelectedCollection(null); }, selectCollection: function(state, collectionId) { state.setSelectedCollection(collectionId === state.selectedCollection ? null : collectionId); } }; // @end:HomeScreen-handlers // @section:HomeScreen-VideoCard @depends:[styles] const renderVideoCard = function(video, theme, onPress) { var collection = video.collection_name || 'Uncategorized'; return React.createElement(TouchableOpacity, { style: [styles.videoCard, { backgroundColor: theme.colors.card, borderColor: theme.colors.border }], onPress: function() { onPress(video); }, componentId: 'video-card-' + video.id }, React.createElement(Image, { source: { uri: 'IMAGE:video-thumbnail-landscape' }, style: styles.videoThumbnail, componentId: 'video-thumbnail-' + video.id }), React.createElement(View, { style: styles.videoInfo, componentId: 'video-info-' + video.id }, React.createElement(Text, { style: [styles.videoTitle, { color: theme.colors.textPrimary }], numberOfLines: 2, componentId: 'video-title-' + video.id }, video.title || 'Untitled Video'), React.createElement(Text, { style: [styles.videoCollection, { color: theme.colors.accent }], numberOfLines: 1, componentId: 'video-collection-' + video.id }, collection), video.description ? React.createElement(Text, { style: [styles.videoDescription, { color: theme.colors.textSecondary }], numberOfLines: 2, componentId: 'video-description-' + video.id }, video.description) : null ) ); }; // @end:HomeScreen-VideoCard // @section:HomeScreen-CollectionChips @depends:[styles] const renderCollectionChips = function(collections, selectedCollection, theme, onSelectCollection) { return React.createElement(ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, style: { flexGrow: 0 }, contentContainerStyle: styles.collectionChipsContainer, componentId: 'collection-chips-scroll' }, collections.map(function(collection) { var isSelected = selectedCollection === collection.id; return React.createElement(TouchableOpacity, { key: collection.id, style: [ styles.collectionChip, { backgroundColor: isSelected ? theme.colors.primary : theme.colors.card, borderColor: isSelected ? theme.colors.primary : theme.colors.border } ], onPress: function() { onSelectCollection(collection.id); }, componentId: 'collection-chip-' + collection.id }, React.createElement(Text, { style: [ styles.collectionChipText, { color: isSelected ? '#FFFFFF' : theme.colors.textPrimary } ], componentId: 'collection-chip-text-' + collection.id }, collection.name || 'Untitled Collection') ); }) ); }; // @end:HomeScreen-CollectionChips // @section:HomeScreen-AddVideoModal @depends:[styles] const AddVideoModal = function(props) { const visible = props.visible; const onClose = props.onClose; const onSubmit = props.onSubmit; const theme = props.theme; const collections = props.collections; const insetsTop = props.insetsTop; const insetsBottom = props.insetsBottom; const titleState = useState(''); const title = titleState[0]; const setTitle = titleState[1]; const descriptionState = useState(''); const description = descriptionState[0]; const setDescription = descriptionState[1]; const sourceUrlState = useState(''); const sourceUrl = sourceUrlState[0]; const setSourceUrl = sourceUrlState[1]; const selectedCollectionState = useState(''); const selectedCollection = selectedCollectionState[0]; const setSelectedCollection = selectedCollectionState[1]; const handleSubmit = useCallback(function() { if (!title.trim()) { Platform.OS === 'web' ? window.alert('Please enter a video title') : Alert.alert('Error', 'Please enter a video title'); return; } onSubmit({ title: title.trim(), description: description.trim(), sourceUrl: sourceUrl.trim(), collection_id: selectedCollection || null, createdAt: new Date().toISOString() }); setTitle(''); setDescription(''); setSourceUrl(''); setSelectedCollection(''); }, [title, description, sourceUrl, selectedCollection, onSubmit]); return React.createElement(Modal, { visible: visible, animationType: 'slide', presentationStyle: 'pageSheet', transparent: true, onRequestClose: onClose }, React.createElement(View, { style: { flex: 1, justifyContent: 'center', backgroundColor: 'rgba(0,0,0,0.5)', marginTop: insetsTop }, componentId: 'add-video-modal-overlay' }, React.createElement(View, { style: { flex: 1, maxHeight: '90%', marginHorizontal: 20, backgroundColor: theme.colors.background, borderRadius: 16, padding: 20, paddingBottom: insetsBottom + 20 }, componentId: 'add-video-modal-content' }, React.createElement(View, { style: styles.modalHeader, componentId: 'add-video-modal-header' }, React.createElement(Text, { style: [styles.modalTitle, { color: theme.colors.textPrimary }], componentId: 'add-video-modal-title' }, 'Add Video'), React.createElement(TouchableOpacity, { onPress: onClose, style: styles.modalCloseButton, componentId: 'add-video-modal-close' }, React.createElement(MaterialIcons, { name: 'close', size: 24, color: theme.colors.textSecondary }) ) ), React.createElement(ScrollView, { style: { flex: 1 }, componentId: 'add-video-modal-scroll' }, React.createElement(View, { style: styles.formGroup, componentId: 'title-form-group' }, React.createElement(Text, { style: [styles.formLabel, { color: theme.colors.textPrimary }], componentId: 'title-label' }, 'Title *'), React.createElement(TextInput, { style: [styles.formInput, { backgroundColor: theme.colors.card, color: theme.colors.textPrimary, borderColor: theme.colors.border }], placeholder: 'Enter video title', placeholderTextColor: theme.colors.textSecondary, value: title, onChangeText: setTitle, componentId: 'title-input' }) ), React.createElement(View, { style: styles.formGroup, componentId: 'description-form-group' }, React.createElement(Text, { style: [styles.formLabel, { color: theme.colors.textPrimary }], componentId: 'description-label' }, 'Description'), React.createElement(TextInput, { style: [styles.formInput, styles.formTextArea, { backgroundColor: theme.colors.card, color: theme.colors.textPrimary, borderColor: theme.colors.border }], placeholder: 'Enter video description', placeholderTextColor: theme.colors.textSecondary, value: description, onChangeText: setDescription, multiline: true, numberOfLines: 3, componentId: 'description-input' }) ), React.createElement(View, { style: styles.formGroup, componentId: 'source-form-group' }, React.createElement(Text, { style: [styles.formLabel, { color: theme.colors.textPrimary }], componentId: 'source-label' }, 'Source URL'), React.createElement(TextInput, { style: [styles.formInput, { backgroundColor: theme.colors.card, color: theme.colors.textPrimary, borderColor: theme.colors.border }], placeholder: 'Enter video URL or file path', placeholderTextColor: theme.colors.textSecondary, value: sourceUrl, onChangeText: setSourceUrl, keyboardType: 'url', componentId: 'source-input' }) ), React.createElement(View, { style: styles.formGroup, componentId: 'collection-form-group' }, React.createElement(Text, { style: [styles.formLabel, { color: theme.colors.textPrimary }], componentId: 'collection-label' }, 'Collection'), React.createElement(ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, style: { flexGrow: 0 }, contentContainerStyle: styles.collectionSelectContainer, componentId: 'collection-select-scroll' }, React.createElement(TouchableOpacity, { style: [ styles.collectionSelectChip, { backgroundColor: !selectedCollection ? theme.colors.primary : theme.colors.card, borderColor: !selectedCollection ? theme.colors.primary : theme.colors.border } ], onPress: function() { setSelectedCollection(''); }, componentId: 'collection-select-none' }, React.createElement(Text, { style: [ styles.collectionSelectChipText, { color: !selectedCollection ? '#FFFFFF' : theme.colors.textPrimary } ], componentId: 'collection-select-none-text' }, 'None') ), collections.map(function(collection) { var isSelected = selectedCollection === collection.id; return React.createElement(TouchableOpacity, { key: collection.id, style: [ styles.collectionSelectChip, { backgroundColor: isSelected ? theme.colors.primary : theme.colors.card, borderColor: isSelected ? theme.colors.primary : theme.colors.border } ], onPress: function() { setSelectedCollection(collection.id); }, componentId: 'collection-select-' + collection.id }, React.createElement(Text, { style: [ styles.collectionSelectChipText, { color: isSelected ? '#FFFFFF' : theme.colors.textPrimary } ], componentId: 'collection-select-text-' + collection.id }, collection.name || 'Untitled') ); }) ) ) ), React.createElement(View, { style: styles.modalFooter, componentId: 'add-video-modal-footer' }, React.createElement(TouchableOpacity, { style: [styles.modalButton, { backgroundColor: theme.colors.border }], onPress: onClose, componentId: 'add-video-cancel-button' }, React.createElement(Text, { style: [styles.modalButtonText, { color: theme.colors.textSecondary }], componentId: 'add-video-cancel-text' }, 'Cancel') ), React.createElement(TouchableOpacity, { style: [styles.modalButton, { backgroundColor: theme.colors.primary }], onPress: handleSubmit, componentId: 'add-video-submit-button' }, React.createElement(Text, { style: [styles.modalButtonText, { color: '#FFFFFF' }], componentId: 'add-video-submit-text' }, 'Add Video') ) ) ) ) ); }; // @end:HomeScreen-AddVideoModal // @section:HomeScreen-FAB @depends:[styles] const renderHomeScreenFAB = function(theme, onPress, bottomOffset) { return React.createElement(TouchableOpacity, { style: [styles.fab, { backgroundColor: theme.colors.primary, bottom: bottomOffset }], onPress: onPress, componentId: 'home-fab-add-video' }, React.createElement(MaterialIcons, { name: 'add', size: 28, color: '#FFFFFF' }) ); }; // @end:HomeScreen-FAB // @section:HomeScreen @depends:[HomeScreen-state,HomeScreen-handlers,HomeScreen-VideoCard,HomeScreen-CollectionChips,HomeScreen-AddVideoModal,HomeScreen-FAB,styles] const HomeScreen = function() { const state = useHomeScreenState(); const handlers = homeScreenHandlers; const insets = useSafeAreaInsets(); const { mutate: insertVideo } = useMutation('videos', 'insert'); const scrollBottomPadding = Platform.OS === 'web' ? WEB_TAB_BAR_PADDING : (TAB_BAR_HEIGHT + insets.bottom + SCROLL_EXTRA_PADDING); const scrollTopPadding = insets.top; const fabBottom = Platform.OS === 'web' ? WEB_TAB_BAR_PADDING : (TAB_BAR_HEIGHT + insets.bottom + FAB_SPACING); const handleAddVideo = useCallback(function(videoData) { insertVideo(videoData) .then(function() { state.refetchVideos(); state.setShowAddModal(false); Platform.OS === 'web' ? window.alert('Video added successfully!') : Alert.alert('Success', 'Video added successfully!'); }) .catch(function(error) { Platform.OS === 'web' ? window.alert(error.message) : Alert.alert('Error', error.message); }); }, [insertVideo, state]); const handleVideoPress = useCallback(function(video) { var message = 'Title: ' + video.title + '\n' + 'Collection: ' + (video.collection_name || 'Uncategorized') + (video.description ? '\n\nDescription: ' + video.description : '') + (video.sourceUrl ? '\n\nSource: ' + video.sourceUrl : ''); Platform.OS === 'web' ? window.alert(message) : Alert.alert('Video Details', message); }, []); if (state.videosLoading || state.collectionsLoading) { return React.createElement(View, { style: [styles.loadingContainer, { backgroundColor: state.theme.colors.background }], componentId: 'home-loading' }, React.createElement(ActivityIndicator, { size: 'large', color: state.theme.colors.primary, componentId: 'home-loading-indicator' }), React.createElement(Text, { style: [styles.loadingText, { color: state.theme.colors.textSecondary }], componentId: 'home-loading-text' }, 'Loading your video library...') ); } return React.createElement(View, { style: [styles.container, { backgroundColor: state.theme.colors.background }], componentId: 'home-screen' }, React.createElement(ScrollView, { style: { flex: 1 }, contentContainerStyle: { paddingTop: scrollTopPadding, paddingBottom: scrollBottomPadding }, showsVerticalScrollIndicator: false, componentId: 'home-scroll' }, React.createElement(View, { style: styles.header, componentId: 'home-header' }, React.createElement(View, { style: styles.headerTop, componentId: 'home-header-top' }, React.createElement(View, { style: styles.headerTitleContainer, componentId: 'home-header-title-container' }, React.createElement(Text, { style: [styles.headerTitle, { color: state.theme.colors.textPrimary }], componentId: 'home-header-title' }, 'Planet'), React.createElement(Text, { style: [styles.headerSubtitle, { color: state.theme.colors.textSecondary }], componentId: 'home-header-subtitle' }, 'Your Personal Video Library') ) ), React.createElement(View, { style: styles.searchContainer, componentId: 'home-search-container' }, React.createElement(View, { style: [styles.searchInputContainer, { backgroundColor: state.theme.colors.card, borderColor: state.theme.colors.border }], componentId: 'home-search-input-container' }, React.createElement(MaterialIcons, { name: 'search', size: 20, color: state.theme.colors.textSecondary }), React.createElement(TextInput, { style: [styles.searchInput, { color: state.theme.colors.textPrimary }], placeholder: 'Search videos...', placeholderTextColor: state.theme.colors.textSecondary, value: state.searchQuery, onChangeText: state.setSearchQuery, componentId: 'home-search-input' }) ), (state.searchQuery || state.selectedCollection) ? React.createElement(TouchableOpacity, { style: [styles.clearFiltersButton, { backgroundColor: state.theme.colors.accent }], onPress: function() { handlers.clearFilters(state); }, componentId: 'home-clear-filters' }, React.createElement(MaterialIcons, { name: 'clear', size: 16, color: '#FFFFFF' }) ) : null ) ), state.collections.length > 0 ? React.createElement(View, { style: styles.collectionsSection, componentId: 'home-collections-section' }, React.createElement(Text, { style: [styles.sectionTitle, { color: state.theme.colors.textPrimary }], componentId: 'home-collections-title' }, 'Collections'), renderCollectionChips(state.collections, state.selectedCollection, state.theme, function(collectionId) { handlers.selectCollection(state, collectionId); }) ) : null, React.createElement(View, { style: styles.videosSection, componentId: 'home-videos-section' }, React.createElement(Text, { style: [styles.sectionTitle, { color: state.theme.colors.textPrimary }], componentId: 'home-videos-title' }, state.filteredVideos.length > 0 ? ('Videos (' + state.filteredVideos.length + ')') : 'No Videos Found'), state.filteredVideos.length > 0 ? state.filteredVideos.map(function(video) { return renderVideoCard(video, state.theme, handleVideoPress); }) : React.createElement(View, { style: styles.emptyState, componentId: 'home-empty-state' }, React.createElement(MaterialIcons, { name: 'video-library', size: 64, color: state.theme.colors.textSecondary }), React.createElement(Text, { style: [styles.emptyStateTitle, { color: state.theme.colors.textPrimary }], componentId: 'home-empty-state-title' }, state.searchQuery || state.selectedCollection ? 'No videos match your filters' : 'No videos in your library'), React.createElement(Text, { style: [styles.emptyStateSubtitle, { color: state.theme.colors.textSecondary }], componentId: 'home-empty-state-subtitle' }, state.searchQuery || state.selectedCollection ? 'Try adjusting your search or filters' : 'Tap the + button to add your first video') ) ) ), renderHomeScreenFAB(state.theme, function() { state.setShowAddModal(true); }, fabBottom), React.createElement(AddVideoModal, { visible: state.showAddModal, onClose: function() { state.setShowAddModal(false); }, onSubmit: handleAddVideo, theme: state.theme, collections: state.collections, insetsTop: insets.top, insetsBottom: insets.bottom }) ); }; // @end:HomeScreen // @section:PlaylistsScreen-state @depends:[ThemeContext] const usePlaylistsScreenState = function() { const themeContext = useTheme(); const theme = themeContext.theme; const { data: playlists, loading: playlistsLoading, refetch: refetchPlaylists } = useQuery('playlists', {}, { column: 'createdAt', ascending: false }); const { data: videos, loading: videosLoading } = useQuery('videos'); const showCreateModalState = useState(false); const showCreateModal = showCreateModalState[0]; const setShowCreateModal = showCreateModalState[1]; return { theme: theme, playlists: playlists || [], videos: videos || [], playlistsLoading: playlistsLoading, videosLoading: videosLoading, showCreateModal: showCreateModal, setShowCreateModal: setShowCreateModal, refetchPlaylists: refetchPlaylists }; }; // @end:PlaylistsScreen-state // @section:PlaylistsScreen-CreateModal @depends:[styles] const CreatePlaylistModal = function(props) { const visible = props.visible; const onClose = props.onClose; const onSubmit = props.onSubmit; const theme = props.theme; const videos = props.videos; const insetsTop = props.insetsTop; const insetsBottom = props.insetsBottom; const nameState = useState(''); const name = nameState[0]; const setName = nameState[1]; const descriptionState = useState(''); const description = descriptionState[0]; const setDescription = descriptionState[1]; const selectedVideosState = useState([]); const selectedVideos = selectedVideosState[0]; const setSelectedVideos = selectedVideosState[1]; const toggleVideoSelection = useCallback(function(videoId) { setSelectedVideos(function(prev) { var index = prev.indexOf(videoId); if (index > -1) { return prev.filter(function(id) { return id !== videoId; }); } else { return prev.concat([videoId]); } }); }, []); const handleSubmit = useCallback(function() { if (!name.trim()) { Platform.OS === 'web' ? window.alert('Please enter a playlist name') : Alert.alert('Error', 'Please enter a playlist name'); return; } onSubmit({ name: name.trim(), description: description.trim(), videoIds: selectedVideos, createdAt: new Date().toISOString() }); setName(''); setDescription(''); setSelectedVideos([]); }, [name, description, selectedVideos, onSubmit]); return React.createElement(Modal, { visible: visible, animationType: 'slide', presentationStyle: 'pageSheet', transparent: true, onRequestClose: onClose }, React.createElement(View, { style: { flex: 1, justifyContent: 'center', backgroundColor: 'rgba(0,0,0,0.5)', marginTop: insetsTop }, componentId: 'create-playlist-modal-overlay' }, React.createElement(View, { style: { flex: 1, maxHeight: '90%', marginHorizontal: 20, backgroundColor: theme.colors.background, borderRadius: 16, padding: 20, paddingBottom: insetsBottom + 20 }, componentId: 'create-playlist-modal-content' }, React.createElement(View, { style: styles.modalHeader, componentId: 'create-playlist-modal-header' }, React.createElement(Text, { style: [styles.modalTitle, { color: theme.colors.textPrimary }], componentId: 'create-playlist-modal-title' }, 'Create Playlist'), React.createElement(TouchableOpacity, { onPress: onClose, style: styles.modalCloseButton, componentId: 'create-playlist-modal-close' }, React.createElement(MaterialIcons, { name: 'close', size: 24, color: theme.colors.textSecondary }) ) ), React.createElement(ScrollView, { style: { flex: 1 }, componentId: 'create-playlist-modal-scroll' }, React.createElement(View, { style: styles.formGroup, componentId: 'playlist-name-form-group' }, React.createElement(Text, { style: [styles.formLabel, { color: theme.colors.textPrimary }], componentId: 'playlist-name-label' }, 'Name *'), React.createElement(TextInput, { style: [styles.formInput, { backgroundColor: theme.colors.card, color: theme.colors.textPrimary, borderColor: theme.colors.border }], placeholder: 'Enter playlist name', placeholderTextColor: theme.colors.textSecondary, value: name, onChangeText: setName, componentId: 'playlist-name-input' }) ), React.createElement(View, { style: styles.formGroup, componentId: 'playlist-description-form-group' }, React.createElement(Text, { style: [styles.formLabel, { color: theme.colors.textPrimary }], componentId: 'playlist-description-label' }, 'Description'), React.createElement(TextInput, { style: [styles.formInput, styles.formTextArea, { backgroundColor: theme.colors.card, color: theme.colors.textPrimary, borderColor: theme.colors.border }], placeholder: 'Enter playlist description', placeholderTextColor: theme.colors.textSecondary, value: description, onChangeText: setDescription, multiline: true, numberOfLines: 3, componentId: 'playlist-description-input' }) ), videos.length > 0 ? React.createElement(View, { style: styles.formGroup, componentId: 'playlist-videos-form-group' }, React.createElement(Text, { style: [styles.formLabel, { color: theme.colors.textPrimary }], componentId: 'playlist-videos-label' }, 'Videos (' + selectedVideos.length + ' selected)'), videos.map(function(video) { var isSelected = selectedVideos.indexOf(video.id) > -1; return React.createElement(TouchableOpacity, { key: video.id, style: [ styles.videoSelectItem, { backgroundColor: isSelected ? theme.colors.primary + '20' : theme.colors.card, borderColor: isSelected ? theme.colors.primary : theme.colors.border } ], onPress: function() { toggleVideoSelection(video.id); }, componentId: 'video-select-' + video.id }, React.createElement(View, { style: styles.videoSelectInfo, componentId: 'video-select-info-' + video.id }, React.createElement(Text, { style: [styles.videoSelectTitle, { color: theme.colors.textPrimary }], numberOfLines: 1, componentId: 'video-select-title-' + video.id }, video.title || 'Untitled Video'), video.description ? React.createElement(Text, { style: [styles.videoSelectDescription, { color: theme.colors.textSecondary }], numberOfLines: 1, componentId: 'video-select-description-' + video.id }, video.description) : null ), React.createElement(MaterialIcons, { name: isSelected ? 'check-circle' : 'radio-button-unchecked', size: 24, color: isSelected ? theme.colors.primary : theme.colors.textSecondary }) ); }) ) : React.createElement(Text, { style: [styles.emptyMessage, { color: theme.colors.textSecondary }], componentId: 'playlist-no-videos' }, 'No videos available to add to playlist') ), React.createElement(View, { style: styles.modalFooter, componentId: 'create-playlist-modal-footer' }, React.createElement(TouchableOpacity, { style: [styles.modalButton, { backgroundColor: theme.colors.border }], onPress: onClose, componentId: 'create-playlist-cancel-button' }, React.createElement(Text, { style: [styles.modalButtonText, { color: theme.colors.textSecondary }], componentId: 'create-playlist-cancel-text' }, 'Cancel') ), React.createElement(TouchableOpacity, { style: [styles.modalButton, { backgroundColor: theme.colors.primary }], onPress: handleSubmit, componentId: 'create-playlist-submit-button' }, React.createElement(Text, { style: [styles.modalButtonText, { color: '#FFFFFF' }], componentId: 'create-playlist-submit-text' }, 'Create Playlist') ) ) ) ) ); }; // @end:PlaylistsScreen-CreateModal // @section:PlaylistsScreen-PlaylistCard @depends:[styles] const renderPlaylistCard = function(playlist, theme, onPress) { var videoCount = (playlist.videoIds && playlist.videoIds.length) || 0; return React.createElement(TouchableOpacity, { style: [styles.playlistCard, { backgroundColor: theme.colors.card, borderColor: theme.colors.border }], onPress: function() { onPress(playlist); }, componentId: 'playlist-card-' + playlist.id }, React.createElement(View, { style: styles.playlistHeader, componentId: 'playlist-header-' + playlist.id }, React.createElement(MaterialIcons, { name: 'playlist-play', size: 40, color: theme.colors.primary }), React.createElement(View, { style: styles.playlistInfo, componentId: 'playlist-info-' + playlist.id }, React.createElement(Text, { style: [styles.playlistTitle, { color: theme.colors.textPrimary }], numberOfLines: 2, componentId: 'playlist-title-' + playlist.id }, playlist.name || 'Untitled Playlist'), React.createElement(Text, { style: [styles.playlistVideoCount, { color: theme.colors.accent }], componentId: 'playlist-video-count-' + playlist.id }, videoCount + ' video' + (videoCount !== 1 ? 's' : '')) ) ), playlist.description ? React.createElement(Text, { style: [styles.playlistDescription, { color: theme.colors.textSecondary }], numberOfLines: 2, componentId: 'playlist-description-' + playlist.id }, playlist.description) : null ); }; // @end:PlaylistsScreen-PlaylistCard // @section:PlaylistsScreen @depends:[PlaylistsScreen-state,PlaylistsScreen-CreateModal,PlaylistsScreen-PlaylistCard,styles] const PlaylistsScreen = function() { const state = usePlaylistsScreenState(); const insets = useSafeAreaInsets(); const { mutate: insertPlaylist } = useMutation('playlists', 'insert'); const scrollBottomPadding = Platform.OS === 'web' ? WEB_TAB_BAR_PADDING : (TAB_BAR_HEIGHT + insets.bottom + SCROLL_EXTRA_PADDING); const scrollTopPadding = insets.top; const fabBottom = Platform.OS === 'web' ? WEB_TAB_BAR_PADDING : (TAB_BAR_HEIGHT + insets.bottom + FAB_SPACING); const handleCreatePlaylist = useCallback(function(playlistData) { insertPlaylist(playlistData) .then(function() { state.refetchPlaylists(); state.setShowCreateModal(false); Platform.OS === 'web' ? window.alert('Playlist created successfully!') : Alert.alert('Success', 'Playlist created successfully!'); }) .catch(function(error) { Platform.OS === 'web' ? window.alert(error.message) : Alert.alert('Error', error.message); }); }, [insertPlaylist, state]); const handlePlaylistPress = useCallback(function(playlist) { var videoCount = (playlist.videoIds && playlist.videoIds.length) || 0; var message = 'Name: ' + playlist.name + '\n' + 'Videos: ' + videoCount + (playlist.description ? '\n\nDescription: ' + playlist.description : ''); Platform.OS === 'web' ? window.alert(message) : Alert.alert('Playlist Details', message); }, []); if (state.playlistsLoading) { return React.createElement(View, { style: [styles.loadingContainer, { backgroundColor: state.theme.colors.background }], componentId: 'playlists-loading' }, React.createElement(ActivityIndicator, { size: 'large', color: state.theme.colors.primary, componentId: 'playlists-loading-indicator' }), React.createElement(Text, { style: [styles.loadingText, { color: state.theme.colors.textSecondary }], componentId: 'playlists-loading-text' }, 'Loading your playlists...') ); } return React.createElement(View, { style: [styles.container, { backgroundColor: state.theme.colors.background }], componentId: 'playlists-screen' }, React.createElement(ScrollView, { style: { flex: 1 }, contentContainerStyle: { paddingTop: scrollTopPadding, paddingBottom: scrollBottomPadding }, showsVerticalScrollIndicator: false, componentId: 'playlists-scroll' }, React.createElement(View, { style: styles.header, componentId: 'playlists-header' }, React.createElement(Text, { style: [styles.headerTitle, { color: state.theme.colors.textPrimary }], componentId: 'playlists-header-title' }, 'Playlists'), React.createElement(Text, { style: [styles.headerSubtitle, { color: state.theme.colors.textSecondary }], componentId: 'playlists-header-subtitle' }, 'Create and manage your video collections') ), React.createElement(View, { style: styles.playlistsSection, componentId: 'playlists-section' }, state.playlists.length > 0 ? state.playlists.map(function(playlist) { return renderPlaylistCard(playlist, state.theme, handlePlaylistPress); }) : React.createElement(View, { style: styles.emptyState, componentId: 'playlists-empty-state' }, React.createElement(MaterialIcons, { name: 'playlist-add', size: 64, color: state.theme.colors.textSecondary }), React.createElement(Text, { style: [styles.emptyStateTitle, { color: state.theme.colors.textPrimary }], componentId: 'playlists-empty-state-title' }, 'No playlists yet'), React.createElement(Text, { style: [styles.emptyStateSubtitle, { color: state.theme.colors.textSecondary }], componentId: 'playlists-empty-state-subtitle' }, 'Create your first playlist to organize your videos') ) ) ), renderHomeScreenFAB(state.theme, function() { state.setShowCreateModal(true); }, fabBottom), React.createElement(CreatePlaylistModal, { visible: state.showCreateModal, onClose: function() { state.setShowCreateModal(false); }, onSubmit: handleCreatePlaylist, theme: state.theme, videos: state.videos, insetsTop: insets.top, insetsBottom: insets.bottom }) ); }; // @end:PlaylistsScreen // @section:CollectionsScreen-state @depends:[ThemeContext] const useCollectionsScreenState = function() { const themeContext = useTheme(); const theme = themeContext.theme; const { data: collections, loading: collectionsLoading, refetch: refetchCollections } = useQuery('collections', {}, { column: 'name', ascending: true }); const { data: videos, loading: videosLoading } = useQuery('videos'); const showCreateModalState = useState(false); const showCreateModal = showCreateModalState[0]; const setShowCreateModal = showCreateModalState[1]; const collectionsWithCounts = useMemo(function() { if (!collections || !videos) return []; return collections.map(function(collection) { var videoCount = videos.filter(function(video) { return video.collection_id === collection.id; }).length; return Object.assign({}, collection, { videoCount: videoCount }); }); }, [collections, videos]); return { theme: theme, collections: collectionsWithCounts, collectionsLoading: collectionsLoading, videosLoading: videosLoading, showCreateModal: showCreateModal, setShowCreateModal: setShowCreateModal, refetchCollections: refetchCollections }; }; // @end:CollectionsScreen-state // @section:CollectionsScreen-CreateModal @depends:[styles] const CreateCollectionModal = function(props) { const visible = props.visible; const onClose = props.onClose; const onSubmit = props.onSubmit; const theme = props.theme; const insetsTop = props.insetsTop; const insetsBottom = props.insetsBottom; const nameState = useState(''); const name = nameState[0]; const setName = nameState[1]; const descriptionState = useState(''); const description = descriptionState[0]; const setDescription = descriptionState[1]; const handleSubmit = useCallback(function() { if (!name.trim()) { Platform.OS === 'web' ? window.alert('Please enter a collection name') : Alert.alert('Error', 'Please enter a collection name'); return; } onSubmit({ name: name.trim(), description: description.trim(), createdAt: new Date().toISOString() }); setName(''); setDescription(''); }, [name, description, onSubmit]); return React.createElement(Modal, { visible: visible, animationType: 'slide', presentationStyle: 'pageSheet', transparent: true, onRequestClose: onClose }, React.createElement(View, { style: { flex: 1, justifyContent: 'center', backgroundColor: 'rgba(0,0,0,0.5)', marginTop: insetsTop }, componentId: 'create-collection-modal-overlay' }, React.createElement(View, { style: { flex: 1, maxHeight: '90%', marginHorizontal: 20, backgroundColor: theme.colors.background, borderRadius: 16, padding: 20, paddingBottom: insetsBottom + 20 }, componentId: 'create-collection-modal-content' }, React.createElement(View, { style: styles.modalHeader, componentId: 'create-collection-modal-header' }, React.createElement(Text, { style: [styles.modalTitle, { color: theme.colors.textPrimary }], componentId: 'create-collection-modal-title' }, 'Create Collection'), React.createElement(TouchableOpacity, { onPress: onClose, style: styles.modalCloseButton, componentId: 'create-collection-modal-close' }, React.createElement(MaterialIcons, { name: 'close', size: 24, color: theme.colors.textSecondary }) ) ), React.createElement(ScrollView, { style: { flex: 1 }, componentId: 'create-collection-modal-scroll' }, React.createElement(View, { style: styles.formGroup, componentId: 'collection-name-form-group' }, React.createElement(Text, { style: [styles.formLabel, { color: theme.colors.textPrimary }], componentId: 'collection-name-label' }, 'Name *'), React.createElement(TextInput, { style: [styles.formInput, { backgroundColor: theme.colors.card, color: theme.colors.textPrimary, borderColor: theme.colors.border }], placeholder: 'Enter collection name', placeholderTextColor: theme.colors.textSecondary, value: name, onChangeText: setName, componentId: 'collection-name-input' }) ), React.createElement(View, { style: styles.formGroup, componentId: 'collection-description-form-group' }, React.createElement(Text, { style: [styles.formLabel, { color: theme.colors.textPrimary }], componentId: 'collection-description-label' }, 'Description'), React.createElement(TextInput, { style: [styles.formInput, styles.formTextArea, { backgroundColor: theme.colors.card, color: theme.colors.textPrimary, borderColor: theme.colors.border }], placeholder: 'Enter collection description', placeholderTextColor: theme.colors.textSecondary, value: description, onChangeText: setDescription, multiline: true, numberOfLines: 3, componentId: 'collection-description-input' }) ) ), React.createElement(View, { style: styles.modalFooter, componentId: 'create-collection-modal-footer' }, React.createElement(TouchableOpacity, { style: [styles.modalButton, { backgroundColor: theme.colors.border }], onPress: onClose, componentId: 'create-collection-cancel-button' }, React.createElement(Text, { style: [styles.modalButtonText, { color: theme.colors.textSecondary }], componentId: 'create-collection-cancel-text' }, 'Cancel') ), React.createElement(TouchableOpacity, { style: [styles.modalButton, { backgroundColor: theme.colors.primary }], onPress: handleSubmit, componentId: 'create-collection-submit-button' }, React.createElement(Text, { style: [styles.modalButtonText, { color: '#FFFFFF' }], componentId: 'create-collection-submit-text' }, 'Create Collection') ) ) ) ) ); }; // @end:CollectionsScreen-CreateModal // @section:CollectionsScreen-CollectionCard @depends:[styles] const renderCollectionCard = function(collection, theme, onPress) { return React.createElement(TouchableOpacity, { style: [styles.collectionCard, { backgroundColor: theme.colors.card, borderColor: theme.colors.border }], onPress: function() { onPress(collection); }, componentId: 'collection-card-' + collection.id }, React.createElement(View, { style: styles.collectionHeader, componentId: 'collection-header-' + collection.id }, React.createElement(MaterialIcons, { name: 'folder', size: 40, color: theme.colors.primary }), React.createElement(View, { style: styles.collectionInfo, componentId: 'collection-info-' + collection.id }, React.createElement(Text, { style: [styles.collectionTitle, { color: theme.colors.textPrimary }], numberOfLines: 2, componentId: 'collection-title-' + collection.id }, collection.name || 'Untitled Collection'), React.createElement(Text, { style: [styles.collectionVideoCount, { color: theme.colors.accent }], componentId: 'collection-video-count-' + collection.id }, collection.videoCount + ' video' + (collection.videoCount !== 1 ? 's' : '')) ) ), collection.description ? React.createElement(Text, { style: [styles.collectionDescription, { color: theme.colors.textSecondary }], numberOfLines: 2, componentId: 'collection-description-' + collection.id }, collection.description) : null ); }; // @end:CollectionsScreen-CollectionCard // @section:CollectionsScreen @depends:[CollectionsScreen-state,CollectionsScreen-CreateModal,CollectionsScreen-CollectionCard,styles] const CollectionsScreen = function() { const state = useCollectionsScreenState(); const insets = useSafeAreaInsets(); const { mutate: insertCollection } = useMutation('collections', 'insert'); const scrollBottomPadding = Platform.OS === 'web' ? WEB_TAB_BAR_PADDING : (TAB_BAR_HEIGHT + insets.bottom + SCROLL_EXTRA_PADDING); const scrollTopPadding = insets.top; const fabBottom = Platform.OS === 'web' ? WEB_TAB_BAR_PADDING : (TAB_BAR_HEIGHT + insets.bottom + FAB_SPACING); const handleCreateCollection = useCallback(function(collectionData) { insertCollection(collectionData) .then(function() { state.refetchCollections(); state.setShowCreateModal(false); Platform.OS === 'web' ? window.alert('Collection created successfully!') : Alert.alert('Success', 'Collection created successfully!'); }) .catch(function(error) { Platform.OS === 'web' ? window.alert(error.message) : Alert.alert('Error', error.message); }); }, [insertCollection, state]); const handleCollectionPress = useCallback(function(collection) { var message = 'Name: ' + collection.name + '\n' + 'Videos: ' + collection.videoCount + (collection.description ? '\n\nDescription: ' + collection.description : ''); Platform.OS === 'web' ? window.alert(message) : Alert.alert('Collection Details', message); }, []); if (state.collectionsLoading) { return React.createElement(View, { style: [styles.loadingContainer, { backgroundColor: state.theme.colors.background }], componentId: 'collections-loading' }, React.createElement(ActivityIndicator, { size: 'large', color: state.theme.colors.primary, componentId: 'collections-loading-indicator' }), React.createElement(Text, { style: [styles.loadingText, { color: state.theme.colors.textSecondary }], componentId: 'collections-loading-text' }, 'Loading your collections...') ); } return React.createElement(View, { style: [styles.container, { backgroundColor: state.theme.colors.background }], componentId: 'collections-screen' }, React.createElement(ScrollView, { style: { flex: 1 }, contentContainerStyle: { paddingTop: scrollTopPadding, paddingBottom: scrollBottomPadding }, showsVerticalScrollIndicator: false, componentId: 'collections-scroll' }, React.createElement(View, { style: styles.header, componentId: 'collections-header' }, React.createElement(Text, { style: [styles.headerTitle, { color: state.theme.colors.textPrimary }], componentId: 'collections-header-title' }, 'Collections'), React.createElement(Text, { style: [styles.headerSubtitle, { color: state.theme.colors.textSecondary }], componentId: 'collections-header-subtitle' }, 'Organize your videos by category') ), React.createElement(View, { style: styles.collectionsSection, componentId: 'collections-list-section' }, state.collections.length > 0 ? state.collections.map(function(collection) { return renderCollectionCard(collection, state.theme, handleCollectionPress); }) : React.createElement(View, { style: styles.emptyState, componentId: 'collections-empty-state' }, React.createElement(MaterialIcons, { name: 'create-new-folder', size: 64, color: state.theme.colors.textSecondary }), React.createElement(Text, { style: [styles.emptyStateTitle, { color: state.theme.colors.textPrimary }], componentId: 'collections-empty-state-title' }, 'No collections yet'), React.createElement(Text, { style: [styles.emptyStateSubtitle, { color: state.theme.colors.textSecondary }], componentId: 'collections-empty-state-subtitle' }, 'Create your first collection to organize your videos') ) ) ), renderHomeScreenFAB(state.theme, function() { state.setShowCreateModal(true); }, fabBottom), React.createElement(CreateCollectionModal, { visible: state.showCreateModal, onClose: function() { state.setShowCreateModal(false); }, onSubmit: handleCreateCollection, theme: state.theme, insetsTop: insets.top, insetsBottom: insets.bottom }) ); }; // @end:CollectionsScreen // @section:TabNavigator @depends:[HomeScreen,PlaylistsScreen,CollectionsScreen,navigation-setup,styles] const TabNavigator = function() { const themeContext = useTheme(); const theme = themeContext.theme; const insets = useSafeAreaInsets(); return React.createElement(Tab.Navigator, { screenOptions: { headerShown: false, tabBarActiveTintColor: theme.colors.primary, tabBarInactiveTintColor: theme.colors.textSecondary, tabBarStyle: { position: 'absolute', bottom: 0, height: TAB_BAR_HEIGHT + insets.bottom, backgroundColor: theme.colors.background, borderTopWidth: 0, elevation: 8, shadowColor: '#000000', shadowOffset: { width: 0, height: -2 }, shadowOpacity: 0.1, shadowRadius: 8 }, tabBarItemStyle: { padding: 0 }, tabBarLabelStyle: { fontSize: 12, fontWeight: '600', marginBottom: Platform.OS === 'ios' ? 0 : 8 } } }, React.createElement(Tab.Screen, { name: 'Home', component: HomeScreen, options: { tabBarIcon: function(props) { return React.createElement(MaterialIcons, { name: 'home', size: 24, color: props.color }); } } }), React.createElement(Tab.Screen, { name: 'Playlists', component: PlaylistsScreen, options: { tabBarIcon: function(props) { return React.createElement(MaterialIcons, { name: 'playlist-play', size: 24, color: props.color }); } } }), React.createElement(Tab.Screen, { name: 'Collections', component: CollectionsScreen, options: { tabBarIcon: function(props) { return React.createElement(MaterialIcons, { name: 'folder', size: 24, color: props.color }); } } }) ); }; // @end:TabNavigator // @section:styles @depends:[theme] const styles = StyleSheet.create({ container: { flex: 1 }, loadingContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20 }, loadingText: { fontSize: 16, marginTop: 12, textAlign: 'center' }, header: { padding: 20, paddingBottom: 16 }, headerTop: { marginBottom: 16 }, headerTitleContainer: { alignItems: 'flex-start' }, headerTitle: { fontSize: 28, fontWeight: 'bold', marginBottom: 4 }, headerSubtitle: { fontSize: 16, opacity: 0.8 }, searchContainer: { flexDirection: 'row', alignItems: 'center', gap: 12 }, searchInputContainer: { flex: 1, flexDirection: 'row', alignItems: 'center', paddingHorizontal: 16, paddingVertical: 12, borderRadius: 12, borderWidth: 1, gap: 8 }, searchInput: { flex: 1, fontSize: 16 }, clearFiltersButton: { width: 44, height: 44, borderRadius: 12, justifyContent: 'center', alignItems: 'center' }, collectionsSection: { paddingHorizontal: 20, marginBottom: 24 }, sectionTitle: { fontSize: 20, fontWeight: '600', marginBottom: 16 }, collectionChipsContainer: { paddingRight: 20, gap: 8 }, collectionChip: { paddingHorizontal: 16, paddingVertical: 8, borderRadius: 20, borderWidth: 1, marginRight: 8 }, collectionChipText: { fontSize: 14, fontWeight: '500' }, videosSection: { paddingHorizontal: 20 }, videoCard: { marginBottom: 16, borderRadius: 16, borderWidth: 1, overflow: 'hidden', elevation: 2, shadowColor: '#000000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 8 }, videoThumbnail: { width: '100%', height: 200, backgroundColor: '#F3F4F6' }, videoInfo: { padding: 16 }, videoTitle: { fontSize: 16, fontWeight: '600', marginBottom: 4, lineHeight: 22 }, videoCollection: { fontSize: 14, fontWeight: '500', marginBottom: 8 }, videoDescription: { fontSize: 14, lineHeight: 20 }, playlistsSection: { paddingHorizontal: 20 }, playlistCard: { marginBottom: 16, padding: 16, borderRadius: 16, borderWidth: 1, elevation: 2, shadowColor: '#000000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 8 }, playlistHeader: { flexDirection: 'row', alignItems: 'center', marginBottom: 8 }, playlistInfo: { flex: 1, marginLeft: 12 }, playlistTitle: { fontSize: 16, fontWeight: '600', marginBottom: 4, lineHeight: 22 }, playlistVideoCount: { fontSize: 14, fontWeight: '500' }, playlistDescription: { fontSize: 14, lineHeight: 20 }, collectionCard: { marginBottom: 16, padding: 16, borderRadius: 16, borderWidth: 1, elevation: 2, shadowColor: '#000000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 8 }, collectionHeader: { flexDirection: 'row', alignItems: 'center', marginBottom: 8 }, collectionInfo: { flex: 1, marginLeft: 12 }, collectionTitle: { fontSize: 16, fontWeight: '600', marginBottom: 4, lineHeight: 22 }, collectionVideoCount: { fontSize: 14, fontWeight: '500' }, collectionDescription: { fontSize: 14, lineHeight: 20 }, emptyState: { alignItems: 'center', padding: 40 }, emptyStateTitle: { fontSize: 18, fontWeight: '600', marginTop: 16, marginBottom: 8, textAlign: 'center' }, emptyStateSubtitle: { fontSize: 16, textAlign: 'center', lineHeight: 22 }, fab: { position: 'absolute', right: 20, width: 56, height: 56, borderRadius: 28, justifyContent: 'center', alignItems: 'center', elevation: 8, shadowColor: '#000000', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 0.3, shadowRadius: 8 }, modalHeader: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: 24 }, modalTitle: { fontSize: 24, fontWeight: 'bold' }, modalCloseButton: { width: 40, height: 40, borderRadius: 20, justifyContent: 'center', alignItems: 'center' }, modalFooter: { flexDirection: 'row', gap: 12, marginTop: 24 }, modalButton: { flex: 1, paddingVertical: 16, borderRadius: 12, alignItems: 'center' }, modalButtonText: { fontSize: 16, fontWeight: '600' }, formGroup: { marginBottom: 20 }, formLabel: { fontSize: 16, fontWeight: '600', marginBottom: 8 }, formInput: { paddingHorizontal: 16, paddingVertical: 12, borderRadius: 12, borderWidth: 1, fontSize: 16 }, formTextArea: { height: 80, textAlignVertical: 'top' }, collectionSelectContainer: { paddingRight: 20, gap: 8 }, collectionSelectChip: { paddingHorizontal: 16, paddingVertical: 8, borderRadius: 20, borderWidth: 1, marginRight: 8 }, collectionSelectChipText: { fontSize: 14, fontWeight: '500' }, videoSelectItem: { flexDirection: 'row', alignItems: 'center', padding: 12, borderRadius: 12, borderWidth: 1, marginBottom: 8 }, videoSelectInfo: { flex: 1, marginRight: 12 }, videoSelectTitle: { fontSize: 16, fontWeight: '500', marginBottom: 2 }, videoSelectDescription: { fontSize: 14 }, emptyMessage: { fontSize: 16, textAlign: 'center', fontStyle: 'italic', padding: 20 } }); // @end:styles // @section:return @depends:[ThemeProvider,TabNavigator] return React.createElement(ThemeProvider, null, React.createElement(View, { style: { flex: 1, width: '100%', height: '100%', overflow: 'hidden' } }, React.createElement(StatusBar, { barStyle: 'dark-content' }), React.createElement(TabNavigator) ) ); // @end:return }; return ComponentFunction;