From 180c202c4e613d24a71fdde2ffddb03d183d510d Mon Sep 17 00:00:00 2001 From: kashaf-ansari-dev Date: Tue, 7 Jul 2026 14:28:23 +0500 Subject: [PATCH] mobile: handle app shortcuts correctly during cold and warm app launches Signed-off-by: kashaf-ansari-dev --- apps/mobile/app/app.tsx | 19 +++++++ apps/mobile/app/hooks/use-shortcut-manager.ts | 21 +++----- .../app/navigation/fluid-panels-view.tsx | 52 +++++++++++-------- .../app/navigation/navigation-stack.tsx | 17 +++++- .../mobile/app/screens/add-reminder/index.tsx | 2 +- 5 files changed, 71 insertions(+), 40 deletions(-) diff --git a/apps/mobile/app/app.tsx b/apps/mobile/app/app.tsx index 6cf5dd016..6224cf8e6 100644 --- a/apps/mobile/app/app.tsx +++ b/apps/mobile/app/app.tsx @@ -44,9 +44,15 @@ import { useUserStore } from "./stores/use-user-store"; import RNBootSplash from "react-native-bootsplash"; import AppLocked from "./components/app-lock"; import { useSettingStore } from "./stores/use-setting-store"; +import { registerAppShortcuts } from "./hooks/use-shortcut-manager"; +import Shortcuts, { ShortcutItem } from "react-native-actions-shortcuts"; I18nManager.allowRTL(false); I18nManager.forceRTL(false); I18nManager.swapLeftAndRightInRTL(false); +declare global { + var __pendingShortcut: ShortcutItem | null | undefined; +} + const { appLockEnabled, appLockMode } = SettingsService.get(); if (appLockEnabled || appLockMode !== "none") { useUserStore.getState().lockApp(true); @@ -59,10 +65,23 @@ Linking.getInitialURL().then((url) => { initialUrl: url }); }); +Shortcuts.getInitialShortcut().then((shortcut) => { + globalThis.__pendingShortcut = shortcut; +}); const App = (props: { configureMode: "note-preview" }) => { useAppEvents(); //@ts-ignore globalThis["IS_MAIN_APP_RUNNING"] = true; + const introCompleted = useSettingStore( + (state) => state.settings.introCompleted + ); + + useEffect(() => { + if (introCompleted) { + registerAppShortcuts(); + } + }, [introCompleted]); + useEffect(() => { SettingsService.onFirstLaunch(); changeSystemBarColors(); diff --git a/apps/mobile/app/hooks/use-shortcut-manager.ts b/apps/mobile/app/hooks/use-shortcut-manager.ts index 011c463a8..7f9fcb614 100644 --- a/apps/mobile/app/hooks/use-shortcut-manager.ts +++ b/apps/mobile/app/hooks/use-shortcut-manager.ts @@ -45,26 +45,12 @@ const defaultShortcuts: ShortcutItem[] = [ } ]; export const useShortcutManager = ({ - onShortcutPressed, - shortcuts = defaultShortcuts + onShortcutPressed }: { onShortcutPressed: (shortcut: ShortcutItem | null) => void; - shortcuts?: ShortcutItem[]; }) => { - const initialShortcutRecieved = useRef(false); - useEffect(() => { if (!isSupported()) return; - Shortcuts.setShortcuts(shortcuts); - }, [shortcuts]); - - useEffect(() => { - if (!isSupported()) return; - Shortcuts.getInitialShortcut().then((shortcut) => { - if (initialShortcutRecieved.current || !shortcut) return; - onShortcutPressed(shortcut); - initialShortcutRecieved.current = true; - }); const subscription = ShortcutsEmitter.addListener( "onShortcutItemPressed", onShortcutPressed @@ -74,3 +60,8 @@ export const useShortcutManager = ({ }; }, [onShortcutPressed]); }; + +export const registerAppShortcuts = () => { + if (!isSupported()) return; + Shortcuts.setShortcuts(defaultShortcuts); +}; diff --git a/apps/mobile/app/navigation/fluid-panels-view.tsx b/apps/mobile/app/navigation/fluid-panels-view.tsx index 9cb659e8a..7a9a601d5 100644 --- a/apps/mobile/app/navigation/fluid-panels-view.tsx +++ b/apps/mobile/app/navigation/fluid-panels-view.tsx @@ -68,6 +68,8 @@ import { fluidTabsRef } from "../utils/global-refs"; import { AppNavigationStack } from "./navigation-stack"; import type { PaneWidths } from "../screens/editor/wrapper"; import AddReminder from "../screens/add-reminder"; +import Navigation from "../services/navigation"; +import { ShortcutItem } from "react-native-actions-shortcuts"; const MOBILE_SIDEBAR_SIZE = 0.85; @@ -112,33 +114,37 @@ export const FluidPanelsView = React.memo( } }, [appLoading]); - useShortcutManager({ - onShortcutPressed: async (item) => { - if (!item) return; + useEffect(() => { + const pending = globalThis.__pendingShortcut; + if ( + pending?.type === "notesnook.action.newnote" && + fluidTabsRef.current && + !appLoading + ) { + eSendEvent(eOnLoadNote, { newNote: true }); + editorState().movedAway = false; + fluidTabsRef.current.goToPage("editor", false); + globalThis.__pendingShortcut = null; + } + }, [deviceMode, appLoading]); - if (item?.type === "notesnook.action.newnote") { - if (!fluidTabsRef.current) { - setTimeout(() => { - eSendEvent(eOnLoadNote, { newNote: true }); - editorState().movedAway = false; - fluidTabsRef.current?.goToPage("editor", false); - }, 1000); - return; - } + const onShortcutPressed = useCallback(async (item: ShortcutItem | null) => { + if (!item) return; + + if (item?.type === "notesnook.action.newnote") { + Navigation.navigate("FluidPanelsView"); + requestAnimationFrame(() => { eSendEvent(eOnLoadNote, { newNote: true }); editorState().movedAway = false; - setTimeout( - () => fluidTabsRef.current?.goToPage("editor", false), - 300 - ); - } - if (item?.type === "notesnook.action.newreminder") { - setTimeout(() => { - AddReminder.present(); - }, 1000); - } + fluidTabsRef.current?.goToPage("editor", false); + }); } - }); + if (item?.type === "notesnook.action.newreminder") { + AddReminder.present(); + } + }, []); + + useShortcutManager({ onShortcutPressed }); const showFullScreenEditor = useCallback(() => { setFullscreen(true); diff --git a/apps/mobile/app/navigation/navigation-stack.tsx b/apps/mobile/app/navigation/navigation-stack.tsx index 570b7e1c8..6dd0e4121 100644 --- a/apps/mobile/app/navigation/navigation-stack.tsx +++ b/apps/mobile/app/navigation/navigation-stack.tsx @@ -316,8 +316,23 @@ export const RootNavigation = () => { [clearSelection] ); + const onNavigationReady = React.useCallback(() => { + const pending = globalThis.__pendingShortcut; + if (pending?.type === "notesnook.action.newreminder") { + rootNavigatorRef.current?.navigate("AddReminder", { + reminder: undefined, + reference: undefined + }); + globalThis.__pendingShortcut = null; + } + }, []); + return ( - + ) { - const { reminder, reference } = props.route.params; + const { reminder, reference } = props.route.params ?? {}; useNavigationFocus(props.navigation, { focusOnInit: true, onFocus: () => {