update starter pack wizard layout
This commit is contained in:
@@ -4,21 +4,24 @@ import {KeyboardAwareScrollView} from 'react-native-keyboard-controller'
|
|||||||
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
||||||
import {Image} from 'expo-image'
|
import {Image} from 'expo-image'
|
||||||
import {
|
import {
|
||||||
AppBskyActorDefs,
|
type AppBskyActorDefs,
|
||||||
AppBskyGraphDefs,
|
type AppBskyGraphDefs,
|
||||||
AtUri,
|
AtUri,
|
||||||
ModerationOpts,
|
type ModerationOpts,
|
||||||
} from '@atproto/api'
|
} from '@atproto/api'
|
||||||
import {GeneratorView} from '@atproto/api/dist/client/types/app/bsky/feed/defs'
|
import {type GeneratorView} from '@atproto/api/dist/client/types/app/bsky/feed/defs'
|
||||||
import {msg, Plural, Trans} from '@lingui/macro'
|
import {msg, Plural, Trans} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {useFocusEffect, useNavigation} from '@react-navigation/native'
|
import {useFocusEffect, useNavigation} from '@react-navigation/native'
|
||||||
import {NativeStackScreenProps} from '@react-navigation/native-stack'
|
import {type NativeStackScreenProps} from '@react-navigation/native-stack'
|
||||||
|
|
||||||
import {STARTER_PACK_MAX_SIZE} from '#/lib/constants'
|
import {STARTER_PACK_MAX_SIZE} from '#/lib/constants'
|
||||||
import {useEnableKeyboardControllerScreen} from '#/lib/hooks/useEnableKeyboardController'
|
import {useEnableKeyboardControllerScreen} from '#/lib/hooks/useEnableKeyboardController'
|
||||||
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
||||||
import {CommonNavigatorParams, NavigationProp} from '#/lib/routes/types'
|
import {
|
||||||
|
type CommonNavigatorParams,
|
||||||
|
type NavigationProp,
|
||||||
|
} from '#/lib/routes/types'
|
||||||
import {logEvent} from '#/lib/statsig/statsig'
|
import {logEvent} from '#/lib/statsig/statsig'
|
||||||
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||||
@@ -41,7 +44,10 @@ import {useSession} from '#/state/session'
|
|||||||
import {useSetMinimalShellMode} from '#/state/shell'
|
import {useSetMinimalShellMode} from '#/state/shell'
|
||||||
import * as Toast from '#/view/com/util/Toast'
|
import * as Toast from '#/view/com/util/Toast'
|
||||||
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
||||||
import {useWizardState, WizardStep} from '#/screens/StarterPack/Wizard/State'
|
import {
|
||||||
|
useWizardState,
|
||||||
|
type WizardStep,
|
||||||
|
} from '#/screens/StarterPack/Wizard/State'
|
||||||
import {StepDetails} from '#/screens/StarterPack/Wizard/StepDetails'
|
import {StepDetails} from '#/screens/StarterPack/Wizard/StepDetails'
|
||||||
import {StepFeeds} from '#/screens/StarterPack/Wizard/StepFeeds'
|
import {StepFeeds} from '#/screens/StarterPack/Wizard/StepFeeds'
|
||||||
import {StepProfiles} from '#/screens/StarterPack/Wizard/StepProfiles'
|
import {StepProfiles} from '#/screens/StarterPack/Wizard/StepProfiles'
|
||||||
@@ -53,7 +59,7 @@ import {ListMaybePlaceholder} from '#/components/Lists'
|
|||||||
import {Loader} from '#/components/Loader'
|
import {Loader} from '#/components/Loader'
|
||||||
import {WizardEditListDialog} from '#/components/StarterPack/Wizard/WizardEditListDialog'
|
import {WizardEditListDialog} from '#/components/StarterPack/Wizard/WizardEditListDialog'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import * as bsky from '#/types/bsky'
|
import type * as bsky from '#/types/bsky'
|
||||||
import {Provider} from './State'
|
import {Provider} from './State'
|
||||||
|
|
||||||
export function Wizard({
|
export function Wizard({
|
||||||
@@ -279,6 +285,17 @@ function WizardInner({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const items =
|
||||||
|
state.currentStep === 'Profiles'
|
||||||
|
? [profile, ...state.profiles]
|
||||||
|
: state.feeds
|
||||||
|
|
||||||
|
const isEditEnabled =
|
||||||
|
(state.currentStep === 'Profiles' && items.length > 1) ||
|
||||||
|
(state.currentStep === 'Feeds' && items.length > 0)
|
||||||
|
|
||||||
|
const editDialogControl = useDialogControl()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout.Center style={[a.flex_1]}>
|
<Layout.Center style={[a.flex_1]}>
|
||||||
<Layout.Header.Outer>
|
<Layout.Header.Outer>
|
||||||
@@ -297,7 +314,19 @@ function WizardInner({
|
|||||||
{currUiStrings.header}
|
{currUiStrings.header}
|
||||||
</Layout.Header.TitleText>
|
</Layout.Header.TitleText>
|
||||||
</Layout.Header.Content>
|
</Layout.Header.Content>
|
||||||
<Layout.Header.Slot />
|
{isEditEnabled ? (
|
||||||
|
<Button
|
||||||
|
label={_(msg`Edit`)}
|
||||||
|
color="secondary"
|
||||||
|
size="small"
|
||||||
|
onPress={editDialogControl.open}>
|
||||||
|
<ButtonText>
|
||||||
|
<Trans>Edit</Trans>
|
||||||
|
</ButtonText>
|
||||||
|
</Button>
|
||||||
|
) : (
|
||||||
|
<Layout.Header.Slot />
|
||||||
|
)}
|
||||||
</Layout.Header.Outer>
|
</Layout.Header.Outer>
|
||||||
|
|
||||||
<Container>
|
<Container>
|
||||||
@@ -314,10 +343,16 @@ function WizardInner({
|
|||||||
<Footer
|
<Footer
|
||||||
onNext={onNext}
|
onNext={onNext}
|
||||||
nextBtnText={currUiStrings.nextBtn}
|
nextBtnText={currUiStrings.nextBtn}
|
||||||
moderationOpts={moderationOpts}
|
|
||||||
profile={profile}
|
profile={profile}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
<WizardEditListDialog
|
||||||
|
control={editDialogControl}
|
||||||
|
state={state}
|
||||||
|
dispatch={dispatch}
|
||||||
|
moderationOpts={moderationOpts}
|
||||||
|
profile={profile}
|
||||||
|
/>
|
||||||
</Layout.Center>
|
</Layout.Center>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -357,18 +392,14 @@ function Container({children}: {children: React.ReactNode}) {
|
|||||||
function Footer({
|
function Footer({
|
||||||
onNext,
|
onNext,
|
||||||
nextBtnText,
|
nextBtnText,
|
||||||
moderationOpts,
|
|
||||||
profile,
|
profile,
|
||||||
}: {
|
}: {
|
||||||
onNext: () => void
|
onNext: () => void
|
||||||
nextBtnText: string
|
nextBtnText: string
|
||||||
moderationOpts: ModerationOpts
|
|
||||||
profile: AppBskyActorDefs.ProfileViewDetailed
|
profile: AppBskyActorDefs.ProfileViewDetailed
|
||||||
}) {
|
}) {
|
||||||
const {_} = useLingui()
|
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const [state, dispatch] = useWizardState()
|
const [state] = useWizardState()
|
||||||
const editDialogControl = useDialogControl()
|
|
||||||
const {bottom: bottomInset} = useSafeAreaInsets()
|
const {bottom: bottomInset} = useSafeAreaInsets()
|
||||||
|
|
||||||
const items =
|
const items =
|
||||||
@@ -376,10 +407,6 @@ function Footer({
|
|||||||
? [profile, ...state.profiles]
|
? [profile, ...state.profiles]
|
||||||
: state.feeds
|
: state.feeds
|
||||||
|
|
||||||
const isEditEnabled =
|
|
||||||
(state.currentStep === 'Profiles' && items.length > 1) ||
|
|
||||||
(state.currentStep === 'Feeds' && items.length > 0)
|
|
||||||
|
|
||||||
const minimumItems = state.currentStep === 'Profiles' ? 8 : 0
|
const minimumItems = state.currentStep === 'Profiles' ? 8 : 0
|
||||||
|
|
||||||
const textStyles = [a.text_md]
|
const textStyles = [a.text_md]
|
||||||
@@ -416,14 +443,26 @@ function Footer({
|
|||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<View style={[a.flex_row, a.gap_xs]}>
|
<View style={[a.flex_row]}>
|
||||||
{items.slice(0, 6).map((p, index) => (
|
{items.slice(0, 6).map((p, index) => (
|
||||||
<UserAvatar
|
<View
|
||||||
key={index}
|
key={index}
|
||||||
avatar={p.avatar}
|
style={[
|
||||||
size={32}
|
a.rounded_full,
|
||||||
type={state.currentStep === 'Profiles' ? 'user' : 'algo'}
|
{
|
||||||
/>
|
borderWidth: 0.5,
|
||||||
|
borderColor: t.atoms.bg.backgroundColor,
|
||||||
|
},
|
||||||
|
state.currentStep === 'Profiles'
|
||||||
|
? {zIndex: 1 - index, marginLeft: index > 0 ? -8 : 0}
|
||||||
|
: {marginRight: 4},
|
||||||
|
]}>
|
||||||
|
<UserAvatar
|
||||||
|
avatar={p.avatar}
|
||||||
|
size={32}
|
||||||
|
type={state.currentStep === 'Profiles' ? 'user' : 'algo'}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
))}
|
))}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
@@ -523,56 +562,31 @@ function Footer({
|
|||||||
|
|
||||||
<View
|
<View
|
||||||
style={[
|
style={[
|
||||||
a.flex_row,
|
|
||||||
a.w_full,
|
a.w_full,
|
||||||
a.justify_between,
|
|
||||||
a.align_center,
|
a.align_center,
|
||||||
|
a.gap_2xl,
|
||||||
isNative ? a.mt_sm : a.mt_md,
|
isNative ? a.mt_sm : a.mt_md,
|
||||||
]}>
|
]}>
|
||||||
{isEditEnabled ? (
|
{state.currentStep === 'Profiles' && items.length < 8 && (
|
||||||
<Button
|
<Text style={[a.font_bold, textStyles, t.atoms.text_contrast_medium]}>
|
||||||
label={_(msg`Edit`)}
|
<Trans>Add {8 - items.length} more to continue</Trans>
|
||||||
variant="solid"
|
</Text>
|
||||||
color="secondary"
|
|
||||||
size="small"
|
|
||||||
style={{width: 70}}
|
|
||||||
onPress={editDialogControl.open}>
|
|
||||||
<ButtonText>
|
|
||||||
<Trans>Edit</Trans>
|
|
||||||
</ButtonText>
|
|
||||||
</Button>
|
|
||||||
) : (
|
|
||||||
<View style={{width: 70, height: 35}} />
|
|
||||||
)}
|
|
||||||
{state.currentStep === 'Profiles' && items.length < 8 ? (
|
|
||||||
<>
|
|
||||||
<Text
|
|
||||||
style={[a.font_bold, textStyles, t.atoms.text_contrast_medium]}>
|
|
||||||
<Trans>Add {8 - items.length} more to continue</Trans>
|
|
||||||
</Text>
|
|
||||||
<View style={{width: 70}} />
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<Button
|
|
||||||
label={nextBtnText}
|
|
||||||
variant="solid"
|
|
||||||
color="primary"
|
|
||||||
size="small"
|
|
||||||
onPress={onNext}
|
|
||||||
disabled={!state.canNext || state.processing}>
|
|
||||||
<ButtonText>{nextBtnText}</ButtonText>
|
|
||||||
{state.processing && <Loader size="xs" style={{color: 'white'}} />}
|
|
||||||
</Button>
|
|
||||||
)}
|
)}
|
||||||
|
<Button
|
||||||
|
label={nextBtnText}
|
||||||
|
style={[a.w_full, a.py_md, a.px_2xl]}
|
||||||
|
color="primary"
|
||||||
|
size="large"
|
||||||
|
onPress={onNext}
|
||||||
|
disabled={
|
||||||
|
!state.canNext ||
|
||||||
|
state.processing ||
|
||||||
|
(state.currentStep === 'Profiles' && items.length < 8)
|
||||||
|
}>
|
||||||
|
<ButtonText>{nextBtnText}</ButtonText>
|
||||||
|
{state.processing && <Loader size="xs" style={{color: 'white'}} />}
|
||||||
|
</Button>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<WizardEditListDialog
|
|
||||||
control={editDialogControl}
|
|
||||||
state={state}
|
|
||||||
dispatch={dispatch}
|
|
||||||
moderationOpts={moderationOpts}
|
|
||||||
profile={profile}
|
|
||||||
/>
|
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user