mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-02-24 12:12:54 +01:00
213 lines
6.3 KiB
TypeScript
Executable File
213 lines
6.3 KiB
TypeScript
Executable File
/*
|
|
This file is part of the Notesnook project (https://notesnook.com/)
|
|
|
|
Copyright (C) 2023 Streetwriters (Private) Limited
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
import { NavigationHelpers, StackActions } from "@react-navigation/native";
|
|
import { NativeStackScreenProps } from "@react-navigation/native-stack";
|
|
import { useFavoriteStore } from "../stores/use-favorite-store";
|
|
import useNavigationStore, {
|
|
GenericRouteParam,
|
|
RouteName,
|
|
RouteParams
|
|
} from "../stores/use-navigation-store";
|
|
import { useNotebookStore } from "../stores/use-notebook-store";
|
|
import { useNoteStore } from "../stores/use-notes-store";
|
|
import { useReminderStore } from "../stores/use-reminder-store";
|
|
import { useTagStore } from "../stores/use-tag-store";
|
|
import { useTrashStore } from "../stores/use-trash-store";
|
|
import { eOnRefreshSearch, eUpdateNotebookRoute } from "../utils/events";
|
|
import {
|
|
appNavigatorRef,
|
|
fluidTabsRef,
|
|
rootNavigatorRef
|
|
} from "../utils/global-refs";
|
|
import { eSendEvent } from "./event-manager";
|
|
import { useArchivedStore } from "../stores/use-archived-store";
|
|
|
|
/**
|
|
* Routes that should be updated on focus
|
|
*/
|
|
let routesUpdateQueue: RouteName[] = [];
|
|
|
|
const routeNames = {
|
|
Notes: "Notes",
|
|
Notebooks: "Notebooks",
|
|
Notebook: "Notebook",
|
|
NotesPage: "NotesPage",
|
|
Tags: "Tags",
|
|
Favorites: "Favorites",
|
|
Trash: "Trash",
|
|
Search: "Search",
|
|
Settings: "Settings",
|
|
TaggedNotes: "TaggedNotes",
|
|
ColoredNotes: "ColoredNotes",
|
|
TopicNotes: "TopicNotes",
|
|
Monographs: "Monographs",
|
|
Auth: "Auth",
|
|
Intro: "Intro",
|
|
Welcome: "Welcome",
|
|
AppLock: "AppLock",
|
|
Login: "Login",
|
|
Signup: "Signup",
|
|
Reminders: "Reminders",
|
|
MoveNotebook: "MoveNotebook",
|
|
LinkNotebooks: "LinkNotebooks",
|
|
MoveNotes: "MoveNotes",
|
|
Archive: "Archive",
|
|
ManageTags: "ManageTags",
|
|
AddReminder: "AddReminder",
|
|
PayWall: "PayWall",
|
|
Wrapped: "Wrapped"
|
|
};
|
|
|
|
export type NavigationProps<T extends RouteName> = NativeStackScreenProps<
|
|
RouteParams,
|
|
T
|
|
>;
|
|
|
|
/**
|
|
* Functions to update each route when required.
|
|
*/
|
|
const routeUpdateFunctions: {
|
|
[name: string]: (...params: GenericRouteParam[]) => void;
|
|
} = {
|
|
Notes: () => useNoteStore.getState().refresh(),
|
|
Notebooks: () => useNotebookStore.getState().refresh(),
|
|
Tags: () => useTagStore.getState().refresh(),
|
|
Favorites: () => useFavoriteStore.getState().refresh(),
|
|
Trash: () => useTrashStore.getState().refresh(),
|
|
Notebook: (params) => eSendEvent(eUpdateNotebookRoute, params),
|
|
NotesPage: (params) => eSendEvent("NotesPage", params),
|
|
TaggedNotes: (params) => eSendEvent("TaggedNotes", params),
|
|
ColoredNotes: (params) => eSendEvent("ColoredNotes", params),
|
|
TopicNotes: (params) => eSendEvent("TopicNotes", params),
|
|
Monographs: (params) => eSendEvent("Monographs", params),
|
|
Reminders: () => useReminderStore.getState().refresh(),
|
|
Search: () => eSendEvent(eOnRefreshSearch),
|
|
Archive: () => useArchivedStore.getState().refresh()
|
|
};
|
|
|
|
function clearRouteFromQueue(routeName: RouteName) {
|
|
if (routesUpdateQueue.indexOf(routeName) !== -1) {
|
|
routesUpdateQueue = [...new Set(routesUpdateQueue)];
|
|
routesUpdateQueue.splice(routesUpdateQueue.indexOf(routeName), 1);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if a route needs update
|
|
*/
|
|
function routeNeedsUpdate(routeName: RouteName, callback: () => void) {
|
|
if (routesUpdateQueue.indexOf(routeName) > -1) {
|
|
clearRouteFromQueue(routeName);
|
|
callback();
|
|
}
|
|
}
|
|
|
|
function queueRoutesForUpdate(...routesToUpdate: RouteName[]) {
|
|
const routes =
|
|
routesToUpdate?.length > 0
|
|
? routesToUpdate
|
|
: (Object.keys(routeNames) as (keyof RouteParams)[]);
|
|
const currentRoute = useNavigationStore.getState().currentRoute;
|
|
if (routes.indexOf(currentRoute) > -1) {
|
|
routeUpdateFunctions[currentRoute]?.();
|
|
clearRouteFromQueue(currentRoute);
|
|
// Remove focused screen from queue
|
|
routes.splice(routes.indexOf(currentRoute), 1);
|
|
}
|
|
routesUpdateQueue = routesUpdateQueue.concat(routes);
|
|
routesUpdateQueue = [...new Set(routesUpdateQueue)];
|
|
}
|
|
|
|
function navigate<T extends RouteName>(screen: T, params?: RouteParams[T]) {
|
|
console.log(`Navigation.navigate ${screen} route`);
|
|
rootNavigatorRef.current?.navigate(screen as any, params);
|
|
}
|
|
|
|
function goBack() {
|
|
rootNavigatorRef.current?.goBack();
|
|
}
|
|
|
|
function push<T extends RouteName>(screen: T, params: RouteParams[T]) {
|
|
console.log(`Navigation.push ${screen} route`);
|
|
rootNavigatorRef.current?.dispatch(StackActions.push(screen as any, params));
|
|
}
|
|
|
|
function replace<T extends RouteName>(screen: T, params: RouteParams[T]) {
|
|
console.log(`Navigation.replace ${screen} route`);
|
|
rootNavigatorRef.current?.dispatch(
|
|
StackActions.replace(screen as string, params)
|
|
);
|
|
}
|
|
|
|
function popToTop() {
|
|
console.log(`Navigation.popToTop`);
|
|
appNavigatorRef.current?.dispatch(StackActions.popToTop());
|
|
}
|
|
|
|
function openDrawer() {
|
|
fluidTabsRef.current?.openDrawer();
|
|
}
|
|
function closeDrawer() {
|
|
fluidTabsRef.current?.closeDrawer();
|
|
}
|
|
|
|
function resetRootState(
|
|
_state?: ReturnType<NavigationHelpers<any, any>["getState"]>
|
|
) {
|
|
const state = _state || rootNavigatorRef.getState();
|
|
const focusedRoute = state.routes[state.index];
|
|
|
|
if (state.routes.length < 2) return;
|
|
|
|
const routes = state.routes.filter(
|
|
(route) =>
|
|
(route.name !== "Auth" && route.name !== "Welcome") ||
|
|
route.key === focusedRoute.key
|
|
);
|
|
|
|
if (routes.length === state.routes.length) return;
|
|
if (routes.length === 0) {
|
|
routes.push(focusedRoute);
|
|
}
|
|
const newIndex = routes.findIndex((route) => route.key === focusedRoute.key);
|
|
rootNavigatorRef.reset({
|
|
...state,
|
|
routes: routes,
|
|
index: newIndex
|
|
});
|
|
}
|
|
|
|
const Navigation = {
|
|
navigate,
|
|
goBack,
|
|
push,
|
|
openDrawer,
|
|
closeDrawer,
|
|
replace,
|
|
popToTop,
|
|
queueRoutesForUpdate,
|
|
routeNeedsUpdate,
|
|
routeNames,
|
|
routeUpdateFunctions,
|
|
resetRootState
|
|
};
|
|
|
|
export default Navigation;
|