Settings revamp (#5745)

* start building storybook

* add title

* add some styles

* try out new icons

* more settings list component parts

* make text do the spacing

* clean up storybook

* gated new settings screen

* switch account

* add current profile

* use Layout.Screen

* Layout.Header and Layout.Content

* translate helpdesk text

thanks @surfdude29!

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* add account settings

* undo changes to export car dialog

* privacy and security screen

* Translate protect account stuff

Thanks @surfdude29!

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* content and media settings

* about settings

* 2fa copy

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* a11y and appearance

* use new components for appearance settings

* redesign accessibility settings

* Update ContentAndMediaSettings.tsx

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* add divider

* remove a11y and appearance middleman screen

* fix web settingslist styles

* new SettingsList.Group component

* explain how portal magic works

* hide pwioptout in old location

* Update Settings.tsx

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* replace gate with `IS_INTERNAL`

* add IS_INTERNAL to app-info.web

* fix profile area growing

* add close button to switch account

---------

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
This commit is contained in:
Samuel Newman
2024-10-29 21:14:54 +00:00
committed by GitHub
parent ab492cd77a
commit c8f264b78b
59 changed files with 1811 additions and 133 deletions
+7 -6
View File
@@ -10,15 +10,15 @@ import {LinearGradient} from 'expo-linear-gradient'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {usePalette} from '#/lib/hooks/usePalette'
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
import {cleanError} from '#/lib/strings/errors'
import {colors, gradients, s} from '#/lib/styles'
import {useTheme} from '#/lib/ThemeContext'
import {isAndroid, isWeb} from '#/platform/detection'
import {useModalControls} from '#/state/modals'
import {DM_SERVICE_HEADERS} from '#/state/queries/messages/const'
import {useAgent, useSession, useSessionApi} from '#/state/session'
import {usePalette} from 'lib/hooks/usePalette'
import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
import {cleanError} from 'lib/strings/errors'
import {colors, gradients, s} from 'lib/styles'
import {useTheme} from 'lib/ThemeContext'
import {isAndroid, isWeb} from 'platform/detection'
import {DeactivateAccountDialog} from '#/screens/Settings/components/DeactivateAccountDialog'
import {atoms as a, useTheme as useNewTheme} from '#/alf'
import {useDialogControl} from '#/components/Dialog'
@@ -210,6 +210,7 @@ export function Component({}: {}) {
to="#"
onPress={e => {
e.preventDefault()
closeModal()
deactivateAccountControl.open()
return false
}}>
+11 -1
View File
@@ -4,6 +4,7 @@ import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useFocusEffect} from '@react-navigation/native'
import {IS_INTERNAL} from '#/lib/app-info'
import {usePalette} from '#/lib/hooks/usePalette'
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
import {CommonNavigatorParams, NativeStackScreenProps} from '#/lib/routes/types'
@@ -26,6 +27,7 @@ import {ToggleButton} from '#/view/com/util/forms/ToggleButton'
import {SimpleViewHeader} from '#/view/com/util/SimpleViewHeader'
import {Text} from '#/view/com/util/text/Text'
import {ScrollView} from '#/view/com/util/Views'
import {AccessibilitySettingsScreen as NewAccessibilitySettingsScreen} from '#/screens/Settings/AccessibilitySettings'
import {atoms as a} from '#/alf'
import * as Layout from '#/components/Layout'
@@ -33,7 +35,15 @@ type Props = NativeStackScreenProps<
CommonNavigatorParams,
'AccessibilitySettings'
>
export function AccessibilitySettingsScreen({}: Props) {
export function AccessibilitySettingsScreen(props: Props) {
return IS_INTERNAL ? (
<NewAccessibilitySettingsScreen {...props} />
) : (
<LegacyAccessibilitySettingsScreen {...props} />
)
}
function LegacyAccessibilitySettingsScreen({}: Props) {
const pal = usePalette('default')
const setMinimalShellMode = useSetMinimalShellMode()
const {isMobile, isTabletOrMobile} = useWebMediaQueries()
@@ -108,7 +108,11 @@ export function DisableEmail2FADialog({
{error ? <ErrorMessage message={error} /> : undefined}
{stage === Stages.Email ? (
<View style={gtMobile && [a.flex_row, a.justify_end, a.gap_md]}>
<View
style={[
a.gap_sm,
gtMobile && [a.flex_row, a.justify_end, a.gap_md],
]}>
<Button
testID="sendEmailButton"
variant="solid"
@@ -157,7 +161,11 @@ export function DisableEmail2FADialog({
/>
</TextField.Root>
</View>
<View style={gtMobile && [a.flex_row, a.justify_end]}>
<View
style={[
a.gap_sm,
gtMobile && [a.flex_row, a.justify_end, a.gap_md],
]}>
<Button
testID="resendCodeBtn"
variant="ghost"
@@ -10,6 +10,7 @@ import * as Toast from '#/view/com/util/Toast'
import {atoms as a, useTheme} from '#/alf'
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import * as Dialog from '#/components/Dialog'
import {Download_Stroke2_Corner0_Rounded as DownloadIcon} from '#/components/icons/Download'
import {InlineLinkText} from '#/components/Link'
import {Loader} from '#/components/Loader'
import {Text} from '#/components/Typography'
@@ -76,6 +77,7 @@ export function ExportCarDialog({
label={_(msg`Download CAR file`)}
disabled={loading}
onPress={download}>
<ButtonIcon icon={DownloadIcon} />
<ButtonText>
<Trans>Download CAR file</Trans>
</ButtonText>
+11 -2
View File
@@ -18,7 +18,7 @@ import {useLingui} from '@lingui/react'
import {useFocusEffect, useNavigation} from '@react-navigation/native'
import {useQueryClient} from '@tanstack/react-query'
import {appVersion, BUNDLE_DATE, bundleInfo} from '#/lib/app-info'
import {appVersion, BUNDLE_DATE, bundleInfo, IS_INTERNAL} from '#/lib/app-info'
import {STATUS_PAGE_URL} from '#/lib/constants'
import {useAccountSwitcher} from '#/lib/hooks/useAccountSwitcher'
import {useCustomPalette} from '#/lib/hooks/useCustomPalette'
@@ -53,6 +53,7 @@ import * as Toast from '#/view/com/util/Toast'
import {UserAvatar} from '#/view/com/util/UserAvatar'
import {ScrollView} from '#/view/com/util/Views'
import {DeactivateAccountDialog} from '#/screens/Settings/components/DeactivateAccountDialog'
import {SettingsScreen as NewSettingsScreen} from '#/screens/Settings/Settings'
import {atoms as a, useTheme} from '#/alf'
import {useDialogControl} from '#/components/Dialog'
import {BirthDateSettingsDialog} from '#/components/dialogs/BirthDateSettings'
@@ -137,7 +138,15 @@ function SettingsAccountCard({
}
type Props = NativeStackScreenProps<CommonNavigatorParams, 'Settings'>
export function SettingsScreen({}: Props) {
export function SettingsScreen(props: Props) {
return IS_INTERNAL ? (
<NewSettingsScreen {...props} />
) : (
<LegacySettingsScreen {...props} />
)
}
function LegacySettingsScreen({}: Props) {
const queryClient = useQueryClient()
const pal = usePalette('default')
const {_} = useLingui()
+134
View File
@@ -0,0 +1,134 @@
import React from 'react'
import {View} from 'react-native'
import * as Toast from '#/view/com/util/Toast'
import * as SettingsList from '#/screens/Settings/components/SettingsList'
import {atoms as a, useTheme} from '#/alf'
import {Alien_Stroke2_Corner0_Rounded as AlienIcon} from '#/components/icons/Alien'
import {BirthdayCake_Stroke2_Corner2_Rounded as BirthdayCakeIcon} from '#/components/icons/BirthdayCake'
import {BubbleInfo_Stroke2_Corner2_Rounded as BubbleInfoIcon} from '#/components/icons/BubbleInfo'
import {CircleQuestion_Stroke2_Corner2_Rounded as CircleQuestionIcon} from '#/components/icons/CircleQuestion'
import {Envelope_Stroke2_Corner2_Rounded as EnvelopeIcon} from '#/components/icons/Envelope'
import {Explosion_Stroke2_Corner0_Rounded as ExplosionIcon} from '#/components/icons/Explosion'
import {Earth_Stroke2_Corner2_Rounded as EarthIcon} from '#/components/icons/Globe'
import {PaintRoller_Stroke2_Corner2_Rounded as PaintRollerIcon} from '#/components/icons/PaintRoller'
import {Person_Stroke2_Corner2_Rounded as PersonIcon} from '#/components/icons/Person'
import {Pizza_Stroke2_Corner0_Rounded as PizzaIcon} from '#/components/icons/Pizza'
import {RaisingHand4Finger_Stroke2_Corner2_Rounded as HandIcon} from '#/components/icons/RaisingHand'
import {Verified_Stroke2_Corner2_Rounded as VerifiedIcon} from '#/components/icons/Verified'
import {Window_Stroke2_Corner2_Rounded as WindowIcon} from '#/components/icons/Window'
import {Text} from '#/components/Typography'
export function Settings() {
const t = useTheme()
return (
<View style={{marginLeft: -20, marginRight: -20}}>
<Text style={{marginLeft: 20, paddingBottom: 12}}>Settings</Text>
<SettingsList.LinkItem to="/settings" label="Account">
<SettingsList.ItemIcon icon={PersonIcon} />
<SettingsList.ItemText>Account</SettingsList.ItemText>
</SettingsList.LinkItem>
<SettingsList.LinkItem to="/settings" label="Privacy and security">
<SettingsList.ItemIcon icon={PaintRollerIcon} />
<SettingsList.ItemText>Privacy and security</SettingsList.ItemText>
</SettingsList.LinkItem>
<SettingsList.LinkItem to="/settings" label="Moderation">
<SettingsList.ItemIcon icon={HandIcon} />
<SettingsList.ItemText>Moderation</SettingsList.ItemText>
</SettingsList.LinkItem>
<SettingsList.LinkItem to="/settings" label="Content and media">
<SettingsList.ItemIcon icon={WindowIcon} />
<SettingsList.ItemText>Content and media</SettingsList.ItemText>
</SettingsList.LinkItem>
<SettingsList.LinkItem
to="/settings"
label="Accessibility and appearance">
<SettingsList.ItemIcon icon={PaintRollerIcon} />
<SettingsList.ItemText>
Accessibilty and appearance
</SettingsList.ItemText>
</SettingsList.LinkItem>
<SettingsList.LinkItem to="/settings" label="Languages">
<SettingsList.ItemIcon icon={EarthIcon} />
<SettingsList.ItemText>Languages</SettingsList.ItemText>
</SettingsList.LinkItem>
<SettingsList.LinkItem to="/settings" label="Help">
<SettingsList.ItemIcon icon={CircleQuestionIcon} />
<SettingsList.ItemText>Help</SettingsList.ItemText>
</SettingsList.LinkItem>
<SettingsList.LinkItem to="/settings" label="About">
<SettingsList.ItemIcon icon={BubbleInfoIcon} />
<SettingsList.ItemText>About</SettingsList.ItemText>
</SettingsList.LinkItem>
<SettingsList.Divider />
<SettingsList.PressableItem
destructive
onPress={() => Toast.show('Sign out pressed')}
label="Sign out">
<SettingsList.ItemText>Sign out</SettingsList.ItemText>
</SettingsList.PressableItem>
<SettingsList.Item style={[a.mt_xl]}>
<SettingsList.ItemIcon icon={PizzaIcon} />
<SettingsList.ItemText>Not pressable</SettingsList.ItemText>
</SettingsList.Item>
<SettingsList.PressableItem
onPress={() => Toast.show('Pressable pressed')}
label="Pressable">
<SettingsList.ItemIcon icon={AlienIcon} />
<SettingsList.ItemText>Pressable</SettingsList.ItemText>
</SettingsList.PressableItem>
<SettingsList.LinkItem
to="/settings"
label="Destructive link"
destructive>
<SettingsList.ItemIcon icon={ExplosionIcon} />
<SettingsList.ItemText>Destructive link</SettingsList.ItemText>
</SettingsList.LinkItem>
<SettingsList.PressableItem
label="Email"
onPress={() => Toast.show('Email change dialog goes here')}>
<SettingsList.ItemIcon icon={EnvelopeIcon} />
<SettingsList.ItemText>Email</SettingsList.ItemText>
<SettingsList.BadgeText>hello@example.com</SettingsList.BadgeText>
</SettingsList.PressableItem>
<SettingsList.PressableItem
onPress={() => Toast.show('Pressable pressed')}
label="Protect your account"
style={[
a.my_sm,
a.mx_lg,
a.rounded_md,
{backgroundColor: t.palette.primary_50},
]}
hoverStyle={[{backgroundColor: t.palette.primary_100}]}
contentContainerStyle={[a.rounded_md, a.px_lg]}>
<SettingsList.ItemIcon
icon={VerifiedIcon}
color={t.palette.primary_500}
/>
<SettingsList.ItemText
style={[{color: t.palette.primary_500}, a.font_bold]}>
Protect your account
</SettingsList.ItemText>
<SettingsList.Chevron color={t.palette.primary_500} />
</SettingsList.PressableItem>
<SettingsList.Divider />
<SettingsList.Item>
<SettingsList.ItemIcon icon={BirthdayCakeIcon} />
<SettingsList.ItemText>Birthday</SettingsList.ItemText>
<SettingsList.BadgeButton
label="Edit"
onPress={() => Toast.show('Show edit birthday dialog')}
/>
</SettingsList.Item>
<SettingsList.LinkItem to="/settings" label="Long test">
<SettingsList.ItemIcon icon={ExplosionIcon} />
<SettingsList.ItemText>
long long long long long long long long long long long long long long
long long long long long long long long long long long long long long
long long long long long long long long long
</SettingsList.ItemText>
</SettingsList.LinkItem>
</View>
)
}
+3
View File
@@ -18,6 +18,7 @@ import {Forms} from './Forms'
import {Icons} from './Icons'
import {Links} from './Links'
import {Menus} from './Menus'
import {Settings} from './Settings'
import {Shadows} from './Shadows'
import {Spacing} from './Spacing'
import {Theming} from './Theming'
@@ -101,6 +102,8 @@ function StorybookInner() {
<Admonitions />
<Settings />
<ThemeProvider theme="light">
<Theming />
</ThemeProvider>