From a08ebb9ce50eb5c965b12a5e706db01b8eff9ff6 Mon Sep 17 00:00:00 2001 From: Henry Heino <46334387+personalizedrefrigerator@users.noreply.github.com> Date: Sat, 9 Nov 2024 04:54:09 -0800 Subject: [PATCH] Android: Fixes #11324: Fix sharing to Joplin causes back navigation to get stuck (#11355) --- .../app-mobile/components/screens/Note.tsx | 8 +++---- packages/app-mobile/package.json | 1 + packages/app-mobile/root.tsx | 16 +++++++++++++- packages/app-mobile/utils/shareHandler.ts | 21 +++++++------------ yarn.lock | 1 + 5 files changed, 29 insertions(+), 18 deletions(-) diff --git a/packages/app-mobile/components/screens/Note.tsx b/packages/app-mobile/components/screens/Note.tsx index a5f4253d8d..a10bc2e0a3 100644 --- a/packages/app-mobile/components/screens/Note.tsx +++ b/packages/app-mobile/components/screens/Note.tsx @@ -245,14 +245,14 @@ class NoteScreenComponent extends BaseScreenComponent implements B } if (this.state.fromShare) { - // effectively the same as NAV_BACK but NAV_BACK causes undesired behaviour in this case: + // Note: In the past, NAV_BACK caused undesired behaviour in this case: // - share to Joplin from some other app // - open Joplin and open any note // - go back -- with NAV_BACK this causes the app to exit rather than just showing notes + // This no longer seems to happen, but this case should be checked when adjusting navigation + // history behavior. this.props.dispatch({ - type: 'NAV_GO', - routeName: 'Notes', - folderId: this.state.note.parent_id, + type: 'NAV_BACK', }); ShareExtension.close(); diff --git a/packages/app-mobile/package.json b/packages/app-mobile/package.json index 8e91d6b0f4..a6d75759e9 100644 --- a/packages/app-mobile/package.json +++ b/packages/app-mobile/package.json @@ -107,6 +107,7 @@ "babel-loader": "9.1.3", "babel-plugin-module-resolver": "4.1.0", "babel-plugin-react-native-web": "0.19.12", + "fast-deep-equal": "3.1.3", "fs-extra": "11.2.0", "gulp": "4.0.2", "jest": "29.7.0", diff --git a/packages/app-mobile/root.tsx b/packages/app-mobile/root.tsx index 84b04110dc..129af71150 100644 --- a/packages/app-mobile/root.tsx +++ b/packages/app-mobile/root.tsx @@ -36,6 +36,7 @@ const DropdownAlert = require('react-native-dropdownalert').default; const AlarmServiceDriver = require('./services/AlarmServiceDriver').default; const SafeAreaView = require('./components/SafeAreaView'); const { connect, Provider } = require('react-redux'); +import fastDeepEqual = require('fast-deep-equal'); import { Provider as PaperProvider, MD3DarkTheme, MD3LightTheme } from 'react-native-paper'; import BackButtonService from './services/BackButtonService'; import NavService from '@joplin/lib/services/NavService'; @@ -89,6 +90,8 @@ import JoplinCloudLoginScreen from './components/screens/JoplinCloudLoginScreen' import SyncTargetNone from '@joplin/lib/SyncTargetNone'; + + SyncTargetRegistry.addClass(SyncTargetNone); SyncTargetRegistry.addClass(SyncTargetOneDrive); SyncTargetRegistry.addClass(SyncTargetNextcloud); @@ -301,7 +304,18 @@ const appReducer = (state = appDefaultState, action: any) => { const currentRoute = state.route; if (!historyGoingBack && historyCanGoBackTo(currentRoute)) { - navHistory.push(currentRoute); + const previousRoute = navHistory.length && navHistory[navHistory.length - 1]; + const isDifferentRoute = !previousRoute || !fastDeepEqual(navHistory[navHistory.length - 1], currentRoute); + + // Avoid multiple consecutive duplicate screens in the navigation history -- these can make + // pressing "back" seem to have no effect. + if (isDifferentRoute) { + navHistory.push(currentRoute); + } + } + + if (action.clearHistory) { + navHistory.splice(0, navHistory.length); } newState = { ...state }; diff --git a/packages/app-mobile/utils/shareHandler.ts b/packages/app-mobile/utils/shareHandler.ts index 5947fc6e4f..f001d57262 100644 --- a/packages/app-mobile/utils/shareHandler.ts +++ b/packages/app-mobile/utils/shareHandler.ts @@ -3,6 +3,7 @@ import shim from '@joplin/lib/shim'; import Note from '@joplin/lib/models/Note'; import checkPermissions from './checkPermissions.js'; +import NavService from '@joplin/lib/services/NavService'; const { ToastAndroid } = require('react-native'); const { PermissionsAndroid } = require('react-native'); const { Platform } = require('react-native'); @@ -27,27 +28,21 @@ export default async (sharedData: SharedData, folderId: string, dispatch: Functi } } + const newNote = await Note.save({ + parent_id: folderId, + }, { provisional: true }); + // This is a bit hacky, but the surest way to go to // the needed note. We go back one screen in case there's // already a note open - if we don't do this, the dispatch // below will do nothing (because routeName wouldn't change) // Then we wait a bit for the state to be set correctly, and // finally we go to the new note. - dispatch({ type: 'NAV_BACK' }); - + await NavService.go('Notes', { folderId, clearHistory: true }); dispatch({ type: 'SIDE_MENU_CLOSE' }); - const newNote = await Note.save({ - parent_id: folderId, - }, { provisional: true }); - - shim.setTimeout(() => { - dispatch({ - type: 'NAV_GO', - routeName: 'Note', - noteId: newNote.id, - sharedData: sharedData, - }); + shim.setTimeout(async () => { + await NavService.go('Note', { noteId: newNote.id, sharedData }); ShareExtension.close(); }, 5); diff --git a/yarn.lock b/yarn.lock index 14c8a5e6ec..0b25738f60 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7507,6 +7507,7 @@ __metadata: crypto-browserify: 3.12.0 deprecated-react-native-prop-types: 5.0.0 events: 3.3.0 + fast-deep-equal: 3.1.3 fs-extra: 11.2.0 gulp: 4.0.2 jest: 29.7.0