From 3cd3bd4e6a6068ba719b13e84294852ca63a7a00 Mon Sep 17 00:00:00 2001 From: serenity <98162476+NekoDrone@users.noreply.github.com> Date: Wed, 17 Sep 2025 22:33:00 +0800 Subject: [PATCH] refactor!: remove deprecated usePalette hook --- src/components/Post/Embed/PostPlaceholder.tsx | 17 +- src/components/Post/Embed/index.tsx | 12 +- src/components/SearchError.tsx | 10 +- src/lib/hooks/usePalette.ts | 65 ------- src/screens/Profile/ProfileFeed/index.tsx | 34 +++- src/screens/Search/SearchResults.tsx | 6 +- src/view/com/composer/Composer.tsx | 37 +++- .../composer/char-progress/CharProgress.tsx | 19 +- src/view/com/lists/MyLists.tsx | 28 ++- src/view/com/modals/CreateOrEditList.tsx | 61 ++++-- src/view/com/modals/CropImage.web.tsx | 6 +- src/view/com/modals/DeleteAccount.tsx | 72 ++++--- src/view/com/modals/InviteCodes.tsx | 73 +++++-- src/view/com/modals/Modal.tsx | 24 ++- src/view/com/modals/Modal.web.tsx | 15 +- src/view/com/modals/UserAddRemoveLists.tsx | 73 +++++-- .../lang-settings/ConfirmLanguagesButton.tsx | 6 +- .../ContentLanguagesSettings.tsx | 29 ++- .../modals/lang-settings/LanguageToggle.tsx | 10 +- .../notifications/NotificationFeedItem.tsx | 59 ++++-- src/view/com/post/Post.tsx | 7 +- src/view/com/posts/CustomFeedEmptyState.tsx | 23 ++- src/view/com/posts/DiscoverFallbackHeader.tsx | 30 ++- src/view/com/posts/FollowingEmptyState.tsx | 34 ++-- src/view/com/posts/FollowingEndOfFeed.tsx | 39 ++-- src/view/com/posts/PostFeedErrorMessage.tsx | 28 ++- src/view/com/posts/PostFeedItem.tsx | 81 ++++++-- src/view/com/posts/ViewFullThread.tsx | 25 ++- src/view/com/profile/ProfileSubpageHeader.tsx | 31 ++- src/view/com/util/EmptyState.tsx | 16 +- src/view/com/util/EmptyStateWithButton.tsx | 25 ++- src/view/com/util/LoadMoreRetryBtn.tsx | 29 ++- src/view/com/util/LoadingPlaceholder.tsx | 77 +++++--- src/view/com/util/ViewSelector.tsx | 47 ++++- src/view/com/util/Views.web.tsx | 9 +- src/view/com/util/error/ErrorMessage.tsx | 20 +- src/view/com/util/error/ErrorScreen.tsx | 17 +- src/view/com/util/forms/NativeDropdown.tsx | 50 +++-- .../com/util/forms/NativeDropdown.web.tsx | 50 +++-- src/view/com/util/layouts/LoggedOutLayout.tsx | 46 +++-- src/view/icons/Logomark.tsx | 12 +- src/view/icons/Logotype.tsx | 12 +- src/view/screens/CommunityGuidelines.tsx | 27 ++- src/view/screens/CopyrightPolicy.tsx | 27 ++- src/view/screens/Debug.tsx | 182 +++++++++++------- src/view/screens/Feeds.tsx | 30 +-- src/view/screens/NotFound.tsx | 32 ++- src/view/screens/PrivacyPolicy.tsx | 25 ++- src/view/screens/Support.tsx | 36 +++- src/view/screens/TermsOfService.tsx | 27 ++- src/view/shell/bottom-bar/BottomBar.tsx | 55 ++++-- src/view/shell/desktop/LeftNav.tsx | 54 +++--- src/view/shell/desktop/Search.tsx | 45 +++-- 53 files changed, 1313 insertions(+), 591 deletions(-) delete mode 100644 src/lib/hooks/usePalette.ts diff --git a/src/components/Post/Embed/PostPlaceholder.tsx b/src/components/Post/Embed/PostPlaceholder.tsx index 840234026..5d081f147 100644 --- a/src/components/Post/Embed/PostPlaceholder.tsx +++ b/src/components/Post/Embed/PostPlaceholder.tsx @@ -1,18 +1,27 @@ import {StyleSheet, View} from 'react-native' -import {usePalette} from '#/lib/hooks/usePalette' import {InfoCircleIcon} from '#/lib/icons' import {Text} from '#/view/com/util/text/Text' import {atoms as a, useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' export function PostPlaceholder({children}: {children: React.ReactNode}) { const t = useTheme() - const pal = usePalette('default') + const colorMode = useColorModeTheme() return ( - - + + {children} diff --git a/src/components/Post/Embed/index.tsx b/src/components/Post/Embed/index.tsx index 8566c2fe6..9ae995043 100644 --- a/src/components/Post/Embed/index.tsx +++ b/src/components/Post/Embed/index.tsx @@ -11,7 +11,6 @@ import { import {Trans} from '@lingui/macro' import {useQueryClient} from '@tanstack/react-query' -import {usePalette} from '#/lib/hooks/usePalette' import {makeProfileLink} from '#/lib/routes/links' import {useModerationOpts} from '#/state/preferences/moderation-opts' import {unstableCacheProfileView} from '#/state/queries/profile' @@ -176,14 +175,14 @@ function RecordEmbed({ case 'post_not_found': { return ( - Deleted + Deleted ) } case 'post_blocked': { return ( - Blocked + Blocked ) } @@ -209,9 +208,9 @@ export function PostDetachedEmbed({ return ( {isViewerOwner ? ( - Removed by you + Removed by you ) : ( - Removed by author + Removed by author )} ) @@ -247,7 +246,6 @@ export function QuoteEmbed({ const t = useTheme() const queryClient = useQueryClient() - const pal = usePalette('default') const itemUrip = new AtUri(quote.uri) const itemHref = makeProfileLink(quote.author, 'post', itemUrip.rkey) const itemTitle = `Post by ${quote.author.handle}` @@ -287,7 +285,7 @@ export function QuoteEmbed({ {!active && } diff --git a/src/components/SearchError.tsx b/src/components/SearchError.tsx index 443bbab8f..633710e34 100644 --- a/src/components/SearchError.tsx +++ b/src/components/SearchError.tsx @@ -1,7 +1,6 @@ import {View} from 'react-native' -import {usePalette} from '#/lib/hooks/usePalette' -import {atoms as a, useBreakpoints} from '#/alf' +import {atoms as a, useBreakpoints, useTheme} from '#/alf' import * as Layout from '#/components/Layout' import {Text} from '#/components/Typography' import {TimesLarge_Stroke2_Corner0_Rounded} from './icons/Times' @@ -13,8 +12,8 @@ export function SearchError({ title?: string children?: React.ReactNode }) { + const theme = useTheme() const {gtMobile} = useBreakpoints() - const pal = usePalette('default') return ( @@ -27,7 +26,10 @@ export function SearchError({ paddingVertical: 150, }, ]}> - + { - const palette = theme.palette[color] - return { - colors: palette, - view: { - backgroundColor: palette.background, - }, - viewLight: { - backgroundColor: palette.backgroundLight, - }, - btn: { - backgroundColor: palette.backgroundLight, - }, - border: { - borderColor: palette.border, - }, - borderDark: { - borderColor: palette.borderDark, - }, - text: { - color: palette.text, - }, - textLight: { - color: palette.textLight, - }, - textInverted: { - color: palette.textInverted, - }, - link: { - color: palette.link, - }, - icon: { - color: palette.icon, - }, - } - }, [theme, color]) -} diff --git a/src/screens/Profile/ProfileFeed/index.tsx b/src/screens/Profile/ProfileFeed/index.tsx index b97fc4ed5..e89af9d93 100644 --- a/src/screens/Profile/ProfileFeed/index.tsx +++ b/src/screens/Profile/ProfileFeed/index.tsx @@ -1,5 +1,5 @@ import React, {useCallback, useMemo} from 'react' -import {StyleSheet, View} from 'react-native' +import {StyleSheet, type TextStyle, View} from 'react-native' import {useAnimatedRef} from 'react-native-reanimated' import {AppBskyFeedDefs} from '@atproto/api' import {msg, Trans} from '@lingui/macro' @@ -10,7 +10,6 @@ import {useQueryClient} from '@tanstack/react-query' import {VIDEO_FEED_URIS} from '#/lib/constants' import {useOpenComposer} from '#/lib/hooks/useOpenComposer' -import {usePalette} from '#/lib/hooks/usePalette' import {useSetTitle} from '#/lib/hooks/useSetTitle' import {ComposeIcon2} from '#/lib/icons' import {type CommonNavigatorParams} from '#/lib/routes/types' @@ -45,6 +44,8 @@ import { ProfileFeedHeader, ProfileFeedHeaderSkeleton, } from '#/screens/Profile/components/ProfileFeedHeader' +import {useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import * as Layout from '#/components/Layout' type Props = NativeStackScreenProps @@ -56,10 +57,15 @@ export function ProfileFeedScreen(props: Props) { feedCacheKey: props.route.params.feedCacheKey, } : undefined - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() const {_} = useLingui() const navigation = useNavigation() + const textStyle: TextStyle = { + color: colorMode === 'light' ? theme.palette.black : theme.palette.white, + } + const uri = useMemo( () => makeRecordUri(handleOrDid, 'app.bsky.feed.generator', rkey), [rkey, handleOrDid], @@ -78,11 +84,21 @@ export function ProfileFeedScreen(props: Props) { return ( - - - Could not load feed + + + Could not load feed - + {error.toString()} @@ -93,8 +109,8 @@ export function ProfileFeedScreen(props: Props) { accessibilityHint={_(msg`Returns to previous page`)} onPress={onPressBack} style={{flexShrink: 1}}> - - Go Back + + Go Back diff --git a/src/screens/Search/SearchResults.tsx b/src/screens/Search/SearchResults.tsx index 4c4068417..5efbc1f67 100644 --- a/src/screens/Search/SearchResults.tsx +++ b/src/screens/Search/SearchResults.tsx @@ -4,7 +4,6 @@ import {type AppBskyFeedDefs} from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {usePalette} from '#/lib/hooks/usePalette' import {augmentSearchQuery} from '#/lib/strings/helpers' import {useActorSearch} from '#/state/queries/actor-search' import {usePopularFeedsSearch} from '#/state/queries/feed' @@ -193,7 +192,6 @@ let SearchScreenPostResults = ({ hasNextPage, } = useSearchPostsQuery({query: augmentedQuery, sort, enabled: active}) - const pal = usePalette('default') const t = useTheme() const onPullToRefresh = useCallback(async () => { setIsPTR(true) @@ -254,7 +252,7 @@ let SearchScreenPostResults = ({ @@ -262,7 +260,7 @@ let SearchScreenPostResults = ({ or diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index 2a9635402..5ab327b52 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -69,7 +69,6 @@ import {useAnimatedScrollHandler} from '#/lib/hooks/useAnimatedScrollHandler_FIX import {useAppState} from '#/lib/hooks/useAppState' import {useIsKeyboardVisible} from '#/lib/hooks/useIsKeyboardVisible' import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' -import {usePalette} from '#/lib/hooks/usePalette' import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' import {mimeToExt} from '#/lib/media/video/util' import {type NavigationProp} from '#/lib/routes/types' @@ -121,6 +120,7 @@ import {VideoTranscodeProgress} from '#/view/com/composer/videos/VideoTranscodeP import {Text} from '#/view/com/util/text/Text' import {UserAvatar} from '#/view/com/util/UserAvatar' import {atoms as a, native, useTheme, web} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfoIcon} from '#/components/icons/CircleInfo' import {EmojiArc_Stroke2_Corner0_Rounded as EmojiSmileIcon} from '#/components/icons/Emoji' @@ -994,7 +994,8 @@ function ComposerTopBar({ topBarAnimatedStyle: StyleProp children?: React.ReactNode }) { - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() const {_} = useLingui() return ( {isPublishing ? ( <> - {publishingStage} + + {publishingStage} + @@ -1085,9 +1094,16 @@ function ComposerTopBar({ } function AltTextReminder({error}: {error: string}) { - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() return ( - + - {error} + + {error} + ) } diff --git a/src/view/com/composer/char-progress/CharProgress.tsx b/src/view/com/composer/char-progress/CharProgress.tsx index 8920132a5..643fac4e7 100644 --- a/src/view/com/composer/char-progress/CharProgress.tsx +++ b/src/view/com/composer/char-progress/CharProgress.tsx @@ -10,8 +10,8 @@ import ProgressCircle from 'react-native-progress/Circle' import ProgressPie from 'react-native-progress/Pie' import {MAX_GRAPHEME_LENGTH} from '#/lib/constants' -import {usePalette} from '#/lib/hooks/usePalette' -import {atoms as a} from '#/alf' +import {atoms as a, useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {Text} from '../../util/text/Text' export function CharProgress({ @@ -27,10 +27,17 @@ export function CharProgress({ textStyle?: StyleProp size?: number }) { + const theme = useTheme() + const colorMode = useColorModeTheme() const maxLength = max || MAX_GRAPHEME_LENGTH - const pal = usePalette('default') - const textColor = count > maxLength ? '#e60000' : pal.colors.text - const circleColor = count > maxLength ? '#e60000' : pal.colors.link + const textColor = + count > maxLength + ? theme.palette.negative_500 + : colorMode === 'light' + ? theme.palette.black + : theme.palette.white + const circleColor = + count > maxLength ? theme.palette.negative_500 : theme.palette.primary_500 return ( @@ -55,7 +62,7 @@ export function CharProgress({ diff --git a/src/view/com/lists/MyLists.tsx b/src/view/com/lists/MyLists.tsx index 18110b8ba..a96547e06 100644 --- a/src/view/com/lists/MyLists.tsx +++ b/src/view/com/lists/MyLists.tsx @@ -11,13 +11,13 @@ import {type AppBskyGraphDefs as GraphDefs} from '@atproto/api' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {usePalette} from '#/lib/hooks/usePalette' import {cleanError} from '#/lib/strings/errors' import {s} from '#/lib/styles' import {logger} from '#/logger' import {useModerationOpts} from '#/state/preferences/moderation-opts' import {type MyListsFilter, useMyListsQuery} from '#/state/queries/my-lists' import {atoms as a, useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {BulletList_Stroke2_Corner0_Rounded as ListIcon} from '#/components/icons/BulletList' import * as ListCard from '#/components/ListCard' import {Text} from '#/components/Typography' @@ -41,8 +41,8 @@ export function MyLists({ renderItem?: (list: GraphDefs.ListView, index: number) => JSX.Element testID?: string }) { - const pal = usePalette('default') - const t = useTheme() + const theme = useTheme() + const colorMode = useColorModeTheme() const {_} = useLingui() const moderationOpts = useModerationOpts() const [isPTRing, setIsPTRing] = React.useState(false) @@ -108,13 +108,13 @@ export function MyLists({ a.align_center, a.justify_center, a.rounded_full, - t.atoms.bg_contrast_25, + theme.atoms.bg_contrast_25, { width: 32, height: 32, }, ]}> - + @@ -159,7 +159,7 @@ export function MyLists({ ) }, - [t, renderItem, error, onRefresh, emptyText], + [theme, renderItem, error, onRefresh, emptyText], ) if (inline) { @@ -175,8 +175,16 @@ export function MyLists({ } contentContainerStyle={[s.contentContainer]} diff --git a/src/view/com/modals/CreateOrEditList.tsx b/src/view/com/modals/CreateOrEditList.tsx index 3687dce90..816873af6 100644 --- a/src/view/com/modals/CreateOrEditList.tsx +++ b/src/view/com/modals/CreateOrEditList.tsx @@ -5,22 +5,23 @@ import { ScrollView, StyleSheet, TextInput, + type TextStyle, TouchableOpacity, + useColorScheme, View, + type ViewStyle, } from 'react-native' import {LinearGradient} from 'expo-linear-gradient' import {type AppBskyGraphDefs, RichText as RichTextAPI} from '@atproto/api' 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, isNetworkError} from '#/lib/strings/errors' import {enforceLen} from '#/lib/strings/helpers' import {richTextToString} from '#/lib/strings/rich-text-helpers' import {shortenLinks, stripInvalidMentions} from '#/lib/strings/rich-text-manip' import {colors, gradients, s} from '#/lib/styles' -import {useTheme} from '#/lib/ThemeContext' import {type ImageMeta} from '#/state/gallery' import {useModalControls} from '#/state/modals' import { @@ -32,6 +33,8 @@ import {ErrorMessage} from '#/view/com/util/error/ErrorMessage' import {Text} from '#/view/com/util/text/Text' import * as Toast from '#/view/com/util/Toast' import {EditableUserAvatar} from '#/view/com/util/UserAvatar' +import {useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' const MAX_NAME = 64 // todo const MAX_DESCRIPTION = 300 // todo @@ -50,8 +53,8 @@ export function Component({ const {closeModal} = useModalControls() const {isMobile} = useWebMediaQueries() const [error, setError] = useState('') - const pal = usePalette('default') const theme = useTheme() + const colorMode = useColorModeTheme() const {_} = useLingui() const listCreateMutation = useListCreateMutation() const listMetadataMutation = useListMetadataMutation() @@ -93,6 +96,25 @@ export function Component({ }, [descriptionRt]) const isDescriptionOver = graphemeLength > MAX_DESCRIPTION + const colorScheme = useColorScheme() ?? 'default' + + const viewStyle: ViewStyle = { + backgroundColor: + colorMode === 'light' ? theme.palette.white : theme.palette.black, + } + + const textStyle: TextStyle = { + color: colorMode === 'light' ? theme.palette.black : theme.palette.white, + } + + const textStyleLight: TextStyle = { + color: colorMode === 'light' ? theme.palette.white : theme.palette.black, + } + + const borderStyle: ViewStyle = { + borderColor: theme.palette.contrast_100, + } + const [avatar, setAvatar] = useState(list?.avatar) const [newAvatar, setNewAvatar] = useState() @@ -211,13 +233,13 @@ export function Component({ - + {isCurateList ? ( list ? ( Edit User List @@ -235,10 +257,19 @@ export function Component({ )} - + List Avatar - + - + List Name Description - {graphemeLength}/{MAX_DESCRIPTION} + style={[!isDescriptionOver ? textStyleLight : s.red3, s.f13]}> + {graphemeLength} / {MAX_DESCRIPTION} - + Cancel diff --git a/src/view/com/modals/CropImage.web.tsx b/src/view/com/modals/CropImage.web.tsx index 78c0466f0..6538e7224 100644 --- a/src/view/com/modals/CropImage.web.tsx +++ b/src/view/com/modals/CropImage.web.tsx @@ -6,13 +6,13 @@ import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import ReactCrop, {type PercentCrop} from 'react-image-crop' -import {usePalette} from '#/lib/hooks/usePalette' import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' import {type PickerImage} from '#/lib/media/picker.shared' import {getDataUriSize} from '#/lib/media/util' import {gradients, s} from '#/lib/styles' import {useModalControls} from '#/state/modals' import {Text} from '#/view/com/util/text/Text' +import {useTheme} from '#/alf' export const snapPoints = ['0%'] @@ -27,7 +27,7 @@ export function Component({ circular?: boolean onSelect: (img?: PickerImage) => void }) { - const pal = usePalette('default') + const theme = useTheme() const {_} = useLingui() const {closeModal} = useModalControls() @@ -78,7 +78,7 @@ export function Component({ return ( - + (false) const [confirmCode, setConfirmCode] = React.useState('') const [password, setPassword] = React.useState('') @@ -95,12 +112,12 @@ export function Component({}: {}) { } return ( - - - + + + Delete Account{' '} - + " {currentAccount?.handle} - + " @@ -121,7 +138,7 @@ export function Component({}: {}) { {!isEmailSent ? ( <> - + For security reasons, we'll need to send a confirmation code to your email address. @@ -166,7 +183,7 @@ export function Component({}: {}) { accessibilityLabel={_(msg`Cancel account deletion`)} accessibilityHint="" onAccessibilityEscape={onCancel}> - + Cancel @@ -182,7 +199,7 @@ export function Component({}: {}) { a.mt_lg, a.p_lg, a.rounded_sm, - t.atoms.bg_contrast_25, + theme.atoms.bg_contrast_25, ]}> Check your inbox for an email with the confirmation code to @@ -216,10 +233,15 @@ export function Component({}: {}) { Please enter your password as well: - + Cancel diff --git a/src/view/com/modals/InviteCodes.tsx b/src/view/com/modals/InviteCodes.tsx index 93f749062..4e09e4ebb 100644 --- a/src/view/com/modals/InviteCodes.tsx +++ b/src/view/com/modals/InviteCodes.tsx @@ -2,8 +2,10 @@ import React from 'react' import { ActivityIndicator, StyleSheet, + type TextStyle, TouchableOpacity, View, + type ViewStyle, } from 'react-native' import {setStringAsync} from 'expo-clipboard' import {type ComAtprotoServerDefs} from '@atproto/api' @@ -14,7 +16,6 @@ import { import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {usePalette} from '#/lib/hooks/usePalette' import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' import {makeProfileLink} from '#/lib/routes/links' import {cleanError} from '#/lib/strings/errors' @@ -25,6 +26,8 @@ import { type InviteCodesQueryResponse, useInviteCodesQuery, } from '#/state/queries/invites' +import {useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {ErrorMessage} from '../util/error/ErrorMessage' import {Button} from '../util/forms/Button' import {Link} from '../util/Link' @@ -50,7 +53,8 @@ export function Component() { } export function Inner({invites}: {invites: InviteCodesQueryResponse}) { - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() const {_} = useLingui() const {closeModal} = useModalControls() const {isTabletOrDesktop} = useWebMediaQueries() @@ -59,11 +63,28 @@ export function Inner({invites}: {invites: InviteCodesQueryResponse}) { closeModal() }, [closeModal]) + const viewStyle: ViewStyle = { + backgroundColor: + colorMode === 'light' ? theme.palette.white : theme.palette.black, + } + + const viewStyleLight: ViewStyle = { + backgroundColor: theme.palette.contrast_25, + } + + const textStyle: TextStyle = { + color: colorMode === 'light' ? theme.palette.black : theme.palette.white, + } + + const borderStyle: ViewStyle = { + borderColor: theme.palette.contrast_100, + } + if (invites.all.length === 0) { return ( - - - + + + You don't have any invite codes yet! We'll send you some when you've been on Bluesky for a little longer. @@ -89,16 +110,16 @@ export function Inner({invites}: {invites: InviteCodesQueryResponse}) { } return ( - - - Invite a Friend + + + Invite a Friend - + Each code works once. You'll receive more invite codes periodically. - + {invites.available.map((invite, i) => ( + style={used ? [textStyleLight, styles.strikeThrough] : textStyle}> {invite.code} {!used && invitesState.copiedInvites.includes(invite.code) && ( - + Copied )} {!used && ( )} @@ -197,7 +231,7 @@ function InviteCode({ gap: 8, paddingTop: 6, }}> - + Used by:{' '} {uses.map((use, i) => ( - - {i !== uses.length - 1 && , } + + {i !== uses.length - 1 && , } ))} diff --git a/src/view/com/modals/Modal.tsx b/src/view/com/modals/Modal.tsx index 79971e660..5dfee190f 100644 --- a/src/view/com/modals/Modal.tsx +++ b/src/view/com/modals/Modal.tsx @@ -1,10 +1,11 @@ import {Fragment, useEffect, useRef} from 'react' -import {StyleSheet} from 'react-native' +import {StyleSheet, type ViewStyle} from 'react-native' import {SafeAreaView} from 'react-native-safe-area-context' import BottomSheet from '@discord/bottom-sheet/src' -import {usePalette} from '#/lib/hooks/usePalette' import {useModalControls, useModals} from '#/state/modals' +import {useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {FullWindowOverlay} from '#/components/FullWindowOverlay' import {createCustomBackdrop} from '../util/BottomSheetCustomBackdrop' import * as CreateOrEditListModal from './CreateOrEditList' @@ -20,9 +21,15 @@ export function ModalsContainer() { const {isModalActive, activeModals} = useModals() const {closeModal} = useModalControls() const bottomSheetRef = useRef(null) - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() const activeModal = activeModals[activeModals.length - 1] + const viewStyle: ViewStyle = { + backgroundColor: + colorMode === 'light' ? theme.palette.white : theme.palette.black, + } + const onBottomSheetChange = async (snapPoint: number) => { if (snapPoint === -1) { closeModal() @@ -65,7 +72,7 @@ export function ModalsContainer() { if (snapPoints[0] === 'fullscreen') { return ( - + {element} ) @@ -86,9 +93,12 @@ export function ModalsContainer() { backdropComponent={ isModalActive ? createCustomBackdrop(onClose) : undefined } - handleIndicatorStyle={{backgroundColor: pal.text.color}} - handleStyle={[styles.handle, pal.view]} - backgroundStyle={pal.view} + handleIndicatorStyle={{ + backgroundColor: + colorMode === 'light' ? theme.palette.black : theme.palette.white, + }} + handleStyle={[styles.handle, viewStyle]} + backgroundStyle={viewStyle} onChange={onBottomSheetChange}> {element} diff --git a/src/view/com/modals/Modal.web.tsx b/src/view/com/modals/Modal.web.tsx index d0799a390..cef4a8bc6 100644 --- a/src/view/com/modals/Modal.web.tsx +++ b/src/view/com/modals/Modal.web.tsx @@ -2,10 +2,11 @@ import {StyleSheet, TouchableWithoutFeedback, View} from 'react-native' import Animated, {FadeIn, FadeOut} from 'react-native-reanimated' import {RemoveScrollBar} from 'react-remove-scroll-bar' -import {usePalette} from '#/lib/hooks/usePalette' import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' import {type Modal as ModalIface} from '#/state/modals' import {useModalControls, useModals} from '#/state/modals' +import {useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import * as CreateOrEditListModal from './CreateOrEditList' import * as DeleteAccountModal from './DeleteAccount' import * as InviteCodesModal from './InviteCodes' @@ -30,9 +31,10 @@ export function ModalsContainer() { } function Modal({modal}: {modal: ModalIface}) { + const theme = useTheme() + const colorMode = useColorModeTheme() const {isModalActive} = useModals() const {closeModal} = useModalControls() - const pal = usePalette('default') const {isMobile} = useWebMediaQueries() if (!isModalActive) { @@ -75,8 +77,13 @@ function Modal({modal}: {modal: ModalIface}) { style={[ styles.container, isMobile && styles.containerMobile, - pal.view, - pal.border, + { + backgroundColor: + colorMode === 'light' + ? theme.palette.white + : theme.palette.black, + borderColor: theme.palette.contrast_100, + }, ]}> {element} diff --git a/src/view/com/modals/UserAddRemoveLists.tsx b/src/view/com/modals/UserAddRemoveLists.tsx index 7c20b50c7..f1005ae28 100644 --- a/src/view/com/modals/UserAddRemoveLists.tsx +++ b/src/view/com/modals/UserAddRemoveLists.tsx @@ -2,6 +2,7 @@ import React, {useCallback} from 'react' import { ActivityIndicator, StyleSheet, + type TextStyle, useWindowDimensions, View, } from 'react-native' @@ -9,7 +10,6 @@ import {type AppBskyGraphDefs as GraphDefs} from '@atproto/api' import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {usePalette} from '#/lib/hooks/usePalette' import {sanitizeDisplayName} from '#/lib/strings/display-names' import {cleanError} from '#/lib/strings/errors' import {sanitizeHandle} from '#/lib/strings/handles' @@ -24,6 +24,8 @@ import { useListMembershipRemoveMutation, } from '#/state/queries/list-memberships' import {useSession} from '#/state/session' +import {useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {MyLists} from '../lists/MyLists' import {Button} from '../util/forms/Button' import {Text} from '../util/text/Text' @@ -45,25 +47,45 @@ export function Component({ onAdd?: (listUri: string) => void onRemove?: (listUri: string) => void }) { + const theme = useTheme() + const colorMode = useColorModeTheme() const {closeModal} = useModalControls() - const pal = usePalette('default') const {height: screenHeight} = useWindowDimensions() const {_} = useLingui() const {data: memberships} = useDangerousListMembershipsQuery() + const textStyle: TextStyle = { + color: colorMode === 'light' ? theme.palette.black : theme.palette.white, + } + const onPressDone = useCallback(() => { closeModal() }, [closeModal]) const listStyle = React.useMemo(() => { if (isMobileWeb) { - return [pal.border, {height: screenHeight / 2}] + return [ + { + borderColor: theme.palette.contrast_100, + }, + {height: screenHeight / 2}, + ] } else if (isWeb) { - return [pal.border, {height: screenHeight / 1.5}] + return [ + { + borderColor: theme.palette.contrast_100, + }, + {height: screenHeight / 1.5}, + ] } - return [pal.border, {flex: 1, borderTopWidth: StyleSheet.hairlineWidth}] - }, [pal.border, screenHeight]) + return [ + { + borderColor: theme.palette.contrast_100, + }, + {flex: 1, borderTopWidth: StyleSheet.hairlineWidth}, + ] + }, [theme, screenHeight]) const headerStyles = [ { @@ -73,7 +95,7 @@ export function Component({ marginBottom: 12, paddingHorizontal: 12, } as const, - pal.text, + textStyle, ] return ( @@ -104,7 +126,13 @@ export function Component({ )} style={listStyle} /> - + ) @@ -809,7 +828,7 @@ function CondensedAuthorsList({ style={[a.ml_xs, a.mr_md, t.atoms.text_contrast_high]} /> - Hide + Hide diff --git a/src/view/com/post/Post.tsx b/src/view/com/post/Post.tsx index 58cb40f71..dd9ee99ec 100644 --- a/src/view/com/post/Post.tsx +++ b/src/view/com/post/Post.tsx @@ -12,7 +12,6 @@ import {useQueryClient} from '@tanstack/react-query' import {MAX_POST_LINES} from '#/lib/constants' import {useOpenComposer} from '#/lib/hooks/useOpenComposer' -import {usePalette} from '#/lib/hooks/usePalette' import {makeProfileLink} from '#/lib/routes/links' import {countLines} from '#/lib/strings/helpers' import {colors} from '#/lib/styles' @@ -26,7 +25,7 @@ import {unstableCacheProfileView} from '#/state/queries/profile' import {Link} from '#/view/com/util/Link' import {PostMeta} from '#/view/com/util/PostMeta' import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar' -import {atoms as a} from '#/alf' +import {atoms as a, useTheme} from '#/alf' import {ContentHider} from '#/components/moderation/ContentHider' import {LabelsOnMyPost} from '#/components/moderation/LabelsOnMe' import {PostAlerts} from '#/components/moderation/PostAlerts' @@ -114,7 +113,7 @@ function PostInner({ onBeforePress?: () => void }) { const queryClient = useQueryClient() - const pal = usePalette('default') + const theme = useTheme() const {openComposer} = useOpenComposer() const [limitLines, setLimitLines] = useState( () => countLines(richText?.text) >= MAX_POST_LINES, @@ -156,7 +155,7 @@ function PostInner({ href={itemHref} style={[ styles.outer, - pal.border, + {borderColor: theme.palette.contrast_100}, !hideTopBorder && {borderTopWidth: StyleSheet.hairlineWidth}, style, ]} diff --git a/src/view/com/posts/CustomFeedEmptyState.tsx b/src/view/com/posts/CustomFeedEmptyState.tsx index 580e5b2e4..575b3522a 100644 --- a/src/view/com/posts/CustomFeedEmptyState.tsx +++ b/src/view/com/posts/CustomFeedEmptyState.tsx @@ -1,5 +1,5 @@ import React from 'react' -import {StyleSheet, View} from 'react-native' +import {StyleSheet, type TextStyle, View} from 'react-native' import { FontAwesomeIcon, type FontAwesomeIconStyle, @@ -7,18 +7,25 @@ import { import {Trans} from '@lingui/macro' import {useNavigation} from '@react-navigation/native' -import {usePalette} from '#/lib/hooks/usePalette' import {MagnifyingGlassIcon} from '#/lib/icons' import {type NavigationProp} from '#/lib/routes/types' import {s} from '#/lib/styles' import {isWeb} from '#/platform/detection' +import {useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {Button} from '../util/forms/Button' import {Text} from '../util/text/Text' export function CustomFeedEmptyState() { - const pal = usePalette('default') - const palInverted = usePalette('inverted') + const theme = useTheme() + const colorMode = useColorModeTheme() const navigation = useNavigation() + const textStyle: TextStyle = { + color: colorMode === 'light' ? theme.palette.black : theme.palette.white, + } + const textStyleInverted: TextStyle = { + color: colorMode === 'light' ? theme.palette.white : theme.palette.black, + } const onPressFindAccounts = React.useCallback(() => { if (isWeb) { @@ -32,9 +39,9 @@ export function CustomFeedEmptyState() { return ( - + - + This feed is empty! You may need to follow more users or tune your language settings. @@ -44,12 +51,12 @@ export function CustomFeedEmptyState() { type="inverted" style={styles.emptyBtn} onPress={onPressFindAccounts}> - + Find accounts to follow diff --git a/src/view/com/posts/DiscoverFallbackHeader.tsx b/src/view/com/posts/DiscoverFallbackHeader.tsx index e35a33aaf..09c1dada3 100644 --- a/src/view/com/posts/DiscoverFallbackHeader.tsx +++ b/src/view/com/posts/DiscoverFallbackHeader.tsx @@ -1,13 +1,15 @@ import {View} from 'react-native' import {Trans} from '@lingui/macro' -import {usePalette} from '#/lib/hooks/usePalette' import {InfoCircleIcon} from '#/lib/icons' +import {useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {TextLink} from '../util/Link' import {Text} from '../util/text/Text' export function DiscoverFallbackHeader() { - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() return ( - + - + We ran out of posts from your follows. Here's the latest from{' '} . diff --git a/src/view/com/posts/FollowingEmptyState.tsx b/src/view/com/posts/FollowingEmptyState.tsx index 352cc1dc0..d5ef0668c 100644 --- a/src/view/com/posts/FollowingEmptyState.tsx +++ b/src/view/com/posts/FollowingEmptyState.tsx @@ -1,5 +1,5 @@ import React from 'react' -import {StyleSheet, View} from 'react-native' +import {StyleSheet, type TextStyle, View} from 'react-native' import { FontAwesomeIcon, type FontAwesomeIconStyle, @@ -7,19 +7,27 @@ import { import {Trans} from '@lingui/macro' import {useNavigation} from '@react-navigation/native' -import {usePalette} from '#/lib/hooks/usePalette' import {MagnifyingGlassIcon} from '#/lib/icons' import {type NavigationProp} from '#/lib/routes/types' import {s} from '#/lib/styles' import {isWeb} from '#/platform/detection' +import {useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {Button} from '../util/forms/Button' import {Text} from '../util/text/Text' export function FollowingEmptyState() { - const pal = usePalette('default') - const palInverted = usePalette('inverted') + const theme = useTheme() + const colorMode = useColorModeTheme() const navigation = useNavigation() + const textStyle: TextStyle = { + color: colorMode === 'light' ? theme.palette.black : theme.palette.white, + } + const textStyleInverted: TextStyle = { + color: colorMode === 'light' ? theme.palette.white : theme.palette.black, + } + const onPressFindAccounts = React.useCallback(() => { if (isWeb) { navigation.navigate('Search', {}) @@ -37,9 +45,9 @@ export function FollowingEmptyState() { - + - + Your following feed is empty! Follow more users to see what's happening. @@ -49,29 +57,29 @@ export function FollowingEmptyState() { type="inverted" style={styles.emptyBtn} onPress={onPressFindAccounts}> - - Find accounts to follow + + Find accounts to follow - + You can also discover new Custom Feeds to follow. diff --git a/src/view/com/posts/FollowingEndOfFeed.tsx b/src/view/com/posts/FollowingEndOfFeed.tsx index e3c84d782..c3646fe81 100644 --- a/src/view/com/posts/FollowingEndOfFeed.tsx +++ b/src/view/com/posts/FollowingEndOfFeed.tsx @@ -1,5 +1,5 @@ import React from 'react' -import {Dimensions, StyleSheet, View} from 'react-native' +import {Dimensions, StyleSheet, type TextStyle, View} from 'react-native' import { FontAwesomeIcon, type FontAwesomeIconStyle, @@ -7,18 +7,27 @@ import { import {Trans} from '@lingui/macro' import {useNavigation} from '@react-navigation/native' -import {usePalette} from '#/lib/hooks/usePalette' import {type NavigationProp} from '#/lib/routes/types' import {s} from '#/lib/styles' import {isWeb} from '#/platform/detection' +import {useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {Button} from '../util/forms/Button' import {Text} from '../util/text/Text' export function FollowingEndOfFeed() { - const pal = usePalette('default') - const palInverted = usePalette('inverted') + const theme = useTheme() + const colorMode = useColorModeTheme() const navigation = useNavigation() + const textStyle: TextStyle = { + color: colorMode === 'light' ? theme.palette.black : theme.palette.white, + } + + const textStyleInverted: TextStyle = { + color: colorMode === 'light' ? theme.palette.white : theme.palette.black, + } + const onPressFindAccounts = React.useCallback(() => { if (isWeb) { navigation.navigate('Search', {}) @@ -36,11 +45,13 @@ export function FollowingEndOfFeed() { - + You've reached the end of your feed! Find some more accounts to follow. @@ -50,29 +61,29 @@ export function FollowingEndOfFeed() { type="inverted" style={styles.emptyBtn} onPress={onPressFindAccounts}> - - Find accounts to follow + + Find accounts to follow - + You can also discover new Custom Feeds to follow. diff --git a/src/view/com/posts/PostFeedErrorMessage.tsx b/src/view/com/posts/PostFeedErrorMessage.tsx index 808ef9fff..eb2fc29db 100644 --- a/src/view/com/posts/PostFeedErrorMessage.tsx +++ b/src/view/com/posts/PostFeedErrorMessage.tsx @@ -9,12 +9,13 @@ import {msg as msgLingui, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useNavigation} from '@react-navigation/native' -import {usePalette} from '#/lib/hooks/usePalette' import {type NavigationProp} from '#/lib/routes/types' import {cleanError} from '#/lib/strings/errors' import {logger} from '#/logger' import {type FeedDescriptor} from '#/state/queries/post-feed' import {useRemoveFeedMutation} from '#/state/queries/preferences' +import {useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import * as Prompt from '#/components/Prompt' import {EmptyState} from '../util/EmptyState' import {ErrorMessage} from '../util/error/ErrorMessage' @@ -94,7 +95,8 @@ function FeedgenErrorMessage({ rawError?: Error savedFeedConfig?: AppBskyActorDefs.SavedFeed }) { - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() const {_: _l} = useLingui() const navigation = useNavigation() const msg = React.useMemo( @@ -189,8 +191,8 @@ function FeedgenErrorMessage({ <> - {msg} + + {msg} + {rawError?.message && ( - - Message from server: {rawError.message} + + Message from server: {rawError.message} )} diff --git a/src/view/com/posts/PostFeedItem.tsx b/src/view/com/posts/PostFeedItem.tsx index 2f03a168b..627d2430a 100644 --- a/src/view/com/posts/PostFeedItem.tsx +++ b/src/view/com/posts/PostFeedItem.tsx @@ -17,7 +17,6 @@ import {useActorStatus} from '#/lib/actor-status' import {isReasonFeedSource, type ReasonFeedSource} from '#/lib/api/feed/types' import {MAX_POST_LINES} from '#/lib/constants' import {useOpenComposer} from '#/lib/hooks/useOpenComposer' -import {usePalette} from '#/lib/hooks/usePalette' import {makeProfileLink} from '#/lib/routes/links' import {sanitizeDisplayName} from '#/lib/strings/display-names' import {sanitizeHandle} from '#/lib/strings/handles' @@ -40,7 +39,8 @@ import {Link, TextLinkOnWebOnly} from '#/view/com/util/Link' import {PostMeta} from '#/view/com/util/PostMeta' import {Text} from '#/view/com/util/text/Text' import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar' -import {atoms as a} from '#/alf' +import {atoms as a, useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {Pin_Stroke2_Corner0_Rounded as PinIcon} from '#/components/icons/Pin' import {Repost_Stroke2_Corner2_Rounded as RepostIcon} from '#/components/icons/Repost' import {ContentHider} from '#/components/moderation/ContentHider' @@ -167,7 +167,8 @@ let FeedItemInner = ({ }): React.ReactNode => { const queryClient = useQueryClient() const {openComposer} = useOpenComposer() - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() const {_} = useLingui() const [hover, setHover] = useState(false) @@ -247,7 +248,7 @@ let FeedItemInner = ({ const outerStyles = [ styles.outer, { - borderColor: pal.colors.border, + borderColor: theme.palette.contrast_100, paddingBottom: isThreadLastChild || (!isThreadChild && !isThreadParent) ? 8 @@ -308,7 +309,10 @@ let FeedItemInner = ({ styles.replyLine, { flexGrow: 1, - backgroundColor: pal.colors.replyLine, + backgroundColor: + colorMode === 'light' + ? theme.palette.contrast_100 + : theme.palette.contrast_200, marginBottom: 4, }, ]} @@ -321,7 +325,12 @@ let FeedItemInner = ({ @@ -332,7 +341,12 @@ let FeedItemInner = ({ href={reason.href} lineHeight={1.2} numberOfLines={1} - style={pal.textLight} + style={{ + color: + colorMode === 'dark' + ? theme.palette.contrast_600 + : theme.palette.contrast_700, + }} /> @@ -352,31 +366,52 @@ let FeedItemInner = ({ } onBeforePress={onOpenReposter}> {isOwner ? ( - Reposted by you + Reposted by you ) : ( Reposted by{' '} {sanitizeDisplayName( reason.by.displayName || @@ -396,16 +431,27 @@ let FeedItemInner = ({ ) : AppBskyFeedDefs.isReasonPin(reason) ? ( - Pinned + Pinned ) : null} @@ -428,7 +474,10 @@ let FeedItemInner = ({ styles.replyLine, { flexGrow: 1, - backgroundColor: pal.colors.replyLine, + backgroundColor: + colorMode === 'light' + ? theme.palette.contrast_100 + : theme.palette.contrast_200, marginTop: live ? 8 : 4, }, ]} diff --git a/src/view/com/posts/ViewFullThread.tsx b/src/view/com/posts/ViewFullThread.tsx index 0f083c330..8f37e40f7 100644 --- a/src/view/com/posts/ViewFullThread.tsx +++ b/src/view/com/posts/ViewFullThread.tsx @@ -5,8 +5,9 @@ import {AtUri} from '@atproto/api' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {usePalette} from '#/lib/hooks/usePalette' import {makeProfileLink} from '#/lib/routes/links' +import {useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {useInteractionState} from '#/components/hooks/useInteractionState' import {SubtleWebHover} from '#/components/SubtleWebHover' import {Link} from '../util/Link' @@ -18,7 +19,8 @@ export function ViewFullThread({uri}: {uri: string}) { onIn: onHoverIn, onOut: onHoverOut, } = useInteractionState() - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() const itemHref = React.useMemo(() => { const urip = new AtUri(uri) return makeProfileLink({did: urip.hostname, handle: ''}, 'post', urip.rkey) @@ -45,16 +47,25 @@ export function ViewFullThread({uri}: {uri: string}) { y1="0" x2="2" y2="15" - stroke={pal.colors.replyLine} + stroke={ + colorMode === 'light' + ? theme.palette.contrast_100 + : theme.palette.contrast_200 + } strokeWidth="2" /> - - - + + + - + {/* HACKFIX: Trans isn't working after SDK 53 upgrade -sfn */} {_(msg`View full thread`)} diff --git a/src/view/com/profile/ProfileSubpageHeader.tsx b/src/view/com/profile/ProfileSubpageHeader.tsx index 02a6704bf..12b5c7861 100644 --- a/src/view/com/profile/ProfileSubpageHeader.tsx +++ b/src/view/com/profile/ProfileSubpageHeader.tsx @@ -1,5 +1,5 @@ import React from 'react' -import {Pressable, View} from 'react-native' +import {Pressable, type TextStyle, View} from 'react-native' import Animated, { measure, type MeasuredDimensions, @@ -12,7 +12,6 @@ import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useNavigation} from '@react-navigation/native' -import {usePalette} from '#/lib/hooks/usePalette' import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' import {makeProfileLink} from '#/lib/routes/links' import {type NavigationProp} from '#/lib/routes/types' @@ -23,6 +22,8 @@ import {TextLink} from '#/view/com/util/Link' import {LoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder' import {Text} from '#/view/com/util/text/Text' import {UserAvatar, type UserAvatarType} from '#/view/com/util/UserAvatar' +import {useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {StarterPack} from '#/components/icons/StarterPack' import * as Layout from '#/components/Layout' @@ -55,10 +56,18 @@ export function ProfileSubpageHeader({ const {_} = useLingui() const {isMobile} = useWebMediaQueries() const {openLightbox} = useLightboxControls() - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() const canGoBack = navigation.canGoBack() const aviRef = useAnimatedRef() + const textLightStyle: TextStyle = { + color: + colorMode === 'dark' + ? theme.palette.contrast_600 + : theme.palette.contrast_700, + } + const _openLightbox = React.useCallback( (uri: string, thumbRect: MeasuredDimensions | null) => { openLightbox({ @@ -142,7 +151,13 @@ export function ProfileSubpageHeader({ testID="headerTitle" type="title-xl" href={href} - style={[pal.text, {fontWeight: '600'}]} + style={{ + fontWeight: '600', + color: + colorMode === 'light' + ? theme.palette.black + : theme.palette.white, + }} text={title || ''} onPress={emitSoftReset} numberOfLines={4} @@ -152,7 +167,7 @@ export function ProfileSubpageHeader({ {isLoading || !creator ? ( ) : ( - + {purpose === 'app.bsky.graph.defs#curatelist' ? ( isOwner ? ( List by you @@ -162,7 +177,7 @@ export function ProfileSubpageHeader({ ) @@ -175,7 +190,7 @@ export function ProfileSubpageHeader({ ) @@ -188,7 +203,7 @@ export function ProfileSubpageHeader({ ) diff --git a/src/view/com/util/EmptyState.tsx b/src/view/com/util/EmptyState.tsx index a3d740e13..d575ac0d0 100644 --- a/src/view/com/util/EmptyState.tsx +++ b/src/view/com/util/EmptyState.tsx @@ -5,9 +5,9 @@ import { type FontAwesomeIconStyle, } from '@fortawesome/react-native-fontawesome' -import {usePalette} from '#/lib/hooks/usePalette' import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' import {UserGroupIcon} from '#/lib/icons' +import {useTheme} from '#/alf' import {Growth_Stroke2_Corner0_Rounded as Growth} from '#/components/icons/Growth' import {Text} from './text/Text' @@ -22,7 +22,7 @@ export function EmptyState({ message: string style?: StyleProp }) { - const pal = usePalette('default') + const theme = useTheme() const {isTabletOrDesktop} = useWebMediaQueries() const iconSize = isTabletOrDesktop ? 64 : 48 return ( @@ -31,21 +31,25 @@ export function EmptyState({ style={[ styles.iconContainer, isTabletOrDesktop && styles.iconContainerBig, - pal.viewLight, + {backgroundColor: theme.palette.contrast_25}, ]}> {icon === 'user-group' ? ( ) : icon === 'growth' ? ( - + ) : ( )} - + {message} diff --git a/src/view/com/util/EmptyStateWithButton.tsx b/src/view/com/util/EmptyStateWithButton.tsx index 5c6ce94a6..284b315ab 100644 --- a/src/view/com/util/EmptyStateWithButton.tsx +++ b/src/view/com/util/EmptyStateWithButton.tsx @@ -1,12 +1,13 @@ -import {StyleSheet, View} from 'react-native' +import {StyleSheet, type TextStyle, View} from 'react-native' import {type IconProp} from '@fortawesome/fontawesome-svg-core' import { FontAwesomeIcon, type FontAwesomeIconStyle, } from '@fortawesome/react-native-fontawesome' -import {usePalette} from '#/lib/hooks/usePalette' import {s} from '#/lib/styles' +import {useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {Button} from './forms/Button' import {Text} from './text/Text' @@ -19,19 +20,27 @@ interface Props { } export function EmptyStateWithButton(props: Props) { - const pal = usePalette('default') - const palInverted = usePalette('inverted') + const theme = useTheme() + const colorMode = useColorModeTheme() + + const textStyle: TextStyle = { + color: colorMode === 'light' ? theme.palette.black : theme.palette.white, + } + + const textStyleInverted: TextStyle = { + color: colorMode === 'light' ? theme.palette.white : theme.palette.black, + } return ( - + {props.message} @@ -42,10 +51,10 @@ export function EmptyStateWithButton(props: Props) { onPress={props.onPress}> - + {props.buttonLabel} diff --git a/src/view/com/util/LoadMoreRetryBtn.tsx b/src/view/com/util/LoadMoreRetryBtn.tsx index 240d5aa34..010c37f19 100644 --- a/src/view/com/util/LoadMoreRetryBtn.tsx +++ b/src/view/com/util/LoadMoreRetryBtn.tsx @@ -4,7 +4,8 @@ import { type FontAwesomeIconStyle, } from '@fortawesome/react-native-fontawesome' -import {usePalette} from '#/lib/hooks/usePalette' +import {useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {Button} from './forms/Button' import {Text} from './text/Text' @@ -15,15 +16,35 @@ export function LoadMoreRetryBtn({ label: string onPress: () => void }) { - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() return ( ) } diff --git a/src/view/com/util/LoadingPlaceholder.tsx b/src/view/com/util/LoadingPlaceholder.tsx index 1b454598b..4e69bcbc3 100644 --- a/src/view/com/util/LoadingPlaceholder.tsx +++ b/src/view/com/util/LoadingPlaceholder.tsx @@ -7,10 +7,9 @@ import { type ViewStyle, } from 'react-native' -import {usePalette} from '#/lib/hooks/usePalette' import {s} from '#/lib/styles' -import {useTheme} from '#/lib/ThemeContext' -import {atoms as a, useTheme as useTheme_NEW} from '#/alf' +import {atoms as a, useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {Bubble_Stroke2_Corner2_Rounded as Bubble} from '#/components/icons/Bubble' import { Heart2_Filled_Stroke2_Corner0_Rounded as HeartIconFilled, @@ -35,7 +34,7 @@ export function LoadingPlaceholder({ { width, height, - backgroundColor: theme.palette.default.backgroundLight, + backgroundColor: theme.palette.contrast_25, }, style, ]} @@ -48,10 +47,18 @@ export function PostLoadingPlaceholder({ }: { style?: StyleProp }) { - const t = useTheme_NEW() - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() return ( - + }) { - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() return ( - + - + @@ -184,9 +197,18 @@ export function ProfileCardLoadingPlaceholder({ }: { style?: StyleProp }) { - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() return ( - + - + }) { - const t = useTheme_NEW() + const theme = useTheme() const random = useMemo(() => Math.random(), []) return ( - + diff --git a/src/view/com/util/ViewSelector.tsx b/src/view/com/util/ViewSelector.tsx index fb0e4b155..3a7d98216 100644 --- a/src/view/com/util/ViewSelector.tsx +++ b/src/view/com/util/ViewSelector.tsx @@ -10,10 +10,11 @@ import { } from 'react-native' import {useColorSchemeStyle} from '#/lib/hooks/useColorSchemeStyle' -import {usePalette} from '#/lib/hooks/usePalette' import {clamp} from '#/lib/numbers' import {colors, s} from '#/lib/styles' import {isAndroid} from '#/platform/detection' +import {useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {Text} from './text/Text' import {FlatList_INTERNAL} from './Views' @@ -59,7 +60,8 @@ export const ViewSelector = React.forwardRef< }, ref, ) { - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() const [selectedIndex, setSelectedIndex] = useState(0) const flatListRef = React.useRef(null) @@ -127,7 +129,9 @@ export const ViewSelector = React.forwardRef< } onEndReachedThreshold={0.6} @@ -147,7 +151,8 @@ export function Selector({ items: string[] onSelect?: (index: number) => void }) { - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() const borderColor = useColorSchemeStyle( {borderColor: colors.black}, {borderColor: colors.white}, @@ -161,13 +166,23 @@ export function Selector({ - + {items.map((item, i) => { const selected = i === selectedIndex return ( @@ -189,8 +204,24 @@ export function Selector({ {item} diff --git a/src/view/com/util/Views.web.tsx b/src/view/com/util/Views.web.tsx index 9a3e8a4ae..aa3734b7b 100644 --- a/src/view/com/util/Views.web.tsx +++ b/src/view/com/util/Views.web.tsx @@ -23,10 +23,9 @@ import { } from 'react-native' import Animated from 'react-native-reanimated' -import {usePalette} from '#/lib/hooks/usePalette' import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' import {addStyle} from '#/lib/styles' -import {useLayoutBreakpoints} from '#/alf' +import {useLayoutBreakpoints, useTheme} from '#/alf' import {useDialogContext} from '#/components/Dialog' import {CENTER_COLUMN_OFFSET} from '#/components/Layout' @@ -47,7 +46,7 @@ export const CenteredView = React.forwardRef(function CenteredView( >, ref: React.Ref, ) { - const pal = usePalette('default') + const theme = useTheme() const {isMobile} = useWebMediaQueries() const {centerColumnOffset} = useLayoutBreakpoints() const {isWithinDialog} = useDialogContext() @@ -61,7 +60,9 @@ export const CenteredView = React.forwardRef(function CenteredView( style = addStyle(style, { borderTopWidth: 1, }) - style = addStyle(style, pal.border) + style = addStyle(style, { + borderColor: theme.palette.contrast_100, + }) } return }) diff --git a/src/view/com/util/error/ErrorMessage.tsx b/src/view/com/util/error/ErrorMessage.tsx index 529406996..46d5de08f 100644 --- a/src/view/com/util/error/ErrorMessage.tsx +++ b/src/view/com/util/error/ErrorMessage.tsx @@ -12,8 +12,7 @@ import { import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {usePalette} from '#/lib/hooks/usePalette' -import {useTheme} from '#/lib/ThemeContext' +import {useTheme} from '#/alf' import * as Layout from '#/components/Layout' import {Text} from '../text/Text' @@ -29,25 +28,30 @@ export function ErrorMessage({ onPressTryAgain?: () => void }) { const theme = useTheme() - const pal = usePalette('error') const {_} = useLingui() return ( - + {message} @@ -63,7 +67,7 @@ export function ErrorMessage({ )}> diff --git a/src/view/com/util/error/ErrorScreen.tsx b/src/view/com/util/error/ErrorScreen.tsx index 26342ec75..7013312c4 100644 --- a/src/view/com/util/error/ErrorScreen.tsx +++ b/src/view/com/util/error/ErrorScreen.tsx @@ -6,8 +6,8 @@ import { import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {usePalette} from '#/lib/hooks/usePalette' import {atoms as a, useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {ArrowRotateCounterClockwise_Stroke2_Corner0_Rounded as ArrowRotateCounterClockwiseIcon} from '#/components/icons/ArrowRotateCounterClockwise' import * as Layout from '#/components/Layout' @@ -29,7 +29,7 @@ export function ErrorScreen({ showHeader?: boolean }) { const t = useTheme() - const pal = usePalette('default') + const colorMode = useColorModeTheme() const {_} = useLingui() return ( @@ -39,7 +39,7 @@ export function ErrorScreen({ - Error + Error @@ -57,7 +57,12 @@ export function ErrorScreen({ ]}> @@ -65,7 +70,7 @@ export function ErrorScreen({ {title} - {message} + {message} {details && ( - Try again + Try again diff --git a/src/view/com/util/forms/NativeDropdown.tsx b/src/view/com/util/forms/NativeDropdown.tsx index 5e2089d29..37809320b 100644 --- a/src/view/com/util/forms/NativeDropdown.tsx +++ b/src/view/com/util/forms/NativeDropdown.tsx @@ -3,6 +3,7 @@ import { Platform, Pressable, StyleSheet, + type TextStyle, View, type ViewStyle, } from 'react-native' @@ -11,9 +12,9 @@ import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' import * as DropdownMenu from 'zeego/dropdown-menu' import {type MenuItemCommonProps} from 'zeego/lib/typescript/menu' -import {usePalette} from '#/lib/hooks/usePalette' -import {useTheme} from '#/lib/ThemeContext' import {isIOS} from '#/platform/detection' +import {useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {Portal} from '#/components/Portal' // Custom Dropdown Menu Components @@ -43,7 +44,8 @@ type TriggerProps = Omit< export const DropdownMenuTrigger = DropdownMenu.create( (props: TriggerProps) => { const theme = useTheme() - const defaultCtrlColor = theme.palette.default.postCtrl + + const defaultCtrlColor = theme.palette.contrast_500 return ( // This Pressable doesn't actually do anything other than @@ -80,8 +82,10 @@ type ItemProps = React.ComponentProps<(typeof DropdownMenu)['Item']> export const DropdownMenuItem = DropdownMenu.create( (props: ItemProps & {testID?: string}) => { const theme = useTheme() + const colorMode = useColorModeTheme() const [focused, setFocused] = React.useState(false) - const backgroundColor = theme.colorScheme === 'dark' ? '#fff1' : '#0001' + const backgroundColor = + colorMode === 'light' ? theme.palette.black : theme.palette.white return ( */ export const DropdownMenuItemTitle = DropdownMenu.create( (props: TitleProps) => { - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() + return ( ) }, @@ -132,10 +145,16 @@ type SeparatorProps = React.ComponentProps<(typeof DropdownMenu)['Separator']> */ export const DropdownMenuSeparator = DropdownMenu.create( (props: SeparatorProps) => { - const pal = usePalette('default') const theme = useTheme() + const colorMode = useColorModeTheme() const {borderColor: separatorColor} = - theme.colorScheme === 'dark' ? pal.borderDark : pal.border + colorMode === 'dark' + ? { + borderColor: theme.palette.contrast_200, + } + : { + borderColor: theme.palette.contrast_100, + } return ( ) { - const pal = usePalette('default') const theme = useTheme() + const colorMode = useColorModeTheme() const [isOpen, setIsOpen] = React.useState(false) - const dropDownBackgroundColor = - theme.colorScheme === 'dark' ? pal.btn : pal.viewLight + const dropDownBackgroundColor = { + backgroundColor: theme.palette.contrast_25, + } + + const textStyle: TextStyle = { + color: colorMode === 'light' ? theme.palette.black : theme.palette.white, + } return ( <> @@ -234,7 +258,7 @@ export function NativeDropdown({ )} @@ -255,7 +279,7 @@ export function NativeDropdown({ )} diff --git a/src/view/com/util/forms/NativeDropdown.web.tsx b/src/view/com/util/forms/NativeDropdown.web.tsx index fb490b9ac..a65908664 100644 --- a/src/view/com/util/forms/NativeDropdown.web.tsx +++ b/src/view/com/util/forms/NativeDropdown.web.tsx @@ -3,6 +3,7 @@ import { Pressable, StyleSheet, Text, + type TextStyle, type View, type ViewStyle, } from 'react-native' @@ -12,8 +13,8 @@ import {DropdownMenu} from 'radix-ui' import {type MenuItemCommonProps} from 'zeego/lib/typescript/menu' import {HITSLOP_10} from '#/lib/constants' -import {usePalette} from '#/lib/hooks/usePalette' -import {useTheme} from '#/lib/ThemeContext' +import {useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' // Custom Dropdown Menu Components // == @@ -22,9 +23,11 @@ export const DropdownMenuContent = DropdownMenu.Content type ItemProps = React.ComponentProps<(typeof DropdownMenu)['Item']> export const DropdownMenuItem = (props: ItemProps & {testID?: string}) => { - const theme = useTheme() const [focused, setFocused] = React.useState(false) - const backgroundColor = theme.colorScheme === 'dark' ? '#fff1' : '#0001' + const theme = useTheme() + const colorMode = useColorModeTheme() + const backgroundColor = + colorMode === 'light' ? theme.palette.black : theme.palette.white return ( }) { - const pal = usePalette('default') const theme = useTheme() + const colorMode = useColorModeTheme() const dropDownBackgroundColor = - theme.colorScheme === 'dark' ? pal.btn : pal.view + colorMode === 'dark' + ? { + backgroundColor: theme.palette.contrast_25, + } + : { + backgroundColor: + colorMode === 'light' ? theme.palette.white : theme.palette.black, + } const {borderColor: separatorColor} = - theme.colorScheme === 'dark' ? pal.borderDark : pal.border + colorMode === 'dark' + ? { + borderColor: theme.palette.contrast_200, + } + : { + borderColor: theme.palette.contrast_100, + } + + const textStyle: TextStyle = { + color: colorMode === 'light' ? theme.palette.black : theme.palette.white, + } return ( - + {item.label} {item.icon && ( )} @@ -218,14 +242,18 @@ function DropdownContent({ - + {item.label} {item.icon && ( )} diff --git a/src/view/com/util/layouts/LoggedOutLayout.tsx b/src/view/com/util/layouts/LoggedOutLayout.tsx index 2ec17799f..3161c40fc 100644 --- a/src/view/com/util/layouts/LoggedOutLayout.tsx +++ b/src/view/com/util/layouts/LoggedOutLayout.tsx @@ -1,12 +1,12 @@ -import {ScrollView, StyleSheet, View} from 'react-native' +import {ScrollView, StyleSheet, View, type ViewStyle} from 'react-native' import type React from 'react' import {useColorSchemeStyle} from '#/lib/hooks/useColorSchemeStyle' import {useIsKeyboardVisible} from '#/lib/hooks/useIsKeyboardVisible' -import {usePalette} from '#/lib/hooks/usePalette' import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' import {isWeb} from '#/platform/detection' -import {atoms as a} from '#/alf' +import {atoms as a, useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {Text} from '../text/Text' export const LoggedOutLayout = ({ @@ -22,11 +22,20 @@ export const LoggedOutLayout = ({ scrollable?: boolean }>) => { const {isMobile, isTabletOrMobile} = useWebMediaQueries() - const pal = usePalette('default') - const sideBg = useColorSchemeStyle(pal.viewLight, pal.view) - const contentBg = useColorSchemeStyle(pal.view, { - backgroundColor: pal.colors.background, - borderColor: pal.colors.border, + const theme = useTheme() + const colorMode = useColorModeTheme() + const viewStyle: ViewStyle = { + backgroundColor: + colorMode === 'light' ? theme.palette.white : theme.palette.black, + } + const sideBg = useColorSchemeStyle( + {backgroundColor: theme.palette.contrast_25}, + viewStyle, + ) + const contentBg = useColorSchemeStyle(viewStyle, { + backgroundColor: + colorMode === 'light' ? theme.palette.white : theme.palette.black, + borderColor: theme.palette.contrast_25, borderLeftWidth: 1, }) @@ -54,7 +63,12 @@ export const LoggedOutLayout = ({ @@ -62,13 +76,23 @@ export const LoggedOutLayout = ({ {title} - + {description} diff --git a/src/view/icons/Logomark.tsx b/src/view/icons/Logomark.tsx index 8d078f434..eecd354c0 100644 --- a/src/view/icons/Logomark.tsx +++ b/src/view/icons/Logomark.tsx @@ -1,6 +1,7 @@ import Svg, {Path, type PathProps, type SvgProps} from 'react-native-svg' -import {usePalette} from '#/lib/hooks/usePalette' +import {useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' const ratio = 54 / 61 @@ -8,7 +9,8 @@ export function Logomark({ fill, ...rest }: {fill?: PathProps['fill']} & SvgProps) { - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() // @ts-ignore it's fiiiiine const size = parseInt(rest.width || 32) @@ -20,7 +22,11 @@ export function Logomark({ width={size} height={Number(size) * ratio}> diff --git a/src/view/icons/Logotype.tsx b/src/view/icons/Logotype.tsx index 270c913fc..40048eee9 100644 --- a/src/view/icons/Logotype.tsx +++ b/src/view/icons/Logotype.tsx @@ -1,6 +1,7 @@ import Svg, {Path, type PathProps, type SvgProps} from 'react-native-svg' -import {usePalette} from '#/lib/hooks/usePalette' +import {useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' const ratio = 17 / 64 @@ -8,7 +9,8 @@ export function Logotype({ fill, ...rest }: {fill?: PathProps['fill']} & SvgProps) { - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() // @ts-ignore it's fiiiiine const size = parseInt(rest.width || 32) @@ -20,7 +22,11 @@ export function Logotype({ width={size} height={Number(size) * ratio}> diff --git a/src/view/screens/CommunityGuidelines.tsx b/src/view/screens/CommunityGuidelines.tsx index 42bf8c1a1..d560b7346 100644 --- a/src/view/screens/CommunityGuidelines.tsx +++ b/src/view/screens/CommunityGuidelines.tsx @@ -4,7 +4,6 @@ import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useFocusEffect} from '@react-navigation/native' -import {usePalette} from '#/lib/hooks/usePalette' import { type CommonNavigatorParams, type NativeStackScreenProps, @@ -14,6 +13,8 @@ import {useSetMinimalShellMode} from '#/state/shell' import {TextLink} from '#/view/com/util/Link' import {Text} from '#/view/com/util/text/Text' import {ScrollView} from '#/view/com/util/Views' +import {useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import * as Layout from '#/components/Layout' import {ViewHeader} from '../com/util/ViewHeader' @@ -22,7 +23,8 @@ type Props = NativeStackScreenProps< 'CommunityGuidelines' > export const CommunityGuidelinesScreen = (_props: Props) => { - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() const {_} = useLingui() const setMinimalShellMode = useSetMinimalShellMode() @@ -35,13 +37,28 @@ export const CommunityGuidelinesScreen = (_props: Props) => { return ( - + - + The Community Guidelines have been moved to{' '} diff --git a/src/view/screens/CopyrightPolicy.tsx b/src/view/screens/CopyrightPolicy.tsx index 45311e729..558b4e6b4 100644 --- a/src/view/screens/CopyrightPolicy.tsx +++ b/src/view/screens/CopyrightPolicy.tsx @@ -4,7 +4,6 @@ import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useFocusEffect} from '@react-navigation/native' -import {usePalette} from '#/lib/hooks/usePalette' import { type CommonNavigatorParams, type NativeStackScreenProps, @@ -14,12 +13,15 @@ import {useSetMinimalShellMode} from '#/state/shell' import {TextLink} from '#/view/com/util/Link' import {Text} from '#/view/com/util/text/Text' import {ScrollView} from '#/view/com/util/Views' +import {useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import * as Layout from '#/components/Layout' import {ViewHeader} from '../com/util/ViewHeader' type Props = NativeStackScreenProps export const CopyrightPolicyScreen = (_props: Props) => { - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() const {_} = useLingui() const setMinimalShellMode = useSetMinimalShellMode() @@ -32,13 +34,28 @@ export const CopyrightPolicyScreen = (_props: Props) => { return ( - + - + The Copyright Policy has been moved to{' '} diff --git a/src/view/screens/Debug.tsx b/src/view/screens/Debug.tsx index 8b81cee10..22cf1bbf0 100644 --- a/src/view/screens/Debug.tsx +++ b/src/view/screens/Debug.tsx @@ -1,15 +1,14 @@ import React from 'react' -import {ScrollView, View} from 'react-native' +import {ScrollView, type TextStyle, View} from 'react-native' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {usePalette} from '#/lib/hooks/usePalette' import { type CommonNavigatorParams, type NativeStackScreenProps, } from '#/lib/routes/types' import {s} from '#/lib/styles' -import {type PaletteColorName, ThemeProvider} from '#/lib/ThemeContext' +import {ThemeProvider} from '#/lib/ThemeContext' import {EmptyState} from '#/view/com/util/EmptyState' import {ErrorMessage} from '#/view/com/util/error/ErrorMessage' import {ErrorScreen} from '#/view/com/util/error/ErrorScreen' @@ -20,6 +19,8 @@ import {Text} from '#/view/com/util/text/Text' import * as Toast from '#/view/com/util/Toast' import {ViewHeader} from '#/view/com/util/ViewHeader' import {ViewSelector} from '#/view/com/util/ViewSelector' +import {useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import * as Layout from '#/components/Layout' const MAIN_VIEWS = ['Base', 'Controls', 'Error', 'Notifs'] @@ -54,7 +55,8 @@ function DebugInner({ onToggleColorScheme: () => void }) { const [currentView, setCurrentView] = React.useState(0) - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() const {_} = useLingui() const renderItem = (item: any) => { @@ -84,7 +86,14 @@ function DebugInner({ const items = [{currentView}] return ( - + - + {label} @@ -114,11 +130,7 @@ function BaseView() { - - - - - + {/* */} @@ -197,136 +209,152 @@ function NotifsView() { ) } - -function PaletteView({palette}: {palette: PaletteColorName}) { - const defaultPal = usePalette('default') - const pal = usePalette(palette) - return ( - - {palette} colors - Light text - Link text - {palette !== 'default' && ( - - Inverted text - - )} - - ) -} +// TODO: provide some way to view all the colours in a given theme. +// since the concept of a 'palette' is mostly deprecated, we need to rethink this debug screen. +// function PaletteView() { +// const defaultTheme = useTheme() +// const currColorMode = useColorModeTheme() +// const pal = usePalette(palette) +// return ( +// +// {palette} colors +// Light text +// Link text +// {palette !== 'default' && ( +// +// Inverted text +// +// )} +// +// ) +// } function TypographyView() { - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() + const textStyle: TextStyle = { + color: colorMode === 'light' ? theme.palette.black : theme.palette.white, + } return ( - - + + '2xl-thin' lorem ipsum dolor - + '2xl' lorem ipsum dolor - + '2xl-medium' lorem ipsum dolor - + '2xl-bold' lorem ipsum dolor - + '2xl-heavy' lorem ipsum dolor - + 'xl-thin' lorem ipsum dolor - + 'xl' lorem ipsum dolor - + 'xl-medium' lorem ipsum dolor - + 'xl-bold' lorem ipsum dolor - + 'xl-heavy' lorem ipsum dolor - + 'lg-thin' lorem ipsum dolor - + 'lg' lorem ipsum dolor - + 'lg-medium' lorem ipsum dolor - + 'lg-bold' lorem ipsum dolor - + 'lg-heavy' lorem ipsum dolor - + 'md-thin' lorem ipsum dolor - + 'md' lorem ipsum dolor - + 'md-medium' lorem ipsum dolor - + 'md-bold' lorem ipsum dolor - + 'md-heavy' lorem ipsum dolor - + 'sm-thin' lorem ipsum dolor - + 'sm' lorem ipsum dolor - + 'sm-medium' lorem ipsum dolor - + 'sm-bold' lorem ipsum dolor - + 'sm-heavy' lorem ipsum dolor - + 'xs-thin' lorem ipsum dolor - + 'xs' lorem ipsum dolor - + 'xs-medium' lorem ipsum dolor - + 'xs-bold' lorem ipsum dolor - + 'xs-heavy' lorem ipsum dolor - + 'title-2xl' lorem ipsum dolor - + 'title-xl' lorem ipsum dolor - + 'title-lg' lorem ipsum dolor - + 'title' lorem ipsum dolor - + Button - - Button-lg + + Button - lg ) @@ -346,10 +374,15 @@ function LoadingPlaceholderView() { } function ButtonsView() { - const defaultPal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() const buttonStyles = {marginRight: 5} return ( - + diff --git a/src/view/shell/desktop/LeftNav.tsx b/src/view/shell/desktop/LeftNav.tsx index b89d77294..3ce7acb3b 100644 --- a/src/view/shell/desktop/LeftNav.tsx +++ b/src/view/shell/desktop/LeftNav.tsx @@ -1,5 +1,5 @@ import {type JSX, useCallback, useMemo, useState} from 'react' -import {StyleSheet, View} from 'react-native' +import {StyleSheet, type TextStyle, View} from 'react-native' import {type AppBskyActorDefs} from '@atproto/api' import {msg, plural, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' @@ -8,7 +8,6 @@ import {useNavigation, useNavigationState} from '@react-navigation/native' import {useActorStatus} from '#/lib/actor-status' import {useAccountSwitcher} from '#/lib/hooks/useAccountSwitcher' import {useOpenComposer} from '#/lib/hooks/useOpenComposer' -import {usePalette} from '#/lib/hooks/usePalette' import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' import {getCurrentRoute, isTab} from '#/lib/routes/helpers' import {makeProfileLink} from '#/lib/routes/links' @@ -33,6 +32,7 @@ import {PressableWithHover} from '#/view/com/util/PressableWithHover' import {UserAvatar} from '#/view/com/util/UserAvatar' import {NavSignupCard} from '#/view/shell/NavSignupCard' import {atoms as a, tokens, useLayoutBreakpoints, useTheme, web} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {type DialogControlProps} from '#/components/Dialog' import {ArrowBoxLeft_Stroke2_Corner0_Rounded as LeaveIcon} from '#/components/icons/ArrowBoxLeft' @@ -585,21 +585,26 @@ function ComposeBtn() { } function ChatNavItem() { - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() const {_} = useLingui() const numUnreadMessages = useUnreadMessageCount() + const textStyle: TextStyle = { + color: colorMode === 'light' ? theme.palette.black : theme.palette.white, + } + return ( + } iconFilled={ @@ -611,7 +616,8 @@ function ChatNavItem() { export function DesktopLeftNav() { const {hasSession, currentAccount} = useSession() - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() const {_} = useLingui() const {isDesktop} = useWebMediaQueries() const {leftNavMinimal, centerColumnOffset} = useLayoutBreakpoints() @@ -619,6 +625,10 @@ export function DesktopLeftNav() { const hasHomeBadge = useHomeBadge() const gate = useGate() + const textStyle: TextStyle = { + color: colorMode === 'light' ? theme.palette.black : theme.palette.white, + } + if (!hasSession && !isDesktop) { return null } @@ -658,14 +668,14 @@ export function DesktopLeftNav() { } iconFilled={ } label={_(msg`Home`)} @@ -674,14 +684,14 @@ export function DesktopLeftNav() { href="/search" icon={ } iconFilled={ @@ -695,14 +705,14 @@ export function DesktopLeftNav() { } iconFilled={ } label={_(msg`Notifications`)} @@ -712,14 +722,14 @@ export function DesktopLeftNav() { href="/feeds" icon={ } iconFilled={ @@ -730,14 +740,14 @@ export function DesktopLeftNav() { href="/lists" icon={ } iconFilled={ @@ -748,14 +758,14 @@ export function DesktopLeftNav() { href="/saved" icon={ } iconFilled={ @@ -773,14 +783,14 @@ export function DesktopLeftNav() { } iconFilled={ } label={_(msg`Profile`)} @@ -791,14 +801,14 @@ export function DesktopLeftNav() { } iconFilled={ } label={_(msg`Settings`)} diff --git a/src/view/shell/desktop/Search.tsx b/src/view/shell/desktop/Search.tsx index 38da4e246..054a1691e 100644 --- a/src/view/shell/desktop/Search.tsx +++ b/src/view/shell/desktop/Search.tsx @@ -2,6 +2,7 @@ import React from 'react' import { ActivityIndicator, StyleSheet, + type TextStyle, TouchableOpacity, View, type ViewStyle, @@ -10,14 +11,14 @@ import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' import {StackActions, useNavigation} from '@react-navigation/native' -import {usePalette} from '#/lib/hooks/usePalette' import {type NavigationProp} from '#/lib/routes/types' import {useModerationOpts} from '#/state/preferences/moderation-opts' import {useActorAutocompleteQuery} from '#/state/queries/actor-autocomplete' import {Link} from '#/view/com/util/Link' import {Text} from '#/view/com/util/text/Text' import {SearchProfileCard} from '#/screens/Search/components/SearchProfileCard' -import {atoms as a} from '#/alf' +import {atoms as a, useTheme} from '#/alf' +import {useColorModeTheme} from '#/alf/util/useColorModeTheme' import {SearchInput} from '#/components/forms/SearchInput' let SearchLinkCard = ({ @@ -31,12 +32,21 @@ let SearchLinkCard = ({ onPress?: () => void style?: ViewStyle }): React.ReactNode => { - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() + + const textStyle: TextStyle = { + color: colorMode === 'light' ? theme.palette.black : theme.palette.white, + } const inner = ( - + style={[ + {borderColor: theme.palette.contrast_100}, + {paddingVertical: 16, paddingHorizontal: 12}, + style, + ]}> + {label} @@ -57,11 +67,11 @@ let SearchLinkCard = ({ - + {label} @@ -73,7 +83,8 @@ export {SearchLinkCard} export function DesktopSearch() { const {_} = useLingui() - const pal = usePalette('default') + const theme = useTheme() + const colorMode = useColorModeTheme() const navigation = useNavigation() const [isActive, setIsActive] = React.useState(false) const [query, setQuery] = React.useState('') @@ -106,7 +117,14 @@ export function DesktopSearch() { }, []) return ( - + -- 2.51.2