Add custom feeds selector, rework search, simplify onboarding (#325)
* Get home screen's swipable pager working with the drawer * Add tab bar to pager * Implement popular & following views on home screen * Visual tune-up * Move the feed selector to the footer * Fix to 'new posts' poll * Add the view header as a feed item * Use the native driver on the tabbar indicator to improve perf * Reduce home polling to the currently active page; also reuse some code * Add soft reset on tap selected in tab bar * Remove explicit 'onboarding' flow * Choose good stuff based on service * Add foaf-based follow discovery * Fall back to who to follow * Fix backgrounds * Switch to the off-spec goodstuff route * 1.8 * Fix for dev & staging * Swap the tab bar items and rename suggested to what's hot * Go to whats-hot by default if you have no follows * Implement pager and tabbar for desktop web * Pin deps to make expo happy * Add language filtering to goodstuff
This commit is contained in:
parent
c31ffdac1b
commit
1de724b24b
33 changed files with 1634 additions and 692 deletions
|
@ -1,16 +1,18 @@
|
|||
import React from 'react'
|
||||
import {observer} from 'mobx-react-lite'
|
||||
import {Button} from '../util/forms/Button'
|
||||
import {Button, ButtonType} from '../util/forms/Button'
|
||||
import {useStores} from 'state/index'
|
||||
import * as apilib from 'lib/api/index'
|
||||
import * as Toast from '../util/Toast'
|
||||
|
||||
const FollowButton = observer(
|
||||
({
|
||||
type = 'inverted',
|
||||
did,
|
||||
declarationCid,
|
||||
onToggleFollow,
|
||||
}: {
|
||||
type?: ButtonType
|
||||
did: string
|
||||
declarationCid: string
|
||||
onToggleFollow?: (v: boolean) => void
|
||||
|
@ -42,7 +44,7 @@ const FollowButton = observer(
|
|||
|
||||
return (
|
||||
<Button
|
||||
type={isFollowing ? 'default' : 'primary'}
|
||||
type={isFollowing ? 'default' : type}
|
||||
onPress={onToggleFollowInner}
|
||||
label={isFollowing ? 'Unfollow' : 'Follow'}
|
||||
/>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react'
|
||||
import {StyleSheet, View} from 'react-native'
|
||||
import {observer} from 'mobx-react-lite'
|
||||
import {AppBskyActorProfile} from '@atproto/api'
|
||||
import {Link} from '../util/Link'
|
||||
import {Text} from '../util/text/Text'
|
||||
import {UserAvatar} from '../util/UserAvatar'
|
||||
|
@ -15,7 +16,9 @@ export function ProfileCard({
|
|||
avatar,
|
||||
description,
|
||||
isFollowedBy,
|
||||
noBg,
|
||||
noBorder,
|
||||
followers,
|
||||
renderButton,
|
||||
}: {
|
||||
handle: string
|
||||
|
@ -23,7 +26,9 @@ export function ProfileCard({
|
|||
avatar?: string
|
||||
description?: string
|
||||
isFollowedBy?: boolean
|
||||
noBg?: boolean
|
||||
noBorder?: boolean
|
||||
followers?: AppBskyActorProfile.View[] | undefined
|
||||
renderButton?: () => JSX.Element
|
||||
}) {
|
||||
const pal = usePalette('default')
|
||||
|
@ -31,9 +36,9 @@ export function ProfileCard({
|
|||
<Link
|
||||
style={[
|
||||
styles.outer,
|
||||
pal.view,
|
||||
pal.border,
|
||||
noBorder && styles.outerNoBorder,
|
||||
!noBg && pal.view,
|
||||
]}
|
||||
href={`/profile/${handle}`}
|
||||
title={handle}
|
||||
|
@ -73,6 +78,25 @@ export function ProfileCard({
|
|||
</Text>
|
||||
</View>
|
||||
) : undefined}
|
||||
{followers?.length ? (
|
||||
<View style={styles.followedBy}>
|
||||
<Text
|
||||
type="sm"
|
||||
style={[styles.followsByDesc, pal.textLight]}
|
||||
numberOfLines={2}
|
||||
lineHeight={1.2}>
|
||||
Followed by{' '}
|
||||
{followers.map(f => f.displayName || f.handle).join(', ')}
|
||||
</Text>
|
||||
{followers.slice(0, 3).map(f => (
|
||||
<View key={f.did} style={styles.followedByAviContainer}>
|
||||
<View style={[styles.followedByAvi, pal.view]}>
|
||||
<UserAvatar avatar={f.avatar} size={32} />
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
) : undefined}
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
@ -86,6 +110,9 @@ export const ProfileCardWithFollowBtn = observer(
|
|||
avatar,
|
||||
description,
|
||||
isFollowedBy,
|
||||
noBg,
|
||||
noBorder,
|
||||
followers,
|
||||
}: {
|
||||
did: string
|
||||
declarationCid: string
|
||||
|
@ -94,6 +121,9 @@ export const ProfileCardWithFollowBtn = observer(
|
|||
avatar?: string
|
||||
description?: string
|
||||
isFollowedBy?: boolean
|
||||
noBg?: boolean
|
||||
noBorder?: boolean
|
||||
followers?: AppBskyActorProfile.View[] | undefined
|
||||
}) => {
|
||||
const store = useStores()
|
||||
const isMe = store.me.handle === handle
|
||||
|
@ -105,6 +135,9 @@ export const ProfileCardWithFollowBtn = observer(
|
|||
avatar={avatar}
|
||||
description={description}
|
||||
isFollowedBy={isFollowedBy}
|
||||
noBg={noBg}
|
||||
noBorder={noBorder}
|
||||
followers={followers}
|
||||
renderButton={
|
||||
isMe
|
||||
? undefined
|
||||
|
@ -128,8 +161,8 @@ const styles = StyleSheet.create({
|
|||
alignItems: 'center',
|
||||
},
|
||||
layoutAvi: {
|
||||
width: 60,
|
||||
paddingLeft: 10,
|
||||
width: 54,
|
||||
paddingLeft: 4,
|
||||
paddingTop: 8,
|
||||
paddingBottom: 10,
|
||||
},
|
||||
|
@ -164,4 +197,27 @@ const styles = StyleSheet.create({
|
|||
marginLeft: 6,
|
||||
paddingHorizontal: 14,
|
||||
},
|
||||
|
||||
followedBy: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'flex-start',
|
||||
paddingLeft: 54,
|
||||
paddingRight: 20,
|
||||
marginBottom: 10,
|
||||
marginTop: -6,
|
||||
},
|
||||
followedByAviContainer: {
|
||||
width: 24,
|
||||
height: 36,
|
||||
},
|
||||
followedByAvi: {
|
||||
width: 36,
|
||||
height: 36,
|
||||
borderRadius: 18,
|
||||
padding: 2,
|
||||
},
|
||||
followsByDesc: {
|
||||
flex: 1,
|
||||
paddingRight: 10,
|
||||
},
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue