Merge branch 'custom-algos' of github.com:bluesky-social/social-app into custom-algos
commit
e33dad8b72
|
@ -8,7 +8,7 @@ import {ListsListModel} from '../lists/lists-list'
|
||||||
export enum Sections {
|
export enum Sections {
|
||||||
Posts = 'Posts',
|
Posts = 'Posts',
|
||||||
PostsWithReplies = 'Posts & replies',
|
PostsWithReplies = 'Posts & replies',
|
||||||
CustomAlgorithms = 'Algos',
|
CustomAlgorithms = 'Feeds',
|
||||||
Lists = 'Lists',
|
Lists = 'Lists',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,7 @@ export const CustomFeed = observer(
|
||||||
}
|
}
|
||||||
accessibilityHint=""
|
accessibilityHint=""
|
||||||
onPress={onToggleSaved}
|
onPress={onToggleSaved}
|
||||||
|
hitSlop={15}
|
||||||
style={styles.btn}>
|
style={styles.btn}>
|
||||||
{item.isSaved ? (
|
{item.isSaved ? (
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
|
|
|
@ -1,151 +0,0 @@
|
||||||
import React, {useEffect, useCallback} from 'react'
|
|
||||||
import {RefreshControl, StyleSheet, View} from 'react-native'
|
|
||||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
|
||||||
import {usePalette} from 'lib/hooks/usePalette'
|
|
||||||
import {observer} from 'mobx-react-lite'
|
|
||||||
import {useStores} from 'state/index'
|
|
||||||
import {FlatList} from 'view/com/util/Views'
|
|
||||||
import {Text} from 'view/com/util/text/Text'
|
|
||||||
import {isDesktopWeb} from 'platform/detection'
|
|
||||||
import {s} from 'lib/styles'
|
|
||||||
import {Link, TextLink} from 'view/com/util/Link'
|
|
||||||
import {CustomFeed} from './CustomFeed'
|
|
||||||
|
|
||||||
export const SavedFeeds = observer(
|
|
||||||
({
|
|
||||||
headerOffset = 0,
|
|
||||||
isPageFocused,
|
|
||||||
}: {
|
|
||||||
headerOffset?: number
|
|
||||||
isPageFocused: boolean
|
|
||||||
}) => {
|
|
||||||
const pal = usePalette('default')
|
|
||||||
const store = useStores()
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (isPageFocused) {
|
|
||||||
store.shell.setMinimalShellMode(false)
|
|
||||||
store.me.savedFeeds.refresh(true)
|
|
||||||
}
|
|
||||||
}, [store, isPageFocused])
|
|
||||||
|
|
||||||
const onRefresh = useCallback(() => {
|
|
||||||
store.me.savedFeeds.refresh()
|
|
||||||
}, [store])
|
|
||||||
|
|
||||||
const renderListEmptyComponent = useCallback(() => {
|
|
||||||
return (
|
|
||||||
<View
|
|
||||||
style={[
|
|
||||||
pal.border,
|
|
||||||
!isDesktopWeb && s.flex1,
|
|
||||||
pal.viewLight,
|
|
||||||
styles.empty,
|
|
||||||
]}>
|
|
||||||
<Text type="lg" style={[pal.text]}>
|
|
||||||
You don't have any saved feeds. You can find feeds by searching on
|
|
||||||
Bluesky.
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
)
|
|
||||||
}, [pal])
|
|
||||||
|
|
||||||
const renderListFooterComponent = useCallback(() => {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<View style={[styles.footerLinks, pal.border]}>
|
|
||||||
<Link style={[styles.footerLink, pal.border]} href="/search/feeds">
|
|
||||||
<FontAwesomeIcon
|
|
||||||
icon="search"
|
|
||||||
size={18}
|
|
||||||
color={pal.colors.icon}
|
|
||||||
/>
|
|
||||||
<Text type="lg-medium" style={pal.textLight}>
|
|
||||||
Discover new feeds
|
|
||||||
</Text>
|
|
||||||
</Link>
|
|
||||||
{!store.me.savedFeeds.isEmpty && (
|
|
||||||
<Link
|
|
||||||
style={[styles.footerLink, pal.border]}
|
|
||||||
href="/settings/saved-feeds">
|
|
||||||
<FontAwesomeIcon icon="cog" size={18} color={pal.colors.icon} />
|
|
||||||
<Text type="lg-medium" style={pal.textLight}>
|
|
||||||
Change Order
|
|
||||||
</Text>
|
|
||||||
</Link>
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
<View style={styles.footerText}>
|
|
||||||
<Text type="sm" style={pal.textLight}>
|
|
||||||
Feeds are custom algorithms that users build with a little coding
|
|
||||||
expertise.{' '}
|
|
||||||
<TextLink
|
|
||||||
type="sm"
|
|
||||||
style={pal.link}
|
|
||||||
href="https://github.com/bluesky-social/feed-generator"
|
|
||||||
text="See this guide"
|
|
||||||
/>{' '}
|
|
||||||
for more information.
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}, [pal, store.me.savedFeeds.isEmpty])
|
|
||||||
|
|
||||||
const renderItem = useCallback(
|
|
||||||
({item}) => <CustomFeed key={item.data.uri} item={item} />,
|
|
||||||
[],
|
|
||||||
)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FlatList
|
|
||||||
style={[!isDesktopWeb && s.flex1, {paddingTop: headerOffset}]}
|
|
||||||
data={store.me.savedFeeds.feeds}
|
|
||||||
keyExtractor={item => item.data.uri}
|
|
||||||
refreshing={store.me.savedFeeds.isRefreshing}
|
|
||||||
refreshControl={
|
|
||||||
<RefreshControl
|
|
||||||
refreshing={store.me.savedFeeds.isRefreshing}
|
|
||||||
onRefresh={onRefresh}
|
|
||||||
tintColor={pal.colors.text}
|
|
||||||
titleColor={pal.colors.text}
|
|
||||||
progressViewOffset={headerOffset}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
renderItem={renderItem}
|
|
||||||
initialNumToRender={10}
|
|
||||||
ListFooterComponent={renderListFooterComponent}
|
|
||||||
ListEmptyComponent={renderListEmptyComponent}
|
|
||||||
extraData={store.me.savedFeeds.isLoading}
|
|
||||||
contentOffset={{x: 0, y: headerOffset * -1}}
|
|
||||||
// @ts-ignore our .web version only -prf
|
|
||||||
desktopFixedHeight
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
footerLinks: {
|
|
||||||
marginTop: 8,
|
|
||||||
borderBottomWidth: 1,
|
|
||||||
},
|
|
||||||
footerLink: {
|
|
||||||
flexDirection: 'row',
|
|
||||||
borderTopWidth: 1,
|
|
||||||
paddingHorizontal: 26,
|
|
||||||
paddingVertical: 18,
|
|
||||||
gap: 18,
|
|
||||||
},
|
|
||||||
empty: {
|
|
||||||
paddingHorizontal: 18,
|
|
||||||
paddingVertical: 16,
|
|
||||||
borderRadius: 8,
|
|
||||||
marginHorizontal: 18,
|
|
||||||
marginTop: 10,
|
|
||||||
},
|
|
||||||
footerText: {
|
|
||||||
paddingHorizontal: 26,
|
|
||||||
paddingVertical: 22,
|
|
||||||
},
|
|
||||||
})
|
|
|
@ -28,7 +28,7 @@ const FeedsTabBarDesktop = observer(
|
||||||
) => {
|
) => {
|
||||||
const store = useStores()
|
const store = useStores()
|
||||||
const items = useMemo(
|
const items = useMemo(
|
||||||
() => ['Following', ...store.me.savedFeeds.pinnedFeedNames, 'My Feeds'],
|
() => ['Following', ...store.me.savedFeeds.pinnedFeedNames],
|
||||||
[store.me.savedFeeds.pinnedFeedNames],
|
[store.me.savedFeeds.pinnedFeedNames],
|
||||||
)
|
)
|
||||||
const pal = usePalette('default')
|
const pal = usePalette('default')
|
||||||
|
|
|
@ -58,7 +58,12 @@ export const FeedsTabBar = observer(
|
||||||
Bluesky
|
Bluesky
|
||||||
</Text>
|
</Text>
|
||||||
<View style={[pal.view]}>
|
<View style={[pal.view]}>
|
||||||
<Link href="/settings/saved-feeds" hitSlop={10}>
|
<Link
|
||||||
|
href="/settings/saved-feeds"
|
||||||
|
hitSlop={10}
|
||||||
|
accessibilityRole="button"
|
||||||
|
accessibilityLabel="Edit Saved Feeds"
|
||||||
|
accessibilityHint="Opens screen to edit Saved Feeds">
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon="satellite-dish"
|
icon="satellite-dish"
|
||||||
size={19}
|
size={19}
|
||||||
|
|
|
@ -110,13 +110,16 @@ const styles = isDesktopWeb
|
||||||
outer: {
|
outer: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
width: 598,
|
width: 598,
|
||||||
paddingHorizontal: 14,
|
|
||||||
},
|
},
|
||||||
contentContainer: {},
|
contentContainer: {
|
||||||
|
columnGap: 14,
|
||||||
|
marginLeft: 14,
|
||||||
|
paddingRight: 14,
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
},
|
||||||
item: {
|
item: {
|
||||||
paddingTop: 14,
|
paddingTop: 14,
|
||||||
paddingBottom: 12,
|
paddingBottom: 12,
|
||||||
paddingHorizontal: 12,
|
|
||||||
borderBottomWidth: 3,
|
borderBottomWidth: 3,
|
||||||
borderBottomColor: 'transparent',
|
borderBottomColor: 'transparent',
|
||||||
},
|
},
|
||||||
|
@ -125,10 +128,13 @@ const styles = isDesktopWeb
|
||||||
outer: {
|
outer: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
|
backgroundColor: 'transparent',
|
||||||
},
|
},
|
||||||
contentContainer: {
|
contentContainer: {
|
||||||
gap: 18,
|
columnGap: 14,
|
||||||
paddingHorizontal: 18,
|
marginLeft: 14,
|
||||||
|
paddingRight: 28,
|
||||||
|
backgroundColor: 'transparent',
|
||||||
},
|
},
|
||||||
item: {
|
item: {
|
||||||
paddingTop: 8,
|
paddingTop: 8,
|
||||||
|
|
|
@ -87,6 +87,8 @@ export function HeaderWithInput({
|
||||||
accessibilityRole="search"
|
accessibilityRole="search"
|
||||||
accessibilityLabel="Search"
|
accessibilityLabel="Search"
|
||||||
accessibilityHint=""
|
accessibilityHint=""
|
||||||
|
autoCorrect={false}
|
||||||
|
autoCapitalize="none"
|
||||||
/>
|
/>
|
||||||
{query ? (
|
{query ? (
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
|
|
|
@ -338,7 +338,11 @@ export const CustomFeedScreen = withAuthRequired(
|
||||||
extraData={[uri, isPinned]}
|
extraData={[uri, isPinned]}
|
||||||
/>
|
/>
|
||||||
{isScrolledDown ? (
|
{isScrolledDown ? (
|
||||||
<LoadLatestBtn onPress={onScrollToTop} label="Scroll to top" />
|
<LoadLatestBtn
|
||||||
|
onPress={onScrollToTop}
|
||||||
|
label="Scroll to top"
|
||||||
|
showIndicator={false}
|
||||||
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
<FAB
|
<FAB
|
||||||
testID="composeFAB"
|
testID="composeFAB"
|
||||||
|
|
|
@ -72,6 +72,7 @@ export const DiscoverFeedsScreen = withAuthRequired(
|
||||||
style={[!isDesktopWeb && s.flex1]}
|
style={[!isDesktopWeb && s.flex1]}
|
||||||
data={feeds.feeds}
|
data={feeds.feeds}
|
||||||
keyExtractor={item => item.data.uri}
|
keyExtractor={item => item.data.uri}
|
||||||
|
contentContainerStyle={styles.contentContainer}
|
||||||
refreshControl={
|
refreshControl={
|
||||||
<RefreshControl
|
<RefreshControl
|
||||||
refreshing={feeds.isRefreshing}
|
refreshing={feeds.isRefreshing}
|
||||||
|
@ -93,7 +94,9 @@ export const DiscoverFeedsScreen = withAuthRequired(
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: {
|
container: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
paddingBottom: isDesktopWeb ? 0 : 100,
|
},
|
||||||
|
contentContainer: {
|
||||||
|
paddingBottom: 100,
|
||||||
},
|
},
|
||||||
containerDesktop: {
|
containerDesktop: {
|
||||||
borderLeftWidth: 1,
|
borderLeftWidth: 1,
|
||||||
|
|
|
@ -204,6 +204,24 @@ export const DesktopLeftNav = observer(function DesktopLeftNav() {
|
||||||
}
|
}
|
||||||
label="Notifications"
|
label="Notifications"
|
||||||
/>
|
/>
|
||||||
|
<NavItem
|
||||||
|
href="/settings/saved-feeds"
|
||||||
|
icon={
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon="satellite-dish"
|
||||||
|
style={pal.text as FontAwesomeIconStyle}
|
||||||
|
size={20}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
iconFilled={
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon="satellite-dish"
|
||||||
|
style={pal.text as FontAwesomeIconStyle}
|
||||||
|
size={20}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
label="My Feeds"
|
||||||
|
/>
|
||||||
<NavItem
|
<NavItem
|
||||||
href="/moderation"
|
href="/moderation"
|
||||||
icon={
|
icon={
|
||||||
|
|
Loading…
Reference in New Issue