Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Ideal nav v2] Update Share code and Status buttons #36805

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions src/components/QRShare/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,12 @@ import QRCode from '@components/QRCode';
import Text from '@components/Text';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import variables from '@styles/variables';
import CONST from '@src/CONST';
import type {QRShareHandle, QRShareProps} from './types';

function QRShare({url, title, subtitle, logo, logoRatio, logoMarginRatio}: QRShareProps, ref: ForwardedRef<QRShareHandle>) {
const styles = useThemeStyles();
const theme = useTheme();
const {isSmallScreenWidth} = useWindowDimensions();

const [qrCodeSize, setQrCodeSize] = useState(1);
const svgRef = useRef<Svg>();
Expand All @@ -32,11 +29,7 @@ function QRShare({url, title, subtitle, logo, logoRatio, logoMarginRatio}: QRSha

const onLayout = (event: LayoutChangeEvent) => {
const containerWidth = event.nativeEvent.layout.width - variables.qrShareHorizontalPadding * 2 || 0;
if (isSmallScreenWidth) {
setQrCodeSize(Math.max(1, containerWidth));
return;
}
setQrCodeSize(Math.max(1, Math.min(containerWidth, CONST.CENTRAL_PANE_ANIMATION_HEIGHT)));
setQrCodeSize(Math.max(1, containerWidth));
};

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,6 @@ const AccountSettingsModalStackNavigator = createModalStackNavigator(
[SCREENS.SETTINGS.PREFERENCES.ROOT]: () => require('../../../pages/settings/Preferences/PreferencesPage').default as React.ComponentType,
[SCREENS.SETTINGS.SECURITY]: () => require('../../../pages/settings/Security/SecuritySettingsPage').default as React.ComponentType,
[SCREENS.SETTINGS.PROFILE.ROOT]: () => require('../../../pages/settings/Profile/ProfilePage').default as React.ComponentType,
[SCREENS.SETTINGS.SHARE_CODE]: () => require('../../../pages/ShareCodePage').default as React.ComponentType,
[SCREENS.SETTINGS.WALLET.ROOT]: () => require('../../../pages/settings/Wallet/WalletPage').default as React.ComponentType,
[SCREENS.SETTINGS.ABOUT]: () => require('../../../pages/settings/AboutPage/AboutPage').default as React.ComponentType,
},
Expand All @@ -203,6 +202,7 @@ const WorkspaceSwitcherModalStackNavigator = createModalStackNavigator<Workspace
});

const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorParamList>({
[SCREENS.SETTINGS.SHARE_CODE]: () => require('../../../pages/ShareCodePage').default as React.ComponentType,
[SCREENS.SETTINGS.PROFILE.PRONOUNS]: () => require('../../../pages/settings/Profile/PronounsPage').default as React.ComponentType,
[SCREENS.SETTINGS.PROFILE.DISPLAY_NAME]: () => require('../../../pages/settings/Profile/DisplayNamePage').default as React.ComponentType,
[SCREENS.SETTINGS.PROFILE.TIMEZONE]: () => require('../../../pages/settings/Profile/TimezoneInitialPage').default as React.ComponentType,
Expand Down
7 changes: 3 additions & 4 deletions src/libs/Navigation/linkingConfig/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,9 @@ const config: LinkingOptions<RootStackParamList>['config'] = {
path: ROUTES.KEYBOARD_SHORTCUTS,
},
[SCREENS.WORKSPACE.NAME]: ROUTES.WORKSPACE_PROFILE_NAME.route,
[SCREENS.SETTINGS.SHARE_CODE]: {
path: ROUTES.SETTINGS_SHARE_CODE,
},
},
},
[SCREENS.RIGHT_MODAL.PRIVATE_NOTES]: {
Expand Down Expand Up @@ -498,10 +501,6 @@ const config: LinkingOptions<RootStackParamList>['config'] = {
},
[SCREENS.SETTINGS_CENTRAL_PANE]: {
screens: {
[SCREENS.SETTINGS.SHARE_CODE]: {
path: ROUTES.SETTINGS_SHARE_CODE,
exact: true,
},
[SCREENS.SETTINGS.PROFILE.ROOT]: {
path: ROUTES.SETTINGS_PROFILE,
exact: true,
Expand Down
17 changes: 12 additions & 5 deletions src/libs/Navigation/linkingConfig/getAdaptedStateFromPath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,16 @@ function createCentralPaneNavigator(route: NavigationPartialRoute<CentralPaneNam
};
}

function createFullScreenNavigator(route: NavigationPartialRoute<FullScreenName>): NavigationPartialRoute<typeof NAVIGATORS.FULL_SCREEN_NAVIGATOR> {
function createFullScreenNavigator(route?: NavigationPartialRoute<FullScreenName>): NavigationPartialRoute<typeof NAVIGATORS.FULL_SCREEN_NAVIGATOR> {
const routes = [];

routes.push({name: SCREENS.SETTINGS.ROOT});
routes.push({
name: SCREENS.SETTINGS_CENTRAL_PANE,
state: getRoutesWithIndex([route]),
});
if (route) {
routes.push({
name: SCREENS.SETTINGS_CENTRAL_PANE,
state: getRoutesWithIndex([route]),
});
}

return {
name: NAVIGATORS.FULL_SCREEN_NAVIGATOR,
Expand Down Expand Up @@ -129,6 +131,11 @@ function getMatchingRootRouteForRHPRoute(
return createFullScreenNavigator({name: fullScreenName as FullScreenName, params: route.params});
}
}

// This screen is opened from the LHN of the FullStackNavigator, so in this case we shouldn't push any CentralPane screen
if (route.name === SCREENS.SETTINGS.SHARE_CODE) {
return createFullScreenNavigator();
}
}

function getAdaptedState(state: PartialState<NavigationState<RootStackParamList>>, policyID?: string): GetAdaptedStateReturnType {
Expand Down
2 changes: 1 addition & 1 deletion src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,7 @@ type RightModalNavigatorParamList = {
[SCREENS.RIGHT_MODAL.NEW_CHAT]: NavigatorScreenParams<NewChatNavigatorParamList>;
[SCREENS.RIGHT_MODAL.DETAILS]: NavigatorScreenParams<DetailsNavigatorParamList>;
[SCREENS.RIGHT_MODAL.PROFILE]: NavigatorScreenParams<ProfileNavigatorParamList>;
[SCREENS.SETTINGS.SHARE_CODE]: undefined;
[SCREENS.RIGHT_MODAL.REPORT_DETAILS]: NavigatorScreenParams<ReportDetailsNavigatorParamList>;
[SCREENS.RIGHT_MODAL.REPORT_SETTINGS]: NavigatorScreenParams<ReportSettingsNavigatorParamList>;
[SCREENS.RIGHT_MODAL.REPORT_DESCRIPTION]: NavigatorScreenParams<ReportDescriptionNavigatorParamList>;
Expand All @@ -441,7 +442,6 @@ type RightModalNavigatorParamList = {
};

type SettingsCentralPaneNavigatorParamList = {
[SCREENS.SETTINGS.SHARE_CODE]: undefined;
[SCREENS.SETTINGS.PROFILE.ROOT]: undefined;
[SCREENS.SETTINGS.PREFERENCES.ROOT]: undefined;
[SCREENS.SETTINGS.SECURITY]: undefined;
Expand Down
100 changes: 38 additions & 62 deletions src/pages/ShareCodePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,14 @@ import expensifyLogo from '@assets/images/expensify-logo-round-transparent.png';
import ContextMenuItem from '@components/ContextMenuItem';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import * as Expensicons from '@components/Icon/Expensicons';
import * as Illustrations from '@components/Icon/Illustrations';
import MenuItem from '@components/MenuItem';
import QRShareWithDownload from '@components/QRShare/QRShareWithDownload';
import type QRShareWithDownloadHandle from '@components/QRShare/QRShareWithDownload/types';
import ScreenWrapper from '@components/ScreenWrapper';
import Section from '@components/Section';
import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails';
import useEnvironment from '@hooks/useEnvironment';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import Clipboard from '@libs/Clipboard';
import getPlatform from '@libs/getPlatform';
import Navigation from '@libs/Navigation/Navigation';
Expand All @@ -39,7 +36,6 @@ function ShareCodePage({report}: ShareCodePageProps) {
const {translate} = useLocalize();
const {environmentURL} = useEnvironment();
const qrCodeRef = useRef<QRShareWithDownloadHandle>(null);
const {isSmallScreenWidth} = useWindowDimensions();
const currentUserPersonalDetails = useCurrentUserPersonalDetails();

const isReport = !!report?.reportID;
Expand Down Expand Up @@ -71,72 +67,52 @@ function ShareCodePage({report}: ShareCodePageProps) {
const isNative = platform === CONST.PLATFORM.IOS || platform === CONST.PLATFORM.ANDROID;

return (
<ScreenWrapper
testID={ShareCodePage.displayName}
shouldShowOfflineIndicatorInWideScreen={!isReport}
>
<ScreenWrapper testID={ShareCodePage.displayName}>
<HeaderWithBackButton
title={translate('common.shareCode')}
onBackButtonPress={() => Navigation.goBack(isReport ? ROUTES.REPORT_WITH_ID_DETAILS.getRoute(report.reportID) : undefined)}
shouldShowBackButton={isReport || isSmallScreenWidth}
icon={Illustrations.QRCode}
shouldShowBackButton
/>
<ScrollView style={[themeStyles.flex1, themeStyles.pt3]}>
<View style={[themeStyles.flex1, isSmallScreenWidth ? themeStyles.workspaceSectionMobile : themeStyles.workspaceSection]}>
<Section
title={translate('shareCodePage.title')}
subtitle={translate('shareCodePage.subtitle')}
isCentralPane
subtitleMuted
childrenStyles={themeStyles.pt5}
titleStyles={themeStyles.accountSettingsSectionTitle}
>
<View style={[isSmallScreenWidth ? themeStyles.workspaceSectionMobile : themeStyles.qrShareSection]}>
<QRShareWithDownload
ref={qrCodeRef}
url={url}
title={title}
subtitle={subtitle}
logo={isReport ? expensifyLogo : (UserUtils.getAvatarUrl(currentUserPersonalDetails?.avatar, currentUserPersonalDetails?.accountID) as ImageSourcePropType)}
logoRatio={isReport ? CONST.QR.EXPENSIFY_LOGO_SIZE_RATIO : CONST.QR.DEFAULT_LOGO_SIZE_RATIO}
logoMarginRatio={isReport ? CONST.QR.EXPENSIFY_LOGO_MARGIN_RATIO : CONST.QR.DEFAULT_LOGO_MARGIN_RATIO}
/>
</View>
<View style={[themeStyles.workspaceSectionMobile, themeStyles.ph5]}>
<QRShareWithDownload
ref={qrCodeRef}
url={url}
title={title}
subtitle={subtitle}
logo={isReport ? expensifyLogo : (UserUtils.getAvatarUrl(currentUserPersonalDetails?.avatar, currentUserPersonalDetails?.accountID) as ImageSourcePropType)}
logoRatio={isReport ? CONST.QR.EXPENSIFY_LOGO_SIZE_RATIO : CONST.QR.DEFAULT_LOGO_SIZE_RATIO}
logoMarginRatio={isReport ? CONST.QR.EXPENSIFY_LOGO_MARGIN_RATIO : CONST.QR.DEFAULT_LOGO_MARGIN_RATIO}
/>
</View>

<View style={{marginTop: 36}}>
<ContextMenuItem
isAnonymousAction
text={translate('qrCodes.copy')}
icon={Expensicons.Copy}
successIcon={Expensicons.Checkmark}
successText={translate('qrCodes.copied')}
onPress={() => Clipboard.setString(url)}
shouldLimitWidth={false}
wrapperStyle={themeStyles.sectionMenuItemTopDescription}
/>
<View style={themeStyles.mt9}>
<ContextMenuItem
isAnonymousAction
text={translate('qrCodes.copy')}
icon={Expensicons.Copy}
successIcon={Expensicons.Checkmark}
successText={translate('qrCodes.copied')}
onPress={() => Clipboard.setString(url)}
shouldLimitWidth={false}
/>

{isNative && (
<MenuItem
isAnonymousAction
title={translate('common.download')}
icon={Expensicons.Download}
// eslint-disable-next-line @typescript-eslint/no-misused-promises
onPress={() => qrCodeRef.current?.download?.()}
wrapperStyle={themeStyles.sectionMenuItemTopDescription}
/>
)}
{isNative && (
<MenuItem
isAnonymousAction
title={translate('common.download')}
icon={Expensicons.Download}
// eslint-disable-next-line @typescript-eslint/no-misused-promises
onPress={() => qrCodeRef.current?.download?.()}
/>
)}

<MenuItem
title={translate(`referralProgram.${CONST.REFERRAL_PROGRAM.CONTENT_TYPES.SHARE_CODE}.buttonText1`)}
icon={Expensicons.Cash}
onPress={() =>
Navigation.navigate(ROUTES.REFERRAL_DETAILS_MODAL.getRoute(CONST.REFERRAL_PROGRAM.CONTENT_TYPES.SHARE_CODE, Navigation.getActiveRouteWithoutParams()))
}
wrapperStyle={themeStyles.sectionMenuItemTopDescription}
shouldShowRightIcon
/>
</View>
</Section>
<MenuItem
title={translate(`referralProgram.${CONST.REFERRAL_PROGRAM.CONTENT_TYPES.SHARE_CODE}.buttonText1`)}
icon={Expensicons.Cash}
onPress={() => Navigation.navigate(ROUTES.REFERRAL_DETAILS_MODAL.getRoute(CONST.REFERRAL_PROGRAM.CONTENT_TYPES.SHARE_CODE, Navigation.getActiveRouteWithoutParams()))}
shouldShowRightIcon
/>
</View>
</ScrollView>
</ScreenWrapper>
Expand Down
46 changes: 41 additions & 5 deletions src/pages/settings/InitialSettingsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ import cardPropTypes from '@components/cardPropTypes';
import ConfirmModal from '@components/ConfirmModal';
import CurrentUserPersonalDetailsSkeletonView from '@components/CurrentUserPersonalDetailsSkeletonView';
import HeaderPageLayout from '@components/HeaderPageLayout';
import Icon from '@components/Icon';
import * as Expensicons from '@components/Icon/Expensicons';
import MenuItem from '@components/MenuItem';
import OfflineWithFeedback from '@components/OfflineWithFeedback';
import {withNetwork} from '@components/OnyxProvider';
import {PressableWithFeedback} from '@components/Pressable';
import Text from '@components/Text';
import Tooltip from '@components/Tooltip';
import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsDefaultProps, withCurrentUserPersonalDetailsPropTypes} from '@components/withCurrentUserPersonalDetails';
import withLocalize, {withLocalizePropTypes} from '@components/withLocalize';
import useLocalize from '@hooks/useLocalize';
Expand All @@ -31,6 +34,7 @@ import Navigation from '@libs/Navigation/Navigation';
import * as UserUtils from '@libs/UserUtils';
import walletTermsPropTypes from '@pages/EnablePayments/walletTermsPropTypes';
import * as ReportActionContextMenu from '@pages/home/report/ContextMenu/ReportActionContextMenu';
import variables from '@styles/variables';
import * as Link from '@userActions/Link';
import * as PaymentMethods from '@userActions/PaymentMethods';
import * as PersonalDetails from '@userActions/PersonalDetails';
Expand Down Expand Up @@ -100,6 +104,7 @@ function InitialSettingsPage(props) {
const popoverAnchor = useRef(null);
const {translate} = useLocalize();
const activeRoute = useNavigationState(getTopmostSettingsCentralPaneName);
const emojiCode = lodashGet(props, 'currentUserPersonalDetails.status.emojiCode', '');

const [shouldShowSignoutConfirmModal, setShouldShowSignoutConfirmModal] = useState(false);

Expand Down Expand Up @@ -151,11 +156,6 @@ function InitialSettingsPage(props) {
? 'error'
: null,
},
{
translationKey: 'common.shareCode',
icon: Expensicons.QrCode,
routeName: ROUTES.SETTINGS_SHARE_CODE,
},
{
translationKey: 'common.preferences',
icon: Expensicons.Gear,
Expand Down Expand Up @@ -332,6 +332,42 @@ function InitialSettingsPage(props) {
<CurrentUserPersonalDetailsSkeletonView avatarSize={CONST.AVATAR_SIZE.XLARGE} />
) : (
<>
<View style={[styles.flexRow, styles.w100, styles.justifyContentBetween, styles.alignItemsCenter, styles.pb5]}>
<Tooltip text={translate('common.shareCode')}>
<PressableWithFeedback
accessibilityRole="button"
onPress={() => Navigation.navigate(ROUTES.SETTINGS_SHARE_CODE)}
>
<View style={styles.primaryMediumIcon}>
<Icon
src={Expensicons.QrCode}
width={variables.iconSizeNormal}
height={variables.iconSizeNormal}
fill={theme.icon}
/>
</View>
</PressableWithFeedback>
</Tooltip>
<Tooltip text={translate('statusPage.status')}>
<PressableWithFeedback
accessibilityRole="button"
onPress={() => Navigation.navigate(ROUTES.SETTINGS_STATUS)}
>
<View style={styles.primaryMediumIcon}>
{emojiCode ? (
<Text style={styles.primaryMediumText}>{emojiCode}</Text>
) : (
<Icon
src={Expensicons.Emoji}
width={variables.iconSizeNormal}
height={variables.iconSizeNormal}
fill={theme.icon}
/>
)}
</View>
</PressableWithFeedback>
</Tooltip>
</View>
<OfflineWithFeedback
pendingAction={lodashGet(props.currentUserPersonalDetails, 'pendingFields.avatar', null)}
style={[styles.mb3, styles.w100]}
Expand Down
14 changes: 14 additions & 0 deletions src/styles/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3062,6 +3062,20 @@ const styles = (theme: ThemeColors) =>
bottom: -8,
},

primaryMediumIcon: {
alignItems: 'center',
backgroundColor: theme.buttonDefaultBG,
borderRadius: 20,
color: theme.textReversed,
height: 40,
width: 40,
justifyContent: 'center',
},

primaryMediumText: {
fontSize: variables.iconSizeNormal,
},

workspaceOwnerAvatarWrapper: {
margin: 6,
},
Expand Down
Loading