From 625adbefec6ca8543da56dbd62fbb5e1a469358a Mon Sep 17 00:00:00 2001 From: VH Date: Thu, 27 Jul 2023 22:28:58 +0700 Subject: [PATCH 01/13] Should not open unlink in desktop --- src/ROUTES.js | 4 ++++ src/components/DeeplinkWrapper/index.website.js | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/ROUTES.js b/src/ROUTES.js index 215a9a6384c3..d2a1d8bc9123 100644 --- a/src/ROUTES.js +++ b/src/ROUTES.js @@ -187,4 +187,8 @@ export default { isSubReportPageRoute: Boolean(lodashGet(pathSegments, 2)), }; }, + + ROUTES_REGEX: { + UNLINK_LOGIN: /\/u($|(\/\/*))/, + } }; diff --git a/src/components/DeeplinkWrapper/index.website.js b/src/components/DeeplinkWrapper/index.website.js index 08c88a2a5da5..af93ab6834be 100644 --- a/src/components/DeeplinkWrapper/index.website.js +++ b/src/components/DeeplinkWrapper/index.website.js @@ -1,6 +1,7 @@ import PropTypes from 'prop-types'; import {PureComponent} from 'react'; import Str from 'expensify-common/lib/str'; +import _ from 'underscore'; import * as Browser from '../../libs/Browser'; import ROUTES from '../../ROUTES'; import * as App from '../../libs/actions/App'; @@ -18,6 +19,10 @@ class DeeplinkWrapper extends PureComponent { return; } + if (this.isUnsupportedDeeplinkRoute()) { + return; + } + // If the current url path is /transition..., meaning it was opened from oldDot, during this transition period: // 1. The user session may not exist, because sign-in has not been completed yet. // 2. There may be non-idempotent operations (e.g. create a new workspace), which obviously should not be executed again in the desktop app. @@ -33,6 +38,14 @@ class DeeplinkWrapper extends PureComponent { return !Browser.isMobile() && typeof navigator === 'object' && typeof navigator.userAgent === 'string' && /Mac/i.test(navigator.userAgent) && !/Electron/i.test(navigator.userAgent); } + // Function to detect if current route should open in Web only. + isUnsupportedDeeplinkRoute() { + return _.some([ROUTES.ROUTES_REGEX.UNLINK_LOGIN], (unsupportRouteRegex) => { + const routeRegex = new RegExp(unsupportRouteRegex); + return routeRegex.test(window.location.pathname); + }); + } + render() { return this.props.children; } From 9e7114f45d52cd54b160ffc861257b704adc4937 Mon Sep 17 00:00:00 2001 From: VH Date: Thu, 27 Jul 2023 22:30:08 +0700 Subject: [PATCH 02/13] Fix unable to unlink due to translation error --- src/libs/actions/Session/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/Session/index.js b/src/libs/actions/Session/index.js index 571c0b7ad0c4..a6522c14d626 100644 --- a/src/libs/actions/Session/index.js +++ b/src/libs/actions/Session/index.js @@ -632,7 +632,7 @@ function unlinkLogin(accountID, validateCode) { key: ONYXKEYS.ACCOUNT, value: { isLoading: false, - message: Localize.translateLocal('unlinkLoginForm.succesfullyUnlinkedLogin'), + message: 'unlinkLoginForm.succesfullyUnlinkedLogin', }, }, { From 870c0131304b5f44dc16e11394345120dd6a29b8 Mon Sep 17 00:00:00 2001 From: VH Date: Thu, 27 Jul 2023 22:40:43 +0700 Subject: [PATCH 03/13] Fix linter --- src/ROUTES.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ROUTES.js b/src/ROUTES.js index d2a1d8bc9123..a7feccd3e79e 100644 --- a/src/ROUTES.js +++ b/src/ROUTES.js @@ -190,5 +190,5 @@ export default { ROUTES_REGEX: { UNLINK_LOGIN: /\/u($|(\/\/*))/, - } + }, }; From 16feab4281d0b9774ae6581b13aa3da6229f96b9 Mon Sep 17 00:00:00 2001 From: VH Date: Thu, 27 Jul 2023 22:49:52 +0700 Subject: [PATCH 04/13] Remove unused util --- src/libs/actions/Session/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/actions/Session/index.js b/src/libs/actions/Session/index.js index a6522c14d626..2cb76342f43a 100644 --- a/src/libs/actions/Session/index.js +++ b/src/libs/actions/Session/index.js @@ -10,7 +10,6 @@ import Log from '../../Log'; import PushNotification from '../../Notification/PushNotification'; import Timing from '../Timing'; import CONST from '../../../CONST'; -import * as Localize from '../../Localize'; import Timers from '../../Timers'; import * as Pusher from '../../Pusher/pusher'; import * as Authentication from '../../Authentication'; From 1e4cba65521c02c03dea7e11fb941c8207caaade Mon Sep 17 00:00:00 2001 From: VH Date: Tue, 1 Aug 2023 23:41:56 +0700 Subject: [PATCH 05/13] Change the regex const to CONST --- src/CONST.js | 1 + src/ROUTES.js | 4 ---- src/components/DeeplinkWrapper/index.website.js | 4 ++-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/CONST.js b/src/CONST.js index 39d190788b41..4b96e7b9e4ec 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -1182,6 +1182,7 @@ const CONST = { ROUTES: { VALIDATE_LOGIN: /\/v($|(\/\/*))/, + UNLINK_LOGIN: /\/u($|(\/\/*))/, }, }, diff --git a/src/ROUTES.js b/src/ROUTES.js index a7feccd3e79e..215a9a6384c3 100644 --- a/src/ROUTES.js +++ b/src/ROUTES.js @@ -187,8 +187,4 @@ export default { isSubReportPageRoute: Boolean(lodashGet(pathSegments, 2)), }; }, - - ROUTES_REGEX: { - UNLINK_LOGIN: /\/u($|(\/\/*))/, - }, }; diff --git a/src/components/DeeplinkWrapper/index.website.js b/src/components/DeeplinkWrapper/index.website.js index af93ab6834be..45a355156045 100644 --- a/src/components/DeeplinkWrapper/index.website.js +++ b/src/components/DeeplinkWrapper/index.website.js @@ -38,9 +38,9 @@ class DeeplinkWrapper extends PureComponent { return !Browser.isMobile() && typeof navigator === 'object' && typeof navigator.userAgent === 'string' && /Mac/i.test(navigator.userAgent) && !/Electron/i.test(navigator.userAgent); } - // Function to detect if current route should open in Web only. + // A function to detect if current route should be opened in Web only. isUnsupportedDeeplinkRoute() { - return _.some([ROUTES.ROUTES_REGEX.UNLINK_LOGIN], (unsupportRouteRegex) => { + return _.some([CONST.REGEX.ROUTES.UNLINK_LOGIN], (unsupportRouteRegex) => { const routeRegex = new RegExp(unsupportRouteRegex); return routeRegex.test(window.location.pathname); }); From a1bf7f38951efa9f958d6e92742fa3ec4b03fbc6 Mon Sep 17 00:00:00 2001 From: VH Date: Fri, 4 Aug 2023 07:19:39 +0700 Subject: [PATCH 06/13] Update comment why unlink is in the list --- src/components/DeeplinkWrapper/index.website.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/DeeplinkWrapper/index.website.js b/src/components/DeeplinkWrapper/index.website.js index 45a355156045..e47b938ef196 100644 --- a/src/components/DeeplinkWrapper/index.website.js +++ b/src/components/DeeplinkWrapper/index.website.js @@ -38,8 +38,9 @@ class DeeplinkWrapper extends PureComponent { return !Browser.isMobile() && typeof navigator === 'object' && typeof navigator.userAgent === 'string' && /Mac/i.test(navigator.userAgent) && !/Electron/i.test(navigator.userAgent); } - // A function to detect if current route should be opened in Web only. isUnsupportedDeeplinkRoute() { + // According to the design, we don't support unlink in Desktop app + // https://github.com/Expensify/App/issues/19681#issuecomment-1610353099 return _.some([CONST.REGEX.ROUTES.UNLINK_LOGIN], (unsupportRouteRegex) => { const routeRegex = new RegExp(unsupportRouteRegex); return routeRegex.test(window.location.pathname); From 6f37650411d3e62505d7b72e22800a064ff1940e Mon Sep 17 00:00:00 2001 From: VH Date: Fri, 4 Aug 2023 09:00:54 +0700 Subject: [PATCH 07/13] Show full screen loading until the request is completed --- src/pages/UnlinkLoginPage.js | 37 ++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/pages/UnlinkLoginPage.js b/src/pages/UnlinkLoginPage.js index ee77bb2d2045..ac7bc7aadd8e 100644 --- a/src/pages/UnlinkLoginPage.js +++ b/src/pages/UnlinkLoginPage.js @@ -1,26 +1,53 @@ -import React from 'react'; +import React, {useEffect} from 'react'; +import PropTypes from 'prop-types'; import lodashGet from 'lodash/get'; +import {withOnyx} from 'react-native-onyx'; import {propTypes as validateLinkPropTypes, defaultProps as validateLinkDefaultProps} from './ValidateLoginPage/validateLinkPropTypes'; import FullScreenLoadingIndicator from '../components/FullscreenLoadingIndicator'; import Navigation from '../libs/Navigation/Navigation'; import * as Session from '../libs/actions/Session'; import ROUTES from '../ROUTES'; +import usePrevious from '../hooks/usePrevious'; +import ONYXKEYS from '../ONYXKEYS'; const propTypes = { /** The accountID and validateCode are passed via the URL */ route: validateLinkPropTypes, + + /** The details about the account that the user is signing in with */ + account: PropTypes.shape({ + /** Whether a sign is loading */ + isLoading: PropTypes.bool, + }), }; const defaultProps = { route: validateLinkDefaultProps, + account: { + isLoading: false, + }, }; function UnlinkLoginPage(props) { const accountID = lodashGet(props.route.params, 'accountID', ''); const validateCode = lodashGet(props.route.params, 'validateCode', ''); + const prevIsLoading = usePrevious(props.account.isLoading); + + useEffect(() => { + Session.unlinkLogin(accountID, validateCode); + // We only want this to run on mount + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + useEffect(() => { + // Only navigate when the unlink login request is completed + if (!prevIsLoading || props.account.isLoading) { + return; + } + + Navigation.navigate(ROUTES.HOME); + }, [prevIsLoading, props.account.isLoading]) - Session.unlinkLogin(accountID, validateCode); - Navigation.navigate(ROUTES.HOME); return ; } @@ -28,4 +55,6 @@ UnlinkLoginPage.propTypes = propTypes; UnlinkLoginPage.defaultProps = defaultProps; UnlinkLoginPage.displayName = 'UnlinkLoginPage'; -export default UnlinkLoginPage; +export default withOnyx({ + account: {key: ONYXKEYS.ACCOUNT}, +})(UnlinkLoginPage); From 2bcd9f50a8c9b3f434ad20f3182e69a473920ada Mon Sep 17 00:00:00 2001 From: VH Date: Fri, 4 Aug 2023 09:10:28 +0700 Subject: [PATCH 08/13] Fix linter --- src/pages/UnlinkLoginPage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/UnlinkLoginPage.js b/src/pages/UnlinkLoginPage.js index ac7bc7aadd8e..67c073820bc0 100644 --- a/src/pages/UnlinkLoginPage.js +++ b/src/pages/UnlinkLoginPage.js @@ -46,7 +46,7 @@ function UnlinkLoginPage(props) { } Navigation.navigate(ROUTES.HOME); - }, [prevIsLoading, props.account.isLoading]) + }, [prevIsLoading, props.account.isLoading]); return ; } From 3f35a3d7836e620a03010d809243600d512b393f Mon Sep 17 00:00:00 2001 From: VH Date: Wed, 9 Aug 2023 17:33:46 +0700 Subject: [PATCH 09/13] Fix merge conflict --- src/components/DeeplinkWrapper/index.website.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/DeeplinkWrapper/index.website.js b/src/components/DeeplinkWrapper/index.website.js index 49e620234877..f2c22f77d46c 100644 --- a/src/components/DeeplinkWrapper/index.website.js +++ b/src/components/DeeplinkWrapper/index.website.js @@ -32,7 +32,7 @@ function DeeplinkWrapper({children}) { return; } - if (this.isUnsupportedDeeplinkRoute()) { + if (isUnsupportedDeeplinkRoute) { return; } From f9b8d0ecb2517c73d320b15a813544ee77e8f546 Mon Sep 17 00:00:00 2001 From: VH Date: Wed, 9 Aug 2023 17:45:43 +0700 Subject: [PATCH 10/13] Fix linter --- .../DeeplinkWrapper/index.website.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/components/DeeplinkWrapper/index.website.js b/src/components/DeeplinkWrapper/index.website.js index f2c22f77d46c..2fe8e582060d 100644 --- a/src/components/DeeplinkWrapper/index.website.js +++ b/src/components/DeeplinkWrapper/index.website.js @@ -18,14 +18,15 @@ function isMacOSWeb() { } function DeeplinkWrapper({children}) { - const isUnsupportedDeeplinkRoute = useMemo(() => { - // According to the design, we don't support unlink in Desktop app - // https://github.com/Expensify/App/issues/19681#issuecomment-1610353099 - return _.some([CONST.REGEX.ROUTES.UNLINK_LOGIN], (unsupportRouteRegex) => { - const routeRegex = new RegExp(unsupportRouteRegex); - return routeRegex.test(window.location.pathname); - }); - }, []); + const isUnsupportedDeeplinkRoute = useMemo( + () => + // According to the design, we don't support unlink in Desktop app https://github.com/Expensify/App/issues/19681#issuecomment-1610353099 + _.some([CONST.REGEX.ROUTES.UNLINK_LOGIN], (unsupportRouteRegex) => { + const routeRegex = new RegExp(unsupportRouteRegex); + return routeRegex.test(window.location.pathname); + }), + [], + ); useEffect(() => { if (!isMacOSWeb() || CONFIG.ENVIRONMENT === CONST.ENVIRONMENT.DEV) { @@ -46,6 +47,8 @@ function DeeplinkWrapper({children}) { } App.beginDeepLinkRedirect(); + // We only want this to run on mount + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return children; From d9586c9df520ed08ae54967abe56aab075ac6b7a Mon Sep 17 00:00:00 2001 From: VH Date: Wed, 9 Aug 2023 17:48:27 +0700 Subject: [PATCH 11/13] Group early exit conditions --- src/components/DeeplinkWrapper/index.website.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/components/DeeplinkWrapper/index.website.js b/src/components/DeeplinkWrapper/index.website.js index 2fe8e582060d..7213919e1b0c 100644 --- a/src/components/DeeplinkWrapper/index.website.js +++ b/src/components/DeeplinkWrapper/index.website.js @@ -29,11 +29,7 @@ function DeeplinkWrapper({children}) { ); useEffect(() => { - if (!isMacOSWeb() || CONFIG.ENVIRONMENT === CONST.ENVIRONMENT.DEV) { - return; - } - - if (isUnsupportedDeeplinkRoute) { + if (!isMacOSWeb() || isUnsupportedDeeplinkRoute || CONFIG.ENVIRONMENT === CONST.ENVIRONMENT.DEV) { return; } From befda6d17e4f9350bad5a2a028961cc71218afd1 Mon Sep 17 00:00:00 2001 From: VH Date: Thu, 10 Aug 2023 21:46:44 +0700 Subject: [PATCH 12/13] Revert using useMemo --- src/components/DeeplinkWrapper/index.website.js | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/components/DeeplinkWrapper/index.website.js b/src/components/DeeplinkWrapper/index.website.js index 7213919e1b0c..3d92b763a9b0 100644 --- a/src/components/DeeplinkWrapper/index.website.js +++ b/src/components/DeeplinkWrapper/index.website.js @@ -1,5 +1,5 @@ import PropTypes from 'prop-types'; -import {useEffect, useMemo} from 'react'; +import {useEffect} from 'react'; import Str from 'expensify-common/lib/str'; import _ from 'underscore'; import * as Browser from '../../libs/Browser'; @@ -18,15 +18,11 @@ function isMacOSWeb() { } function DeeplinkWrapper({children}) { - const isUnsupportedDeeplinkRoute = useMemo( - () => - // According to the design, we don't support unlink in Desktop app https://github.com/Expensify/App/issues/19681#issuecomment-1610353099 - _.some([CONST.REGEX.ROUTES.UNLINK_LOGIN], (unsupportRouteRegex) => { - const routeRegex = new RegExp(unsupportRouteRegex); - return routeRegex.test(window.location.pathname); - }), - [], - ); + // According to the design, we don't support unlink in Desktop app https://github.com/Expensify/App/issues/19681#issuecomment-1610353099 + const isUnsupportedDeeplinkRoute = _.some([CONST.REGEX.ROUTES.UNLINK_LOGIN], (unsupportRouteRegex) => { + const routeRegex = new RegExp(unsupportRouteRegex); + return routeRegex.test(window.location.pathname); + }); useEffect(() => { if (!isMacOSWeb() || isUnsupportedDeeplinkRoute || CONFIG.ENVIRONMENT === CONST.ENVIRONMENT.DEV) { From 21f34cc06141774c583e25a9893ea006524e778a Mon Sep 17 00:00:00 2001 From: VH Date: Thu, 10 Aug 2023 21:53:51 +0700 Subject: [PATCH 13/13] Refactor code --- src/components/DeeplinkWrapper/index.website.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/components/DeeplinkWrapper/index.website.js b/src/components/DeeplinkWrapper/index.website.js index 3d92b763a9b0..1f5988da3224 100644 --- a/src/components/DeeplinkWrapper/index.website.js +++ b/src/components/DeeplinkWrapper/index.website.js @@ -18,13 +18,13 @@ function isMacOSWeb() { } function DeeplinkWrapper({children}) { - // According to the design, we don't support unlink in Desktop app https://github.com/Expensify/App/issues/19681#issuecomment-1610353099 - const isUnsupportedDeeplinkRoute = _.some([CONST.REGEX.ROUTES.UNLINK_LOGIN], (unsupportRouteRegex) => { - const routeRegex = new RegExp(unsupportRouteRegex); - return routeRegex.test(window.location.pathname); - }); - useEffect(() => { + // According to the design, we don't support unlink in Desktop app https://github.com/Expensify/App/issues/19681#issuecomment-1610353099 + const isUnsupportedDeeplinkRoute = _.some([CONST.REGEX.ROUTES.UNLINK_LOGIN], (unsupportRouteRegex) => { + const routeRegex = new RegExp(unsupportRouteRegex); + return routeRegex.test(window.location.pathname); + }); + if (!isMacOSWeb() || isUnsupportedDeeplinkRoute || CONFIG.ENVIRONMENT === CONST.ENVIRONMENT.DEV) { return; } @@ -39,8 +39,6 @@ function DeeplinkWrapper({children}) { } App.beginDeepLinkRedirect(); - // We only want this to run on mount - // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return children;