import React, {useCallback, useMemo} from 'react' import { RefreshControl, StyleSheet, View, ActivityIndicator, FlatList, TouchableOpacity, ScrollView, } from 'react-native' import {useFocusEffect} from '@react-navigation/native' import {NativeStackScreenProps} from '@react-navigation/native-stack' import {useAnalytics} from 'lib/analytics' import {usePalette} from 'lib/hooks/usePalette' import {CommonNavigatorParams} from 'lib/routes/types' import {observer} from 'mobx-react-lite' import {useStores} from 'state/index' import {withAuthRequired} from 'view/com/auth/withAuthRequired' import {ViewHeader} from 'view/com/util/ViewHeader' import {CenteredView} from 'view/com/util/Views' import {Text} from 'view/com/util/text/Text' import {isDesktopWeb, isWeb} from 'platform/detection' import {s} from 'lib/styles' import {SavedFeedsModel} from 'state/models/feeds/algo/saved' import {Link} from 'view/com/util/Link' import {UserAvatar} from 'view/com/util/UserAvatar' import {SavedFeedItem} from 'view/com/algos/SavedFeedItem' import {AtUri} from '@atproto/api' type Props = NativeStackScreenProps export const SavedFeeds = withAuthRequired( observer(({navigation}: Props) => { // hooks for global items const pal = usePalette('default') const rootStore = useStores() const {screen} = useAnalytics() // hooks for local const savedFeeds = useMemo(() => rootStore.me.savedFeeds, [rootStore]) useFocusEffect( useCallback(() => { screen('SavedFeeds') rootStore.shell.setMinimalShellMode(false) savedFeeds.refresh() }, [screen, rootStore, savedFeeds]), ) const _ListEmptyComponent = () => { return ( You don't have any saved feeds. To save a feed, click the save button when a custom feed or algorithm shows up. ) } const _ListFooterComponent = () => { return ( {savedFeeds.isLoading && } ) } return ( item.data.uri} refreshing={savedFeeds.isRefreshing} refreshControl={ savedFeeds.refresh()} tintColor={pal.colors.text} titleColor={pal.colors.text} /> } renderItem={({item}) => ( )} initialNumToRender={10} ListHeaderComponent={() => ( )} ListFooterComponent={_ListFooterComponent} ListEmptyComponent={_ListEmptyComponent} extraData={savedFeeds.isLoading} // @ts-ignore our .web version only -prf desktopFixedHeight /> ) }), ) const ListHeaderComponent = observer( ({ savedFeeds, navigation, }: { savedFeeds: SavedFeedsModel navigation: Props['navigation'] }) => { const pal = usePalette('default') return ( {savedFeeds.pinned.length > 0 ? ( Pinned Feeds Edit {savedFeeds.pinned.map(item => { return ( { navigation.navigate('CustomFeed', { name: item.data.creator.did, rkey: new AtUri(item.data.uri).rkey, displayName: item.data.displayName ?? `${item.data.creator.displayName}'s feed`, }) }} style={styles.pinnedItem}> {item.data.displayName ?? `${item.data.creator.displayName}'s feed`} ) })} ) : null} All Saved Feeds ) }, ) const styles = StyleSheet.create({ footer: { paddingVertical: 20, }, empty: { paddingHorizontal: 20, paddingVertical: 20, borderRadius: 16, marginHorizontal: 24, marginTop: 10, }, headerContainer: {paddingHorizontal: 18, paddingTop: 18}, pinnedContainer: {marginBottom: 18, gap: 18}, pinnedHeader: {flexDirection: 'row', justifyContent: 'space-between'}, pinnedItem: { flex: 1, alignItems: 'center', marginRight: 18, maxWidth: 100, }, pinnedItemName: {marginTop: 8, textAlign: 'center'}, editPinned: {textDecorationLine: 'underline'}, })