diff --git a/apps/mobile/app/components/delay-layout/index.tsx b/apps/mobile/app/components/delay-layout/index.tsx
index 5c1438304..c0be3b79f 100644
--- a/apps/mobile/app/components/delay-layout/index.tsx
+++ b/apps/mobile/app/components/delay-layout/index.tsx
@@ -17,11 +17,11 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
+import { useThemeColors } from "@notesnook/theme";
import React from "react";
import { ViewProps } from "react-native";
-import Animated, { FadeOutUp } from "react-native-reanimated";
+import Animated, { FadeOut } from "react-native-reanimated";
import { useDelayLayout } from "../../hooks/use-delay-layout";
-import { useThemeColors } from "@notesnook/theme";
import { DefaultPlaceholder } from "./default-placeholder";
import { SettingsPlaceholder } from "./settings-placeholder";
@@ -50,7 +50,7 @@ export default function DelayLayout({
return loading || props.wait ? (
-
{moveToTop ? (
@@ -248,104 +243,102 @@ const NotebookItem = ({
);
const { colors } = useThemeColors();
- return selectedNotebooks.find(
- (n) => n.id === notebook?.id
- ) ? null : !notebook ? (
+ return selectedNotebooks.find((n) => n.id === notebook?.id) ? null : (
- ) : (
-
- onPress(notebook)}
+
- {nestedNotebooks?.placeholders.length ? (
- {
- if (!notebook) return;
- useNotebookExpandedStore.getState().setExpanded(notebook.id);
- }}
- />
- ) : (
-
+ {!notebook ? null : (
+ <>
+ onPress(notebook)}
+ style={{
+ flexDirection: "row",
+ paddingHorizontal: DefaultAppStyles.GAP,
+ height: 45,
+ gap: DefaultAppStyles.GAP_SMALL,
+ borderRadius: 0
+ }}
+ >
+ {
+ if (!notebook) return;
+ useNotebookExpandedStore.getState().setExpanded(notebook.id);
+ }}
+ />
+
+
+
+ {notebook.title}
+
+
+ {
+ if (!notebook) return;
+ AddNotebookSheet.present(
+ undefined,
+ notebook,
+ "move-notebooks",
+ undefined,
+ false
+ );
+ }}
+ size={AppFontSize.lg}
+ />
+
+
+
+ {nestedNotebooks?.placeholders?.length && isExpanded ? (
+ 0 && level + 1 < 5 ? 15 : 0,
+ marginTop: 5
+ }}
+ >
+ {nestedNotebooks.placeholders.map((item, index) => (
+
+ ))}
+
+ ) : null}
+ >
)}
-
-
-
- {notebook.title}
-
-
- {
- if (!notebook) return;
- AddNotebookSheet.present(
- undefined,
- notebook,
- "move-notebooks",
- undefined,
- false
- );
- }}
- size={AppFontSize.lg}
- />
-
-
-
- {nestedNotebooks?.placeholders?.length && isExpanded ? (
- 0 && level + 1 < 5 ? 15 : 0,
- marginTop: 5
- }}
- >
- {nestedNotebooks.placeholders.map((item, index) => (
-
- ))}
-
- ) : null}
+
);
};
diff --git a/apps/mobile/app/components/sheets/sort/index.tsx b/apps/mobile/app/components/sheets/sort/index.tsx
index cac0e6c19..c4594f84e 100644
--- a/apps/mobile/app/components/sheets/sort/index.tsx
+++ b/apps/mobile/app/components/sheets/sort/index.tsx
@@ -103,7 +103,7 @@ const Sort = ({
}}
>
- {strings.groupBy()}
+ {strings.groupBy()}
(
- <>
- {
- switch (item.title) {
- case "Select all": {
- if (notebookSelectionEnabled) {
- useSideMenuNotebookSelectionStore
- .getState()
- .selectAll?.();
- } else {
- useSideMenuTagsSelectionStore.getState().selectAll?.();
- }
+ ].map((item) =>
+ item.hidden ? null : (
+ <>
+ {
+ switch (item.title) {
+ case "Select all": {
+ if (notebookSelectionEnabled) {
+ useSideMenuNotebookSelectionStore
+ .getState()
+ .selectAll?.();
+ } else {
+ useSideMenuTagsSelectionStore
+ .getState()
+ .selectAll?.();
+ }
- break;
- }
- case "Delete": {
- if (notebookSelectionEnabled) {
+ break;
+ }
+ case "Delete": {
+ if (notebookSelectionEnabled) {
+ const ids = useSideMenuNotebookSelectionStore
+ .getState()
+ .getSelectedItemIds();
+ deleteItems("notebook", ids);
+ } else {
+ const ids = useSideMenuTagsSelectionStore
+ .getState()
+ .getSelectedItemIds();
+ await deleteItems("tag", ids);
+ }
+ break;
+ }
+ case "Move": {
const ids = useSideMenuNotebookSelectionStore
.getState()
.getSelectedItemIds();
- deleteItems("notebook", ids);
- } else {
- const ids = useSideMenuTagsSelectionStore
- .getState()
- .getSelectedItemIds();
- deleteItems("tag", ids);
+ const notebooks = await db.notebooks.all.items(ids);
+ MoveNotebookSheet.present(notebooks);
+ break;
+ }
+ case "Close": {
+ useSideMenuNotebookSelectionStore.setState({
+ enabled: false,
+ selection: {}
+ });
+ useSideMenuTagsSelectionStore.setState({
+ enabled: false,
+ selection: {}
+ });
+ break;
}
- break;
}
- case "Move": {
- const ids = useSideMenuNotebookSelectionStore
- .getState()
- .getSelectedItemIds();
- const notebooks = await db.notebooks.all.items(ids);
- MoveNotebookSheet.present(notebooks);
- break;
- }
- case "Close": {
- useSideMenuNotebookSelectionStore.setState({
- enabled: false,
- selection: {}
- });
- useSideMenuTagsSelectionStore.setState({
- enabled: false,
- selection: {}
- });
- break;
- }
- }
- }}
- style={{
- borderRadius: 10,
- paddingVertical: 2,
- width: "25%"
- }}
- type="plain"
- >
-
-
- {item.title}
-
-
- >
- ))}
+
+
+ {item.title}
+
+
+ >
+ )
+ )}
>
) : (
<>
diff --git a/apps/mobile/app/components/side-menu/side-menu-notebooks.tsx b/apps/mobile/app/components/side-menu/side-menu-notebooks.tsx
index 026c45061..58e8639af 100644
--- a/apps/mobile/app/components/side-menu/side-menu-notebooks.tsx
+++ b/apps/mobile/app/components/side-menu/side-menu-notebooks.tsx
@@ -195,7 +195,8 @@ const NotebookItem = ({
return (
0 && item.depth < 6 ? 15 : undefined,
+ paddingLeft:
+ item.depth > 0 && item.depth < 6 ? 15 * item.depth : undefined,
width: "100%",
marginTop: 2
}}
@@ -248,9 +249,9 @@ const NotebookItem = ({
}
}}
top={0}
- left={0}
+ left={20}
bottom={0}
- right={0}
+ right={20}
style={{
width: 32,
height: 32,
@@ -451,76 +452,82 @@ export const SideMenuNotebooks = () => {
);
};
-const NotebookItemWrapper = ({
- item,
- index
-}: {
- item: TreeItem;
- index: number;
-}) => {
- const expanded = useSideMenuNotebookExpandedStore(
- (state) => state.expanded[item.notebook.id]
- );
- const selectionEnabled = useSideMenuNotebookSelectionStore(
- (state) => state.enabled
- );
- const selected = useSideMenuNotebookSelectionStore(
- (state) => state.selection[item.notebook.id] === "selected"
- );
- const focused = useNavigationStore(
- (state) => state.focusedRouteId === item.notebook.id
- );
+const NotebookItemWrapper = React.memo(
+ ({ item, index }: { item: TreeItem; index: number }) => {
+ const expanded = useSideMenuNotebookExpandedStore(
+ (state) => state.expanded[item.notebook.id]
+ );
+ const selectionEnabled = useSideMenuNotebookSelectionStore(
+ (state) => state.enabled
+ );
+ const selected = useSideMenuNotebookSelectionStore(
+ (state) => state.selection[item.notebook.id] === "selected"
+ );
+ const focused = useNavigationStore(
+ (state) => state.focusedRouteId === item.notebook.id
+ );
- useEffect(() => {
- if (expanded) {
- useSideMenuNotebookTreeStore
- .getState()
- .fetchAndAdd(item.notebook.id, item.depth + 1);
- } else {
- useSideMenuNotebookTreeStore.getState().removeChildren(item.notebook.id);
- }
- }, [expanded, item.depth, item.notebook]);
+ useEffect(() => {
+ if (expanded) {
+ useSideMenuNotebookTreeStore
+ .getState()
+ .fetchAndAdd(item.notebook.id, item.depth + 1);
+ } else {
+ useSideMenuNotebookTreeStore
+ .getState()
+ .removeChildren(item.notebook.id);
+ }
+ }, [expanded, item.depth, item.notebook]);
- const onItemUpdate = React.useCallback(async () => {
- const notebook = await db.notebooks.notebook(item.notebook.id);
- if (notebook) {
- useSideMenuNotebookTreeStore
- .getState()
- .updateItem(item.notebook.id, notebook);
- } else {
- useSideMenuNotebookTreeStore.getState().removeItem(item.notebook.id);
- }
- }, [item.notebook.id]);
+ const onItemUpdate = React.useCallback(async () => {
+ const notebook = await db.notebooks.notebook(item.notebook.id);
+ if (notebook) {
+ useSideMenuNotebookTreeStore
+ .getState()
+ .updateItem(item.notebook.id, notebook);
+ } else {
+ useSideMenuNotebookTreeStore.getState().removeItem(item.notebook.id);
+ }
+ }, [item.notebook.id]);
- return (
-
- {
- useSideMenuNotebookExpandedStore
- .getState()
- .setExpanded(item.notebook.id);
+ return (
+ {
- NotebookScreen.navigate(item.notebook, false);
- Navigation.closeDrawer();
- }}
- onLongPress={() => {
- Properties.present(item.notebook, false);
- }}
- />
-
- );
-};
+ >
+ {
+ useSideMenuNotebookExpandedStore
+ .getState()
+ .setExpanded(item.notebook.id);
+ }}
+ selected={selected}
+ selectionEnabled={selectionEnabled}
+ selectionStore={useSideMenuNotebookSelectionStore}
+ onItemUpdate={onItemUpdate}
+ focused={focused}
+ onPress={() => {
+ NotebookScreen.navigate(item.notebook, false);
+ Navigation.closeDrawer();
+ }}
+ onLongPress={() => {
+ Properties.present(item.notebook, false);
+ }}
+ />
+
+ );
+ },
+ (prev, next) => {
+ return (
+ prev.item.notebook.id === next.item.notebook.id &&
+ prev.item.notebook.dateModified === next.item.notebook.dateModified &&
+ prev.item.notebook.dateEdited === next.item.notebook.dateEdited
+ );
+ }
+);
+NotebookItemWrapper.displayName = "NotebookItemWrapper";
diff --git a/apps/mobile/app/components/side-menu/side-menu-tags.tsx b/apps/mobile/app/components/side-menu/side-menu-tags.tsx
index cbef1faea..b65e4be02 100644
--- a/apps/mobile/app/components/side-menu/side-menu-tags.tsx
+++ b/apps/mobile/app/components/side-menu/side-menu-tags.tsx
@@ -204,7 +204,6 @@ export const SideMenuTags = () => {
const updateTags = React.useCallback(() => {
if (lastQuery.current) {
- console.log("Looking up...", lastQuery.current);
db.lookup
.tags(lastQuery.current.trim())
.sorted()
diff --git a/apps/mobile/app/stores/create-notebook-tree-stores.ts b/apps/mobile/app/stores/create-notebook-tree-stores.ts
index 173744252..180356983 100644
--- a/apps/mobile/app/stores/create-notebook-tree-stores.ts
+++ b/apps/mobile/app/stores/create-notebook-tree-stores.ts
@@ -20,6 +20,8 @@ import { Notebook } from "@notesnook/core";
import create from "zustand";
import { db } from "../common/database";
import { createItemSelectionStore } from "./item-selection-store";
+import { persist, StateStorage } from "zustand/middleware";
+import { MMKV } from "../common/database/mmkv";
export type TreeItem = {
parentId: string;
@@ -164,17 +166,25 @@ export function createNotebookTreeStores(
[id: string]: boolean;
};
setExpanded: (id: string) => void;
- }>((set, get) => ({
- expanded: {},
- setExpanded(id: string) {
- set({
- expanded: {
- ...get().expanded,
- [id]: !get().expanded[id]
+ }>(
+ persist(
+ (set, get) => ({
+ expanded: {},
+ setExpanded(id: string) {
+ set({
+ expanded: {
+ ...get().expanded,
+ [id]: !get().expanded[id]
+ }
+ });
}
- });
- }
- }));
+ }),
+ {
+ name: "side-menu-notebook-expanded",
+ getStorage: () => MMKV as unknown as StateStorage
+ }
+ )
+ );
return {
useSideMenuNotebookTreeStore,
diff --git a/apps/mobile/app/utils/functions.ts b/apps/mobile/app/utils/functions.ts
index 1992aad3b..09e971c36 100644
--- a/apps/mobile/app/utils/functions.ts
+++ b/apps/mobile/app/utils/functions.ts
@@ -22,6 +22,10 @@ import { strings } from "@notesnook/intl";
import { Linking } from "react-native";
import { db } from "../common/database";
import { presentDialog } from "../components/dialog/functions";
+import {
+ useSideMenuNotebookSelectionStore,
+ useSideMenuTagsSelectionStore
+} from "../components/side-menu/stores";
import { eSendEvent, ToastManager } from "../services/event-manager";
import Navigation from "../services/navigation";
import { useMenuStore } from "../stores/use-menu-store";
@@ -129,6 +133,10 @@ export const deleteItems = async (
for (const id of itemIds) {
await deleteNotebook(id, result.deleteNotes);
}
+ useSideMenuNotebookSelectionStore.setState({
+ enabled: false,
+ selection: {}
+ });
} else if (type === "tag") {
presentDialog({
title: strings.doActions.delete.tag(itemIds.length),
@@ -139,6 +147,10 @@ export const deleteItems = async (
await db.tags.remove(...itemIds);
useTagStore.getState().refresh();
useRelationStore.getState().update();
+ useSideMenuTagsSelectionStore.setState({
+ enabled: false,
+ selection: {}
+ });
},
context: context
});