diff options
Diffstat (limited to 'src/view/com/util')
-rw-r--r-- | src/view/com/util/PostMeta.tsx | 22 | ||||
-rw-r--r-- | src/view/com/util/WelcomeBanner.tsx | 81 | ||||
-rw-r--r-- | src/view/com/util/forms/Button.tsx | 14 |
3 files changed, 97 insertions, 20 deletions
diff --git a/src/view/com/util/PostMeta.tsx b/src/view/com/util/PostMeta.tsx index af08708b4..cde5a3e92 100644 --- a/src/view/com/util/PostMeta.tsx +++ b/src/view/com/util/PostMeta.tsx @@ -24,20 +24,18 @@ export const PostMeta = observer(function (opts: PostMetaOpts) { let handle = opts.authorHandle const store = useStores() const isMe = opts.did === store.me.did + const isFollowing = + typeof opts.did === 'string' && store.me.follows.isFollowing(opts.did) - // NOTE we capture `isFollowing` via a memo so that follows - // don't change this UI immediately, but rather upon future - // renders - const isFollowing = React.useMemo( - () => - typeof opts.did === 'string' && store.me.follows.isFollowing(opts.did), - [opts.did, store.me.follows], - ) + const [didFollow, setDidFollow] = React.useState(false) + const onToggleFollow = React.useCallback(() => { + setDidFollow(true) + }, [setDidFollow]) if ( opts.showFollowBtn && !isMe && - !isFollowing && + (!isFollowing || didFollow) && opts.did && opts.declarationCid ) { @@ -71,7 +69,11 @@ export const PostMeta = observer(function (opts: PostMetaOpts) { </View> <View> - <FollowButton did={opts.did} declarationCid={opts.declarationCid} /> + <FollowButton + did={opts.did} + declarationCid={opts.declarationCid} + onToggleFollow={onToggleFollow} + /> </View> </View> ) diff --git a/src/view/com/util/WelcomeBanner.tsx b/src/view/com/util/WelcomeBanner.tsx index d52288502..e236bfb48 100644 --- a/src/view/com/util/WelcomeBanner.tsx +++ b/src/view/com/util/WelcomeBanner.tsx @@ -1,11 +1,43 @@ import React from 'react' import {StyleSheet, View} from 'react-native' +import {observer} from 'mobx-react-lite' +import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import {usePalette} from 'lib/hooks/usePalette' import {Text} from './text/Text' +import {Button} from './forms/Button' import {s} from 'lib/styles' +import {useStores} from 'state/index' +import {SUGGESTED_FOLLOWS} from 'lib/constants' +// @ts-ignore no type definition -prf +import ProgressBar from 'react-native-progress/Bar' -export function WelcomeBanner() { +export const WelcomeBanner = observer(() => { const pal = usePalette('default') + const store = useStores() + const [isReady, setIsReady] = React.useState(false) + + const numFollows = Math.min( + SUGGESTED_FOLLOWS(String(store.agent.service)).length, + 5, + ) + const remaining = numFollows - store.me.follows.numFollows + + React.useEffect(() => { + if (remaining <= 0) { + // wait 500ms for the progress bar anim to finish + const ti = setTimeout(() => { + setIsReady(true) + }, 500) + return () => clearTimeout(ti) + } else { + setIsReady(false) + } + }, [remaining]) + + const onPressDone = React.useCallback(() => { + store.shell.setOnboarding(false) + }, [store]) + return ( <View testID="welcomeBanner" @@ -16,18 +48,53 @@ export function WelcomeBanner() { lineHeight={1.1}> Welcome to the private beta! </Text> - <Text type="lg" style={[pal.text, s.textCenter]}> - Here are some recent posts. Follow their creators to build your feed. - </Text> + {isReady ? ( + <View style={styles.controls}> + <Button + type="primary" + style={[s.flexRow, s.alignCenter]} + onPress={onPressDone}> + <Text type="md-bold" style={s.white}> + See my feed! + </Text> + <FontAwesomeIcon icon="angle-right" size={14} style={s.white} /> + </Button> + </View> + ) : ( + <> + <Text type="lg" style={[pal.text, s.textCenter]}> + Follow at least {remaining} {remaining === 1 ? 'person' : 'people'}{' '} + to build your feed. + </Text> + <View style={[styles.controls, styles.progress]}> + <ProgressBar + progress={Math.max( + store.me.follows.numFollows / numFollows, + 0.05, + )} + /> + </View> + </> + )} </View> ) -} +}) const styles = StyleSheet.create({ container: { - paddingTop: 30, - paddingBottom: 26, + paddingTop: 16, + paddingBottom: 16, paddingHorizontal: 20, borderTopWidth: 1, + borderBottomWidth: 1, + }, + controls: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + marginTop: 10, + }, + progress: { + marginTop: 12, }, }) diff --git a/src/view/com/util/forms/Button.tsx b/src/view/com/util/forms/Button.tsx index a070d2f0f..f3f4d1c79 100644 --- a/src/view/com/util/forms/Button.tsx +++ b/src/view/com/util/forms/Button.tsx @@ -13,6 +13,7 @@ import {choose} from 'lib/functions' export type ButtonType = | 'primary' | 'secondary' + | 'default' | 'inverted' | 'primary-outline' | 'secondary-outline' @@ -40,6 +41,9 @@ export function Button({ secondary: { backgroundColor: theme.palette.secondary.background, }, + default: { + backgroundColor: theme.palette.default.backgroundLight, + }, inverted: { backgroundColor: theme.palette.inverted.background, }, @@ -66,15 +70,18 @@ export function Button({ const labelStyle = choose<TextStyle, Record<ButtonType, TextStyle>>(type, { primary: { color: theme.palette.primary.text, - fontWeight: theme.palette.primary.isLowContrast ? '500' : undefined, + fontWeight: '600', }, secondary: { color: theme.palette.secondary.text, fontWeight: theme.palette.secondary.isLowContrast ? '500' : undefined, }, + default: { + color: theme.palette.default.text, + }, inverted: { color: theme.palette.inverted.text, - fontWeight: theme.palette.inverted.isLowContrast ? '500' : undefined, + fontWeight: '600', }, 'primary-outline': { color: theme.palette.primary.textInverted, @@ -114,7 +121,8 @@ export function Button({ const styles = StyleSheet.create({ outer: { - paddingHorizontal: 10, + paddingHorizontal: 14, paddingVertical: 8, + borderRadius: 24, }, }) |