From 3b78fa4b7fe3292504e828284a0d788b571bf360 Mon Sep 17 00:00:00 2001 From: Joel Jeremy Marquez Date: Mon, 16 Oct 2023 11:35:43 -0700 Subject: [PATCH 1/3] Custom useNavigate which tracks previous location --- .../src/components/FinancesApp.tsx | 2 +- .../src/components/GlobalKeys.tsx | 3 +- .../src/components/Titlebar.tsx | 3 +- .../src/components/accounts/MobileAccount.js | 3 +- .../src/components/accounts/MobileAccounts.js | 2 +- .../src/components/budget/index.js | 3 +- .../src/components/common/ButtonLink.tsx | 3 +- .../src/components/common/Link.tsx | 3 +- .../src/components/manager/ConfigServer.tsx | 2 +- .../manager/subscribe/ChangePassword.tsx | 2 +- .../components/manager/subscribe/Error.tsx | 3 +- .../components/manager/subscribe/common.tsx | 3 +- .../components/modals/CreateLocalAccount.tsx | 2 +- .../src/components/payees/ManagePayeesPage.js | 2 +- .../src/components/settings/UI.tsx | 2 +- .../components/sidebar/SidebarWithData.tsx | 2 +- .../src/components/sidebar/Tools.tsx | 2 +- .../transactions/MobileTransaction.js | 4 +- .../desktop-client/src/hooks/useNavigate.ts | 51 +++++++++++++++++++ .../desktop-client/src/util/router-tools.tsx | 2 +- 20 files changed, 80 insertions(+), 19 deletions(-) create mode 100644 packages/desktop-client/src/hooks/useNavigate.ts diff --git a/packages/desktop-client/src/components/FinancesApp.tsx b/packages/desktop-client/src/components/FinancesApp.tsx index c3e82793c0b..92711dceaa6 100644 --- a/packages/desktop-client/src/components/FinancesApp.tsx +++ b/packages/desktop-client/src/components/FinancesApp.tsx @@ -6,7 +6,6 @@ import { Routes, Navigate, NavLink, - useNavigate, BrowserRouter, useLocation, useHref, @@ -21,6 +20,7 @@ import checkForUpdateNotification from 'loot-core/src/client/update-notification import * as undo from 'loot-core/src/platform/client/undo'; import { useActions } from '../hooks/useActions'; +import useNavigate from '../hooks/useNavigate'; import Add from '../icons/v1/Add'; import Cog from '../icons/v1/Cog'; import PiggyBank from '../icons/v1/PiggyBank'; diff --git a/packages/desktop-client/src/components/GlobalKeys.tsx b/packages/desktop-client/src/components/GlobalKeys.tsx index a75c0763509..cff3d38ae2f 100644 --- a/packages/desktop-client/src/components/GlobalKeys.tsx +++ b/packages/desktop-client/src/components/GlobalKeys.tsx @@ -1,8 +1,9 @@ import { useEffect } from 'react'; -import { useNavigate } from 'react-router-dom'; import * as Platform from 'loot-core/src/client/platform'; +import useNavigate from '../hooks/useNavigate'; + export default function GlobalKeys() { let navigate = useNavigate(); useEffect(() => { diff --git a/packages/desktop-client/src/components/Titlebar.tsx b/packages/desktop-client/src/components/Titlebar.tsx index 6c305f23787..2300bb43408 100644 --- a/packages/desktop-client/src/components/Titlebar.tsx +++ b/packages/desktop-client/src/components/Titlebar.tsx @@ -7,7 +7,7 @@ import React, { type ReactNode, } from 'react'; import { useSelector } from 'react-redux'; -import { Routes, Route, useLocation, useNavigate } from 'react-router-dom'; +import { Routes, Route, useLocation } from 'react-router-dom'; import * as Platform from 'loot-core/src/client/platform'; import * as queries from 'loot-core/src/client/queries'; @@ -15,6 +15,7 @@ import { listen } from 'loot-core/src/platform/client/fetch'; import { useActions } from '../hooks/useActions'; import useFeatureFlag from '../hooks/useFeatureFlag'; +import useNavigate from '../hooks/useNavigate'; import ArrowLeft from '../icons/v1/ArrowLeft'; import AlertTriangle from '../icons/v2/AlertTriangle'; import SvgEye from '../icons/v2/Eye'; diff --git a/packages/desktop-client/src/components/accounts/MobileAccount.js b/packages/desktop-client/src/components/accounts/MobileAccount.js index 83a3f6c5b14..fcf3a487e41 100644 --- a/packages/desktop-client/src/components/accounts/MobileAccount.js +++ b/packages/desktop-client/src/components/accounts/MobileAccount.js @@ -1,6 +1,6 @@ import React, { useEffect, useMemo, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useParams, useNavigate } from 'react-router-dom'; +import { useParams } from 'react-router-dom'; import debounce from 'debounce'; import memoizeOne from 'memoize-one'; @@ -20,6 +20,7 @@ import { } from 'loot-core/src/shared/transactions'; import useCategories from '../../hooks/useCategories'; +import useNavigate from '../../hooks/useNavigate'; import { useSetThemeColor } from '../../hooks/useSetThemeColor'; import { theme } from '../../style'; diff --git a/packages/desktop-client/src/components/accounts/MobileAccounts.js b/packages/desktop-client/src/components/accounts/MobileAccounts.js index 573bc9040b0..e85d77ba1f8 100644 --- a/packages/desktop-client/src/components/accounts/MobileAccounts.js +++ b/packages/desktop-client/src/components/accounts/MobileAccounts.js @@ -1,11 +1,11 @@ import React, { useEffect, useState } from 'react'; import { useSelector } from 'react-redux'; -import { useNavigate } from 'react-router-dom'; import * as queries from 'loot-core/src/client/queries'; import { useActions } from '../../hooks/useActions'; import useCategories from '../../hooks/useCategories'; +import useNavigate from '../../hooks/useNavigate'; import { useSetThemeColor } from '../../hooks/useSetThemeColor'; import { theme, styles } from '../../style'; import Button from '../common/Button'; diff --git a/packages/desktop-client/src/components/budget/index.js b/packages/desktop-client/src/components/budget/index.js index 68a67017f91..65f984d2a08 100644 --- a/packages/desktop-client/src/components/budget/index.js +++ b/packages/desktop-client/src/components/budget/index.js @@ -7,7 +7,7 @@ import React, { useRef, } from 'react'; import { useSelector } from 'react-redux'; -import { useLocation, useMatch, useNavigate } from 'react-router-dom'; +import { useLocation, useMatch } from 'react-router-dom'; import { useSpreadsheet } from 'loot-core/src/client/SpreadsheetProvider'; import { send, listen } from 'loot-core/src/platform/client/fetch'; @@ -26,6 +26,7 @@ import * as monthUtils from 'loot-core/src/shared/months'; import { useActions } from '../../hooks/useActions'; import useCategories from '../../hooks/useCategories'; import useFeatureFlag from '../../hooks/useFeatureFlag'; +import useNavigate from '../../hooks/useNavigate'; import { styles } from '../../style'; import View from '../common/View'; import { TitlebarContext } from '../Titlebar'; diff --git a/packages/desktop-client/src/components/common/ButtonLink.tsx b/packages/desktop-client/src/components/common/ButtonLink.tsx index dca78f6c2d4..1ab6215b61d 100644 --- a/packages/desktop-client/src/components/common/ButtonLink.tsx +++ b/packages/desktop-client/src/components/common/ButtonLink.tsx @@ -1,6 +1,7 @@ import React, { type ComponentProps } from 'react'; -import { useMatch, useNavigate } from 'react-router-dom'; +import { useMatch } from 'react-router-dom'; +import useNavigate from '../../hooks/useNavigate'; import { type CSSProperties } from '../../style'; import Button from './Button'; diff --git a/packages/desktop-client/src/components/common/Link.tsx b/packages/desktop-client/src/components/common/Link.tsx index 19f7fc08ec0..17b146cf349 100644 --- a/packages/desktop-client/src/components/common/Link.tsx +++ b/packages/desktop-client/src/components/common/Link.tsx @@ -1,8 +1,9 @@ import React, { type ReactNode, type ComponentProps } from 'react'; -import { NavLink, useMatch, useNavigate } from 'react-router-dom'; +import { NavLink, useMatch } from 'react-router-dom'; import { css } from 'glamor'; +import useNavigate from '../../hooks/useNavigate'; import { type CSSProperties, styles } from '../../style'; import Button from './Button'; diff --git a/packages/desktop-client/src/components/manager/ConfigServer.tsx b/packages/desktop-client/src/components/manager/ConfigServer.tsx index 1331fa5676c..cda664eb51a 100644 --- a/packages/desktop-client/src/components/manager/ConfigServer.tsx +++ b/packages/desktop-client/src/components/manager/ConfigServer.tsx @@ -1,5 +1,4 @@ import React, { useState, useEffect } from 'react'; -import { useNavigate } from 'react-router-dom'; import { isNonProductionEnvironment, @@ -7,6 +6,7 @@ import { } from 'loot-core/src/shared/environment'; import { useActions } from '../../hooks/useActions'; +import useNavigate from '../../hooks/useNavigate'; import { useSetThemeColor } from '../../hooks/useSetThemeColor'; import { theme } from '../../style'; import Button, { ButtonWithLoading } from '../common/Button'; diff --git a/packages/desktop-client/src/components/manager/subscribe/ChangePassword.tsx b/packages/desktop-client/src/components/manager/subscribe/ChangePassword.tsx index 5ee9f149963..68adb49b8d4 100644 --- a/packages/desktop-client/src/components/manager/subscribe/ChangePassword.tsx +++ b/packages/desktop-client/src/components/manager/subscribe/ChangePassword.tsx @@ -1,8 +1,8 @@ import React, { useState } from 'react'; -import { useNavigate } from 'react-router-dom'; import { send } from 'loot-core/src/platform/client/fetch'; +import useNavigate from '../../../hooks/useNavigate'; import { theme } from '../../../style'; import Button from '../../common/Button'; import Text from '../../common/Text'; diff --git a/packages/desktop-client/src/components/manager/subscribe/Error.tsx b/packages/desktop-client/src/components/manager/subscribe/Error.tsx index 969a0856358..30429f89fd2 100644 --- a/packages/desktop-client/src/components/manager/subscribe/Error.tsx +++ b/packages/desktop-client/src/components/manager/subscribe/Error.tsx @@ -1,6 +1,7 @@ import React from 'react'; -import { useNavigate, useLocation } from 'react-router-dom'; +import { useLocation } from 'react-router-dom'; +import useNavigate from '../../../hooks/useNavigate'; import { theme } from '../../../style'; import Button from '../../common/Button'; import Text from '../../common/Text'; diff --git a/packages/desktop-client/src/components/manager/subscribe/common.tsx b/packages/desktop-client/src/components/manager/subscribe/common.tsx index fdc940f1ba4..9cc46ca8a66 100644 --- a/packages/desktop-client/src/components/manager/subscribe/common.tsx +++ b/packages/desktop-client/src/components/manager/subscribe/common.tsx @@ -1,8 +1,9 @@ import React, { useEffect, useState } from 'react'; -import { useNavigate, useLocation } from 'react-router-dom'; +import { useLocation } from 'react-router-dom'; import { send } from 'loot-core/src/platform/client/fetch'; +import useNavigate from '../../../hooks/useNavigate'; import { theme } from '../../../style'; import { useSetServerURL } from '../../ServerContext'; diff --git a/packages/desktop-client/src/components/modals/CreateLocalAccount.tsx b/packages/desktop-client/src/components/modals/CreateLocalAccount.tsx index 349cc4a221d..2264f452051 100644 --- a/packages/desktop-client/src/components/modals/CreateLocalAccount.tsx +++ b/packages/desktop-client/src/components/modals/CreateLocalAccount.tsx @@ -1,9 +1,9 @@ import React, { useState } from 'react'; -import { useNavigate } from 'react-router-dom'; import { toRelaxedNumber } from 'loot-core/src/shared/util'; import { type BoundActions } from '../../hooks/useActions'; +import useNavigate from '../../hooks/useNavigate'; import { theme } from '../../style'; import { type CommonModalProps } from '../../types/modals'; import Button from '../common/Button'; diff --git a/packages/desktop-client/src/components/payees/ManagePayeesPage.js b/packages/desktop-client/src/components/payees/ManagePayeesPage.js index f4d5e903187..2d707f39131 100644 --- a/packages/desktop-client/src/components/payees/ManagePayeesPage.js +++ b/packages/desktop-client/src/components/payees/ManagePayeesPage.js @@ -1,5 +1,5 @@ import React from 'react'; -import { useLocation } from 'react-router'; +import { useLocation } from 'react-router-dom'; import { Page } from '../Page'; diff --git a/packages/desktop-client/src/components/settings/UI.tsx b/packages/desktop-client/src/components/settings/UI.tsx index 766e4952f68..0e96292cb8b 100644 --- a/packages/desktop-client/src/components/settings/UI.tsx +++ b/packages/desktop-client/src/components/settings/UI.tsx @@ -1,5 +1,5 @@ import React, { useState, type ReactNode } from 'react'; -import { useLocation } from 'react-router'; +import { useLocation } from 'react-router-dom'; import { css, media } from 'glamor'; diff --git a/packages/desktop-client/src/components/sidebar/SidebarWithData.tsx b/packages/desktop-client/src/components/sidebar/SidebarWithData.tsx index 0a3f23bf860..5fa7122b7b4 100644 --- a/packages/desktop-client/src/components/sidebar/SidebarWithData.tsx +++ b/packages/desktop-client/src/components/sidebar/SidebarWithData.tsx @@ -1,6 +1,5 @@ import React, { useState, useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; -import { useNavigate } from 'react-router'; import { closeBudget } from 'loot-core/src/client/actions/budgets'; import * as Platform from 'loot-core/src/client/platform'; @@ -9,6 +8,7 @@ import { send } from 'loot-core/src/platform/client/fetch'; import { type LocalPrefs } from 'loot-core/src/types/prefs'; import { useActions } from '../../hooks/useActions'; +import useNavigate from '../../hooks/useNavigate'; import ExpandArrow from '../../icons/v0/ExpandArrow'; import { styles, theme } from '../../style'; import Button from '../common/Button'; diff --git a/packages/desktop-client/src/components/sidebar/Tools.tsx b/packages/desktop-client/src/components/sidebar/Tools.tsx index 216cc397e0c..d07e50ea8b8 100644 --- a/packages/desktop-client/src/components/sidebar/Tools.tsx +++ b/packages/desktop-client/src/components/sidebar/Tools.tsx @@ -1,5 +1,5 @@ import React, { useState, useCallback, useEffect } from 'react'; -import { useLocation } from 'react-router'; +import { useLocation } from 'react-router-dom'; import CheveronDown from '../../icons/v1/CheveronDown'; import CheveronRight from '../../icons/v1/CheveronRight'; diff --git a/packages/desktop-client/src/components/transactions/MobileTransaction.js b/packages/desktop-client/src/components/transactions/MobileTransaction.js index 52db1dbb342..922b301c97e 100644 --- a/packages/desktop-client/src/components/transactions/MobileTransaction.js +++ b/packages/desktop-client/src/components/transactions/MobileTransaction.js @@ -5,9 +5,10 @@ import React, { useEffect, useState, useRef, + memo, } from 'react'; import { useSelector } from 'react-redux'; -import { useNavigate, useParams, Link } from 'react-router-dom'; +import { useParams, Link } from 'react-router-dom'; import { useFocusRing } from '@react-aria/focus'; import { useListBox, useListBoxSection, useOption } from '@react-aria/listbox'; @@ -45,6 +46,7 @@ import { import { useActions } from '../../hooks/useActions'; import useCategories from '../../hooks/useCategories'; +import useNavigate from '../../hooks/useNavigate'; import { useSetThemeColor } from '../../hooks/useSetThemeColor'; import SvgAdd from '../../icons/v1/Add'; import CheveronLeft from '../../icons/v1/CheveronLeft'; diff --git a/packages/desktop-client/src/hooks/useNavigate.ts b/packages/desktop-client/src/hooks/useNavigate.ts new file mode 100644 index 00000000000..21387e423b0 --- /dev/null +++ b/packages/desktop-client/src/hooks/useNavigate.ts @@ -0,0 +1,51 @@ +import { useCallback } from 'react'; +import { + type Location, + type NavigateFunction, + type NavigateOptions, + type To, + useLocation, + useNavigate as useNavigateReactRouter, +} from 'react-router-dom'; + +export default function useNavigate(): NavigateFunction { + const location = useLocation(); + const navigate = useNavigateReactRouter(); + return useCallback( + (to: To | number, options: NavigateOptions = {}) => { + if (typeof to === 'number') { + navigate(to); + } else { + const optionsWithPrevLocation: NavigateOptions = { + replace: + options.replace || isSamePath(to, location) ? true : undefined, + ...options, + state: { + ...options?.state, + previousLocation: location, + }, + }; + + let { previousLocation, ...previousOriginalState } = + location.state || {}; + + if ( + previousLocation == null || + !isSamePath(to, previousLocation) || + JSON.stringify(options?.state || {}) !== + JSON.stringify(previousOriginalState) + ) { + navigate(to, optionsWithPrevLocation); + } else { + // `to` is the same as the previous location. Just go back. + navigate(-1); + } + } + }, + [navigate, location], + ); +} + +function isSamePath(to: To, location: Location) { + return to === location.pathname + location.search + location.hash; +} diff --git a/packages/desktop-client/src/util/router-tools.tsx b/packages/desktop-client/src/util/router-tools.tsx index 21e89c061ae..d7bdcba08ec 100644 --- a/packages/desktop-client/src/util/router-tools.tsx +++ b/packages/desktop-client/src/util/router-tools.tsx @@ -1,5 +1,5 @@ import { useLayoutEffect } from 'react'; -import { useNavigate } from 'react-router-dom'; +import useNavigate from '../hooks/useNavigate'; export function ExposeNavigate() { let navigate = useNavigate(); From aa5e93ef47b51366264f900b5cb926aecfe78f03 Mon Sep 17 00:00:00 2001 From: Joel Jeremy Marquez Date: Mon, 16 Oct 2023 11:37:33 -0700 Subject: [PATCH 2/3] Release notes --- upcoming-release-notes/1808.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 upcoming-release-notes/1808.md diff --git a/upcoming-release-notes/1808.md b/upcoming-release-notes/1808.md new file mode 100644 index 00000000000..dd21148d476 --- /dev/null +++ b/upcoming-release-notes/1808.md @@ -0,0 +1,6 @@ +--- +category: Bugfix +authors: [joel-jeremy] +--- + +Fix flaky mobile back button on account transactions. From 03982ae66611b5db76b1fa063c521362ba3a5e28 Mon Sep 17 00:00:00 2001 From: Joel Jeremy Marquez Date: Mon, 16 Oct 2023 11:53:04 -0700 Subject: [PATCH 3/3] Fix lint errors --- .../src/components/transactions/MobileTransaction.js | 1 - packages/desktop-client/src/util/router-tools.tsx | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/desktop-client/src/components/transactions/MobileTransaction.js b/packages/desktop-client/src/components/transactions/MobileTransaction.js index 922b301c97e..01606bb3036 100644 --- a/packages/desktop-client/src/components/transactions/MobileTransaction.js +++ b/packages/desktop-client/src/components/transactions/MobileTransaction.js @@ -5,7 +5,6 @@ import React, { useEffect, useState, useRef, - memo, } from 'react'; import { useSelector } from 'react-redux'; import { useParams, Link } from 'react-router-dom'; diff --git a/packages/desktop-client/src/util/router-tools.tsx b/packages/desktop-client/src/util/router-tools.tsx index d7bdcba08ec..ec4b37bbf21 100644 --- a/packages/desktop-client/src/util/router-tools.tsx +++ b/packages/desktop-client/src/util/router-tools.tsx @@ -1,4 +1,5 @@ import { useLayoutEffect } from 'react'; + import useNavigate from '../hooks/useNavigate'; export function ExposeNavigate() {