diff --git a/apps/mobile/app/components/list-items/note/index.tsx b/apps/mobile/app/components/list-items/note/index.tsx
index 9aeec050a..c85c8b1fe 100644
--- a/apps/mobile/app/components/list-items/note/index.tsx
+++ b/apps/mobile/app/components/list-items/note/index.tsx
@@ -105,7 +105,7 @@ const NoteItem = ({
{compactMode ? null : (
diff --git a/apps/mobile/app/components/list/card.tsx b/apps/mobile/app/components/list/card.tsx
index c47422e0c..97f8015d6 100644
--- a/apps/mobile/app/components/list/card.tsx
+++ b/apps/mobile/app/components/list/card.tsx
@@ -99,15 +99,12 @@ export const Card = ({
flexWrap: "nowrap",
flexShrink: 1
}}
- size={AppFontSize.xs}
+ size={AppFontSize.sm}
color={colors.primary.heading}
>
{messageBoardState.actionText}
-
+
{messageBoardState.message}
diff --git a/apps/mobile/app/components/list/empty.tsx b/apps/mobile/app/components/list/empty.tsx
index 490f17112..62304c2cf 100644
--- a/apps/mobile/app/components/list/empty.tsx
+++ b/apps/mobile/app/components/list/empty.tsx
@@ -19,18 +19,17 @@ along with this program. If not, see .
import { useThemeColors } from "@notesnook/theme";
import React from "react";
-import { ActivityIndicator, useWindowDimensions, View } from "react-native";
+import { ActivityIndicator, View } from "react-native";
import { notesnook } from "../../../e2e/test.ids";
-import useGlobalSafeAreaInsets from "../../hooks/use-global-safe-area-insets";
import { TTip, useTip } from "../../services/tip-manager";
+import { RouteParams } from "../../stores/use-navigation-store";
import { useSettingStore } from "../../stores/use-setting-store";
-import { defaultBorderRadius, AppFontSize } from "../../utils/size";
+import { AppFontSize, defaultBorderRadius } from "../../utils/size";
import { Tip } from "../tip";
import { Button } from "../ui/button";
import Seperator from "../ui/seperator";
import Heading from "../ui/typography/heading";
import Paragraph from "../ui/typography/paragraph";
-import { RouteParams } from "../../stores/use-navigation-store";
export type PlaceholderData = {
title: string;
@@ -59,8 +58,6 @@ export const Empty = React.memo(function Empty({
screen
}: EmptyListProps) {
const { colors } = useThemeColors();
- const insets = useGlobalSafeAreaInsets();
- const { height } = useWindowDimensions();
const introCompleted = useSettingStore(
(state) => state.settings.introCompleted
);
@@ -75,7 +72,7 @@ export const Empty = React.memo(function Empty({
- {
- fluidTabsRef.current?.unlock();
- }}
- getItemType={(item: number, index: number) => {
- return props.data?.type(index);
- }}
- estimatedItemSize={isCompactModeEnabled ? 60 : 120}
- directionalLockEnabled={true}
- keyboardShouldPersistTaps="always"
- keyboardDismissMode="interactive"
- refreshControl={
- props.isRenderedInActionSheet ? null : (
-
- )
- }
- ListEmptyComponent={
- props.placeholder ? (
-
+ {props.CustomLisHeader ? (
+ props.CustomLisHeader
+ ) : !props.headerTitle ? null : (
+
- ) : null
- }
- ListHeaderComponent={
- <>
- {props.CustomLisHeader ? (
- props.CustomLisHeader
- ) : !props.headerTitle ? null : (
-
+ >
+ ) : (
+ {
+ fluidTabsRef.current?.unlock();
+ }}
+ getItemType={(item: number, index: number) => {
+ return props.data?.type(index);
+ }}
+ estimatedItemSize={isCompactModeEnabled ? 60 : 120}
+ directionalLockEnabled={true}
+ keyboardShouldPersistTaps="always"
+ keyboardDismissMode="interactive"
+ refreshControl={
+ props.isRenderedInActionSheet ? null : (
+
- )}
- >
- }
- />
+ )
+ }
+ ListHeaderComponent={
+ <>
+ {props.CustomLisHeader ? (
+ props.CustomLisHeader
+ ) : !props.headerTitle ? null : (
+
+ )}
+ >
+ }
+ />
+ )}
>
);
diff --git a/apps/mobile/app/components/side-menu/menu-item.tsx b/apps/mobile/app/components/side-menu/menu-item.tsx
index edaee742d..2c379e81c 100644
--- a/apps/mobile/app/components/side-menu/menu-item.tsx
+++ b/apps/mobile/app/components/side-menu/menu-item.tsx
@@ -21,8 +21,8 @@ import { useThemeColors } from "@notesnook/theme";
import React, { useEffect, useRef, useState } from "react";
import { View } from "react-native";
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
-import { db } from "../../common/database";
import { useTotalNotes } from "../../hooks/use-db-item";
+
import Navigation from "../../services/navigation";
import { useFavoriteStore } from "../../stores/use-favorite-store";
import useNavigationStore, {
@@ -35,6 +35,7 @@ import { defaultBorderRadius, AppFontSize } from "../../utils/size";
import { DefaultAppStyles } from "../../utils/styles";
import { Pressable } from "../ui/pressable";
import Paragraph from "../ui/typography/paragraph";
+import { useMonographStore } from "../../stores/use-monograph-store";
function _MenuItem({
item,
@@ -93,10 +94,12 @@ function _MenuItem({
);
break;
case "Monographs":
- db.monographs.all.count().then((count) => {
- setItemCount(count);
+ unsub = useMonographStore.subscribe((state) => {
+ setItemCount(state.items?.placeholders.length || 0);
});
- // TODO make it reactive?
+ setItemCount(
+ useMonographStore.getState().items?.placeholders?.length || 0
+ );
break;
case "Trash":
unsub = useTrashStore.subscribe((state) => {
@@ -184,16 +187,14 @@ function _MenuItem({
- {menuItemCount > 0 ? (
-
- {menuItemCount}
-
- ) : null}
+
+ {menuItemCount}
+
);
}
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 58e8639af..7d35cfe5f 100644
--- a/apps/mobile/app/components/side-menu/side-menu-notebooks.tsx
+++ b/apps/mobile/app/components/side-menu/side-menu-notebooks.tsx
@@ -202,7 +202,7 @@ const NotebookItem = ({
}}
>
{
@@ -246,12 +246,14 @@ const NotebookItem = ({
onPress={() => {
if (item.hasChildren) {
onToggleExpanded?.();
+ } else {
+ onPress?.();
}
}}
top={0}
- left={20}
+ left={50}
bottom={0}
- right={20}
+ right={40}
style={{
width: 32,
height: 32,
@@ -299,14 +301,12 @@ const NotebookItem = ({
) : (
<>
- {totalNotes(notebook?.id) ? (
-
- {totalNotes?.(notebook?.id)}
-
- ) : null}
+
+ {totalNotes?.(notebook?.id) || 0}
+
>
)}
@@ -327,7 +327,10 @@ export const SideMenuNotebooks = () => {
for (let i = 0; i < filteredNotebooks.placeholders.length; i++) {
_notebooks[i] = (await filteredNotebooks?.item(i))?.item as Notebook;
}
- useSideMenuNotebookTreeStore.getState().addNotebooks("root", _notebooks, 0);
+ const items = await useSideMenuNotebookTreeStore
+ .getState()
+ .addNotebooks("root", _notebooks, 0);
+ useSideMenuNotebookTreeStore.getState().setTree(items);
}, [filteredNotebooks]);
const updateNotebooks = React.useCallback(() => {
@@ -391,6 +394,8 @@ export const SideMenuNotebooks = () => {
[]
);
+ console.log("RENDERING ROOT");
+
return (
{
bounces={false}
bouncesZoom={false}
overScrollMode="never"
+ keyExtractor={(item) => item.notebook.id}
+ windowSize={3}
ListHeaderComponent={
state.expanded[item.notebook.id]
);
+
const selectionEnabled = useSideMenuNotebookSelectionStore(
(state) => state.enabled
);
@@ -467,18 +475,6 @@ const NotebookItemWrapper = React.memo(
(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]);
-
const onItemUpdate = React.useCallback(async () => {
const notebook = await db.notebooks.notebook(item.notebook.id);
if (notebook) {
@@ -490,6 +486,8 @@ const NotebookItemWrapper = React.memo(
}
}, [item.notebook.id]);
+ console.log("RENDERING", item?.notebook?.title, item.parentId);
+
return (
{
+ onToggleExpanded={async () => {
useSideMenuNotebookExpandedStore
.getState()
.setExpanded(item.notebook.id);
+ if (!expanded) {
+ useSideMenuNotebookTreeStore
+ .getState()
+ .setTree(
+ await useSideMenuNotebookTreeStore
+ .getState()
+ .fetchAndAdd(item.notebook.id, item.depth + 1)
+ );
+ } else {
+ useSideMenuNotebookTreeStore
+ .getState()
+ .removeChildren(item.notebook.id);
+ }
}}
selected={selected}
selectionEnabled={selectionEnabled}
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 8160c0a08..14e840bf6 100644
--- a/apps/mobile/app/components/side-menu/side-menu-tags.tsx
+++ b/apps/mobile/app/components/side-menu/side-menu-tags.tsx
@@ -66,7 +66,7 @@ const TagItem = (props: {
{item ? (
diff --git a/apps/mobile/app/components/tip/index.tsx b/apps/mobile/app/components/tip/index.tsx
index 2a6d77861..523ac4c12 100644
--- a/apps/mobile/app/components/tip/index.tsx
+++ b/apps/mobile/app/components/tip/index.tsx
@@ -70,7 +70,7 @@ export const Tip = ({
{neverShowAgain && (
@@ -114,7 +116,7 @@ export const Tip = ({
{tip.text()}
diff --git a/apps/mobile/app/screens/settings/section-item.tsx b/apps/mobile/app/screens/settings/section-item.tsx
index f6ea27bbe..2c0c0e32e 100644
--- a/apps/mobile/app/screens/settings/section-item.tsx
+++ b/apps/mobile/app/screens/settings/section-item.tsx
@@ -38,6 +38,8 @@ import { SettingStore, useSettingStore } from "../../stores/use-setting-store";
import { AppFontSize } from "../../utils/size";
import { components } from "./components";
import { RouteParams, SettingSection } from "./types";
+import Heading from "../../components/ui/typography/heading";
+import { DefaultAppStyles } from "../../utils/styles";
const _SectionItem = ({ item }: { item: SettingSection }) => {
const { colors } = useThemeColors();
@@ -117,10 +119,10 @@ const _SectionItem = ({ item }: { item: SettingSection }) => {
style={{
width: "100%",
alignItems: "center",
- padding: 12,
+ padding: DefaultAppStyles.GAP,
flexDirection: "row",
justifyContent: "space-between",
- paddingVertical: 20,
+ paddingVertical: DefaultAppStyles.GAP,
opacity: isDisabled ? 0.5 : 1,
borderRadius: 0,
...styles
@@ -188,16 +190,17 @@ const _SectionItem = ({ item }: { item: SettingSection }) => {
paddingRight: item.type === "switch" ? 10 : 0
}}
>
-
{typeof item.name === "function" ? item.name(current) : item.name}
-
+
+
{!!item.description && (
void;
+ depth: number,
+ tree?: TreeItem[]
+ ) => Promise;
updateItem: (id: string, notebook: Notebook) => void;
- fetchAndAdd: (parentId: string, depth: number) => Promise;
+ fetchAndAdd: (
+ parentId: string,
+ depth: number,
+ tree?: TreeItem[]
+ ) => Promise;
removeChildren: (id: string) => void;
}>((set, get) => ({
tree: [],
@@ -77,12 +82,9 @@ export function createNotebookTreeStores(
addNotebooks: async (
parentId: string,
notebooks: Notebook[],
- depth: number
+ depth: number,
+ tree?: TreeItem[]
) => {
- const parentIndex = get().tree.findIndex(
- (item) => item.notebook.id === parentId
- );
-
const items = await db.relations
.from(
{
@@ -93,29 +95,46 @@ export function createNotebookTreeStores(
)
.get();
- let newTree = get().tree.slice();
+ let newTree = tree || get().tree.slice();
+
+ const parentIndex = newTree.findIndex(
+ (item) => item.notebook.id === parentId
+ );
+
for (const item of newTree) {
if (item.parentId === parentId) {
newTree = removeTreeItem(newTree, item.notebook.id);
}
}
- newTree.splice(
- parentIndex + 1,
- 0,
- ...notebooks.map((notebook) => {
- return {
- parentId,
- notebook,
- depth: depth,
- hasChildren: items.some((item) => {
- return item.fromId === notebook.id;
- })
- };
- })
- );
- set({
- tree: newTree
+
+ const newTreeItems = notebooks.map((notebook) => {
+ return {
+ parentId,
+ notebook,
+ depth: depth,
+ hasChildren: items.some((item) => {
+ return item.fromId === notebook.id;
+ })
+ };
});
+
+ newTree.splice(parentIndex + 1, 0, ...newTreeItems);
+
+ for (const item of newTreeItems) {
+ const expanded =
+ useSideMenuNotebookExpandedStore.getState().expanded[
+ item.notebook.id
+ ] && item.hasChildren;
+ if (expanded) {
+ newTree = await get().fetchAndAdd(
+ item.notebook.id,
+ depth + 1,
+ newTree
+ );
+ }
+ }
+
+ return newTree;
},
removeItem(id) {
@@ -123,7 +142,7 @@ export function createNotebookTreeStores(
tree: removeTreeItem(get().tree, id).slice()
});
},
- fetchAndAdd: async (parentId: string, depth: number) => {
+ fetchAndAdd: async (parentId: string, depth: number, tree?: TreeItem[]) => {
const selector = db.relations.from(
{
type: "notebook",
@@ -135,13 +154,15 @@ export function createNotebookTreeStores(
const grouped = await selector.sorted(
db.settings.getGroupOptions("notebooks")
);
-
const notebooks: Notebook[] = [];
for (let index = 0; index < grouped.placeholders.length; index++) {
const notebook = (await grouped.item(index)).item;
if (notebook) notebooks.push(notebook);
}
- get().addNotebooks(parentId, notebooks, depth);
+
+ tree = await get().addNotebooks(parentId, notebooks, depth, tree);
+
+ return tree;
},
removeChildren(id: string) {
let newTree = get().tree.slice();
@@ -169,7 +190,9 @@ export function createNotebookTreeStores(
}>(
persist(
(set, get) => ({
- expanded: {},
+ expanded: {
+ root: true
+ },
setExpanded(id: string) {
set({
expanded: {
@@ -180,7 +203,7 @@ export function createNotebookTreeStores(
}
}),
{
- name: "side-menu-notebook-expanded",
+ name: "side-menu-notebook-expanded-v1",
getStorage: () => MMKV as unknown as StateStorage
}
)
diff --git a/apps/mobile/app/stores/index.ts b/apps/mobile/app/stores/index.ts
index f4546cf65..0909ea480 100644
--- a/apps/mobile/app/stores/index.ts
+++ b/apps/mobile/app/stores/index.ts
@@ -23,6 +23,7 @@ import { NotePreviewWidget } from "../services/note-preview-widget";
import Notifications from "../services/notifications";
import { useFavoriteStore } from "./use-favorite-store";
import { useMenuStore } from "./use-menu-store";
+import { useMonographStore } from "./use-monograph-store";
import { useNotebookStore } from "./use-notebook-store";
import { useNoteStore } from "./use-notes-store";
import { useRelationStore } from "./use-relation-store";
@@ -39,6 +40,7 @@ export function initAfterSync() {
useRelationStore.getState().update();
useMenuStore.getState().setColorNotes();
useMenuStore.getState().setMenuPins();
+ useMonographStore.getState().refresh();
useUserStore.setState({
profile: db.settings.getProfile()
});
@@ -57,4 +59,5 @@ export function clearAllStores() {
useMenuStore.getState().clearAll();
useTrashStore.getState().clear();
useReminderStore.getState().clear();
+ useMonographStore.getState().clear();
}
diff --git a/apps/mobile/app/stores/use-monograph-store.ts b/apps/mobile/app/stores/use-monograph-store.ts
new file mode 100644
index 000000000..2652b23e8
--- /dev/null
+++ b/apps/mobile/app/stores/use-monograph-store.ts
@@ -0,0 +1,30 @@
+/*
+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 .
+*/
+
+import { db } from "../common/database";
+import createDBCollectionStore from "./create-db-collection-store";
+
+const { useStore: useMonographStore, useCollection: useMonographs } =
+ createDBCollectionStore({
+ getCollection: () =>
+ db.monographs.all.grouped(db.settings.getGroupOptions("notes")),
+ eagerlyFetchFirstBatch: true
+ });
+
+export { useMonographStore, useMonographs };
diff --git a/apps/mobile/app/utils/size/index.js b/apps/mobile/app/utils/size/index.js
index 97452348a..2efc6819e 100644
--- a/apps/mobile/app/utils/size/index.js
+++ b/apps/mobile/app/utils/size/index.js
@@ -84,10 +84,10 @@ export const normalize = (size) => {
function getSize() {
return {
- xxxs: normalize(11) * scale.fontScale,
+ xxxs: normalize(11.5) * scale.fontScale,
xxs: normalize(12.5) * scale.fontScale,
- xs: normalize(14) * scale.fontScale,
- sm: normalize(15) * scale.fontScale,
+ xs: normalize(13.5) * scale.fontScale,
+ sm: normalize(14.5) * scale.fontScale,
md: normalize(16.5) * scale.fontScale,
lg: normalize(22) * scale.fontScale,
xl: normalize(24) * scale.fontScale,
diff --git a/apps/mobile/native/globals.js b/apps/mobile/native/globals.js
index e4b8151b2..b149a7ff6 100644
--- a/apps/mobile/native/globals.js
+++ b/apps/mobile/native/globals.js
@@ -25,7 +25,7 @@ import {
import Config from "react-native-config";
i18n.load({
- en: __DEV__ && Config.isTesting !== "true" ? $pseudo : $en
+ en: !__DEV__ && Config.isTesting !== "true" ? $pseudo : $en
});
setI18nGlobal(i18n);
i18n.activate("en");