From 372e20efa36c52a04cf2aa48816b82a1d96e0711 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Tue, 9 Sep 2025 22:40:25 +0300 Subject: ALF saved feeds screen (#8844) --- src/view/screens/SavedFeeds.tsx | 450 ---------------------------------------- 1 file changed, 450 deletions(-) delete mode 100644 src/view/screens/SavedFeeds.tsx (limited to 'src/view/screens/SavedFeeds.tsx') diff --git a/src/view/screens/SavedFeeds.tsx b/src/view/screens/SavedFeeds.tsx deleted file mode 100644 index 0e85bdf73..000000000 --- a/src/view/screens/SavedFeeds.tsx +++ /dev/null @@ -1,450 +0,0 @@ -import React from 'react' -import {ActivityIndicator, Pressable, StyleSheet, View} from 'react-native' -import Animated, {LinearTransition} from 'react-native-reanimated' -import {type AppBskyActorDefs} from '@atproto/api' -import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import {msg, Trans} from '@lingui/macro' -import {useLingui} from '@lingui/react' -import {useFocusEffect} from '@react-navigation/native' -import {useNavigation} from '@react-navigation/native' -import {type NativeStackScreenProps} from '@react-navigation/native-stack' - -import {useHaptics} from '#/lib/haptics' -import {usePalette} from '#/lib/hooks/usePalette' -import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' -import { - type CommonNavigatorParams, - type NavigationProp, -} from '#/lib/routes/types' -import {colors, s} from '#/lib/styles' -import {logger} from '#/logger' -import { - useOverwriteSavedFeedsMutation, - usePreferencesQuery, -} from '#/state/queries/preferences' -import {type UsePreferencesQueryResponse} from '#/state/queries/preferences/types' -import {useSetMinimalShellMode} from '#/state/shell' -import {FeedSourceCard} from '#/view/com/feeds/FeedSourceCard' -import {TextLink} from '#/view/com/util/Link' -import {Text} from '#/view/com/util/text/Text' -import * as Toast from '#/view/com/util/Toast' -import {NoFollowingFeed} from '#/screens/Feeds/NoFollowingFeed' -import {NoSavedFeedsOfAnyType} from '#/screens/Feeds/NoSavedFeedsOfAnyType' -import {atoms as a, useTheme} from '#/alf' -import {Button, ButtonIcon, ButtonText} from '#/components/Button' -import {FilterTimeline_Stroke2_Corner0_Rounded as FilterTimeline} from '#/components/icons/FilterTimeline' -import {FloppyDisk_Stroke2_Corner0_Rounded as SaveIcon} from '#/components/icons/FloppyDisk' -import * as Layout from '#/components/Layout' -import {Loader} from '#/components/Loader' -import {Text as NewText} from '#/components/Typography' - -type Props = NativeStackScreenProps -export function SavedFeeds({}: Props) { - const {data: preferences} = usePreferencesQuery() - if (!preferences) { - return - } - return -} - -function SavedFeedsInner({ - preferences, -}: { - preferences: UsePreferencesQueryResponse -}) { - const pal = usePalette('default') - const {_} = useLingui() - const {isMobile, isDesktop} = useWebMediaQueries() - const setMinimalShellMode = useSetMinimalShellMode() - const {mutateAsync: overwriteSavedFeeds, isPending: isOverwritePending} = - useOverwriteSavedFeedsMutation() - const navigation = useNavigation() - - /* - * Use optimistic data if exists and no error, otherwise fallback to remote - * data - */ - const [currentFeeds, setCurrentFeeds] = React.useState( - () => preferences.savedFeeds || [], - ) - const hasUnsavedChanges = currentFeeds !== preferences.savedFeeds - const pinnedFeeds = currentFeeds.filter(f => f.pinned) - const unpinnedFeeds = currentFeeds.filter(f => !f.pinned) - const noSavedFeedsOfAnyType = pinnedFeeds.length + unpinnedFeeds.length === 0 - const noFollowingFeed = - currentFeeds.every(f => f.type !== 'timeline') && !noSavedFeedsOfAnyType - - useFocusEffect( - React.useCallback(() => { - setMinimalShellMode(false) - }, [setMinimalShellMode]), - ) - - const onSaveChanges = React.useCallback(async () => { - try { - await overwriteSavedFeeds(currentFeeds) - Toast.show(_(msg({message: 'Feeds updated!', context: 'toast'}))) - if (navigation.canGoBack()) { - navigation.goBack() - } else { - navigation.navigate('Feeds') - } - } catch (e) { - Toast.show(_(msg`There was an issue contacting the server`), 'xmark') - logger.error('Failed to toggle pinned feed', {message: e}) - } - }, [_, overwriteSavedFeeds, currentFeeds, navigation]) - - return ( - - - - - - Feeds - - - - - - - {noSavedFeedsOfAnyType && ( - - - - )} - - - - Pinned Feeds - - - - {preferences ? ( - !pinnedFeeds.length ? ( - - - You don't have any pinned feeds. - - - ) : ( - pinnedFeeds.map(f => ( - - )) - ) - ) : ( - - )} - - {noFollowingFeed && ( - - - - )} - - - - Saved Feeds - - - {preferences ? ( - !unpinnedFeeds.length ? ( - - - You don't have any saved feeds. - - - ) : ( - unpinnedFeeds.map(f => ( - - )) - ) - ) : ( - - )} - - - - - Feeds are custom algorithms that users build with a little coding - expertise.{' '} - {' '} - for more information. - - - - - - ) -} - -function ListItem({ - feed, - isPinned, - currentFeeds, - setCurrentFeeds, -}: { - feed: AppBskyActorDefs.SavedFeed - isPinned: boolean - currentFeeds: AppBskyActorDefs.SavedFeed[] - setCurrentFeeds: React.Dispatch - preferences: UsePreferencesQueryResponse -}) { - const {_} = useLingui() - const pal = usePalette('default') - const playHaptic = useHaptics() - const feedUri = feed.value - - const onTogglePinned = React.useCallback(async () => { - playHaptic() - setCurrentFeeds( - currentFeeds.map(f => - f.id === feed.id ? {...feed, pinned: !feed.pinned} : f, - ), - ) - }, [playHaptic, feed, currentFeeds, setCurrentFeeds]) - - const onPressUp = React.useCallback(async () => { - if (!isPinned) return - - const nextFeeds = currentFeeds.slice() - const ids = currentFeeds.map(f => f.id) - const index = ids.indexOf(feed.id) - const nextIndex = index - 1 - - if (index === -1 || index === 0) return - ;[nextFeeds[index], nextFeeds[nextIndex]] = [ - nextFeeds[nextIndex], - nextFeeds[index], - ] - - setCurrentFeeds(nextFeeds) - }, [feed, isPinned, setCurrentFeeds, currentFeeds]) - - const onPressDown = React.useCallback(async () => { - if (!isPinned) return - - const nextFeeds = currentFeeds.slice() - const ids = currentFeeds.map(f => f.id) - const index = ids.indexOf(feed.id) - const nextIndex = index + 1 - - if (index === -1 || index >= nextFeeds.filter(f => f.pinned).length - 1) - return - ;[nextFeeds[index], nextFeeds[nextIndex]] = [ - nextFeeds[nextIndex], - nextFeeds[index], - ] - - setCurrentFeeds(nextFeeds) - }, [feed, isPinned, setCurrentFeeds, currentFeeds]) - - const onPressRemove = React.useCallback(async () => { - playHaptic() - setCurrentFeeds(currentFeeds.filter(f => f.id !== feed.id)) - }, [playHaptic, feed, currentFeeds, setCurrentFeeds]) - - return ( - - {feed.type === 'timeline' ? ( - - ) : ( - - )} - {isPinned ? ( - <> - ({ - backgroundColor: pal.viewLight.backgroundColor, - paddingHorizontal: 12, - paddingVertical: 10, - borderRadius: 4, - marginRight: 8, - opacity: state.hovered || state.pressed ? 0.5 : 1, - })} - testID={`feed-${feed.type}-moveUp`}> - - - ({ - backgroundColor: pal.viewLight.backgroundColor, - paddingHorizontal: 12, - paddingVertical: 10, - borderRadius: 4, - marginRight: 8, - opacity: state.hovered || state.pressed ? 0.5 : 1, - })} - testID={`feed-${feed.type}-moveDown`}> - - - - ) : ( - ({ - marginRight: 8, - paddingHorizontal: 12, - paddingVertical: 10, - borderRadius: 4, - opacity: state.hovered || state.focused ? 0.5 : 1, - })}> - - - )} - - ({ - backgroundColor: pal.viewLight.backgroundColor, - paddingHorizontal: 12, - paddingVertical: 10, - borderRadius: 4, - opacity: state.hovered || state.focused ? 0.5 : 1, - })} - testID={`feed-${feed.type}-togglePin`}> - - - - - ) -} - -function FollowingFeedCard() { - const t = useTheme() - return ( - - - - - - - Following - - - - ) -} - -const styles = StyleSheet.create({ - empty: { - paddingHorizontal: 20, - paddingVertical: 20, - borderRadius: 8, - marginHorizontal: 10, - marginTop: 10, - }, - title: { - paddingHorizontal: 14, - paddingTop: 20, - paddingBottom: 10, - borderBottomWidth: StyleSheet.hairlineWidth, - }, - itemContainer: { - flexDirection: 'row', - alignItems: 'center', - borderBottomWidth: StyleSheet.hairlineWidth, - }, - footerText: { - paddingHorizontal: 26, - paddingVertical: 22, - }, -}) -- cgit 1.4.1