Remove redundant feed-settings page
parent
177df36330
commit
998879d6d6
|
@ -55,9 +55,8 @@ import {CopyrightPolicyScreen} from './view/screens/CopyrightPolicy'
|
||||||
import {AppPasswords} from 'view/screens/AppPasswords'
|
import {AppPasswords} from 'view/screens/AppPasswords'
|
||||||
import {ModerationMutedAccounts} from 'view/screens/ModerationMutedAccounts'
|
import {ModerationMutedAccounts} from 'view/screens/ModerationMutedAccounts'
|
||||||
import {ModerationBlockedAccounts} from 'view/screens/ModerationBlockedAccounts'
|
import {ModerationBlockedAccounts} from 'view/screens/ModerationBlockedAccounts'
|
||||||
|
import {SavedFeeds} from 'view/screens/SavedFeeds'
|
||||||
import {getRoutingInstrumentation} from 'lib/sentry'
|
import {getRoutingInstrumentation} from 'lib/sentry'
|
||||||
import {SavedFeeds} from './view/screens/SavedFeeds'
|
|
||||||
import {PinnedFeeds} from 'view/screens/PinnedFeeds'
|
|
||||||
import {bskyTitle} from 'lib/strings/headings'
|
import {bskyTitle} from 'lib/strings/headings'
|
||||||
|
|
||||||
const navigationRef = createNavigationContainerRef<AllNavigatorParams>()
|
const navigationRef = createNavigationContainerRef<AllNavigatorParams>()
|
||||||
|
@ -189,7 +188,6 @@ function commonScreens(Stack: typeof HomeTab, unreadCountLabel?: string) {
|
||||||
options={{title: title('App Passwords')}}
|
options={{title: title('App Passwords')}}
|
||||||
/>
|
/>
|
||||||
<Stack.Screen name="SavedFeeds" component={SavedFeeds} />
|
<Stack.Screen name="SavedFeeds" component={SavedFeeds} />
|
||||||
<Stack.Screen name="PinnedFeeds" component={PinnedFeeds} />
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,6 @@ export type CommonNavigatorParams = {
|
||||||
CopyrightPolicy: undefined
|
CopyrightPolicy: undefined
|
||||||
AppPasswords: undefined
|
AppPasswords: undefined
|
||||||
SavedFeeds: undefined
|
SavedFeeds: undefined
|
||||||
PinnedFeeds: undefined
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type BottomTabNavigatorParams = CommonNavigatorParams & {
|
export type BottomTabNavigatorParams = CommonNavigatorParams & {
|
||||||
|
|
|
@ -21,7 +21,6 @@ export const router = new Router({
|
||||||
Log: '/sys/log',
|
Log: '/sys/log',
|
||||||
AppPasswords: '/settings/app-passwords',
|
AppPasswords: '/settings/app-passwords',
|
||||||
SavedFeeds: '/settings/saved-feeds',
|
SavedFeeds: '/settings/saved-feeds',
|
||||||
PinnedFeeds: '/settings/pinned-feeds',
|
|
||||||
Support: '/support',
|
Support: '/support',
|
||||||
PrivacyPolicy: '/support/privacy',
|
PrivacyPolicy: '/support/privacy',
|
||||||
TermsOfService: '/support/tos',
|
TermsOfService: '/support/tos',
|
||||||
|
|
|
@ -50,7 +50,7 @@ export const SavedFeeds = observer(
|
||||||
return (
|
return (
|
||||||
<Link
|
<Link
|
||||||
style={[styles.footerLink, pal.border]}
|
style={[styles.footerLink, pal.border]}
|
||||||
href="/settings/pinned-feeds">
|
href="/settings/saved-feeds">
|
||||||
<FontAwesomeIcon icon="cog" size={18} color={pal.colors.icon} />
|
<FontAwesomeIcon icon="cog" size={18} color={pal.colors.icon} />
|
||||||
<Text type="lg-medium" style={pal.textLight}>
|
<Text type="lg-medium" style={pal.textLight}>
|
||||||
Settings
|
Settings
|
||||||
|
|
|
@ -60,14 +60,17 @@ import {faPenNib} from '@fortawesome/free-solid-svg-icons/faPenNib'
|
||||||
import {faPenToSquare} from '@fortawesome/free-solid-svg-icons/faPenToSquare'
|
import {faPenToSquare} from '@fortawesome/free-solid-svg-icons/faPenToSquare'
|
||||||
import {faPlus} from '@fortawesome/free-solid-svg-icons/faPlus'
|
import {faPlus} from '@fortawesome/free-solid-svg-icons/faPlus'
|
||||||
import {faQuoteLeft} from '@fortawesome/free-solid-svg-icons/faQuoteLeft'
|
import {faQuoteLeft} from '@fortawesome/free-solid-svg-icons/faQuoteLeft'
|
||||||
|
import {faReply} from '@fortawesome/free-solid-svg-icons/faReply'
|
||||||
|
import {faRetweet} from '@fortawesome/free-solid-svg-icons/faRetweet'
|
||||||
|
import {faRss} from '@fortawesome/free-solid-svg-icons/faRss'
|
||||||
|
import {faSatelliteDish} from '@fortawesome/free-solid-svg-icons/faSatelliteDish'
|
||||||
import {faShare} from '@fortawesome/free-solid-svg-icons/faShare'
|
import {faShare} from '@fortawesome/free-solid-svg-icons/faShare'
|
||||||
import {faShareFromSquare} from '@fortawesome/free-solid-svg-icons/faShareFromSquare'
|
import {faShareFromSquare} from '@fortawesome/free-solid-svg-icons/faShareFromSquare'
|
||||||
import {faShield} from '@fortawesome/free-solid-svg-icons/faShield'
|
import {faShield} from '@fortawesome/free-solid-svg-icons/faShield'
|
||||||
import {faSquarePlus} from '@fortawesome/free-regular-svg-icons/faSquarePlus'
|
import {faSquarePlus} from '@fortawesome/free-regular-svg-icons/faSquarePlus'
|
||||||
import {faSignal} from '@fortawesome/free-solid-svg-icons/faSignal'
|
import {faSignal} from '@fortawesome/free-solid-svg-icons/faSignal'
|
||||||
import {faReply} from '@fortawesome/free-solid-svg-icons/faReply'
|
import {faTicket} from '@fortawesome/free-solid-svg-icons/faTicket'
|
||||||
import {faRetweet} from '@fortawesome/free-solid-svg-icons/faRetweet'
|
import {faTrashCan} from '@fortawesome/free-regular-svg-icons/faTrashCan'
|
||||||
import {faRss} from '@fortawesome/free-solid-svg-icons/faRss'
|
|
||||||
import {faUser} from '@fortawesome/free-regular-svg-icons/faUser'
|
import {faUser} from '@fortawesome/free-regular-svg-icons/faUser'
|
||||||
import {faUsers} from '@fortawesome/free-solid-svg-icons/faUsers'
|
import {faUsers} from '@fortawesome/free-solid-svg-icons/faUsers'
|
||||||
import {faUserCheck} from '@fortawesome/free-solid-svg-icons/faUserCheck'
|
import {faUserCheck} from '@fortawesome/free-solid-svg-icons/faUserCheck'
|
||||||
|
@ -75,8 +78,6 @@ import {faUserSlash} from '@fortawesome/free-solid-svg-icons/faUserSlash'
|
||||||
import {faUserPlus} from '@fortawesome/free-solid-svg-icons/faUserPlus'
|
import {faUserPlus} from '@fortawesome/free-solid-svg-icons/faUserPlus'
|
||||||
import {faUserXmark} from '@fortawesome/free-solid-svg-icons/faUserXmark'
|
import {faUserXmark} from '@fortawesome/free-solid-svg-icons/faUserXmark'
|
||||||
import {faUsersSlash} from '@fortawesome/free-solid-svg-icons/faUsersSlash'
|
import {faUsersSlash} from '@fortawesome/free-solid-svg-icons/faUsersSlash'
|
||||||
import {faTicket} from '@fortawesome/free-solid-svg-icons/faTicket'
|
|
||||||
import {faTrashCan} from '@fortawesome/free-regular-svg-icons/faTrashCan'
|
|
||||||
import {faX} from '@fortawesome/free-solid-svg-icons/faX'
|
import {faX} from '@fortawesome/free-solid-svg-icons/faX'
|
||||||
import {faXmark} from '@fortawesome/free-solid-svg-icons/faXmark'
|
import {faXmark} from '@fortawesome/free-solid-svg-icons/faXmark'
|
||||||
import {faPlay} from '@fortawesome/free-solid-svg-icons/faPlay'
|
import {faPlay} from '@fortawesome/free-solid-svg-icons/faPlay'
|
||||||
|
@ -148,6 +149,7 @@ export function setup() {
|
||||||
faReply,
|
faReply,
|
||||||
faRetweet,
|
faRetweet,
|
||||||
faRss,
|
faRss,
|
||||||
|
faSatelliteDish,
|
||||||
faShare,
|
faShare,
|
||||||
faShareFromSquare,
|
faShareFromSquare,
|
||||||
faShield,
|
faShield,
|
||||||
|
|
|
@ -1,179 +0,0 @@
|
||||||
import React, {useCallback, useMemo} from 'react'
|
|
||||||
import {
|
|
||||||
RefreshControl,
|
|
||||||
StyleSheet,
|
|
||||||
View,
|
|
||||||
ActivityIndicator,
|
|
||||||
Pressable,
|
|
||||||
TouchableOpacity,
|
|
||||||
} 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 DraggableFlatList, {
|
|
||||||
ShadowDecorator,
|
|
||||||
ScaleDecorator,
|
|
||||||
} from 'react-native-draggable-flatlist'
|
|
||||||
import {SavedFeedItem} from 'view/com/feeds/SavedFeedItem'
|
|
||||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
|
||||||
import {CustomFeedModel} from 'state/models/feeds/custom-feed'
|
|
||||||
|
|
||||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'PinnedFeeds'>
|
|
||||||
|
|
||||||
export const PinnedFeeds = withAuthRequired(
|
|
||||||
observer(({}: 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 (
|
|
||||||
<View
|
|
||||||
style={[
|
|
||||||
pal.border,
|
|
||||||
!isDesktopWeb && s.flex1,
|
|
||||||
pal.viewLight,
|
|
||||||
styles.empty,
|
|
||||||
]}>
|
|
||||||
<Text type="lg" style={[pal.text]}>
|
|
||||||
You don't have any pinned feeds. To pin a feed, go back to the Saved
|
|
||||||
Feeds screen and click the pin icon!
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
const _ListFooterComponent = () => {
|
|
||||||
return (
|
|
||||||
<View style={styles.footer}>
|
|
||||||
{savedFeeds.isLoading && <ActivityIndicator />}
|
|
||||||
</View>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<CenteredView style={[s.flex1]}>
|
|
||||||
<ViewHeader title="Edit My Feeds" showOnDesktop />
|
|
||||||
<DraggableFlatList
|
|
||||||
containerStyle={[!isDesktopWeb && s.flex1]}
|
|
||||||
data={[...savedFeeds.pinned, ...savedFeeds.unpinned]} // make a copy so this FlatList re-renders when pinned changes
|
|
||||||
keyExtractor={item => item.data.uri}
|
|
||||||
refreshing={savedFeeds.isRefreshing}
|
|
||||||
refreshControl={
|
|
||||||
<RefreshControl
|
|
||||||
refreshing={savedFeeds.isRefreshing}
|
|
||||||
onRefresh={() => savedFeeds.refresh()}
|
|
||||||
tintColor={pal.colors.text}
|
|
||||||
titleColor={pal.colors.text}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
renderItem={({item, drag}) => <ListItem item={item} drag={drag} />}
|
|
||||||
initialNumToRender={10}
|
|
||||||
ListFooterComponent={_ListFooterComponent}
|
|
||||||
ListEmptyComponent={_ListEmptyComponent}
|
|
||||||
extraData={savedFeeds.isLoading}
|
|
||||||
onDragEnd={({data}) => savedFeeds.reorderPinnedFeeds(data)}
|
|
||||||
// @ts-ignore our .web version only -prf
|
|
||||||
desktopFixedHeight
|
|
||||||
/>
|
|
||||||
</CenteredView>
|
|
||||||
)
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
const ListItem = observer(
|
|
||||||
({item, drag}: {item: CustomFeedModel; drag: () => void}) => {
|
|
||||||
const pal = usePalette('default')
|
|
||||||
const rootStore = useStores()
|
|
||||||
const savedFeeds = useMemo(() => rootStore.me.savedFeeds, [rootStore])
|
|
||||||
const isPinned = savedFeeds.isPinned(item)
|
|
||||||
return (
|
|
||||||
<ScaleDecorator>
|
|
||||||
<ShadowDecorator>
|
|
||||||
<Pressable
|
|
||||||
accessibilityRole="button"
|
|
||||||
onLongPress={isPinned ? drag : undefined}
|
|
||||||
style={[styles.itemContainer, pal.border]}>
|
|
||||||
{isPinned && isWeb ? (
|
|
||||||
<View style={styles.webArrowButtonsContainer}>
|
|
||||||
<TouchableOpacity
|
|
||||||
accessibilityRole="button"
|
|
||||||
onPress={() => {
|
|
||||||
savedFeeds.movePinnedItem(item, 'up')
|
|
||||||
}}>
|
|
||||||
<FontAwesomeIcon
|
|
||||||
icon="arrow-up"
|
|
||||||
size={20}
|
|
||||||
style={[s.mr10, pal.text, styles.webArrowUpButton]}
|
|
||||||
/>
|
|
||||||
</TouchableOpacity>
|
|
||||||
<TouchableOpacity
|
|
||||||
accessibilityRole="button"
|
|
||||||
onPress={() => {
|
|
||||||
savedFeeds.movePinnedItem(item, 'down')
|
|
||||||
}}>
|
|
||||||
<FontAwesomeIcon
|
|
||||||
icon="arrow-down"
|
|
||||||
size={20}
|
|
||||||
style={[s.mr10, pal.text]}
|
|
||||||
/>
|
|
||||||
</TouchableOpacity>
|
|
||||||
</View>
|
|
||||||
) : isPinned ? (
|
|
||||||
<FontAwesomeIcon
|
|
||||||
icon="bars"
|
|
||||||
size={20}
|
|
||||||
color={pal.colors.text}
|
|
||||||
style={s.ml20}
|
|
||||||
/>
|
|
||||||
) : null}
|
|
||||||
<SavedFeedItem item={item} savedFeeds={savedFeeds} showSaveBtn />
|
|
||||||
</Pressable>
|
|
||||||
</ShadowDecorator>
|
|
||||||
</ScaleDecorator>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
footer: {
|
|
||||||
paddingVertical: 20,
|
|
||||||
},
|
|
||||||
empty: {
|
|
||||||
paddingHorizontal: 20,
|
|
||||||
paddingVertical: 20,
|
|
||||||
borderRadius: 16,
|
|
||||||
marginHorizontal: 24,
|
|
||||||
marginTop: 10,
|
|
||||||
},
|
|
||||||
itemContainer: {
|
|
||||||
flex: 1,
|
|
||||||
flexDirection: 'row',
|
|
||||||
alignItems: 'center',
|
|
||||||
borderTopWidth: 1,
|
|
||||||
},
|
|
||||||
webArrowButtonsContainer: {
|
|
||||||
flexDirection: 'column',
|
|
||||||
justifyContent: 'space-around',
|
|
||||||
},
|
|
||||||
webArrowUpButton: {marginBottom: 10},
|
|
||||||
})
|
|
|
@ -4,9 +4,8 @@ import {
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
View,
|
View,
|
||||||
ActivityIndicator,
|
ActivityIndicator,
|
||||||
FlatList,
|
Pressable,
|
||||||
TouchableOpacity,
|
TouchableOpacity,
|
||||||
ScrollView,
|
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
import {useFocusEffect} from '@react-navigation/native'
|
import {useFocusEffect} from '@react-navigation/native'
|
||||||
import {NativeStackScreenProps} from '@react-navigation/native-stack'
|
import {NativeStackScreenProps} from '@react-navigation/native-stack'
|
||||||
|
@ -21,16 +20,18 @@ import {CenteredView} from 'view/com/util/Views'
|
||||||
import {Text} from 'view/com/util/text/Text'
|
import {Text} from 'view/com/util/text/Text'
|
||||||
import {isDesktopWeb, isWeb} from 'platform/detection'
|
import {isDesktopWeb, isWeb} from 'platform/detection'
|
||||||
import {s} from 'lib/styles'
|
import {s} from 'lib/styles'
|
||||||
import {SavedFeedsModel} from 'state/models/ui/saved-feeds'
|
import DraggableFlatList, {
|
||||||
import {Link} from 'view/com/util/Link'
|
ShadowDecorator,
|
||||||
import {UserAvatar} from 'view/com/util/UserAvatar'
|
ScaleDecorator,
|
||||||
|
} from 'react-native-draggable-flatlist'
|
||||||
import {SavedFeedItem} from 'view/com/feeds/SavedFeedItem'
|
import {SavedFeedItem} from 'view/com/feeds/SavedFeedItem'
|
||||||
import {AtUri} from '@atproto/api'
|
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||||
|
import {CustomFeedModel} from 'state/models/feeds/custom-feed'
|
||||||
|
|
||||||
type Props = NativeStackScreenProps<CommonNavigatorParams, 'SavedFeeds'>
|
type Props = NativeStackScreenProps<CommonNavigatorParams, 'SavedFeeds'>
|
||||||
|
|
||||||
export const SavedFeeds = withAuthRequired(
|
export const SavedFeeds = withAuthRequired(
|
||||||
observer(({navigation}: Props) => {
|
observer(({}: Props) => {
|
||||||
// hooks for global items
|
// hooks for global items
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
const rootStore = useStores()
|
const rootStore = useStores()
|
||||||
|
@ -55,8 +56,8 @@ export const SavedFeeds = withAuthRequired(
|
||||||
styles.empty,
|
styles.empty,
|
||||||
]}>
|
]}>
|
||||||
<Text type="lg" style={[pal.text]}>
|
<Text type="lg" style={[pal.text]}>
|
||||||
You don't have any saved feeds. To save a feed, click the save
|
You don't have any pinned feeds. To pin a feed, go back to the Saved
|
||||||
button when a custom feed or algorithm shows up.
|
Feeds screen and click the pin icon!
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
|
@ -71,10 +72,10 @@ export const SavedFeeds = withAuthRequired(
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CenteredView style={[s.flex1]}>
|
<CenteredView style={[s.flex1]}>
|
||||||
<ViewHeader title="Saved Feeds" showOnDesktop />
|
<ViewHeader title="Edit My Feeds" showOnDesktop />
|
||||||
<FlatList
|
<DraggableFlatList
|
||||||
style={[!isDesktopWeb && s.flex1]}
|
containerStyle={[!isDesktopWeb && s.flex1]}
|
||||||
data={savedFeeds.feeds}
|
data={[...savedFeeds.pinned, ...savedFeeds.unpinned]} // make a copy so this FlatList re-renders when pinned changes
|
||||||
keyExtractor={item => item.data.uri}
|
keyExtractor={item => item.data.uri}
|
||||||
refreshing={savedFeeds.isRefreshing}
|
refreshing={savedFeeds.isRefreshing}
|
||||||
refreshControl={
|
refreshControl={
|
||||||
|
@ -85,19 +86,12 @@ export const SavedFeeds = withAuthRequired(
|
||||||
titleColor={pal.colors.text}
|
titleColor={pal.colors.text}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
renderItem={({item}) => (
|
renderItem={({item, drag}) => <ListItem item={item} drag={drag} />}
|
||||||
<SavedFeedItem item={item} savedFeeds={savedFeeds} />
|
|
||||||
)}
|
|
||||||
initialNumToRender={10}
|
initialNumToRender={10}
|
||||||
ListHeaderComponent={() => (
|
|
||||||
<ListHeaderComponent
|
|
||||||
savedFeeds={savedFeeds}
|
|
||||||
navigation={navigation}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
ListFooterComponent={_ListFooterComponent}
|
ListFooterComponent={_ListFooterComponent}
|
||||||
ListEmptyComponent={_ListEmptyComponent}
|
ListEmptyComponent={_ListEmptyComponent}
|
||||||
extraData={savedFeeds.isLoading}
|
extraData={savedFeeds.isLoading}
|
||||||
|
onDragEnd={({data}) => savedFeeds.reorderPinnedFeeds(data)}
|
||||||
// @ts-ignore our .web version only -prf
|
// @ts-ignore our .web version only -prf
|
||||||
desktopFixedHeight
|
desktopFixedHeight
|
||||||
/>
|
/>
|
||||||
|
@ -106,64 +100,56 @@ export const SavedFeeds = withAuthRequired(
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
const ListHeaderComponent = observer(
|
const ListItem = observer(
|
||||||
({
|
({item, drag}: {item: CustomFeedModel; drag: () => void}) => {
|
||||||
savedFeeds,
|
|
||||||
navigation,
|
|
||||||
}: {
|
|
||||||
savedFeeds: SavedFeedsModel
|
|
||||||
navigation: Props['navigation']
|
|
||||||
}) => {
|
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
|
const rootStore = useStores()
|
||||||
|
const savedFeeds = useMemo(() => rootStore.me.savedFeeds, [rootStore])
|
||||||
|
const isPinned = savedFeeds.isPinned(item)
|
||||||
return (
|
return (
|
||||||
<View style={styles.headerContainer}>
|
<ScaleDecorator>
|
||||||
{savedFeeds.pinned.length > 0 ? (
|
<ShadowDecorator>
|
||||||
<View style={styles.pinnedContainer}>
|
<Pressable
|
||||||
<View style={styles.pinnedHeader}>
|
accessibilityRole="button"
|
||||||
<Text type="lg-bold" style={[pal.text]}>
|
onLongPress={isPinned ? drag : undefined}
|
||||||
Pinned Feeds
|
style={[styles.itemContainer, pal.border]}>
|
||||||
</Text>
|
{isPinned && isWeb ? (
|
||||||
<Link href="/settings/pinned-feeds">
|
<View style={styles.webArrowButtonsContainer}>
|
||||||
<Text style={[styles.editPinned, pal.text]}>Edit</Text>
|
<TouchableOpacity
|
||||||
</Link>
|
accessibilityRole="button"
|
||||||
</View>
|
onPress={() => {
|
||||||
|
savedFeeds.movePinnedItem(item, 'up')
|
||||||
<ScrollView
|
}}>
|
||||||
horizontal={true}
|
<FontAwesomeIcon
|
||||||
showsHorizontalScrollIndicator={isWeb}>
|
icon="arrow-up"
|
||||||
{savedFeeds.pinned.map(item => {
|
size={20}
|
||||||
return (
|
style={[s.mr10, pal.text, styles.webArrowUpButton]}
|
||||||
<TouchableOpacity
|
/>
|
||||||
key={item.data.uri}
|
</TouchableOpacity>
|
||||||
accessibilityRole="button"
|
<TouchableOpacity
|
||||||
onPress={() => {
|
accessibilityRole="button"
|
||||||
navigation.navigate('ProfileCustomFeed', {
|
onPress={() => {
|
||||||
name: item.data.creator.did,
|
savedFeeds.movePinnedItem(item, 'down')
|
||||||
rkey: new AtUri(item.data.uri).rkey,
|
}}>
|
||||||
})
|
<FontAwesomeIcon
|
||||||
}}
|
icon="arrow-down"
|
||||||
style={styles.pinnedItem}>
|
size={20}
|
||||||
<UserAvatar
|
style={[s.mr10, pal.text]}
|
||||||
type="algo"
|
/>
|
||||||
avatar={item.data.avatar}
|
</TouchableOpacity>
|
||||||
size={80}
|
</View>
|
||||||
/>
|
) : isPinned ? (
|
||||||
<Text
|
<FontAwesomeIcon
|
||||||
type="sm-medium"
|
icon="bars"
|
||||||
numberOfLines={1}
|
size={20}
|
||||||
style={[pal.text, styles.pinnedItemName]}>
|
color={pal.colors.text}
|
||||||
{item.data.displayName ??
|
style={s.ml20}
|
||||||
`${item.data.creator.displayName}'s feed`}
|
/>
|
||||||
</Text>
|
) : null}
|
||||||
</TouchableOpacity>
|
<SavedFeedItem item={item} savedFeeds={savedFeeds} showSaveBtn />
|
||||||
)
|
</Pressable>
|
||||||
})}
|
</ShadowDecorator>
|
||||||
</ScrollView>
|
</ScaleDecorator>
|
||||||
</View>
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
<Text type="lg-bold">All Saved Feeds</Text>
|
|
||||||
</View>
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -179,15 +165,15 @@ const styles = StyleSheet.create({
|
||||||
marginHorizontal: 24,
|
marginHorizontal: 24,
|
||||||
marginTop: 10,
|
marginTop: 10,
|
||||||
},
|
},
|
||||||
headerContainer: {paddingHorizontal: 18, paddingTop: 18},
|
itemContainer: {
|
||||||
pinnedContainer: {marginBottom: 18, gap: 18},
|
|
||||||
pinnedHeader: {flexDirection: 'row', justifyContent: 'space-between'},
|
|
||||||
pinnedItem: {
|
|
||||||
flex: 1,
|
flex: 1,
|
||||||
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
marginRight: 18,
|
borderTopWidth: 1,
|
||||||
maxWidth: 100,
|
|
||||||
},
|
},
|
||||||
pinnedItemName: {marginTop: 8, textAlign: 'center'},
|
webArrowButtonsContainer: {
|
||||||
editPinned: {textDecorationLine: 'underline'},
|
flexDirection: 'column',
|
||||||
|
justifyContent: 'space-around',
|
||||||
|
},
|
||||||
|
webArrowUpButton: {marginBottom: 10},
|
||||||
})
|
})
|
||||||
|
|
|
@ -284,23 +284,6 @@ export const SettingsScreen = withAuthRequired(
|
||||||
|
|
||||||
<View style={styles.spacer20} />
|
<View style={styles.spacer20} />
|
||||||
|
|
||||||
<Link
|
|
||||||
testID="bookmarkedAlgosBtn"
|
|
||||||
style={[styles.linkCard, pal.view, isSwitching && styles.dimmed]}
|
|
||||||
accessibilityHint="Custom Algorithms"
|
|
||||||
accessibilityLabel="Opens screen with all bookmarked custom algorithms"
|
|
||||||
href="/settings/saved-feeds">
|
|
||||||
<View style={[styles.iconContainer, pal.btn]}>
|
|
||||||
<FontAwesomeIcon
|
|
||||||
icon="rss"
|
|
||||||
style={pal.text as FontAwesomeIconStyle}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
<Text type="lg" style={pal.text}>
|
|
||||||
Custom Algorithms
|
|
||||||
</Text>
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
<Text type="xl-bold" style={[pal.text, styles.heading]}>
|
<Text type="xl-bold" style={[pal.text, styles.heading]}>
|
||||||
Advanced
|
Advanced
|
||||||
</Text>
|
</Text>
|
||||||
|
@ -318,6 +301,22 @@ export const SettingsScreen = withAuthRequired(
|
||||||
App passwords
|
App passwords
|
||||||
</Text>
|
</Text>
|
||||||
</Link>
|
</Link>
|
||||||
|
<Link
|
||||||
|
testID="savedFeedsBtn"
|
||||||
|
style={[styles.linkCard, pal.view, isSwitching && styles.dimmed]}
|
||||||
|
accessibilityHint="Saved Feeds"
|
||||||
|
accessibilityLabel="Opens screen with all saved feeds"
|
||||||
|
href="/settings/saved-feeds">
|
||||||
|
<View style={[styles.iconContainer, pal.btn]}>
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon="satellite-dish"
|
||||||
|
style={pal.text as FontAwesomeIconStyle}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<Text type="lg" style={pal.text}>
|
||||||
|
Saved Feeds
|
||||||
|
</Text>
|
||||||
|
</Link>
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
testID="contentLanguagesBtn"
|
testID="contentLanguagesBtn"
|
||||||
style={[styles.linkCard, pal.view, isSwitching && styles.dimmed]}
|
style={[styles.linkCard, pal.view, isSwitching && styles.dimmed]}
|
||||||
|
|
Loading…
Reference in New Issue