diff --git a/src/CONST.ts b/src/CONST.ts index f0139d82e614..f3fb7d14263c 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -3650,24 +3650,24 @@ const CONST = { type: 'createWorkspace', autoCompleted: true, title: 'Create a workspace', - subtitle: 'Create a workspace to track expenses, scan receipts, chat, and more.', + subtitle: 'Create a workspace to track expenses, scan receipts, chat, and more.', message: 'Here’s how to create a workspace:\n' + '\n' + '1. Click your profile picture.\n' + '2. Click Workspaces > New workspace.\n' + '\n' + - 'Your new workspace is ready! It’ll keep all of your spend (and chats) in one place.', + 'Your new workspace is ready! It’ll keep all of your spend (and chats) in one place.', }, { type: 'trackExpense', autoCompleted: false, title: 'Track an expense', - subtitle: 'Track an expense in any currency, in just a few clicks.', + subtitle: 'Track an expense in any currency, in just a few clicks.', message: 'Here’s how to track an expense:\n' + '\n' + - '1. Click the green + button.\n' + + '1. Click the green + button.\n' + '2. Choose Track expense.\n' + '3. Enter an amount or scan a receipt.\n' + '4. Click Track.\n' + @@ -3690,11 +3690,11 @@ const CONST = { type: 'submitExpense', autoCompleted: false, title: 'Submit an expense', - subtitle: 'Submit an expense by entering an amount or scanning a receipt.', + subtitle: 'Submit an expense by entering an amount or scanning a receipt.', message: 'Here’s how to submit an expense:\n' + '\n' + - '1. Click the green + button.\n' + + '1. Click the green + button.\n' + '2. Choose Submit expense.\n' + '3. Enter an amount or scan a receipt.\n' + '4. Add your reimburser to the request.\n' + @@ -3705,7 +3705,7 @@ const CONST = { type: 'enableWallet', autoCompleted: false, title: 'Enable your wallet', - subtitle: 'You’ll need to enable your Expensify Wallet to get paid back. Don’t worry, it’s easy!', + subtitle: 'You’ll need to enable your Expensify Wallet to get paid back. Don’t worry, it’s easy!', message: 'Here’s how to set up your wallet:\n' + '\n' + @@ -3731,14 +3731,14 @@ const CONST = { type: 'createWorkspace', autoCompleted: true, title: 'Create a workspace', - subtitle: 'Create a workspace to track expenses, scan receipts, chat, and more.', + subtitle: 'Create a workspace to track expenses, scan receipts, chat, and more.', message: 'Here’s how to create a workspace:\n' + '\n' + '1. Click your profile picture.\n' + '2. Click Workspaces > New workspace.\n' + '\n' + - 'Your new workspace is ready! It’ll keep all of your spend (and chats) in one place.', + 'Your new workspace is ready! It’ll keep all of your spend (and chats) in one place.', }, { type: 'meetGuide', @@ -3754,7 +3754,7 @@ const CONST = { type: 'setupCategories', autoCompleted: false, title: 'Set up categories', - subtitle: 'Set up categories so your team can code expenses for easy reporting.', + subtitle: 'Set up categories so your team can code expenses for easy reporting.', message: 'Here’s how to set up categories:\n' + '\n' + @@ -3764,21 +3764,21 @@ const CONST = { '4. Enable and disable default categories.\n' + '5. Click Add categories to make your own.\n' + '\n' + - 'For more controls like requiring a category for every expense, click Settings.', + 'For more controls like requiring a category for every expense, click Settings.', }, { type: 'addExpenseApprovals', autoCompleted: false, title: 'Add expense approvals', - subtitle: 'Add expense approvals to review your team’s spend and keep it under control.', + subtitle: 'Add expense approvals to review your team’s spend and keep it under control.', message: 'Here’s how to add expense approvals:\n' + '\n' + '1. Click your profile picture.\n' + - '2. Go to Workspaces > [your workspace].\n' + + '2. Go to Workspaces > [your workspace].\n' + '3. Click More features.\n' + '4. Enable Workflows.\n' + - '5. In Workflows, enable Add approvals.\n' + + '5. In Workflows, enable Add approvals.\n' + '\n' + 'You’ll be set as the expense approver. You can change this to any admin once you invite your team.', }, @@ -3786,7 +3786,7 @@ const CONST = { type: 'inviteTeam', autoCompleted: false, title: 'Invite your team', - subtitle: 'Invite your team to Expensify so they can start tracking expenses today.', + subtitle: 'Invite your team to Expensify so they can start tracking expenses today.', message: 'Here’s how to invite your team:\n' + '\n' + @@ -3814,14 +3814,14 @@ const CONST = { type: 'trackExpense', autoCompleted: false, title: 'Track an expense', - subtitle: 'Track an expense in any currency, whether you have a receipt or not.', + subtitle: 'Track an expense in any currency, whether you have a receipt or not.', message: 'Here’s how to track an expense:\n' + '\n' + - '1. Click the green + button.\n' + + '1. Click the green + button.\n' + '2. Choose Track expense.\n' + '3. Enter an amount or scan a receipt.\n' + - '4. Click Track.\n' + + '4. Click Track.\n' + '\n' + 'And you’re done! Yep, it’s that easy.', }, @@ -3841,15 +3841,15 @@ const CONST = { type: 'startChat', autoCompleted: false, title: 'Start a chat', - subtitle: 'Start a chat with a friend or group using their email or phone number.', + subtitle: 'Start a chat with a friend or group using their email or phone number.', message: 'Here’s how to start a chat:\n' + '\n' + - '1. Click the green + button.\n' + + '1. Click the green + button.\n' + '2. Choose Start chat.\n' + '3. Enter emails or phone numbers.\n' + '\n' + - 'If any of your friends aren’t using Expensify already, they’ll be invited automatically. \n' + + 'If any of your friends aren’t using Expensify already, they’ll be invited automatically.\n' + '\n' + 'Every chat will also turn into an email or text that they can respond to directly.', }, @@ -3857,11 +3857,11 @@ const CONST = { type: 'splitExpense', autoCompleted: false, title: 'Split an expense', - subtitle: 'Split an expense right in your chat with one or more friends.', + subtitle: 'Split an expense right in your chat with one or more friends.', message: 'Here’s how to request money:\n' + '\n' + - '1. Click the green + button.\n' + + '1. Click the green + button.\n' + '2. Choose Split expense.\n' + '3. Scan a receipt or enter an amount.\n' + '4. Add your friend(s) to the request.\n' + @@ -3872,7 +3872,7 @@ const CONST = { type: 'enableWallet', autoCompleted: false, title: 'Enable your wallet', - subtitle: 'You’ll need to enable your Expensify Wallet to get paid back. Don’t worry, it’s easy!', + subtitle: 'You’ll need to enable your Expensify Wallet to get paid back. Don’t worry, it’s easy!', message: 'Here’s how to enable your wallet:\n' + '\n' + diff --git a/src/components/OnboardingWelcomeVideo.tsx b/src/components/OnboardingWelcomeVideo.tsx index 6858d29f4d3c..8c851a452eda 100644 --- a/src/components/OnboardingWelcomeVideo.tsx +++ b/src/components/OnboardingWelcomeVideo.tsx @@ -148,7 +148,7 @@ function OnboardingWelcomeVideo() { success pressOnEnter onPress={closeModal} - text={translate('onboarding.welcomeVideo.button')} + text={translate('footer.getStarted')} /> diff --git a/src/languages/en.ts b/src/languages/en.ts index ab802ae4321b..728b214d65cf 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1320,8 +1320,7 @@ export default { onboarding: { welcomeVideo: { title: 'Welcome to Expensify', - description: 'Getting paid is as easy as sending a message.', - button: "Let's go", + description: 'One app to handle all your business and personal spend in a chat. Built for your business, your team, and your friends.', }, whatsYourName: "What's your name?", whereYouWork: 'Where do you work?', diff --git a/src/languages/es.ts b/src/languages/es.ts index f8c882dc3ac9..6ca7c4a210e1 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -314,7 +314,7 @@ export default { subtitleText2: 'o crea algo usando el botón', subtitleText3: '.', }, - businessName: 'Nombre del Negocio', + businessName: 'Nombre de la empresa', }, location: { useCurrent: 'Usar ubicación actual', @@ -1319,8 +1319,7 @@ export default { onboarding: { welcomeVideo: { title: 'Bienvenido a Expensify', - description: 'Cobrar es tan fácil como enviar un mensaje.', - button: 'Vámonos', + description: 'Una aplicación para gestionar todos tus gastos de empresa y personales en un chat. Pensada para tu empresa, tu equipo y tus amigos.', }, whatsYourName: '¿Cómo te llamas?', whereYouWork: '¿Dónde trabajas?', diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.tsx b/src/libs/Navigation/AppNavigator/AuthScreens.tsx index 096a88254eae..917f206cf4f0 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.tsx +++ b/src/libs/Navigation/AppNavigator/AuthScreens.tsx @@ -10,6 +10,7 @@ import useWindowDimensions from '@hooks/useWindowDimensions'; import KeyboardShortcut from '@libs/KeyboardShortcut'; import Log from '@libs/Log'; import getCurrentUrl from '@libs/Navigation/currentUrl'; +import getOnboardingModalScreenOptions from '@libs/Navigation/getOnboardingModalScreenOptions'; import Navigation from '@libs/Navigation/Navigation'; import type {AuthScreensParamList} from '@libs/Navigation/types'; import NetworkConnection from '@libs/NetworkConnection'; @@ -160,7 +161,11 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie const {isSmallScreenWidth} = useWindowDimensions(); const {shouldUseNarrowLayout} = useOnboardingLayout(); const screenOptions = getRootNavigatorScreenOptions(isSmallScreenWidth, styles, StyleUtils); - const onboardingScreenOptions = useMemo(() => screenOptions.onboardingModalNavigator(shouldUseNarrowLayout), [screenOptions, shouldUseNarrowLayout]); + const onboardingModalScreenOptions = useMemo(() => screenOptions.onboardingModalNavigator(shouldUseNarrowLayout), [screenOptions, shouldUseNarrowLayout]); + const onboardingScreenOptions = useMemo( + () => getOnboardingModalScreenOptions(isSmallScreenWidth, styles, StyleUtils, shouldUseNarrowLayout), + [StyleUtils, isSmallScreenWidth, shouldUseNarrowLayout, styles], + ); const isInitialRender = useRef(true); if (isInitialRender.current) { @@ -364,12 +369,12 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie /> { + const hasSubtitle = !!task.subtitle; const currentTask = ReportUtils.buildOptimisticTaskReport( actorAccountID, undefined, @@ -3065,13 +3066,13 @@ function completeOnboarding( actorAccountID, index + 3, { - childVisibleActionCount: 2, + childVisibleActionCount: hasSubtitle ? 2 : 1, childCommenterCount: 1, childLastVisibleActionCreated: DateUtils.getDBTime(), childOldestFourAccountIDs: `${actorAccountID}`, }, ); - const subtitleComment = task.subtitle ? ReportUtils.buildOptimisticAddCommentReportAction(task.subtitle, undefined, actorAccountID) : null; + const subtitleComment = hasSubtitle ? ReportUtils.buildOptimisticAddCommentReportAction(task.subtitle, undefined, actorAccountID, 0, false) : null; const isTaskMessageFunction = typeof task.message === 'function'; const taskMessage = isTaskMessageFunction ? task.message({ @@ -3218,6 +3219,33 @@ function completeOnboarding( [], ); + const tasksForFailureData = tasksData.reduce((acc, {currentTask, taskReportAction}) => { + const tasksForFailureDataAcc: OnyxUpdate[] = [ + ...acc, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${targetChatReportID}`, + value: { + [taskReportAction.reportAction.reportActionID]: { + errors: ErrorUtils.getMicroSecondOnyxError('report.genericAddCommentFailureMessage'), + } as ReportAction, + }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${currentTask.reportID}`, + value: null, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${currentTask.reportID}`, + value: null, + }, + ]; + + return tasksForFailureDataAcc; + }, []); + const optimisticData: OnyxUpdate[] = [ ...tasksForOptimisticData, { @@ -3253,6 +3281,52 @@ function completeOnboarding( }, }, ]; + let failureReport: Partial = { + lastMessageTranslationKey: '', + lastMessageText: '', + lastVisibleActionCreated: '', + }; + const {lastMessageText = '', lastMessageTranslationKey = ''} = ReportActionsUtils.getLastVisibleMessage(targetChatReportID); + if (lastMessageText || lastMessageTranslationKey) { + const lastVisibleAction = ReportActionsUtils.getLastVisibleAction(targetChatReportID); + const lastVisibleActionCreated = lastVisibleAction?.created; + const lastActorAccountID = lastVisibleAction?.actorAccountID; + failureReport = { + lastMessageTranslationKey, + lastMessageText, + lastVisibleActionCreated, + lastActorAccountID, + }; + } + + const failureData: OnyxUpdate[] = [ + ...tasksForFailureData, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT}${targetChatReportID}`, + value: failureReport, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${targetChatReportID}`, + value: { + [mentionCommentAction.reportActionID]: { + errors: ErrorUtils.getMicroSecondOnyxError('report.genericAddCommentFailureMessage'), + } as ReportAction, + [textCommentAction.reportActionID]: { + errors: ErrorUtils.getMicroSecondOnyxError('report.genericAddCommentFailureMessage'), + } as ReportAction, + [videoCommentAction.reportActionID]: { + errors: ErrorUtils.getMicroSecondOnyxError('report.genericAddCommentFailureMessage'), + } as ReportAction, + }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.NVP_INTRO_SELECTED, + value: {choice: null}, + }, + ]; const guidedSetupData: GuidedSetupData = [ {type: 'message', ...mentionMessage}, @@ -3268,7 +3342,7 @@ function completeOnboarding( guidedSetupData: JSON.stringify(guidedSetupData), }; - API.write(WRITE_COMMANDS.COMPLETE_GUIDED_SETUP, parameters, {optimisticData, successData}); + API.write(WRITE_COMMANDS.COMPLETE_GUIDED_SETUP, parameters, {optimisticData, successData, failureData}); } /** diff --git a/src/styles/variables.ts b/src/styles/variables.ts index ff1b20893110..c7de01fdf6c6 100644 --- a/src/styles/variables.ts +++ b/src/styles/variables.ts @@ -203,7 +203,7 @@ export default { sectionIllustrationHeight: 220, photoUploadPopoverWidth: 335, onboardingModalWidth: 500, - welcomeVideoDelay: 500, + welcomeVideoDelay: 1000, // The height of the empty list is 14px (2px for borders and 12px for vertical padding) // This is calculated based on the values specified in the 'getGoogleListViewStyle' function of the 'StyleUtils' utility