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 });