diff --git a/src/components/AccountSwitcher.tsx b/src/components/AccountSwitcher.tsx index a9e223e5663..7449836e77f 100644 --- a/src/components/AccountSwitcher.tsx +++ b/src/components/AccountSwitcher.tsx @@ -131,6 +131,7 @@ function AccountSwitcher() { }} ref={buttonRef} interactive={canSwitchAccounts} + pressDimmingValue={canSwitchAccounts ? undefined : 1} wrapperStyle={[styles.flexGrow1, styles.flex1, styles.mnw0, styles.justifyContentCenter]} > @@ -145,7 +146,7 @@ function AccountSwitcher() { {currentUserPersonalDetails?.displayName} diff --git a/src/components/AvatarSkeleton.tsx b/src/components/AvatarSkeleton.tsx index 273143f7609..a88304b15fc 100644 --- a/src/components/AvatarSkeleton.tsx +++ b/src/components/AvatarSkeleton.tsx @@ -1,17 +1,22 @@ import React from 'react'; import {Circle} from 'react-native-svg'; +import type {ValueOf} from 'type-fest'; +import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; -import variables from '@styles/variables'; +import CONST from '@src/CONST'; import SkeletonViewContentLoader from './SkeletonViewContentLoader'; -function AvatarSkeleton() { +function AvatarSkeleton({size = CONST.AVATAR_SIZE.SMALL}: {size?: ValueOf}) { const theme = useTheme(); - const skeletonCircleRadius = variables.sidebarAvatarSize / 2; + + const StyleUtils = useStyleUtils(); + const avatarSize = StyleUtils.getAvatarSize(size); + const skeletonCircleRadius = avatarSize / 2; return ( diff --git a/src/components/AvatarWithImagePicker.tsx b/src/components/AvatarWithImagePicker.tsx index 6b9995e7781..011b7f51027 100644 --- a/src/components/AvatarWithImagePicker.tsx +++ b/src/components/AvatarWithImagePicker.tsx @@ -193,6 +193,10 @@ function AvatarWithImagePicker({ setError(null, {}); }, [isFocused]); + useEffect(() => { + setError(null, {}); + }, [source, avatarID]); + /** * Check if the attachment extension is allowed. */ @@ -325,7 +329,7 @@ function AvatarWithImagePicker({ ); return ( - + diff --git a/src/libs/actions/Delegate.ts b/src/libs/actions/Delegate.ts index 50d2ee7fc19..573a8ca2ca6 100644 --- a/src/libs/actions/Delegate.ts +++ b/src/libs/actions/Delegate.ts @@ -21,7 +21,7 @@ Onyx.connect({ }, }); -const KEYS_TO_PRESERVE_DELEGATE_ACCESS = [ONYXKEYS.NVP_TRY_FOCUS_MODE, ONYXKEYS.PREFERRED_THEME, ONYXKEYS.NVP_PREFERRED_LOCALE, ONYXKEYS.SESSION]; +const KEYS_TO_PRESERVE_DELEGATE_ACCESS = [ONYXKEYS.NVP_TRY_FOCUS_MODE, ONYXKEYS.PREFERRED_THEME, ONYXKEYS.NVP_PREFERRED_LOCALE, ONYXKEYS.SESSION, ONYXKEYS.IS_LOADING_APP]; function connect(email: string) { if (!delegatedAccess?.delegators) { diff --git a/src/pages/settings/Profile/ProfilePage.tsx b/src/pages/settings/Profile/ProfilePage.tsx index cc3d93c3db2..83fcdefb352 100755 --- a/src/pages/settings/Profile/ProfilePage.tsx +++ b/src/pages/settings/Profile/ProfilePage.tsx @@ -1,7 +1,7 @@ import React from 'react'; import {View} from 'react-native'; -import type {OnyxEntry} from 'react-native-onyx'; -import {withOnyx} from 'react-native-onyx'; +import {useOnyx} from 'react-native-onyx'; +import AvatarSkeleton from '@components/AvatarSkeleton'; import AvatarWithImagePicker from '@components/AvatarWithImagePicker'; import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; @@ -16,8 +16,7 @@ import ScrollView from '@components/ScrollView'; import Section from '@components/Section'; import Text from '@components/Text'; import Tooltip from '@components/Tooltip'; -import type {WithCurrentUserPersonalDetailsProps} from '@components/withCurrentUserPersonalDetails'; -import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalDetails'; +import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; import useLocalize from '@hooks/useLocalize'; import useResponsiveLayout from '@hooks/useResponsiveLayout'; import useStyleUtils from '@hooks/useStyleUtils'; @@ -33,44 +32,21 @@ import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import type {LoginList, PrivatePersonalDetails} from '@src/types/onyx'; +import {isEmptyObject} from '@src/types/utils/EmptyObject'; -type ProfilePageOnyxProps = { - loginList: OnyxEntry; - /** User's private personal details */ - privatePersonalDetails: OnyxEntry; - /** Whether app is loading */ - isLoadingApp: OnyxEntry; -}; - -type ProfilePageProps = ProfilePageOnyxProps & WithCurrentUserPersonalDetailsProps; - -function ProfilePage({ - loginList, - privatePersonalDetails = { - legalFirstName: '', - legalLastName: '', - dob: '', - addresses: [ - { - street: '', - street2: '', - city: '', - state: '', - zip: '', - country: '', - }, - ], - }, - currentUserPersonalDetails, - isLoadingApp, -}: ProfilePageProps) { +function ProfilePage() { const theme = useTheme(); const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); const {translate} = useLocalize(); const {shouldUseNarrowLayout} = useResponsiveLayout(); + const [loginList] = useOnyx(ONYXKEYS.LOGIN_LIST); + const [privatePersonalDetails] = useOnyx(ONYXKEYS.PRIVATE_PERSONAL_DETAILS); + const currentUserPersonalDetails = useCurrentUserPersonalDetails(); + + const isLoadingApp = useOnyx(ONYXKEYS.IS_LOADING_APP); + const getPronouns = (): string => { const pronounsKey = currentUserPersonalDetails?.pronouns?.replace(CONST.PRONOUNS.PREFIX, '') ?? ''; return pronounsKey ? translate(`pronouns.${pronounsKey}` as TranslationPaths) : translate('profilePage.selectYourPronouns'); @@ -155,27 +131,31 @@ function ProfilePage({ titleStyles={styles.accountSettingsSectionTitle} > - - Navigation.navigate(ROUTES.PROFILE_AVATAR.getRoute(String(accountID)))} - previewSource={UserUtils.getFullSizeAvatar(avatarURL, accountID)} - originalFileName={currentUserPersonalDetails.originalFileName} - headerTitle={translate('profilePage.profileAvatar')} - fallbackIcon={currentUserPersonalDetails?.fallbackIcon} - editIconStyle={styles.profilePageAvatar} - /> - + {isEmptyObject(currentUserPersonalDetails) || accountID === -1 || !avatarURL ? ( + + ) : ( + + Navigation.navigate(ROUTES.PROFILE_AVATAR.getRoute(String(accountID)))} + previewSource={UserUtils.getFullSizeAvatar(avatarURL, accountID)} + originalFileName={currentUserPersonalDetails.originalFileName} + headerTitle={translate('profilePage.profileAvatar')} + fallbackIcon={currentUserPersonalDetails?.fallbackIcon} + editIconStyle={styles.profilePageAvatar} + /> + + )} {publicOptions.map((detail, index) => ( ({ - loginList: { - key: ONYXKEYS.LOGIN_LIST, - }, - privatePersonalDetails: { - key: ONYXKEYS.PRIVATE_PERSONAL_DETAILS, - }, - isLoadingApp: { - key: ONYXKEYS.IS_LOADING_APP, - }, - })(ProfilePage), -); +export default ProfilePage; diff --git a/src/pages/settings/Security/AddDelegate/AddDelegatePage.tsx b/src/pages/settings/Security/AddDelegate/AddDelegatePage.tsx index eae54fa88c2..ade900f365a 100644 --- a/src/pages/settings/Security/AddDelegate/AddDelegatePage.tsx +++ b/src/pages/settings/Security/AddDelegate/AddDelegatePage.tsx @@ -48,7 +48,7 @@ function useOptions() { 0, ); - const headerMessage = OptionsListUtils.getHeaderMessage((recentReports?.length || 0) + (personalDetails?.length || 0) !== 0 || !!currentUserOption, !!userToInvite, ''); + const headerMessage = OptionsListUtils.getHeaderMessage((recentReports?.length || 0) + (personalDetails?.length || 0) !== 0, !!userToInvite, ''); if (isLoading) { setIsLoading(false); @@ -72,7 +72,7 @@ function useOptions() { maxRecentReportsToShow: CONST.IOU.MAX_RECENT_REPORTS_TO_SHOW, }); const headerMessage = OptionsListUtils.getHeaderMessage( - (filteredOptions.recentReports?.length || 0) + (filteredOptions.personalDetails?.length || 0) !== 0 || !!filteredOptions.currentUserOption, + (filteredOptions.recentReports?.length || 0) + (filteredOptions.personalDetails?.length || 0) !== 0, !!filteredOptions.userToInvite, debouncedSearchValue, ); diff --git a/src/pages/settings/Security/AddDelegate/SelectDelegateRolePage.tsx b/src/pages/settings/Security/AddDelegate/SelectDelegateRolePage.tsx index e295a9a7ece..551f5c2c223 100644 --- a/src/pages/settings/Security/AddDelegate/SelectDelegateRolePage.tsx +++ b/src/pages/settings/Security/AddDelegate/SelectDelegateRolePage.tsx @@ -24,9 +24,9 @@ function SelectDelegateRolePage({route}: SelectDelegateRolePageProps) { const roleOptions = Object.values(CONST.DELEGATE_ROLE).map((role) => ({ value: role, text: translate('delegate.role', role), - keyForList: role, alternateText: translate('delegate.roleDescription', role), isSelected: role === route.params.role, + keyForList: role, })); return ( @@ -41,6 +41,8 @@ function SelectDelegateRolePage({route}: SelectDelegateRolePageProps) { role.isSelected)?.keyForList} + shouldUpdateFocusedIndex headerContent={ <> diff --git a/src/pages/settings/Security/SecuritySettingsPage.tsx b/src/pages/settings/Security/SecuritySettingsPage.tsx index 1de5cb58bf3..6403b0ac64e 100644 --- a/src/pages/settings/Security/SecuritySettingsPage.tsx +++ b/src/pages/settings/Security/SecuritySettingsPage.tsx @@ -119,7 +119,7 @@ function SecuritySettingsPage() { description: personalDetail?.displayName ? formattedEmail : '', badgeText: translate('delegate.role', role), avatarID: personalDetail?.accountID ?? -1, - icon: personalDetail?.avatar ?? '', + icon: personalDetail?.avatar ?? FallbackAvatar, iconType: CONST.ICON_TYPE_AVATAR, numberOfLinesDescription: 1, wrapperStyle: [styles.sectionMenuItemTopDescription], @@ -163,7 +163,7 @@ function SecuritySettingsPage() {
( - + {translate('delegate.copilotDelegatedAccessDescription')} {translate('common.learnMore')} - + )} isCentralPane subtitleMuted diff --git a/src/pages/settings/Subscription/SubscriptionSettingsPage.tsx b/src/pages/settings/Subscription/SubscriptionSettingsPage.tsx index c6112ec19c8..16fa481b16a 100644 --- a/src/pages/settings/Subscription/SubscriptionSettingsPage.tsx +++ b/src/pages/settings/Subscription/SubscriptionSettingsPage.tsx @@ -1,5 +1,7 @@ import React, {useEffect} from 'react'; import {View} from 'react-native'; +import {useOnyx} from 'react-native-onyx'; +import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import * as Illustrations from '@components/Icon/Illustrations'; import ScreenWrapper from '@components/ScreenWrapper'; @@ -11,6 +13,7 @@ import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; import NotFoundPage from '@pages/ErrorPage/NotFoundPage'; import * as Subscription from '@userActions/Subscription'; +import ONYXKEYS from '@src/ONYXKEYS'; import CardSection from './CardSection/CardSection'; import ReducedFunctionalityMessage from './ReducedFunctionalityMessage'; import SubscriptionDetails from './SubscriptionDetails'; @@ -26,7 +29,11 @@ function SubscriptionSettingsPage() { useEffect(() => { Subscription.openSubscriptionPage(); }, []); + const [isAppLoading] = useOnyx(ONYXKEYS.IS_LOADING_APP); + if (!subscriptionPlan && isAppLoading) { + return ; + } if (!subscriptionPlan) { return ; }