diff --git a/packages/app-mobile/components/screens/Note.tsx b/packages/app-mobile/components/screens/Note.tsx index a5f4253d8..a10bc2e0a 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 8e91d6b0f..a6d75759e 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 84b04110d..129af7115 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 5947fc6e4..f001d5726 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 14c8a5e6e..0b25738f6 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