mobile: fix minor bugs

This commit is contained in:
Ammar Ahmed
2025-02-15 12:32:16 +05:00
committed by Abdullah Atta
parent 9e79a311cf
commit b30fa436bd
8 changed files with 281 additions and 255 deletions

View File

@@ -17,11 +17,11 @@ 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 { 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 ? (
<Animated.View
exiting={animated ? FadeOutUp : undefined}
exiting={animated ? FadeOut : undefined}
style={{
backgroundColor: colors.primary.background,
flex: 1,

View File

@@ -36,14 +36,15 @@ import {
getParentNotebookId
} from "../../../utils/notebooks";
import { AppFontSize } from "../../../utils/size";
import { DefaultAppStyles } from "../../../utils/styles";
import { Dialog } from "../../dialog";
import DialogHeader from "../../dialog/dialog-header";
import { presentDialog } from "../../dialog/functions";
import SheetProvider from "../../sheet-provider";
import AppIcon from "../../ui/AppIcon";
import { Button } from "../../ui/button";
import { IconButton } from "../../ui/icon-button";
import { Pressable } from "../../ui/pressable";
import Seperator from "../../ui/seperator";
import Paragraph from "../../ui/typography/paragraph";
import { AddNotebookSheet } from "../add-notebook";
@@ -125,13 +126,8 @@ export const MoveNotebookSheet = ({
eSendEvent(eOnNotebookUpdated, parent);
}
}
if (!parent) {
useNotebookStore.getState().refresh();
} else {
eSendEvent(eOnNotebookUpdated, selectedNotebook.id);
}
useNotebookStore.getState().refresh();
eSendEvent(eOnNotebookUpdated, selectedNotebook.id);
close?.();
}
});
@@ -149,7 +145,7 @@ export const MoveNotebookSheet = ({
<View
style={{
paddingHorizontal: 12
paddingHorizontal: DefaultAppStyles.GAP
}}
>
<DialogHeader
@@ -159,7 +155,6 @@ export const MoveNotebookSheet = ({
)}
/>
</View>
<Seperator />
<FlatList
data={notebooks?.placeholders}
@@ -168,7 +163,7 @@ export const MoveNotebookSheet = ({
ListHeaderComponent={
<View
style={{
paddingHorizontal: 12
paddingHorizontal: DefaultAppStyles.GAP
}}
>
{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 : (
<View
style={{
height: 45
}}
/>
) : (
<View
style={{
minHeight: 45,
borderRadius: 0
}}
>
<Pressable
onPress={() => onPress(notebook)}
<View
style={{
flexDirection: "row",
paddingHorizontal: 12,
height: 45
minHeight: 45
}}
>
{nestedNotebooks?.placeholders.length ? (
<IconButton
name={isExpanded ? "chevron-down" : "chevron-right"}
color={colors.primary.icon}
size={20}
onPress={() => {
if (!notebook) return;
useNotebookExpandedStore.getState().setExpanded(notebook.id);
}}
/>
) : (
<View
style={{
width: 35,
height: 30,
justifyContent: "center",
alignItems: "center"
}}
/>
{!notebook ? null : (
<>
<Pressable
onPress={() => onPress(notebook)}
style={{
flexDirection: "row",
paddingHorizontal: DefaultAppStyles.GAP,
height: 45,
gap: DefaultAppStyles.GAP_SMALL,
borderRadius: 0
}}
>
<AppIcon
name={
nestedNotebooks?.placeholders.length
? isExpanded
? "chevron-down"
: "chevron-right"
: "book-outline"
}
color={colors.primary.icon}
size={20}
onPress={() => {
if (!notebook) return;
useNotebookExpandedStore.getState().setExpanded(notebook.id);
}}
/>
<View
style={{
flexDirection: "row",
justifyContent: "space-between",
flexGrow: 1,
alignItems: "center"
}}
>
<Paragraph
numberOfLines={1}
style={{
color: colors.primary.paragraph,
fontSize: 15
}}
>
{notebook.title}
</Paragraph>
<IconButton
name="plus"
onPress={() => {
if (!notebook) return;
AddNotebookSheet.present(
undefined,
notebook,
"move-notebooks",
undefined,
false
);
}}
size={AppFontSize.lg}
/>
</View>
</Pressable>
{nestedNotebooks?.placeholders?.length && isExpanded ? (
<View
style={{
paddingLeft: level + 1 > 0 && level + 1 < 5 ? 15 : 0,
marginTop: 5
}}
>
{nestedNotebooks.placeholders.map((item, index) => (
<NotebookItem
key={notebook?.id + index}
id={index}
onPress={onPress}
level={level + 1}
items={nestedNotebooks}
selectedNotebooks={selectedNotebooks}
/>
))}
</View>
) : null}
</>
)}
<View
style={{
flexDirection: "row",
justifyContent: "space-between",
flexGrow: 1,
alignItems: "center"
}}
>
<Paragraph
numberOfLines={1}
style={{
color: colors.primary.paragraph,
fontSize: 15
}}
>
{notebook.title}
</Paragraph>
<IconButton
name="plus"
onPress={() => {
if (!notebook) return;
AddNotebookSheet.present(
undefined,
notebook,
"move-notebooks",
undefined,
false
);
}}
size={AppFontSize.lg}
/>
</View>
</Pressable>
{nestedNotebooks?.placeholders?.length && isExpanded ? (
<View
style={{
paddingLeft: level + 1 > 0 && level + 1 < 5 ? 15 : 0,
marginTop: 5
}}
>
{nestedNotebooks.placeholders.map((item, index) => (
<NotebookItem
key={notebook?.id + index}
id={index}
onPress={onPress}
level={level + 1}
items={nestedNotebooks}
selectedNotebooks={selectedNotebooks}
/>
))}
</View>
) : null}
</View>
</View>
);
};

View File

@@ -103,7 +103,7 @@ const Sort = ({
}}
>
<Heading
size={AppFontSize.md}
size={AppFontSize.lg}
style={{
alignSelf: "center"
}}
@@ -209,7 +209,7 @@ const Sort = ({
paddingVertical: DefaultAppStyles.GAP_VERTICAL
}}
>
<Heading size={AppFontSize.md}>{strings.groupBy()}</Heading>
<Heading size={AppFontSize.lg}>{strings.groupBy()}</Heading>
</View>
<View

View File

@@ -160,85 +160,90 @@ const TabBar = (
{
title: "Move",
icon: "arrow-right-bold-box-outline",
hidden: !notebookSelectionEnabled
hidden:
!notebookSelectionEnabled || props.navigationState.index !== 1
},
{
title: "Close",
icon: "close"
}
].map((item) => (
<>
<Pressable
key={item.title}
onPress={async () => {
switch (item.title) {
case "Select all": {
if (notebookSelectionEnabled) {
useSideMenuNotebookSelectionStore
.getState()
.selectAll?.();
} else {
useSideMenuTagsSelectionStore.getState().selectAll?.();
}
].map((item) =>
item.hidden ? null : (
<>
<Pressable
key={item.title}
onPress={async () => {
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"
>
<Icon
name={item.icon}
color={colors.primary.icon}
size={AppFontSize.lg}
/>
<Paragraph
color={colors.secondary.paragraph}
size={AppFontSize.xxxs - 1}
}}
style={{
borderRadius: 10,
paddingVertical: 2,
width: "25%"
}}
type="plain"
>
{item.title}
</Paragraph>
</Pressable>
</>
))}
<Icon
name={item.icon}
color={colors.primary.icon}
size={AppFontSize.lg}
/>
<Paragraph
color={colors.secondary.paragraph}
size={AppFontSize.xxxs - 1}
>
{item.title}
</Paragraph>
</Pressable>
</>
)
)}
</>
) : (
<>

View File

@@ -195,7 +195,8 @@ const NotebookItem = ({
return (
<View
style={{
paddingLeft: item.depth > 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 (
<View
style={{
paddingHorizontal: DefaultAppStyles.GAP,
marginTop: index === 0 ? DefaultAppStyles.GAP : 0
}}
>
<NotebookItem
item={item}
index={index}
expanded={expanded}
onToggleExpanded={() => {
useSideMenuNotebookExpandedStore
.getState()
.setExpanded(item.notebook.id);
return (
<View
style={{
paddingHorizontal: DefaultAppStyles.GAP,
marginTop: index === 0 ? DefaultAppStyles.GAP : 0
}}
selected={selected}
selectionEnabled={selectionEnabled}
selectionStore={useSideMenuNotebookSelectionStore}
onItemUpdate={onItemUpdate}
focused={focused}
onPress={() => {
NotebookScreen.navigate(item.notebook, false);
Navigation.closeDrawer();
}}
onLongPress={() => {
Properties.present(item.notebook, false);
}}
/>
</View>
);
};
>
<NotebookItem
item={item}
index={index}
expanded={expanded}
onToggleExpanded={() => {
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);
}}
/>
</View>
);
},
(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";

View File

@@ -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()

View File

@@ -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,

View File

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