Store/sync pinned feeds on the server

This commit is contained in:
Paul Frazee 2023-05-18 11:51:25 -05:00
parent d88c27a419
commit 7691fe4f48
8 changed files with 278 additions and 240 deletions

View file

@ -39,20 +39,30 @@ export const CustomFeed = observer(
const pal = usePalette('default')
const navigation = useNavigation<NavigationProp>()
const onToggleSaved = React.useCallback(() => {
const onToggleSaved = React.useCallback(async () => {
if (item.data.viewer?.saved) {
store.shell.openModal({
name: 'confirm',
title: 'Remove from my feeds',
message: `Remove ${item.displayName} from my feeds?`,
onPressConfirm: () => {
store.me.savedFeeds.unsave(item)
Toast.show('Removed from my feeds')
onPressConfirm: async () => {
try {
await store.me.savedFeeds.unsave(item)
Toast.show('Removed from my feeds')
} catch (e) {
Toast.show('There was an issue contacting your server')
store.log.error('Failed to unsave feed', {e})
}
},
})
} else {
store.me.savedFeeds.save(item)
Toast.show('Added to my feeds')
try {
await store.me.savedFeeds.save(item)
Toast.show('Added to my feeds')
} catch (e) {
Toast.show('There was an issue contacting your server')
store.log.error('Failed to save feed', {e})
}
}
}, [store, item])

View file

@ -29,6 +29,10 @@ export const SavedFeeds = observer(
}
}, [store, isPageFocused])
const onRefresh = useCallback(() => {
store.me.savedFeeds.refresh()
}, [store])
const renderListEmptyComponent = useCallback(() => {
return (
<View
@ -73,7 +77,7 @@ export const SavedFeeds = observer(
refreshControl={
<RefreshControl
refreshing={store.me.savedFeeds.isRefreshing}
onRefresh={() => store.me.savedFeeds.refresh()}
onRefresh={onRefresh}
tintColor={pal.colors.text}
titleColor={pal.colors.text}
progressViewOffset={headerOffset}

View file

@ -1,12 +1,9 @@
import React from 'react'
import {Animated, View} from 'react-native'
import {useAnimatedValue} from 'lib/hooks/useAnimatedValue'
import {View} from 'react-native'
import {s} from 'lib/styles'
export interface RenderTabBarFnProps {
selectedPage: number
position: Animated.Value
offset: Animated.Value
onSelect?: (index: number) => void
}
export type RenderTabBarFn = (props: RenderTabBarFnProps) => JSX.Element
@ -17,53 +14,51 @@ interface Props {
renderTabBar: RenderTabBarFn
onPageSelected?: (index: number) => void
}
export const Pager = ({
children,
tabBarPosition = 'top',
initialPage = 0,
renderTabBar,
onPageSelected,
}: React.PropsWithChildren<Props>) => {
const [selectedPage, setSelectedPage] = React.useState(initialPage)
const position = useAnimatedValue(0)
const offset = useAnimatedValue(0)
export const Pager = React.forwardRef(
(
{
children,
tabBarPosition = 'top',
initialPage = 0,
renderTabBar,
onPageSelected,
}: React.PropsWithChildren<Props>,
ref,
) => {
const [selectedPage, setSelectedPage] = React.useState(initialPage)
const onTabBarSelect = React.useCallback(
(index: number) => {
setSelectedPage(index)
onPageSelected?.(index)
Animated.timing(position, {
toValue: index,
duration: 200,
useNativeDriver: true,
}).start()
},
[setSelectedPage, onPageSelected, position],
)
React.useImperativeHandle(ref, () => ({
setPage: (index: number) => setSelectedPage(index),
}))
return (
<View>
{tabBarPosition === 'top' &&
renderTabBar({
selectedPage,
position,
offset,
onSelect: onTabBarSelect,
})}
{React.Children.map(children, (child, i) => (
<View
style={selectedPage === i ? undefined : s.hidden}
key={`page-${i}`}>
{child}
</View>
))}
{tabBarPosition === 'bottom' &&
renderTabBar({
selectedPage,
position,
offset,
onSelect: onTabBarSelect,
})}
</View>
)
}
const onTabBarSelect = React.useCallback(
(index: number) => {
setSelectedPage(index)
onPageSelected?.(index)
},
[setSelectedPage, onPageSelected],
)
return (
<View>
{tabBarPosition === 'top' &&
renderTabBar({
selectedPage,
onSelect: onTabBarSelect,
})}
{React.Children.map(children, (child, i) => (
<View
style={selectedPage === i ? undefined : s.hidden}
key={`page-${i}`}>
{child}
</View>
))}
{tabBarPosition === 'bottom' &&
renderTabBar({
selectedPage,
onSelect: onTabBarSelect,
})}
</View>
)
},
)