mobile: push changes

This commit is contained in:
Ammar Ahmed
2023-11-24 15:11:38 +05:00
committed by Abdullah Atta
parent 189a9da5b5
commit 44df437c4e
56 changed files with 1079 additions and 968 deletions

View File

@@ -1,40 +0,0 @@
/*
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 React, { PropsWithChildren } from "react";
import { View } from "react-native";
import { useSelectionStore } from "../../stores/use-selection-store";
import { useThemeColors } from "@notesnook/theme";
export const ContainerHeader = (props: PropsWithChildren) => {
const { colors } = useThemeColors();
const selectionMode = useSelectionStore((state) => state.selectionMode);
return !selectionMode ? (
<View
style={{
backgroundColor: colors.primary.background,
width: "100%",
overflow: "hidden"
}}
>
{props.children}
</View>
) : null;
};

View File

@@ -21,14 +21,9 @@ import React, { PropsWithChildren } from "react";
import { KeyboardAvoidingView, Platform } from "react-native";
import useGlobalSafeAreaInsets from "../../hooks/use-global-safe-area-insets";
import useIsFloatingKeyboard from "../../hooks/use-is-floating-keyboard";
import { useSettingStore } from "../../stores/use-setting-store";
import SelectionHeader from "../selection-header";
export const Container = ({ children }: PropsWithChildren) => {
const floating = useIsFloatingKeyboard();
const introCompleted = useSettingStore(
(state) => state.settings.introCompleted
);
const insets = useGlobalSafeAreaInsets();
return (
@@ -42,12 +37,6 @@ export const Container = ({ children }: PropsWithChildren) => {
paddingBottom: Platform.OS === "android" ? 0 : insets.bottom
}}
>
{!introCompleted ? null : (
<>
<SelectionHeader />
</>
)}
{children}
</KeyboardAvoidingView>
);

View File

@@ -212,7 +212,6 @@ export class VaultDialog extends Component {
this.password = null;
this.confirmPassword = null;
SearchService.updateAndSearch();
this.setState({
visible: false,
note: {},
@@ -459,7 +458,7 @@ export class VaultDialog extends Component {
async _deleteNote() {
try {
await db.vault.remove(this.state.note.id, this.password);
await deleteItems(this.state.note);
await deleteItems([this.state.note.id], "note");
this.close();
} catch (e) {
this._takeErrorAction(e);

View File

@@ -17,6 +17,7 @@ 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, { useCallback, useEffect, useState } from "react";
import { Platform, StyleSheet, View } from "react-native";
import useGlobalSafeAreaInsets from "../../hooks/use-global-safe-area-insets";
@@ -24,15 +25,14 @@ import {
eSubscribeEvent,
eUnSubscribeEvent
} from "../../services/event-manager";
import useNavigationStore, {
RouteName
} from "../../stores/use-navigation-store";
import { useSelectionStore } from "../../stores/use-selection-store";
import { useThemeColors } from "@notesnook/theme";
import { eScrollEvent } from "../../utils/events";
import { LeftMenus } from "./left-menus";
import { RightMenus } from "./right-menus";
import { Title } from "./title";
import useNavigationStore, {
RouteName
} from "../../stores/use-navigation-store";
type HeaderRightButton = {
title: string;

View File

@@ -60,7 +60,6 @@ export const LeftMenus = ({
height: 40,
width: 40,
borderRadius: 100,
marginLeft: -5,
marginRight: DDS.isLargeTablet() ? 10 : 7
}}
left={40}
@@ -72,9 +71,6 @@ export const LeftMenus = ({
}}
name={canGoBack ? "arrow-left" : "menu"}
color={colors.primary.paragraph}
iconStyle={{
marginLeft: canGoBack ? -5 : 0
}}
/>
);
};

View File

@@ -105,7 +105,7 @@ const NoteItem = ({
{notebooks?.items
?.filter(
(item) =>
item.id !== useNavigationStore.getState().currentRoute?.id
item.id !== useNavigationStore.getState().focusedRouteId
)
.map((item) => (
<Button
@@ -133,7 +133,7 @@ const NoteItem = ({
marginBottom: 5
}}
onPress={() => {
NotebookScreen.navigate(item);
NotebookScreen.navigate(item, true);
}}
/>
))}

View File

@@ -55,8 +55,8 @@ export const openNote = async (
const { selectedItemsList, selectionMode, clearSelection, setSelectedItem } =
useSelectionStore.getState();
if (selectedItemsList.length > 0 && selectionMode) {
setSelectedItem(note);
if (selectedItemsList.length > 0 && selectionMode === item.type) {
setSelectedItem(note.id);
return;
} else {
clearSelection();

View File

@@ -21,6 +21,7 @@ import { BaseTrashItem, Notebook } from "@notesnook/core";
import React from "react";
import { NotebookItem } from ".";
import { db } from "../../../common/database";
import NotebookScreen from "../../../screens/notebook";
import { ToastManager } from "../../../services/event-manager";
import Navigation from "../../../services/navigation";
import { useSelectionStore } from "../../../stores/use-selection-store";
@@ -28,30 +29,12 @@ import { useTrashStore } from "../../../stores/use-trash-store";
import { presentDialog } from "../../dialog/functions";
import SelectionWrapper from "../selection-wrapper";
const navigateToNotebook = (item: Notebook, canGoBack?: boolean) => {
if (!item) return;
Navigation.navigate(
{
title: item.title,
name: "Notebook",
id: item.id,
type: "notebook"
},
{
title: item.title,
item: item,
canGoBack
}
);
};
export const openNotebookTopic = (item: Notebook | BaseTrashItem<Notebook>) => {
export const openNotebook = (item: Notebook | BaseTrashItem<Notebook>) => {
const isTrash = item.type === "trash";
const { selectedItemsList, setSelectedItem, selectionMode, clearSelection } =
useSelectionStore.getState();
if (selectedItemsList.length > 0 && selectionMode) {
setSelectedItem(item);
if (selectedItemsList.length > 0 && selectionMode === item.type) {
setSelectedItem(item.id);
return;
} else {
clearSelection();
@@ -59,14 +42,14 @@ export const openNotebookTopic = (item: Notebook | BaseTrashItem<Notebook>) => {
if (isTrash) {
presentDialog({
title: `Restore ${item.itemType}`,
paragraph: `Restore or delete ${item.itemType} forever`,
title: `Restore notebook`,
paragraph: `Restore or delete notebook forever`,
positiveText: "Restore",
negativeText: "Delete",
positivePress: async () => {
await db.trash.restore(item.id);
Navigation.queueRoutesForUpdate();
useSelectionStore.getState().setSelectionMode(false);
useSelectionStore.getState().setSelectionMode(undefined);
ToastManager.show({
heading: "Restore successful",
type: "success"
@@ -75,7 +58,7 @@ export const openNotebookTopic = (item: Notebook | BaseTrashItem<Notebook>) => {
onClose: async () => {
await db.trash.delete(item.id);
useTrashStore.getState().setTrash();
useSelectionStore.getState().setSelectionMode(false);
useSelectionStore.getState().setSelectionMode(undefined);
ToastManager.show({
heading: "Permanently deleted items",
type: "success",
@@ -85,7 +68,7 @@ export const openNotebookTopic = (item: Notebook | BaseTrashItem<Notebook>) => {
});
return;
}
navigateToNotebook(item, true);
NotebookScreen.navigate(item, true);
};
type NotebookWrapperProps = {
@@ -105,7 +88,7 @@ export const NotebookWrapper = React.memo(
const isTrash = item.type === "trash";
return (
<SelectionWrapper onPress={() => openNotebookTopic(item)} item={item}>
<SelectionWrapper onPress={() => openNotebook(item)} item={item}>
<NotebookItem
item={item}
date={date}

View File

@@ -16,20 +16,21 @@ 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 { Reminder } from "@notesnook/core";
import { useThemeColors } from "@notesnook/theme";
import React from "react";
import { View } from "react-native";
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
import { notesnook } from "../../../../e2e/test.ids";
import { useThemeColors } from "@notesnook/theme";
import { useSelectionStore } from "../../../stores/use-selection-store";
import { SIZE } from "../../../utils/size";
import { Properties } from "../../properties";
import ReminderSheet from "../../sheets/reminder";
import { IconButton } from "../../ui/icon-button";
import { ReminderTime } from "../../ui/reminder-time";
import Heading from "../../ui/typography/heading";
import Paragraph from "../../ui/typography/paragraph";
import SelectionWrapper from "../selection-wrapper";
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
import ReminderSheet from "../../sheets/reminder";
import { ReminderTime } from "../../ui/reminder-time";
import { Reminder } from "@notesnook/core";
const ReminderItem = React.memo(
({
@@ -43,17 +44,23 @@ const ReminderItem = React.memo(
}) => {
const { colors } = useThemeColors();
const openReminder = () => {
const {
selectedItemsList,
setSelectedItem,
selectionMode,
clearSelection
} = useSelectionStore.getState();
if (selectedItemsList.length > 0 && selectionMode === item.type) {
setSelectedItem(item.id);
return;
} else {
clearSelection();
}
ReminderSheet.present(item, undefined, isSheet);
};
return (
<SelectionWrapper
//@ts-ignore
index={index}
height={100}
onPress={openReminder}
item={item}
isSheet={isSheet}
>
<SelectionWrapper onPress={openReminder} item={item} isSheet={isSheet}>
<View
style={{
flexShrink: 1,

View File

@@ -53,10 +53,10 @@ const SelectionWrapper = ({
}
const onLongPress = () => {
if (!useSelectionStore.getState().selectionMode) {
useSelectionStore.getState().setSelectionMode(true);
if (useSelectionStore.getState().selectionMode !== item.type) {
useSelectionStore.getState().setSelectionMode(item.type);
}
useSelectionStore.getState().setSelectedItem(item);
useSelectionStore.getState().setSelectedItem(item.id);
};
return (

View File

@@ -23,12 +23,13 @@ import React from "react";
import { View } from "react-native";
import { notesnook } from "../../../../e2e/test.ids";
import { TaggedNotes } from "../../../screens/notes/tagged";
import { useSelectionStore } from "../../../stores/use-selection-store";
import { SIZE } from "../../../utils/size";
import { Properties } from "../../properties";
import { IconButton } from "../../ui/icon-button";
import { PressableButton } from "../../ui/pressable";
import Heading from "../../ui/typography/heading";
import Paragraph from "../../ui/typography/paragraph";
import SelectionWrapper from "../selection-wrapper";
const TagItem = React.memo(
({
@@ -40,30 +41,34 @@ const TagItem = React.memo(
index: number;
totalNotes: number;
}) => {
const { colors, isDark } = useThemeColors();
const { colors } = useThemeColors();
const onPress = () => {
const {
selectedItemsList,
setSelectedItem,
selectionMode,
clearSelection
} = useSelectionStore.getState();
if (selectedItemsList.length > 0 && selectionMode === item.type) {
setSelectedItem(item.id);
return;
} else {
clearSelection();
}
TaggedNotes.navigate(item, true);
};
return (
<PressableButton
<SelectionWrapper
onPress={onPress}
customSelectedColor={colors.secondary.background}
item={item}
testID={notesnook.ids.tag.get(index)}
customAlpha={!isDark ? -0.02 : 0.02}
customOpacity={1}
customStyle={{
paddingHorizontal: 12,
flexDirection: "row",
paddingVertical: 12,
alignItems: "center",
width: "100%",
justifyContent: "space-between"
}}
>
<View
style={{
maxWidth: "92%"
flexGrow: 1,
flexShrink: 1
}}
>
<Heading size={SIZE.md}>
@@ -108,7 +113,7 @@ const TagItem = React.memo(
alignItems: "center"
}}
/>
</PressableButton>
</SelectionWrapper>
);
},
(prev, next) => {

View File

@@ -63,7 +63,6 @@ export const Empty = React.memo(function Empty({
const introCompleted = useSettingStore(
(state) => state.settings.introCompleted
);
const tip = useTip(
screen === "Notes" && introCompleted
? "first-note"
@@ -139,37 +138,3 @@ export const Empty = React.memo(function Empty({
</View>
);
});
/**
* Make a tips manager.
* The tip manager stores many tips. Each tip has following values
* 1. Text
* 2. contexts: An array of context strings. // Places where the tip can be shown
* 3. Button if any.
* 4. Image/Gif asset.
*
* Tip manager adds the following methods -> get(context). Returns a random tip for the following context.
*
* Tips can be shown in a sheet or in a list. For sheets, GeneralSheet can be used to
* render tips.
*
* Where can the tips be shown and how?
* 1. When transitioning, show tips in a sheet. Make sure its useful
* 2. Replace placeholders with tips.
* 3. Show tips in editor placeholder.
* 4. Show tips between list items?
*
* Tooltips.
* Small tooltips can be shown in initial render first time.
* Especially for items that are not shown on blank page. Should be
* in places where it makes sense and does not interrupt the user.
*
* Can also be shown when first time entering a screen that
* has something that the user might not know of. Like sorting and side menu.
*
* Todo:
* 1. Make a tip manager.
* 2. Make a list of tips.
* 3. Add images for those tips.
* 4. Show tips
*/

View File

@@ -79,6 +79,8 @@ export default function List(props: ListProps) {
? "home"
: props.renderedInRoute === "Favorites"
? "favorites"
: props.renderedInRoute === "Trash"
? "trash"
: `${props.dataType}s`;
const groupOptions = useGroupOptions(groupType);

View File

@@ -130,9 +130,6 @@ export const Properties = ({ close = () => {}, item, buttons = [] }) => {
buttons={buttons}
close={() => {
close();
setTimeout(() => {
SearchService.updateAndSearch();
}, 1000);
}}
/>

View File

@@ -1,360 +0,0 @@
/*
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 React, { useCallback, useEffect } from "react";
import { BackHandler, Platform, View } from "react-native";
import { db } from "../../common/database";
import useGlobalSafeAreaInsets from "../../hooks/use-global-safe-area-insets";
import { ToastManager } from "../../services/event-manager";
import Navigation from "../../services/navigation";
import SearchService from "../../services/search";
import useNavigationStore from "../../stores/use-navigation-store";
import { useSelectionStore } from "../../stores/use-selection-store";
import { useThemeColors } from "@notesnook/theme";
import { deleteItems } from "../../utils/functions";
import { tabBarRef } from "../../utils/global-refs";
import { SIZE } from "../../utils/size";
import { sleep } from "../../utils/time";
import { presentDialog } from "../dialog/functions";
import MoveNoteSheet from "../sheets/add-to";
import ExportNotesSheet from "../sheets/export-notes";
import { IconButton } from "../ui/icon-button";
import Heading from "../ui/typography/heading";
import ManageTagsSheet from "../sheets/manage-tags";
export const SelectionHeader = React.memo(() => {
const { colors } = useThemeColors();
const selectionMode = useSelectionStore((state) => state.selectionMode);
const selectedItemsList = useSelectionStore(
(state) => state.selectedItemsList
);
const setSelectionMode = useSelectionStore((state) => state.setSelectionMode);
const clearSelection = useSelectionStore((state) => state.clearSelection);
const currentRoute = useNavigationStore((state) => state.currentRoute);
const insets = useGlobalSafeAreaInsets();
SearchService.prepareSearch?.();
const allItems = SearchService.getSearchInformation()?.get() || [];
const allSelected = allItems.length === selectedItemsList.length;
useEffect(() => {
if (selectionMode) {
tabBarRef.current?.lock();
} else {
tabBarRef.current?.unlock();
}
}, [selectionMode]);
const addToFavorite = async () => {
if (selectedItemsList.length > 0) {
selectedItemsList.forEach((item) => {
db.notes.note(item.id).favorite();
});
Navigation.queueRoutesForUpdate();
clearSelection();
}
};
const restoreItem = async () => {
if (selectedItemsList.length > 0) {
let noteIds = [];
selectedItemsList.forEach((item) => {
noteIds.push(item.id);
});
await db.trash.restore(...noteIds);
Navigation.queueRoutesForUpdate();
clearSelection();
ToastManager.show({
heading: "Restore successful",
type: "success"
});
}
};
const deleteItem = async () => {
presentDialog({
title: `Delete ${selectedItemsList.length > 1 ? "items" : "item"}`,
paragraph: `Are you sure you want to delete ${
selectedItemsList.length > 1
? "these items permanently?"
: "this item permanently?"
}`,
positiveText: "Delete",
negativeText: "Cancel",
positivePress: async () => {
if (selectedItemsList.length > 0) {
let noteIds = [];
selectedItemsList.forEach((item) => {
noteIds.push(item.id);
});
await db.trash.delete(...noteIds);
Navigation.queueRoutesForUpdate();
clearSelection();
}
},
positiveType: "errorShade"
});
};
const onBackPress = useCallback(() => {
clearSelection();
return true;
}, [clearSelection]);
useEffect(() => {
if (selectionMode) {
BackHandler.addEventListener("hardwareBackPress", onBackPress);
} else {
BackHandler.removeEventListener("hardwareBackPress", onBackPress);
}
}, [onBackPress, selectionMode]);
return !selectionMode ? null : (
<View
style={{
width: "100%",
height: Platform.OS === "android" ? 50 + insets.top : 50,
paddingTop: Platform.OS === "android" ? insets.top : null,
backgroundColor: colors.primary.background,
justifyContent: "space-between",
alignItems: "center",
flexDirection: "row",
zIndex: 999,
paddingHorizontal: 12,
marginVertical: 10
}}
>
<View
style={{
flexDirection: "row",
justifyContent: "flex-start",
alignItems: "center",
borderRadius: 100
}}
>
<IconButton
customStyle={{
justifyContent: "center",
alignItems: "center",
height: 40,
width: 40,
borderRadius: 100,
marginRight: 10
}}
type="grayBg"
onPress={() => {
setSelectionMode(!selectionMode);
}}
size={SIZE.xl}
color={colors.primary.icon}
name="close"
/>
<View
style={{
backgroundColor: colors.secondary.background,
height: 40,
borderRadius: 100,
paddingHorizontal: 16,
justifyContent: "center",
flexDirection: "row",
alignItems: "center"
}}
>
<Heading size={SIZE.md} color={colors.primary.accent}>
{selectedItemsList.length}
</Heading>
</View>
</View>
<View
style={{
flexDirection: "row",
justifyContent: "flex-start",
alignItems: "center"
}}
>
<IconButton
onPress={async () => {
useSelectionStore
.getState()
.setAll(allSelected ? [] : [...allItems]);
}}
tooltipText="Select all"
tooltipPosition={4}
customStyle={{
marginLeft: 10
}}
color={colors.primary.paragraph}
name="select-all"
size={SIZE.xl}
/>
{currentRoute === "Trash" ||
currentRoute === "Notebooks" ||
currentRoute === "Reminders" ? null : (
<>
<IconButton
onPress={async () => {
await sleep(100);
ManageTagsSheet.present(selectedItemsList);
}}
customStyle={{
marginLeft: 10
}}
color={colors.primary.icon}
tooltipText="Manage tags"
tooltipPosition={4}
name="pound"
size={SIZE.xl}
/>
<IconButton
onPress={async () => {
ExportNotesSheet.present(selectedItemsList);
}}
tooltipText="Export"
tooltipPosition={4}
customStyle={{
marginLeft: 10
}}
color={colors.primary.paragraph}
name="export"
size={SIZE.xl}
/>
<IconButton
onPress={async () => {
//setSelectionMode(false);
await sleep(100);
MoveNoteSheet.present();
}}
customStyle={{
marginLeft: 10
}}
tooltipText="Add to notebooks"
tooltipPosition={4}
color={colors.primary.paragraph}
name="plus"
size={SIZE.xl}
/>
</>
)}
{currentRoute === "Notebook" ? (
<IconButton
onPress={async () => {
if (selectedItemsList.length > 0) {
const { focusedRouteId } = useNavigationStore.getState();
if (currentRoute === "Notebook") {
for (const item of selectedItemsList) {
await db.relations.unlink(
{ type: "notebook", id: focusedRouteId },
item
);
}
} else {
await db.notes.removeFromNotebook(
{
id: currentScreen.notebookId,
topic: currentScreen.id
},
...selectedItemsList.map((item) => item.id)
);
}
Navigation.queueRoutesForUpdate();
clearSelection();
}
}}
customStyle={{
marginLeft: 10
}}
tooltipText={`Remove from Notebook`}
tooltipPosition={4}
testID="select-minus"
color={colors.primary.paragraph}
name="minus"
size={SIZE.xl}
/>
) : null}
{currentRoute === "Favorites" ? (
<IconButton
onPress={addToFavorite}
customStyle={{
marginLeft: 10
}}
tooltipText="Remove from favorites"
tooltipPosition={4}
color={colors.primary.paragraph}
name="star-off"
size={SIZE.xl}
/>
) : null}
{currentRoute === "Trash" ? null : (
<IconButton
customStyle={{
marginLeft: 10
}}
onPress={() => {
deleteItems();
}}
tooltipText="Move to trash"
tooltipPosition={1}
color={colors.primary.paragraph}
name="delete"
size={SIZE.xl}
/>
)}
{currentRoute === "Trash" ? (
<>
<IconButton
customStyle={{
marginLeft: 10
}}
color={colors.primary.paragraph}
onPress={restoreItem}
name="delete-restore"
tooltipText="Restore"
tooltipPosition={4}
size={SIZE.xl - 3}
/>
<IconButton
customStyle={{
marginLeft: 10
}}
color={colors.primary.paragraph}
onPress={deleteItem}
tooltipText="Delete"
tooltipPosition={4}
name="delete"
size={SIZE.xl - 3}
/>
</>
) : null}
</View>
</View>
);
});
SelectionHeader.displayName = "SelectionHeader";
export default SelectionHeader;

View File

@@ -0,0 +1,368 @@
/*
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 { Item, ItemType, VirtualizedGrouping } from "@notesnook/core";
import { useThemeColors } from "@notesnook/theme";
import React, { useCallback, useEffect } from "react";
import {
BackHandler,
NativeEventSubscription,
Platform,
View
} from "react-native";
import { db } from "../../common/database";
import useGlobalSafeAreaInsets from "../../hooks/use-global-safe-area-insets";
import { ToastManager } from "../../services/event-manager";
import Navigation from "../../services/navigation";
import useNavigationStore from "../../stores/use-navigation-store";
import { useSelectionStore } from "../../stores/use-selection-store";
import { deleteItems } from "../../utils/functions";
import { tabBarRef } from "../../utils/global-refs";
import { updateNotebook } from "../../utils/notebooks";
import { SIZE } from "../../utils/size";
import { sleep } from "../../utils/time";
import { presentDialog } from "../dialog/functions";
import MoveNoteSheet from "../sheets/add-to";
import ExportNotesSheet from "../sheets/export-notes";
import ManageTagsSheet from "../sheets/manage-tags";
import { IconButton } from "../ui/icon-button";
import Heading from "../ui/typography/heading";
import Animated, { FadeInUp } from "react-native-reanimated";
export const SelectionHeader = React.memo(
({
items,
type,
id
}: {
items?: VirtualizedGrouping<Item>;
id?: string;
type?: ItemType;
}) => {
const { colors } = useThemeColors();
const selectionMode = useSelectionStore((state) => state.selectionMode);
const selectedItemsList = useSelectionStore(
(state) => state.selectedItemsList
);
const clearSelection = useSelectionStore((state) => state.clearSelection);
const insets = useGlobalSafeAreaInsets();
const allSelected =
items?.ids?.filter((id) => typeof id === "string").length ===
selectedItemsList.length;
const focusedRouteId = useNavigationStore((state) => state.focusedRouteId);
useEffect(() => {
if (selectionMode) {
tabBarRef.current?.lock();
} else {
tabBarRef.current?.unlock();
}
}, [selectionMode]);
const addToFavorite = async () => {
if (!selectedItemsList.length) return;
db.notes.favorite(true, ...selectedItemsList);
Navigation.queueRoutesForUpdate();
clearSelection();
};
const restoreItem = async () => {
if (!selectedItemsList.length) return;
await db.trash.restore(...selectedItemsList);
Navigation.queueRoutesForUpdate();
clearSelection();
ToastManager.show({
heading: "Restore successful",
type: "success"
});
};
const deleteItem = async () => {
presentDialog({
title: `Delete ${selectedItemsList.length > 1 ? "items" : "item"}`,
paragraph: `Are you sure you want to delete ${
selectedItemsList.length > 1
? "these items permanently?"
: "this item permanently?"
}`,
positiveText: "Delete",
negativeText: "Cancel",
positivePress: async () => {
if (!selectedItemsList.length) return;
await db.trash.delete(...selectedItemsList);
Navigation.queueRoutesForUpdate();
clearSelection();
},
positiveType: "errorShade"
});
};
useEffect(() => {
const onBackPress = () => {
clearSelection();
return true;
};
let sub: NativeEventSubscription | undefined;
if (selectionMode) {
sub = BackHandler.addEventListener("hardwareBackPress", onBackPress);
}
return () => {
sub?.remove();
};
}, [clearSelection, selectionMode]);
return selectionMode !== type || focusedRouteId !== id ? null : (
<Animated.View
entering={FadeInUp}
style={{
width: "100%",
height: Platform.OS === "android" ? 50 + insets.top : 50,
paddingTop: Platform.OS === "android" ? insets.top : null,
backgroundColor: colors.primary.background,
justifyContent: "space-between",
alignItems: "center",
flexDirection: "row",
zIndex: 999,
paddingHorizontal: 12,
marginVertical: 10
}}
>
<View
style={{
flexDirection: "row",
justifyContent: "flex-start",
alignItems: "center",
borderRadius: 100
}}
>
<IconButton
customStyle={{
justifyContent: "center",
alignItems: "center",
height: 40,
width: 40,
borderRadius: 100,
marginRight: 10
}}
type="grayBg"
onPress={() => {
clearSelection();
}}
size={SIZE.xl}
color={colors.primary.icon}
name="close"
/>
<View
style={{
backgroundColor: colors.secondary.background,
height: 40,
borderRadius: 100,
paddingHorizontal: 16,
justifyContent: "center",
flexDirection: "row",
alignItems: "center"
}}
>
<Heading size={SIZE.md} color={colors.primary.accent}>
{selectedItemsList.length}
</Heading>
</View>
</View>
<View
style={{
flexDirection: "row",
justifyContent: "flex-start",
alignItems: "center"
}}
>
<IconButton
onPress={async () => {
useSelectionStore
.getState()
.setAll(
allSelected
? []
: [
...((items?.ids.filter(
(id) => typeof id !== "object"
) as string[]) || [])
]
);
}}
tooltipText="Select all"
tooltipPosition={4}
customStyle={{
marginLeft: 10
}}
color={
allSelected ? colors.primary.accent : colors.primary.paragraph
}
name="select-all"
size={SIZE.xl}
/>
{type === "note" ||
(type === "notebook" && focusedRouteId === "Notebooks") ? null : (
<>
<IconButton
onPress={async () => {
await sleep(100);
ManageTagsSheet.present(selectedItemsList);
}}
customStyle={{
marginLeft: 10
}}
color={colors.primary.icon}
tooltipText="Manage tags"
tooltipPosition={4}
name="pound"
size={SIZE.xl}
/>
<IconButton
onPress={async () => {
ExportNotesSheet.present(selectedItemsList);
}}
tooltipText="Export"
tooltipPosition={4}
customStyle={{
marginLeft: 10
}}
color={colors.primary.paragraph}
name="export"
size={SIZE.xl}
/>
<IconButton
onPress={async () => {
MoveNoteSheet.present();
}}
customStyle={{
marginLeft: 10
}}
tooltipText="Add to notebooks"
tooltipPosition={4}
color={colors.primary.paragraph}
name="plus"
size={SIZE.xl}
/>
</>
)}
{type === "notebook" && focusedRouteId !== "Notebooks" ? (
<IconButton
onPress={async () => {
if (selectedItemsList.length > 0) {
const { focusedRouteId } = useNavigationStore.getState();
if (!focusedRouteId) return;
await db.notes.removeFromNotebook(
focusedRouteId,
...selectedItemsList
);
updateNotebook(focusedRouteId);
Navigation.queueRoutesForUpdate();
clearSelection();
}
}}
customStyle={{
marginLeft: 10
}}
tooltipText={`Remove from Notebook`}
tooltipPosition={4}
testID="select-minus"
color={colors.primary.paragraph}
name="minus"
size={SIZE.xl}
/>
) : null}
{focusedRouteId === "Favorites" ? (
<IconButton
onPress={addToFavorite}
customStyle={{
marginLeft: 10
}}
tooltipText="Remove from favorites"
tooltipPosition={4}
color={colors.primary.paragraph}
name="star-off"
size={SIZE.xl}
/>
) : null}
{type === "trash" ? null : (
<IconButton
customStyle={{
marginLeft: 10
}}
onPress={() => {
deleteItems(
undefined,
useSelectionStore.getState().selectionMode
);
}}
tooltipText="Move to trash"
tooltipPosition={1}
color={colors.primary.paragraph}
name="delete"
size={SIZE.xl}
/>
)}
{type === "trash" ? (
<>
<IconButton
customStyle={{
marginLeft: 10
}}
color={colors.primary.paragraph}
onPress={restoreItem}
name="delete-restore"
tooltipText="Restore"
tooltipPosition={4}
size={SIZE.xl - 3}
/>
<IconButton
customStyle={{
marginLeft: 10
}}
color={colors.primary.paragraph}
onPress={deleteItem}
tooltipText="Delete"
tooltipPosition={4}
name="delete"
size={SIZE.xl - 3}
/>
</>
) : null}
</View>
</Animated.View>
);
}
);
SelectionHeader.displayName = "SelectionHeader";
export default SelectionHeader;

View File

@@ -85,18 +85,20 @@ export const AddNotebookSheet = ({
useMenuStore.getState().setMenuPins();
Navigation.queueRoutesForUpdate();
useRelationStore.getState().update();
const parent =
parentNotebook?.id || (await getParentNotebookId(notebook?.id || id));
eSendEvent(eOnNotebookUpdated, parent);
if (notebook) {
const parent = await getParentNotebookId(notebook.id);
eSendEvent(eOnNotebookUpdated, parent);
setImmediate(() => {
console.log(parent, notebook.id);
eSendEvent(eOnNotebookUpdated, notebook.id);
});
}
if (!notebook) {
setTimeout(async () => {
MoveNotes.present(await db.notebooks.notebook(id));
}, 500);
MoveNotes.present(await db.notebooks.notebook(id));
} else {
close?.();
}

View File

@@ -23,22 +23,22 @@ import React, { RefObject, useCallback, useEffect } from "react";
import { Keyboard, TouchableOpacity, View } from "react-native";
import { ActionSheetRef, FlashList } from "react-native-actions-sheet";
import { db } from "../../../common/database";
import { eSendEvent, presentSheet } from "../../../services/event-manager";
import { presentSheet } from "../../../services/event-manager";
import Navigation from "../../../services/navigation";
import SearchService from "../../../services/search";
import { ItemSelection } from "../../../stores/item-selection-store";
import { useNotebookStore } from "../../../stores/use-notebook-store";
import { useRelationStore } from "../../../stores/use-relation-store";
import { useSelectionStore } from "../../../stores/use-selection-store";
import { useSettingStore } from "../../../stores/use-setting-store";
import { eOnNotebookUpdated } from "../../../utils/events";
import { updateNotebook } from "../../../utils/notebooks";
import { Dialog } from "../../dialog";
import DialogHeader from "../../dialog/dialog-header";
import SheetProvider from "../../sheet-provider";
import { Button } from "../../ui/button";
import { IconButton } from "../../ui/icon-button";
import Paragraph from "../../ui/typography/paragraph";
import { NotebookItem } from "./notebook-item";
import { useNotebookItemSelectionStore } from "./store";
import SheetProvider from "../../sheet-provider";
import { ItemSelection } from "../../../stores/item-selection-store";
async function updateInitialSelectionState(items: string[]) {
const relations = await db.relations
@@ -90,15 +90,13 @@ const MoveNoteSheet = ({
const selectedItemsList = useSelectionStore(
(state) => state.selectedItemsList
);
const setNotebooks = useNotebookStore((state) => state.setNotebooks);
const multiSelect = useNotebookItemSelectionStore(
(state) => state.multiSelect
);
useEffect(() => {
const items = note
? [note.id]
: (selectedItemsList as Note[]).map((note) => note.id);
const items = note ? [note.id] : selectedItemsList;
updateInitialSelectionState(items);
return () => {
useNotebookItemSelectionStore.setState({
@@ -111,9 +109,7 @@ const MoveNoteSheet = ({
}, [note, selectedItemsList]);
const onSave = async () => {
const noteIds = note
? [note.id]
: selectedItemsList.map((n) => (n as Note).id);
const noteIds = note ? [note.id] : selectedItemsList;
const changedNotebooks = useNotebookItemSelectionStore.getState().selection;
@@ -123,18 +119,17 @@ const MoveNoteSheet = ({
if (changedNotebooks[id] === "selected") {
for (const id of noteIds) {
await db.relations.add(item, { id: id, type: "note" });
updateNotebook(item.id);
}
} else if (changedNotebooks[id] === "deselected") {
for (const id of noteIds) {
await db.relations.unlink(item, { id: id, type: "note" });
updateNotebook(item.id);
}
}
}
Navigation.queueRoutesForUpdate();
setNotebooks();
eSendEvent(eOnNotebookUpdated);
SearchService.updateAndSearch();
useRelationStore.getState().update();
actionSheetRef.current?.hide();
};
@@ -182,48 +177,46 @@ const MoveNoteSheet = ({
: "Select topics you want to add note(s) to."
}
/>
<Button
height={35}
<View
style={{
borderRadius: 100,
paddingHorizontal: 24,
alignSelf: "flex-start"
flexDirection: "row",
columnGap: 10
}}
title="Save"
type={"accent"}
onPress={onSave}
/>
>
<IconButton
name="restore"
type="grayAccent"
onPress={() => {
const items = note ? [note.id] : selectedItemsList;
updateInitialSelectionState(items);
}}
customStyle={{
width: 40,
height: 40
}}
/>
<Button
height={40}
style={{
borderRadius: 100,
paddingHorizontal: 24,
alignSelf: "flex-start"
}}
title="Save"
type={"accent"}
onPress={onSave}
/>
</View>
</View>
<View
style={{
paddingHorizontal: 12
}}
>
<Button
title="Reset selection"
height={30}
style={{
alignSelf: "flex-start",
paddingHorizontal: 0,
width: "100%",
marginTop: 6
}}
type="grayAccent"
onPress={() => {
const items = note
? [note.id]
: (selectedItemsList as Note[]).map((note) => note.id);
updateInitialSelectionState(items);
}}
/>
</View>
<View
style={{
paddingHorizontal: 12,
paddingHorizontal: 0,
maxHeight: dimensions.height * 0.85,
height: 50 * ((notebooks?.ids.length || 0) + 2)
height: dimensions.height * 0.85,
paddingTop: 6
}}
>
<FlashList

View File

@@ -55,13 +55,13 @@ export const NotebookItem = ({
const { nestedNotebooks, notebook: item } = useNotebook(id, items);
const ids = useMemo(() => (id ? [id] : []), [id]);
const { totalNotes: totalNotes } = useTotalNotes(ids, "notebook");
const screen = useNavigationStore((state) => state.currentRoute);
const focusedRouteId = useNavigationStore((state) => state.focusedRouteId);
const { colors } = useThemeColors("sheet");
const selection = useNotebookItemSelectionStore((state) =>
id ? state.selection[id] : undefined
);
const isSelected = selection === "selected";
const isFocused = screen.id === id;
const isFocused = focusedRouteId === id;
const { fontScale } = useWindowDimensions();
const expanded = useNotebookExpandedStore((state) => state.expanded[id]);
@@ -114,9 +114,10 @@ export const NotebookItem = ({
width: "100%",
alignItems: "center",
flexDirection: "row",
paddingLeft: 0,
paddingLeft: 12,
paddingRight: 12,
borderRadius: 0
borderRadius: 0,
height: 45
}}
>
<View
@@ -125,8 +126,27 @@ export const NotebookItem = ({
alignItems: "center"
}}
>
{nestedNotebooks?.ids.length ? (
<IconButton
size={SIZE.xl}
color={isSelected ? colors.selected.icon : colors.primary.icon}
onPress={() => {
useNotebookExpandedStore.getState().setExpanded(id);
}}
top={0}
left={0}
bottom={0}
right={0}
customStyle={{
width: 35,
height: 35
}}
name={expanded ? "chevron-down" : "chevron-right"}
/>
) : null}
<IconButton
size={SIZE.lg}
size={SIZE.xl}
color={
isSelected
? colors.selected.icon
@@ -154,34 +174,6 @@ export const NotebookItem = ({
}
/>
{nestedNotebooks?.ids.length ? (
<IconButton
size={SIZE.lg}
color={isSelected ? colors.selected.icon : colors.primary.icon}
onPress={() => {
useNotebookExpandedStore.getState().setExpanded(id);
}}
top={0}
left={0}
bottom={0}
right={0}
customStyle={{
width: 40,
height: 40
}}
name={expanded ? "chevron-down" : "chevron-right"}
/>
) : (
<>
<View
style={{
width: 40,
height: 40
}}
/>
</>
)}
<Paragraph
color={
isFocused ? colors.selected.paragraph : colors.secondary.paragraph
@@ -189,31 +181,40 @@ export const NotebookItem = ({
size={SIZE.sm}
>
{item?.title}{" "}
{totalNotes?.(id) ? (
<Paragraph size={SIZE.xs} color={colors.secondary.paragraph}>
{totalNotes(id)}
</Paragraph>
) : null}
</Paragraph>
</View>
<IconButton
name="plus"
customStyle={{
width: 40 * fontScale,
height: 40 * fontScale
<View
style={{
flexDirection: "row",
columnGap: 10,
alignItems: "center"
}}
testID={notesnook.ids.notebook.menu}
onPress={() => {
if (!item) return;
AddNotebookSheet.present(undefined, item, "link-notebooks");
}}
left={0}
right={0}
bottom={0}
top={0}
color={colors.primary.icon}
size={SIZE.xl}
/>
>
{totalNotes?.(id) ? (
<Paragraph size={SIZE.sm} color={colors.secondary.paragraph}>
{totalNotes(id)}
</Paragraph>
) : null}
<IconButton
name="plus"
customStyle={{
width: 40 * fontScale,
height: 40 * fontScale
}}
testID={notesnook.ids.notebook.menu}
onPress={() => {
if (!item) return;
AddNotebookSheet.present(undefined, item, "link-notebooks");
}}
left={0}
right={0}
bottom={0}
top={0}
color={colors.primary.icon}
size={SIZE.xl}
/>
</View>
</PressableButton>
{!expanded

View File

@@ -17,24 +17,27 @@ 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, { Fragment, useState } from "react";
import { Platform, StyleSheet, View, ActivityIndicator } from "react-native";
import { ActivityIndicator, Platform, StyleSheet, View } from "react-native";
import FileViewer from "react-native-file-viewer";
import Share from "react-native-share";
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
import { notesnook } from "../../../../e2e/test.ids";
import { db } from "../../../common/database";
import { requestInAppReview } from "../../../services/app-review";
import {
presentSheet,
PresentSheetOptions,
ToastManager
ToastManager,
eSendEvent,
presentSheet
} from "../../../services/event-manager";
import Exporter from "../../../services/exporter";
import PremiumService from "../../../services/premium";
import { useThemeColors } from "@notesnook/theme";
import { useUserStore } from "../../../stores/use-user-store";
import { getElevationStyle } from "../../../utils/elevation";
import { ph, pv, SIZE } from "../../../utils/size";
import { eCloseSheet } from "../../../utils/events";
import { SIZE, ph, pv } from "../../../utils/size";
import { sleep } from "../../../utils/time";
import DialogHeader from "../../dialog/dialog-header";
import { ProTag } from "../../premium/pro-tag";
@@ -44,17 +47,12 @@ import { PressableButton } from "../../ui/pressable";
import Seperator from "../../ui/seperator";
import Heading from "../../ui/typography/heading";
import Paragraph from "../../ui/typography/paragraph";
import { eSendEvent } from "../../../services/event-manager";
import { eCloseSheet } from "../../../utils/events";
import { requestInAppReview } from "../../../services/app-review";
import { Dialog } from "../../dialog";
import { Note } from "@notesnook/core";
const ExportNotesSheet = ({
notes,
ids,
update
}: {
notes: Note[];
ids: string[];
update: ((props: PresentSheetOptions) => void) | undefined;
}) => {
const { colors } = useThemeColors();
@@ -79,10 +77,10 @@ const ExportNotesSheet = ({
update?.({ disableClosing: true } as PresentSheetOptions);
setComplete(false);
let result;
if (notes.length > 1) {
result = await Exporter.bulkExport(notes, type, setStatus);
if (ids.length > 1) {
result = await Exporter.bulkExport(ids, type, setStatus);
} else {
result = await Exporter.exportNote(notes[0], type);
result = await Exporter.exportNote(ids[0], type);
await sleep(1000);
}
if (!result) {
@@ -161,9 +159,7 @@ const ExportNotesSheet = ({
<DialogHeader
icon="export"
title={
notes.length > 1
? `Export ${notes.length} Notes`
: "Export Note"
ids.length > 1 ? `Export ${ids.length} Notes` : "Export Note"
}
paragraph={`All exports are saved in ${
Platform.OS === "android"
@@ -251,7 +247,7 @@ const ExportNotesSheet = ({
<>
<ActivityIndicator />
<Paragraph>
{notes.length === 1
{ids.length === 1
? "Exporting note... Please wait"
: `Exporting notes${
status ? ` (${status})` : ``
@@ -276,8 +272,8 @@ const ExportNotesSheet = ({
}}
color={colors.secondary.heading}
>
{notes.length > 1
? `${notes.length} Notes exported`
{ids.length > 1
? `${ids.length} Notes exported`
: "Note exported"}
</Heading>
<Paragraph
@@ -285,7 +281,7 @@ const ExportNotesSheet = ({
textAlign: "center"
}}
>
Your {notes.length > 1 ? "notes are" : "note is"} exported
Your {ids.length > 1 ? "notes are" : "note is"} exported
successfully as {result?.fileName}
</Paragraph>
<Button
@@ -363,11 +359,11 @@ const ExportNotesSheet = ({
);
};
ExportNotesSheet.present = async (notes?: Note[], allNotes?: boolean) => {
const exportNotes = allNotes ? await db.notes.all?.items() : notes || [];
ExportNotesSheet.present = async (ids?: string[], allNotes?: boolean) => {
const exportNoteIds = allNotes ? await db.notes.all?.ids() : ids || [];
presentSheet({
component: (ref, close, update) => (
<ExportNotesSheet notes={exportNotes} update={update} />
<ExportNotesSheet ids={exportNoteIds} update={update} />
),
keyboardHandlerDisabled: true
});

View File

@@ -19,7 +19,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import { VirtualizedGrouping } from "@notesnook/core";
import { Tags } from "@notesnook/core/dist/collections/tags";
import { Note, Tag } from "@notesnook/core/dist/types";
import { Tag } from "@notesnook/core/dist/types";
import { useThemeColors } from "@notesnook/theme";
import React, {
RefObject,
@@ -30,11 +30,7 @@ import React, {
useState
} from "react";
import { TextInput, View, useWindowDimensions } from "react-native";
import {
ActionSheetRef,
FlashList,
FlatList
} from "react-native-actions-sheet";
import { ActionSheetRef, FlatList } from "react-native-actions-sheet";
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
import { db } from "../../../common/database";
import { useDBItem } from "../../../hooks/use-db-item";
@@ -47,7 +43,6 @@ import {
import { useRelationStore } from "../../../stores/use-relation-store";
import { useTagStore } from "../../../stores/use-tag-store";
import { SIZE } from "../../../utils/size";
import { IconButton } from "../../ui/icon-button";
import Input from "../../ui/input";
import { PressableButton } from "../../ui/pressable";
import Heading from "../../ui/typography/heading";
@@ -88,11 +83,11 @@ async function updateInitialSelectionState(items: string[]) {
const useTagItemSelection = createItemSelectionStore(true);
const ManageTagsSheet = (props: {
notes?: Note[];
ids?: string[];
actionSheetRef: RefObject<ActionSheetRef>;
}) => {
const { colors } = useThemeColors();
const notes = useMemo(() => props.notes || [], [props.notes]);
const ids = useMemo(() => props.ids || [], [props.ids]);
const [tags, setTags] = useState<VirtualizedGrouping<Tag>>();
const [query, setQuery] = useState<string>();
const inputRef = useRef<TextInput>(null);
@@ -100,7 +95,6 @@ const ManageTagsSheet = (props: {
const [queryExists, setQueryExists] = useState(false);
const dimensions = useWindowDimensions();
const refreshSelection = useCallback(() => {
const ids = notes.map((item) => item.id);
updateInitialSelectionState(ids).then((selection) => {
useTagItemSelection.setState({
initialState: selection,
@@ -108,14 +102,17 @@ const ManageTagsSheet = (props: {
});
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [notes, tags]);
}, [ids, tags]);
const refreshTags = useCallback(() => {
if (query && query.trim() !== "") {
db.lookup.tags(query).then((items) => {
setTags(items);
console.log("searched tags");
});
db.lookup
.tags(query)
.sorted()
.then((items) => {
setTags(items);
console.log("searched tags");
});
} else {
db.tags.all.sorted(db.settings.getGroupOptions("tags")).then((items) => {
console.log("items loaded tags");
@@ -149,7 +146,6 @@ const ManageTagsSheet = (props: {
}
const tag = query;
setQuery(undefined);
inputRef.current?.setNativeProps({
text: ""
});
@@ -166,20 +162,23 @@ const ManageTagsSheet = (props: {
});
if (id) {
for (const note of notes) {
for (const noteId of ids) {
await db.relations.add(
{
id: id,
type: "tag"
},
note
{
id: noteId,
type: "note"
}
);
}
}
useRelationStore.getState().update();
useTagStore.getState().setTags();
refreshTags();
setQuery(undefined);
} catch (e) {
ToastManager.show({
heading: "Cannot add tag",
@@ -194,7 +193,7 @@ const ManageTagsSheet = (props: {
const onPress = useCallback(
async (id: string) => {
for (const note of notes) {
for (const noteId of ids) {
try {
if (!id) return;
const isSelected =
@@ -205,7 +204,10 @@ const ManageTagsSheet = (props: {
id: id,
type: "tag"
},
note
{
id: noteId,
type: "note"
}
);
} else {
await db.relations.add(
@@ -213,7 +215,10 @@ const ManageTagsSheet = (props: {
id: id,
type: "tag"
},
note
{
id: noteId,
type: "note"
}
);
}
} catch (e) {
@@ -228,7 +233,7 @@ const ManageTagsSheet = (props: {
}, 1);
refreshSelection();
},
[notes, refreshSelection, refreshTags]
[ids, refreshSelection, refreshTags]
);
const renderTag = useCallback(
@@ -332,10 +337,10 @@ const ManageTagsSheet = (props: {
);
};
ManageTagsSheet.present = (notes?: Note[]) => {
ManageTagsSheet.present = (ids?: string[]) => {
presentSheet({
component: (ref) => {
return <ManageTagsSheet actionSheetRef={ref} notes={notes} />;
return <ManageTagsSheet actionSheetRef={ref} ids={ids} />;
}
});
};

View File

@@ -27,7 +27,7 @@ import { FlashList } from "react-native-actions-sheet/dist/src/views/FlashList";
import { db } from "../../../common/database";
import { presentSheet } from "../../../services/event-manager";
import Navigation from "../../../services/navigation";
import SearchService from "../../../services/search";
import { updateNotebook } from "../../../utils/notebooks";
import { SIZE } from "../../../utils/size";
import { Dialog } from "../../dialog";
import DialogHeader from "../../dialog/dialog-header";
@@ -140,8 +140,8 @@ export const MoveNotes = ({
currentNotebook.id,
...selectedNoteIds
);
updateNotebook(currentNotebook.id);
Navigation.queueRoutesForUpdate();
SearchService.updateAndSearch();
fwdRef?.current?.hide();
}}
title="Move selected notes"

View File

@@ -181,7 +181,13 @@ export const NotebookSheet = () => {
if (!focusedRouteId) return;
const nextRoot = await findRootNotebookId(focusedRouteId);
setRoot(nextRoot);
if (nextRoot !== currentItem.current) {
console.log(
"NotebookSheet.useEffect.canShow",
"Root changed to",
nextRoot
);
setSelection([]);
setEnabled(false);
}
@@ -196,6 +202,7 @@ export const NotebookSheet = () => {
} else {
ref.current?.show(snapPoint);
}
console.log("NotebookSheet.useEffect.canShow", focusedRouteId);
onRequestUpdate();
}, 0);
} else {
@@ -203,7 +210,7 @@ export const NotebookSheet = () => {
setEnabled(false);
ref.current?.hide();
}
}, [canShow, currentRoute, onRequestUpdate, focusedRouteId]);
}, [canShow, onRequestUpdate, focusedRouteId]);
return (
<ActionSheet
@@ -302,11 +309,10 @@ export const NotebookSheet = () => {
height: 40 * fontScale
}}
onPress={async () => {
//@ts-ignore
useSelectionStore.setState({
selectedItemsList: selection
});
await deleteItems();
await deleteItems(
selection.map((notebook) => notebook.id),
"notebook"
);
useSelectionStore.getState().clearSelection();
setEnabled(false);
setSelection([]);

View File

@@ -24,7 +24,7 @@ import { eSendEvent } from "../../../services/event-manager";
import Navigation from "../../../services/navigation";
import { useThemeColors } from "@notesnook/theme";
import { GROUP, SORT } from "../../../utils/constants";
import { refreshNotesPage } from "../../../utils/events";
import { eGroupOptionsUpdated, refreshNotesPage } from "../../../utils/events";
import { SIZE } from "../../../utils/size";
import { Button } from "../../ui/button";
import Seperator from "../../ui/seperator";
@@ -42,7 +42,7 @@ const Sort = ({ type, screen }) => {
setGroupOptions(_groupOptions);
setTimeout(() => {
if (screen !== "TopicSheet") Navigation.queueRoutesForUpdate(screen);
eSendEvent("groupOptionsUpdate");
eSendEvent(eGroupOptionsUpdated, type);
eSendEvent(refreshNotesPage);
}, 1);
};

View File

@@ -43,10 +43,9 @@ export const MenuItem = React.memo(
if (item.func) {
item.func();
} else {
Navigation.navigate(
{ name: item.name, beta: item.isBeta },
{ canGoBack: false }
);
if (useNavigationStore.getState().currentRoute !== item.name) {
Navigation.push(item.name, { canGoBack: false, beta: item.isBeta });
}
}
if (item.close) {
setImmediate(() => {

View File

@@ -247,7 +247,7 @@ export const useActions = ({
try {
close();
await sleep(300);
await deleteItems(item);
await deleteItems([item.id], item.type);
} catch (e) {
console.error(e);
}
@@ -268,7 +268,7 @@ export const useActions = ({
await db.trash.delete(item.id);
setImmediate(() => {
Navigation.queueRoutesForUpdate();
useSelectionStore.getState().setSelectionMode(false);
useSelectionStore.getState().setSelectionMode(undefined);
ToastManager.show({
heading: "Permanently deleted items",
type: "success",
@@ -457,7 +457,7 @@ export const useActions = ({
async function exportNote() {
if (item.type !== "note") return;
ExportNotesSheet.present([item]);
ExportNotesSheet.present([item.id]);
}
async function toggleLocalOnly() {
@@ -495,8 +495,6 @@ export const useActions = ({
}
function addTo() {
clearSelection();
setSelectedItem(item);
MoveNoteSheet.present(item as Note);
}

View File

@@ -55,13 +55,8 @@ export const useDBItem = <T extends keyof ItemTypeKey>(
useEffect(() => {
const onUpdateItem = (itemId?: string) => {
if (typeof itemId === "string" && itemId !== id) return;
if (!id) {
if (item) {
setItem(undefined);
}
return;
}
console.log("onUpdateItem", id, type);
if (!id) return;
console.log("useDBItem.onUpdateItem", id, type);
if (items) {
items.item(id).then((item) => {
@@ -85,10 +80,10 @@ export const useDBItem = <T extends keyof ItemTypeKey>(
return () => {
eUnSubscribeEvent(eDBItemUpdate, onUpdateItem);
};
}, [id, type, items, item]);
}, [id, type, items]);
return [
item as ItemTypeKey[T],
id ? (item as ItemTypeKey[T]) : undefined,
() => {
if (id) {
eSendEvent(eDBItemUpdate, id);
@@ -115,7 +110,7 @@ export const useTotalNotes = (
for (const id of ids) {
totalNotesById[id] = relations.filter(
(relation) => relation.fromId === id && relation.toType === "note"
);
)?.length;
}
setTotalNotesById(totalNotesById);
});

View File

@@ -20,6 +20,7 @@ import { useEffect, useState } from "react";
import { db } from "../common/database";
import { eSubscribeEvent, eUnSubscribeEvent } from "../services/event-manager";
import Navigation from "../services/navigation";
import { eGroupOptionsUpdated } from "../utils/events";
export function useGroupOptions(type: any) {
const [groupOptions, setGroupOptions] = useState(
@@ -27,8 +28,10 @@ export function useGroupOptions(type: any) {
);
useEffect(() => {
const onUpdate = () => {
const onUpdate = (groupType: string) => {
if (groupType !== type) return;
const options = db.settings?.getGroupOptions(type) as any;
console.log("useGroupOptions.onUpdate", type, options);
if (
groupOptions?.groupBy !== options.groupBy ||
groupOptions?.sortBy !== options.sortBy ||
@@ -39,9 +42,9 @@ export function useGroupOptions(type: any) {
}
};
eSubscribeEvent("groupOptionsUpdate", onUpdate);
eSubscribeEvent(eGroupOptionsUpdated, onUpdate);
return () => {
eUnSubscribeEvent("groupOptionsUpdate", onUpdate);
eUnSubscribeEvent(eGroupOptionsUpdated, onUpdate);
};
}, [type, groupOptions]);

View File

@@ -20,7 +20,7 @@ import { Notebook, VirtualizedGrouping } from "@notesnook/core";
import React, { useCallback, useEffect, useState } from "react";
import { db } from "../common/database";
import { eSubscribeEvent, eUnSubscribeEvent } from "../services/event-manager";
import { eOnNotebookUpdated } from "../utils/events";
import { eGroupOptionsUpdated, eOnNotebookUpdated } from "../utils/events";
import { useDBItem, useTotalNotes } from "./use-db-item";
export const useNotebook = (
@@ -38,30 +38,37 @@ export const useNotebook = (
);
const onRequestUpdate = React.useCallback(() => {
if (!item || !id) {
if (notebooks) {
setNotebooks(undefined);
}
return;
}
console.log("useNotebook.onRequestUpdate", id);
if (!id) return;
console.log("useNotebook.onRequestUpdate", id, Date.now());
db.relations
.from(item, "notebook")
.from(
{
type: "notebook",
id: id
},
"notebook"
)
.selector.sorted(db.settings.getGroupOptions("notebooks"))
.then((notebooks) => {
setNotebooks(notebooks);
});
}, [item, id, notebooks]);
}, [id]);
useEffect(() => {
onRequestUpdate();
}, [item, onRequestUpdate]);
const onUpdate = useCallback(() => {
setGroupOptions({ ...(db.settings.getGroupOptions("notebooks") as any) });
console.log("useNotebook.useEffect.onRequestUpdate");
onRequestUpdate();
}, [onRequestUpdate]);
const onUpdate = useCallback(
(type: string) => {
if (type !== "notebooks") return;
setGroupOptions({ ...(db.settings.getGroupOptions("notebooks") as any) });
onRequestUpdate();
console.log("useNotebook.onUpdate", id, Date.now());
},
[id, onRequestUpdate]
);
useEffect(() => {
const onNotebookUpdate = (id?: string) => {
if (typeof id === "string" && id !== id) return;
@@ -71,10 +78,10 @@ export const useNotebook = (
});
};
eSubscribeEvent("groupOptionsUpdate", onUpdate);
eSubscribeEvent(eGroupOptionsUpdated, onUpdate);
eSubscribeEvent(eOnNotebookUpdated, onNotebookUpdate);
return () => {
eUnSubscribeEvent("groupOptionsUpdate", onUpdate);
eUnSubscribeEvent(eGroupOptionsUpdated, onUpdate);
eUnSubscribeEvent(eOnNotebookUpdated, onNotebookUpdate);
};
}, [onUpdate, onRequestUpdate, id, refresh]);
@@ -82,7 +89,7 @@ export const useNotebook = (
return {
notebook: item,
nestedNotebookNotesCount,
nestedNotebooks: notebooks,
nestedNotebooks: item ? notebooks : undefined,
onUpdate: onRequestUpdate,
groupOptions
};

View File

@@ -17,24 +17,23 @@ 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 { Item } from "@notesnook/core";
import { useSelectionStore } from "../stores/use-selection-store";
export default function useIsSelected(item: any) {
export default function useIsSelected(item: Item) {
const selectionMode = useSelectionStore((state) => state.selectionMode);
const selectedItemsList = useSelectionStore(
(state) => state.selectedItemsList
);
const selected =
selectionMode &&
selectedItemsList.findIndex(
(selectedItem: any) => selectedItem.id === item.id
) > -1;
selectedItemsList.findIndex((selectedId) => selectedId === item.id) > -1;
function toggle() {
if (!useSelectionStore.getState().selectionMode) {
useSelectionStore.getState().setSelectionMode(true);
if (useSelectionStore.getState().selectionMode !== item.type) {
useSelectionStore.getState().setSelectionMode(item.type);
}
useSelectionStore.getState().setSelectedItem(item);
useSelectionStore.getState().setSelectedItem(item.id);
}
return [selected, toggle];

View File

@@ -86,7 +86,7 @@ const _Tabs = () => {
const screenHeight = height - (50 + insets.top + insets.bottom);
React.useEffect(() => {
setTimeout(() => {
useNavigationStore.getState().update({ name: homepage });
useNavigationStore.getState().update(homepage);
}, 1000);
}, [homepage]);

View File

@@ -18,25 +18,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import React from "react";
import { db } from "../../common/database";
import DelayLayout from "../../components/delay-layout";
import { Header } from "../../components/header";
import List from "../../components/list";
import { useNavigationFocus } from "../../hooks/use-navigation-focus";
import Navigation, { NavigationProps } from "../../services/navigation";
import SearchService from "../../services/search";
import SettingsService from "../../services/settings";
import { useFavoriteStore } from "../../stores/use-favorite-store";
import useNavigationStore from "../../stores/use-navigation-store";
import { useNoteStore } from "../../stores/use-notes-store";
import { Header } from "../../components/header";
const prepareSearch = () => {
SearchService.update({
placeholder: "Search in favorites",
type: "notes",
title: "Favorites",
get: () => db.notes?.favorites
});
};
import SelectionHeader from "../../components/selection-header";
export const Favorites = ({
navigation,
@@ -52,7 +43,6 @@ export const Favorites = ({
Navigation.routeUpdateFunctions[route.name]
);
useNavigationStore.getState().setFocusedRouteId(route?.name);
SearchService.prepareSearch = prepareSearch;
return !prev?.current;
},
onBlur: () => false,
@@ -61,6 +51,7 @@ export const Favorites = ({
return (
<>
<SelectionHeader id={route.name} items={favorites} type="note" />
<Header
renderedInRoute={route.name}
title={route.name}

View File

@@ -28,6 +28,7 @@ import SettingsService from "../../services/settings";
import { useNoteStore } from "../../stores/use-notes-store";
import { openEditor } from "../notes/common";
import useNavigationStore from "../../stores/use-navigation-store";
import SelectionHeader from "../../components/selection-header";
export const Home = ({ navigation, route }: NavigationProps<"Notes">) => {
const notes = useNoteStore((state) => state.notes);
@@ -47,6 +48,7 @@ export const Home = ({ navigation, route }: NavigationProps<"Notes">) => {
return (
<>
<SelectionHeader id={route.name} items={notes} type="note" />
<Header
renderedInRoute={route.name}
title={route.name}

View File

@@ -27,6 +27,7 @@ import { NotebookHeader } from "../../components/list-items/headers/notebook-hea
import { AddNotebookSheet } from "../../components/sheets/add-notebook";
import { useNavigationFocus } from "../../hooks/use-navigation-focus";
import {
eSendEvent,
eSubscribeEvent,
eUnSubscribeEvent
} from "../../services/event-manager";
@@ -34,8 +35,10 @@ import Navigation, { NavigationProps } from "../../services/navigation";
import useNavigationStore, {
NotebookScreenParams
} from "../../stores/use-navigation-store";
import { eOnNewTopicAdded } from "../../utils/events";
import { eUpdateNotebookRoute } from "../../utils/events";
import { findRootNotebookId } from "../../utils/notebooks";
import { openEditor, setOnFirstSave } from "../notes/common";
import SelectionHeader from "../../components/selection-header";
const NotebookScreen = ({ route, navigation }: NavigationProps<"Notebook">) => {
const [notes, setNotes] = useState<VirtualizedGrouping<Note>>();
@@ -64,8 +67,24 @@ const NotebookScreen = ({ route, navigation }: NavigationProps<"Notebook">) => {
const onRequestUpdate = React.useCallback(
async (data?: NotebookScreenParams) => {
if (data?.item?.id && params.current.item?.id !== data?.item?.id) {
const nextRootNotebookId = await findRootNotebookId(data?.item?.id);
const currentNotebookRoot = await findRootNotebookId(
params.current.item.id
);
if (
nextRootNotebookId !== currentNotebookRoot ||
nextRootNotebookId === params.current?.item?.id
) {
// Never update notebook in route if root is different or if the root is current notebook.
return;
}
}
if (data) params.current = data;
params.current.title = params.current.item.title;
try {
const notebook = await db.notebooks?.notebook(
params?.current?.item?.id
@@ -89,9 +108,9 @@ const NotebookScreen = ({ route, navigation }: NavigationProps<"Notebook">) => {
useEffect(() => {
onRequestUpdate();
eSubscribeEvent(eOnNewTopicAdded, onRequestUpdate);
eSubscribeEvent(eUpdateNotebookRoute, onRequestUpdate);
return () => {
eUnSubscribeEvent(eOnNewTopicAdded, onRequestUpdate);
eUnSubscribeEvent(eUpdateNotebookRoute, onRequestUpdate);
};
}, [onRequestUpdate]);
@@ -103,6 +122,7 @@ const NotebookScreen = ({ route, navigation }: NavigationProps<"Notebook">) => {
return (
<>
<SelectionHeader id={route.name} items={notes} type="note" />
<Header
renderedInRoute={route.name}
title={params.current.item?.title}
@@ -117,6 +137,7 @@ const NotebookScreen = ({ route, navigation }: NavigationProps<"Notebook">) => {
ids: notes?.ids.filter((id) => typeof id === "string") as string[]
});
}}
titleHiddenOnRender
id={params.current.item?.id}
onPressDefaultRightButton={openEditor}
/>
@@ -154,13 +175,49 @@ const NotebookScreen = ({ route, navigation }: NavigationProps<"Notebook">) => {
);
};
NotebookScreen.navigate = (item: Notebook, canGoBack?: boolean) => {
NotebookScreen.navigate = async (item: Notebook, canGoBack?: boolean) => {
if (!item) return;
Navigation.navigate<"Notebook">("Notebook", {
title: item.title,
item: item,
canGoBack
});
const { currentRoute, focusedRouteId } = useNavigationStore.getState();
if (currentRoute === "Notebooks") {
Navigation.push("Notebook", {
title: item.title,
item: item,
canGoBack
});
} else if (currentRoute === "Notebook") {
if (!focusedRouteId) return;
const rootNotebookId = await findRootNotebookId(focusedRouteId);
const currentNotebookRoot = await findRootNotebookId(item?.id);
if (
(rootNotebookId === currentNotebookRoot &&
focusedRouteId !== rootNotebookId) ||
focusedRouteId == item?.id
) {
// Update the route in place instead
console.log("Updating existing route in place");
eSendEvent(eUpdateNotebookRoute, {
item: item,
title: item.title,
canGoBack: canGoBack
});
} else {
console.log("Pushing new notebook route");
// Push a new route
Navigation.push("Notebook", {
title: item.title,
item: item,
canGoBack
});
}
} else {
// Push a new route anyways
Navigation.push("Notebook", {
title: item.title,
item: item,
canGoBack
});
}
};
export default NotebookScreen;

View File

@@ -30,6 +30,7 @@ import Navigation, { NavigationProps } from "../../services/navigation";
import SettingsService from "../../services/settings";
import useNavigationStore from "../../stores/use-navigation-store";
import { useNotebookStore } from "../../stores/use-notebook-store";
import SelectionHeader from "../../components/selection-header";
const onButtonPress = () => {
AddNotebookSheet.present();
@@ -65,6 +66,7 @@ export const Notebooks = ({
return (
<>
<SelectionHeader id={route.name} items={notebooks} type="notebook" />
<Header
renderedInRoute={route.name}
title={route.name}

View File

@@ -22,7 +22,9 @@ import React from "react";
import NotesPage from ".";
import { db } from "../../common/database";
import Navigation, { NavigationProps } from "../../services/navigation";
import { NotesScreenParams } from "../../stores/use-navigation-store";
import useNavigationStore, {
NotesScreenParams
} from "../../stores/use-navigation-store";
import { PLACEHOLDER_DATA, openEditor, toCamelCase } from "./common";
export const ColoredNotes = ({
navigation,
@@ -53,7 +55,15 @@ ColoredNotes.get = async (params: NotesScreenParams, grouped = true) => {
ColoredNotes.navigate = (item: Color, canGoBack: boolean) => {
if (!item) return;
Navigation.navigate<"ColoredNotes">("ColoredNotes", {
const { focusedRouteId } = useNavigationStore.getState();
if (focusedRouteId === item.id) {
console.log("ColoredNotes.navigate: route already focused for color");
return;
}
Navigation.push<"ColoredNotes">("ColoredNotes", {
item: item,
canGoBack,
title: toCamelCase(item.title)

View File

@@ -31,7 +31,6 @@ import {
eUnSubscribeEvent
} from "../../services/event-manager";
import Navigation, { NavigationProps } from "../../services/navigation";
import SearchService from "../../services/search";
import useNavigationStore, {
HeaderRightButton,
NotesScreenParams,
@@ -102,18 +101,6 @@ const NotesPage = ({
focusOnInit: !focusControl
});
const prepareSearch = React.useCallback(() => {
const { item } = params.current;
SearchService.update({
placeholder: `Search in ${item.title}`,
type: "notes",
title: item.type === "tag" ? "#" + item.title : item.title,
get: () => {
return get(params.current, false);
}
});
}, [get]);
const syncWithNavigation = React.useCallback(() => {
const { item } = params.current;
@@ -126,13 +113,7 @@ const NotesPage = ({
type: getItemType(route.name),
id: item.id
});
}, [
isMonograph,
onPressFloatingButton,
prepareSearch,
rightButtons,
route.name
]);
}, [isMonograph, route.name]);
const onRequestUpdate = React.useCallback(
async (data?: NotesScreenParams) => {
@@ -188,7 +169,7 @@ const NotesPage = ({
<>
<Header
renderedInRoute={route.name}
title={title}
title={title || route.name}
canGoBack={params?.current?.canGoBack}
hasSearch={true}
id={
@@ -214,7 +195,7 @@ const NotesPage = ({
dataType="note"
onRefresh={onRequestUpdate}
loading={loading || !isFocused}
renderedInRoute="Notes"
renderedInRoute={route.name}
headerTitle={title}
customAccentColor={accentColor}
placeholder={placeholder}

View File

@@ -22,7 +22,9 @@ import React from "react";
import NotesPage from ".";
import { db } from "../../common/database";
import Navigation, { NavigationProps } from "../../services/navigation";
import { NotesScreenParams } from "../../stores/use-navigation-store";
import useNavigationStore, {
NotesScreenParams
} from "../../stores/use-navigation-store";
import { PLACEHOLDER_DATA, openEditor } from "./common";
export const TaggedNotes = ({
@@ -54,7 +56,15 @@ TaggedNotes.get = async (params: NotesScreenParams, grouped = true) => {
TaggedNotes.navigate = (item: Tag, canGoBack?: boolean) => {
if (!item) return;
Navigation.navigate<"TaggedNotes">("TaggedNotes", {
const { focusedRouteId } = useNavigationStore.getState();
if (focusedRouteId === item.id) {
console.log("TaggedNotes.navigate: route already focused for tag");
return;
}
Navigation.push<"TaggedNotes">("TaggedNotes", {
item: item,
canGoBack,
title: item.title

View File

@@ -28,6 +28,7 @@ import Navigation, { NavigationProps } from "../../services/navigation";
import SettingsService from "../../services/settings";
import useNavigationStore from "../../stores/use-navigation-store";
import { useReminderStore } from "../../stores/use-reminder-store";
import SelectionHeader from "../../components/selection-header";
export const Reminders = ({
navigation,
@@ -50,6 +51,7 @@ export const Reminders = ({
return (
<>
<SelectionHeader id={route.name} items={reminders} type="reminder" />
<Header
renderedInRoute={route.name}
title={route.name}
@@ -63,6 +65,7 @@ export const Reminders = ({
route: route.name
});
}}
isBeta
id={route.name}
onPressDefaultRightButton={() => {
ReminderSheet.present();

View File

@@ -18,53 +18,90 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { Item, VirtualizedGrouping } from "@notesnook/core";
import React, { useState } from "react";
import DelayLayout from "../../components/delay-layout";
import React, { useEffect, useRef, useState } from "react";
import { db } from "../../common/database";
import List from "../../components/list";
import { NavigationProps } from "../../services/navigation";
import { SearchBar } from "./search-bar";
import { db } from "../../common/database";
export const Search = ({ route }: NavigationProps<"Search">) => {
import { useNavigationFocus } from "../../hooks/use-navigation-focus";
import useNavigationStore from "../../stores/use-navigation-store";
import {
eSubscribeEvent,
eUnSubscribeEvent
} from "../../services/event-manager";
import { eOnRefreshSearch } from "../../utils/events";
import SelectionHeader from "../../components/selection-header";
export const Search = ({ route, navigation }: NavigationProps<"Search">) => {
const [results, setResults] = useState<VirtualizedGrouping<Item>>();
const [loading, setLoading] = useState(false);
const [searchStatus, setSearchStatus] = useState<string>();
const currentQuery = useRef<string>();
const isFocused = useNavigationFocus(navigation, {
onFocus: (prev) => {
useNavigationStore.getState().setFocusedRouteId(route.name);
return !prev?.current;
},
onBlur: () => false
});
const onSearch = async (query: string) => {
if (!query) {
setResults(undefined);
setLoading(false);
setSearchStatus(undefined);
return;
}
try {
setLoading(true);
const type =
route.params.type === "trash"
? "trash"
: ((route.params?.type + "s") as keyof typeof db.lookup);
console.log(
`Searching in ${type} for ${query}`,
route.params?.ids?.length
);
const results = await db.lookup[type](
query,
route.params?.type === "note" ? route.params?.ids : undefined
);
console.log(`Found ${results.ids?.length} results for ${query}`);
setResults(results);
if (results.ids?.length === 0) {
setSearchStatus(`No results found for ${query}`);
} else {
const onSearch = React.useCallback(
async (query?: string) => {
currentQuery.current = query;
if (!query) {
setResults(undefined);
setLoading(false);
setSearchStatus(undefined);
return;
}
setLoading(false);
} catch (e) {
console.log(e);
}
};
try {
setLoading(true);
const type =
route.params.type === "trash"
? "trash"
: ((route.params?.type + "s") as keyof typeof db.lookup);
console.log(
`Searching in ${type} for ${query}`,
route.params?.ids?.length
);
const results = await db.lookup[type](
query,
route.params?.type === "note" ? route.params?.ids : undefined
).sorted();
console.log(`Found ${results.ids?.length} results for ${query}`);
setResults(results);
if (results.ids?.length === 0) {
setSearchStatus(`No results found for ${query}`);
} else {
setSearchStatus(undefined);
}
setLoading(false);
} catch (e) {
console.log(e);
}
},
[route.params?.ids, route.params.type]
);
useEffect(() => {
const onRefreshSearch = (type: string) => {
if (type === route.params?.type) {
onSearch(currentQuery.current);
}
};
eSubscribeEvent(eOnRefreshSearch, onRefreshSearch);
return () => {
eUnSubscribeEvent(eOnRefreshSearch, onRefreshSearch);
};
}, [onSearch, route.params?.type]);
return (
<>
<SelectionHeader
id={route.name}
items={results}
type={route.params?.type}
/>
<SearchBar onChangeText={onSearch} loading={loading} />
<List
data={results}

View File

@@ -26,6 +26,8 @@ import Navigation from "../../services/navigation";
import { SIZE } from "../../utils/size";
import useGlobalSafeAreaInsets from "../../hooks/use-global-safe-area-insets";
import { DDS } from "../../services/device-detection";
import { useSelectionStore } from "../../stores/use-selection-store";
import useNavigationStore from "../../stores/use-navigation-store";
export const SearchBar = ({
onChangeText,
loading
@@ -33,6 +35,10 @@ export const SearchBar = ({
onChangeText: (value: string) => void;
loading?: boolean;
}) => {
const selectionMode = useSelectionStore((state) => state.selectionMode);
const isFocused = useNavigationStore(
(state) => state.focusedRouteId === "Search"
);
const insets = useGlobalSafeAreaInsets();
const { colors } = useThemeColors();
const inputRef = useRef<TextInput>(null);
@@ -40,7 +46,7 @@ export const SearchBar = ({
onChangeText(value);
};
return (
return selectionMode && isFocused ? null : (
<View
style={{
height: 50 + insets.top,

View File

@@ -107,16 +107,7 @@ const _SectionItem = ({ item }: { item: SettingSection }) => {
switch (item.type) {
case "screen":
navigation.dispatch(StackActions.push("SettingsGroup", item));
useNavigationStore.getState().update(
{
name: "SettingsGroup" as never,
title:
typeof item.name === "function"
? item.name(current)
: item.name
},
true
);
useNavigationStore.getState().update("Settings");
break;
case "switch":
onChangeSettings();

View File

@@ -27,6 +27,7 @@ import SettingsService from "../../services/settings";
import useNavigationStore from "../../stores/use-navigation-store";
import { useTagStore } from "../../stores/use-tag-store";
import { db } from "../../common/database";
import SelectionHeader from "../../components/selection-header";
export const Tags = ({ navigation, route }: NavigationProps<"Tags">) => {
const tags = useTagStore((state) => state.tags);
@@ -45,6 +46,7 @@ export const Tags = ({ navigation, route }: NavigationProps<"Tags">) => {
return (
<>
<SelectionHeader id={route.name} items={tags} type="tag" />
<Header
renderedInRoute={route.name}
title={route.name}

View File

@@ -30,6 +30,7 @@ import Navigation, { NavigationProps } from "../../services/navigation";
import useNavigationStore from "../../stores/use-navigation-store";
import { useSelectionStore } from "../../stores/use-selection-store";
import { useTrashStore } from "../../stores/use-trash-store";
import SelectionHeader from "../../components/selection-header";
const onPressFloatingButton = () => {
presentDialog({
@@ -87,6 +88,7 @@ export const Trash = ({ navigation, route }: NavigationProps<"Trash">) => {
return (
<>
<SelectionHeader id={route.name} items={trash} type="trash" />
<Header
renderedInRoute={route.name}
title={route.name}

View File

@@ -221,7 +221,10 @@ async function unlockVault() {
*
* @param {"txt" | "pdf" | "md" | "html" | "md-frontmatter"} type
*/
async function exportNote(note, type) {
async function exportNote(id, type) {
const note = await db.notes.note(id);
if (!note) return;
let content;
if (note.locked) {
@@ -283,7 +286,7 @@ function getUniqueFileName(fileName, results) {
*
* @param {"txt" | "pdf" | "md" | "html" | "md-frontmatter"} type
*/
async function bulkExport(notes, type, callback) {
async function bulkExport(ids, type, callback) {
let path = await getPath(FolderNames[type]);
if (!path) return;
@@ -309,9 +312,11 @@ async function bulkExport(notes, type, callback) {
};
const results = {};
for (var i = 0; i < notes.length; i++) {
for (var i = 0; i < ids.length; i++) {
try {
let note = notes[i];
let note = await db.notes.note(ids[i]);
if (!note) continue;
let content;
if (note.locked) {
try {
@@ -326,6 +331,7 @@ async function bulkExport(notes, type, callback) {
continue;
}
}
let result = await exportAs(type, note, true, content);
let fileName = sanitizeFilename(note.title, {
replacement: "_"
@@ -390,12 +396,12 @@ async function bulkExport(notes, type, callback) {
writeFile(`/${exportedNoteName}`, result);
}
}
callback(`${i + 1}/${notes.length}`);
callback(`${i + 1}/${ids.length}`);
} catch (e) {
DatabaseLogger.error(e);
}
}
const fileName = `nn-export-${notes.length}-${type}-${Date.now()}.zip`;
const fileName = `nn-export-${ids.length}-${type}-${Date.now()}.zip`;
try {
callback("zipping");

View File

@@ -30,11 +30,9 @@ 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 { eOnNewTopicAdded } from "../utils/events";
import { eOnRefreshSearch, eUpdateNotebookRoute } from "../utils/events";
import { rootNavigatorRef, tabBarRef } from "../utils/global-refs";
import { eSendEvent } from "./event-manager";
import SearchService from "./search";
import SettingsService from "./settings";
/**
* Routes that should be updated on focus
@@ -80,14 +78,14 @@ const routeUpdateFunctions: {
Tags: () => useTagStore.getState().setTags(),
Favorites: () => useFavoriteStore.getState().setFavorites(),
Trash: () => useTrashStore.getState().setTrash(),
Notebook: (params) => eSendEvent(eOnNewTopicAdded, params),
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().setReminders(),
Search: () => SearchService.updateAndSearch()
Search: () => eSendEvent(eOnRefreshSearch)
};
function clearRouteFromQueue(routeName: RouteName) {
@@ -124,6 +122,7 @@ function queueRoutesForUpdate(...routesToUpdate: RouteName[]) {
}
function navigate<T extends RouteName>(screen: T, params?: RouteParams[T]) {
console.log(`Navigation.navigate ${screen} route`);
rootNavigatorRef.current?.navigate(screen as any, params);
}
@@ -132,14 +131,17 @@ function 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, params));
}
function popToTop() {
console.log(`Navigation.popToTop`);
rootNavigatorRef.current?.dispatch(StackActions.popToTop());
}

View File

@@ -17,46 +17,48 @@ 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 { Item } from "@notesnook/core/dist/types";
import { ItemType } from "@notesnook/core";
import create, { State } from "zustand";
export interface SelectionStore extends State {
selectedItemsList: Array<unknown>;
selectionMode: boolean;
setAll: (all: Array<unknown>) => void;
setSelectionMode: (mode: boolean) => void;
setSelectedItem: (item: Item) => void;
selectedItemsList: Array<string>;
selectionMode?: ItemType;
setAll: (all: Array<string>) => void;
setSelectionMode: (mode?: ItemType) => void;
setSelectedItem: (item: string) => void;
clearSelection: () => void;
}
export const useSelectionStore = create<SelectionStore>((set, get) => ({
selectedItemsList: [],
selectionMode: false,
selectionMode: undefined,
setAll: (all) => {
set({ selectedItemsList: all });
},
setSelectionMode: (mode) => {
set({
selectionMode: mode,
selectedItemsList: mode ? get().selectedItemsList : []
selectedItemsList:
mode === get().selectionMode ? get().selectedItemsList : []
});
},
setSelectedItem: (item) => {
let selectedItems = get().selectedItemsList as Item[];
const index = selectedItems.findIndex((i) => (i as Item).id === item.id);
setSelectedItem: (id) => {
let selectedItems = get().selectedItemsList as string[];
const index = selectedItems.findIndex((i) => i === id);
if (index !== -1) {
selectedItems.splice(index, 1);
} else {
selectedItems.push(item);
selectedItems.push(id);
}
selectedItems = [...new Set(selectedItems)];
set({
selectedItemsList: selectedItems,
selectionMode: selectedItems.length === 0 ? false : get().selectionMode
selectionMode:
selectedItems.length === 0 ? undefined : get().selectionMode
});
},
clearSelection: () => {
set({ selectionMode: false, selectedItemsList: [] });
set({ selectionMode: undefined, selectedItemsList: [] });
}
}));

View File

@@ -69,7 +69,7 @@ export const eThemeUpdated = "527";
export const eScrollEvent = "528";
export const eOnNewTopicAdded = "529";
export const eUpdateNotebookRoute = "529";
export const eOpenVaultDialog = "530";
@@ -161,3 +161,5 @@ export const eUserLoggedIn = "608";
export const eLoginSessionExpired = "609";
export const eDBItemUpdate = "610";
export const eGroupOptionsUpdated = "611";
export const eOnRefreshSearch = "612";

View File

@@ -22,7 +22,6 @@ import { db } from "../common/database";
import { presentDialog } from "../components/dialog/functions";
import { eSendEvent, ToastManager } from "../services/event-manager";
import Navigation from "../services/navigation";
import SearchService from "../services/search";
import { useMenuStore } from "../stores/use-menu-store";
import { useRelationStore } from "../stores/use-relation-store";
import { useSelectionStore } from "../stores/use-selection-store";
@@ -75,35 +74,15 @@ async function deleteNotebook(id, deleteNotes) {
}
}
export const deleteItems = async (item, context) => {
if (item && db.monographs.isPublished(item.id)) {
ToastManager.show({
heading: "Can not delete note",
message: "Unpublish note to delete it",
type: "error",
context: "global"
});
return;
}
export const deleteItems = async (items, type, context) => {
const ids = items ? items : useSelectionStore.getState().selectedItemsList;
const itemsToDelete = item
? [item]
: useSelectionStore.getState().selectedItemsList;
let notes = itemsToDelete.filter((i) => i.type === "note");
let notebooks = itemsToDelete.filter((i) => i.type === "notebook");
let reminders = itemsToDelete.filter((i) => i.type === "reminder");
if (reminders.length > 0) {
for (let reminder of reminders) {
await db.reminders.remove(reminder.id);
}
if (type === "reminder") {
await db.reminders.remove(...ids);
useRelationStore.getState().update();
}
if (notes?.length > 0) {
for (const note of notes) {
if (db.monographs.isPublished(note.id)) {
} else if (type === "note") {
for (const id of ids) {
if (db.monographs.isPublished(id)) {
ToastManager.show({
heading: "Some notes are published",
message: "Unpublish published notes to delete them",
@@ -112,53 +91,54 @@ export const deleteItems = async (item, context) => {
});
continue;
}
await db.notes.delete(note.id);
await db.notes.moveToTrash(id);
}
eSendEvent(eClearEditor);
}
if (notebooks?.length > 0) {
const result = await confirmDeleteAllNotes(notebooks, "notebook", context);
} else if (type === "notebook") {
const result = await confirmDeleteAllNotes(ids, "notebook", context);
if (!result.delete) return;
for (const notebook of notebooks) {
await deleteNotebook(notebook.id, result.deleteNotes);
for (const id of ids) {
await deleteNotebook(id, result.deleteNotes);
eSendEvent(eOnNotebookUpdated, await getParentNotebookId(id));
}
}
let message = `${itemsToDelete.length} ${
itemsToDelete.length === 1 ? "item" : "items"
let message = `${ids.length} ${
ids.length === 1 ? "item" : "items"
} moved to trash.`;
let deletedItems = [...itemsToDelete];
if (reminders.length === 0 && (notes.length > 0 || notebooks.length > 0)) {
let deletedIds = [...ids];
if (type === "notebook" || type === "note") {
ToastManager.show({
heading: message,
type: "success",
func: async () => {
let trash = db.trash.all;
let ids = [];
for (var i = 0; i < deletedItems.length; i++) {
let it = deletedItems[i];
let trashItem = trash.find((item) => item.id === it.id);
ids.push(trashItem.id);
}
await db.trash.restore(...ids);
await db.trash.restore(...deletedIds);
Navigation.queueRoutesForUpdate();
useMenuStore.getState().setMenuPins();
useMenuStore.getState().setColorNotes();
ToastManager.hide();
if (type === "notebook") {
deletedIds.forEach(async (id) => {
eSendEvent(eOnNotebookUpdated, await getParentNotebookId(id));
});
}
},
actionText: "Undo"
});
}
Navigation.queueRoutesForUpdate();
if (!item) {
if (!items) {
useSelectionStore.getState().clearSelection();
}
useMenuStore.getState().setMenuPins();
useMenuStore.getState().setColorNotes();
SearchService.updateAndSearch();
if (type === "notebook") {
ids.forEach(async (id) => {
eSendEvent(eOnNotebookUpdated, await getParentNotebookId(id));
});
useMenuStore.getState().setMenuPins();
}
};
export const openLinkInBrowser = async (link) => {

View File

@@ -1,4 +1,24 @@
/*
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 { db } from "../common/database";
import { eSendEvent } from "../services/event-manager";
import { eOnNotebookUpdated } from "./events";
export async function findRootNotebookId(id: string) {
const relation = await db.relations
@@ -30,3 +50,10 @@ export async function getParentNotebookId(id: string) {
return relation?.[0]?.fromId;
}
export async function updateNotebook(id?: string) {
eSendEvent(eOnNotebookUpdated, id);
if (id) {
eSendEvent(eOnNotebookUpdated, await getParentNotebookId(id));
}
}

View File

@@ -8,6 +8,8 @@ import { SafeAreaProvider } from 'react-native-safe-area-context';
import appJson from './app.json';
import Notifications from "../app/services/notifications";
import NetInfo from "@react-native-community/netinfo";
import { enableFreeze } from "react-native-screens";
enableFreeze(true);
NetInfo.configure({
reachabilityUrl: "https://notesnook.com",
reachabilityTest: (response) => {

View File

@@ -22927,6 +22927,7 @@
},
"../../packages/editor/node_modules/react": {
"version": "17.0.2",
"dev": true,
"license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0",
@@ -22946,6 +22947,7 @@
},
"../../packages/editor/node_modules/react-dom": {
"version": "17.0.2",
"dev": true,
"license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0",
@@ -23072,6 +23074,7 @@
},
"../../packages/editor/node_modules/scheduler": {
"version": "0.20.2",
"dev": true,
"license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0",
@@ -25657,6 +25660,7 @@
},
"../../packages/theme/node_modules/loose-envify": {
"version": "1.4.0",
"dev": true,
"license": "MIT",
"dependencies": {
"js-tokens": "^3.0.0 || ^4.0.0"
@@ -25756,6 +25760,7 @@
},
"../../packages/theme/node_modules/react": {
"version": "17.0.2",
"dev": true,
"license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0",
@@ -26754,6 +26759,7 @@
},
"../../packages/ui/node_modules/react": {
"version": "17.0.2",
"dev": true,
"license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0",
@@ -26765,6 +26771,7 @@
},
"../../packages/ui/node_modules/react-dom": {
"version": "17.0.2",
"dev": true,
"license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0",
@@ -26828,6 +26835,7 @@
},
"../../packages/ui/node_modules/scheduler": {
"version": "0.20.2",
"dev": true,
"license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0",
@@ -30610,6 +30618,7 @@
},
"node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.22.5"
@@ -30623,6 +30632,7 @@
},
"node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.22.5",
@@ -30769,6 +30779,7 @@
},
"node_modules/@babel/plugin-proposal-private-property-in-object": {
"version": "7.21.0-placeholder-for-preset-env.2",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -30779,6 +30790,7 @@
},
"node_modules/@babel/plugin-proposal-unicode-property-regex": {
"version": "7.18.6",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.18.6",
@@ -30824,6 +30836,7 @@
},
"node_modules/@babel/plugin-syntax-class-static-block": {
"version": "7.14.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.14.5"
@@ -30860,6 +30873,7 @@
},
"node_modules/@babel/plugin-syntax-export-namespace-from": {
"version": "7.8.3",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.8.3"
@@ -30883,6 +30897,7 @@
},
"node_modules/@babel/plugin-syntax-import-assertions": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.22.5"
@@ -30896,6 +30911,7 @@
},
"node_modules/@babel/plugin-syntax-import-attributes": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.22.5"
@@ -30909,6 +30925,7 @@
},
"node_modules/@babel/plugin-syntax-import-meta": {
"version": "7.10.4",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.10.4"
@@ -30919,6 +30936,7 @@
},
"node_modules/@babel/plugin-syntax-json-strings": {
"version": "7.8.3",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.8.0"
@@ -30942,6 +30960,7 @@
},
"node_modules/@babel/plugin-syntax-logical-assignment-operators": {
"version": "7.10.4",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.10.4"
@@ -31002,6 +31021,7 @@
},
"node_modules/@babel/plugin-syntax-private-property-in-object": {
"version": "7.14.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.14.5"
@@ -31015,6 +31035,7 @@
},
"node_modules/@babel/plugin-syntax-top-level-await": {
"version": "7.14.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.14.5"
@@ -31041,6 +31062,7 @@
},
"node_modules/@babel/plugin-syntax-unicode-sets-regex": {
"version": "7.18.6",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.18.6",
@@ -31068,6 +31090,7 @@
},
"node_modules/@babel/plugin-transform-async-generator-functions": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-environment-visitor": "^7.22.5",
@@ -31125,6 +31148,7 @@
},
"node_modules/@babel/plugin-transform-class-properties": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-create-class-features-plugin": "^7.22.5",
@@ -31139,6 +31163,7 @@
},
"node_modules/@babel/plugin-transform-class-static-block": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-create-class-features-plugin": "^7.22.5",
@@ -31202,6 +31227,7 @@
},
"node_modules/@babel/plugin-transform-dotall-regex": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.22.5",
@@ -31216,6 +31242,7 @@
},
"node_modules/@babel/plugin-transform-duplicate-keys": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.22.5"
@@ -31229,6 +31256,7 @@
},
"node_modules/@babel/plugin-transform-dynamic-import": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.22.5",
@@ -31257,6 +31285,7 @@
},
"node_modules/@babel/plugin-transform-export-namespace-from": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.22.5",
@@ -31313,6 +31342,7 @@
},
"node_modules/@babel/plugin-transform-json-strings": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.22.5",
@@ -31340,6 +31370,7 @@
},
"node_modules/@babel/plugin-transform-logical-assignment-operators": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.22.5",
@@ -31367,6 +31398,7 @@
},
"node_modules/@babel/plugin-transform-modules-amd": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-module-transforms": "^7.22.5",
@@ -31396,6 +31428,7 @@
},
"node_modules/@babel/plugin-transform-modules-systemjs": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-hoist-variables": "^7.22.5",
@@ -31412,6 +31445,7 @@
},
"node_modules/@babel/plugin-transform-modules-umd": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-module-transforms": "^7.22.5",
@@ -31440,6 +31474,7 @@
},
"node_modules/@babel/plugin-transform-new-target": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.22.5"
@@ -31453,6 +31488,7 @@
},
"node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.22.5",
@@ -31467,6 +31503,7 @@
},
"node_modules/@babel/plugin-transform-numeric-separator": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.22.5",
@@ -31494,6 +31531,7 @@
},
"node_modules/@babel/plugin-transform-object-rest-spread": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/compat-data": "^7.22.5",
@@ -31525,6 +31563,7 @@
},
"node_modules/@babel/plugin-transform-optional-catch-binding": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.22.5",
@@ -31539,6 +31578,7 @@
},
"node_modules/@babel/plugin-transform-optional-chaining": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.22.5",
@@ -31581,6 +31621,7 @@
},
"node_modules/@babel/plugin-transform-private-property-in-object": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-annotate-as-pure": "^7.22.5",
@@ -31680,6 +31721,7 @@
},
"node_modules/@babel/plugin-transform-reserved-words": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.22.5"
@@ -31771,6 +31813,7 @@
},
"node_modules/@babel/plugin-transform-typeof-symbol": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.22.5"
@@ -31800,6 +31843,7 @@
},
"node_modules/@babel/plugin-transform-unicode-escapes": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.22.5"
@@ -31813,6 +31857,7 @@
},
"node_modules/@babel/plugin-transform-unicode-property-regex": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.22.5",
@@ -31841,6 +31886,7 @@
},
"node_modules/@babel/plugin-transform-unicode-sets-regex": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-create-regexp-features-plugin": "^7.22.5",
@@ -31855,6 +31901,7 @@
},
"node_modules/@babel/preset-env": {
"version": "7.22.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/compat-data": "^7.22.5",
@@ -31947,6 +31994,7 @@
},
"node_modules/@babel/preset-env/node_modules/semver": {
"version": "6.3.0",
"dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -31969,6 +32017,7 @@
},
"node_modules/@babel/preset-modules": {
"version": "0.1.5",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-plugin-utils": "^7.0.0",
@@ -34581,6 +34630,7 @@
},
"node_modules/@types/eslint": {
"version": "8.40.2",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/estree": "*",
@@ -34589,6 +34639,7 @@
},
"node_modules/@types/eslint-scope": {
"version": "3.7.4",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/eslint": "*",
@@ -34597,6 +34648,7 @@
},
"node_modules/@types/estree": {
"version": "1.0.1",
"dev": true,
"license": "MIT"
},
"node_modules/@types/graceful-fs": {
@@ -35045,6 +35097,7 @@
},
"node_modules/@webassemblyjs/ast": {
"version": "1.11.6",
"dev": true,
"license": "MIT",
"dependencies": {
"@webassemblyjs/helper-numbers": "1.11.6",
@@ -35053,18 +35106,22 @@
},
"node_modules/@webassemblyjs/floating-point-hex-parser": {
"version": "1.11.6",
"dev": true,
"license": "MIT"
},
"node_modules/@webassemblyjs/helper-api-error": {
"version": "1.11.6",
"dev": true,
"license": "MIT"
},
"node_modules/@webassemblyjs/helper-buffer": {
"version": "1.11.6",
"dev": true,
"license": "MIT"
},
"node_modules/@webassemblyjs/helper-numbers": {
"version": "1.11.6",
"dev": true,
"license": "MIT",
"dependencies": {
"@webassemblyjs/floating-point-hex-parser": "1.11.6",
@@ -35074,10 +35131,12 @@
},
"node_modules/@webassemblyjs/helper-wasm-bytecode": {
"version": "1.11.6",
"dev": true,
"license": "MIT"
},
"node_modules/@webassemblyjs/helper-wasm-section": {
"version": "1.11.6",
"dev": true,
"license": "MIT",
"dependencies": {
"@webassemblyjs/ast": "1.11.6",
@@ -35088,6 +35147,7 @@
},
"node_modules/@webassemblyjs/ieee754": {
"version": "1.11.6",
"dev": true,
"license": "MIT",
"dependencies": {
"@xtuc/ieee754": "^1.2.0"
@@ -35095,6 +35155,7 @@
},
"node_modules/@webassemblyjs/leb128": {
"version": "1.11.6",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@xtuc/long": "4.2.2"
@@ -35102,10 +35163,12 @@
},
"node_modules/@webassemblyjs/utf8": {
"version": "1.11.6",
"dev": true,
"license": "MIT"
},
"node_modules/@webassemblyjs/wasm-edit": {
"version": "1.11.6",
"dev": true,
"license": "MIT",
"dependencies": {
"@webassemblyjs/ast": "1.11.6",
@@ -35120,6 +35183,7 @@
},
"node_modules/@webassemblyjs/wasm-gen": {
"version": "1.11.6",
"dev": true,
"license": "MIT",
"dependencies": {
"@webassemblyjs/ast": "1.11.6",
@@ -35131,6 +35195,7 @@
},
"node_modules/@webassemblyjs/wasm-opt": {
"version": "1.11.6",
"dev": true,
"license": "MIT",
"dependencies": {
"@webassemblyjs/ast": "1.11.6",
@@ -35141,6 +35206,7 @@
},
"node_modules/@webassemblyjs/wasm-parser": {
"version": "1.11.6",
"dev": true,
"license": "MIT",
"dependencies": {
"@webassemblyjs/ast": "1.11.6",
@@ -35153,6 +35219,7 @@
},
"node_modules/@webassemblyjs/wast-printer": {
"version": "1.11.6",
"dev": true,
"license": "MIT",
"dependencies": {
"@webassemblyjs/ast": "1.11.6",
@@ -35210,10 +35277,12 @@
},
"node_modules/@xtuc/ieee754": {
"version": "1.2.0",
"dev": true,
"license": "BSD-3-Clause"
},
"node_modules/@xtuc/long": {
"version": "4.2.2",
"dev": true,
"license": "Apache-2.0"
},
"node_modules/@yarnpkg/lockfile": {
@@ -35269,6 +35338,7 @@
},
"node_modules/acorn-import-assertions": {
"version": "1.9.0",
"dev": true,
"license": "MIT",
"peerDependencies": {
"acorn": "^8"
@@ -36370,6 +36440,7 @@
},
"node_modules/chrome-trace-event": {
"version": "1.0.3",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0"
@@ -37431,6 +37502,7 @@
},
"node_modules/enhanced-resolve": {
"version": "5.15.0",
"dev": true,
"license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.4",
@@ -37543,6 +37615,7 @@
},
"node_modules/es-module-lexer": {
"version": "1.3.0",
"dev": true,
"license": "MIT"
},
"node_modules/es-set-tostringtag": {
@@ -37873,6 +37946,7 @@
},
"node_modules/eslint-scope": {
"version": "5.1.1",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"esrecurse": "^4.3.0",
@@ -37884,6 +37958,7 @@
},
"node_modules/eslint-scope/node_modules/estraverse": {
"version": "4.3.0",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=4.0"
@@ -38069,6 +38144,7 @@
},
"node_modules/esrecurse": {
"version": "4.3.0",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"estraverse": "^5.2.0"
@@ -38079,6 +38155,7 @@
},
"node_modules/estraverse": {
"version": "5.3.0",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=4.0"
@@ -38086,6 +38163,7 @@
},
"node_modules/esutils": {
"version": "2.0.3",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.10.0"
@@ -39138,6 +39216,7 @@
},
"node_modules/glob-to-regexp": {
"version": "0.4.1",
"dev": true,
"license": "BSD-2-Clause"
},
"node_modules/global": {
@@ -41375,6 +41454,7 @@
},
"node_modules/json-parse-even-better-errors": {
"version": "2.3.1",
"dev": true,
"license": "MIT"
},
"node_modules/json-schema-traverse": {
@@ -41641,6 +41721,7 @@
},
"node_modules/loader-runner": {
"version": "4.3.0",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.11.5"
@@ -44263,6 +44344,7 @@
},
"node_modules/randombytes": {
"version": "2.1.0",
"dev": true,
"license": "MIT",
"dependencies": {
"safe-buffer": "^5.1.0"
@@ -44312,28 +44394,6 @@
}
}
},
"node_modules/react-dom": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
"integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.0"
},
"peerDependencies": {
"react": "^18.2.0"
}
},
"node_modules/react-dom/node_modules/scheduler": {
"version": "0.23.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
"integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0"
}
},
"node_modules/react-freeze": {
"version": "1.0.3",
"license": "MIT",
@@ -45020,6 +45080,7 @@
},
"node_modules/react-test-renderer": {
"version": "18.2.0",
"dev": true,
"license": "MIT",
"dependencies": {
"react-is": "^18.2.0",
@@ -45032,10 +45093,12 @@
},
"node_modules/react-test-renderer/node_modules/react-is": {
"version": "18.2.0",
"dev": true,
"license": "MIT"
},
"node_modules/react-test-renderer/node_modules/scheduler": {
"version": "0.23.0",
"dev": true,
"license": "MIT",
"dependencies": {
"loose-envify": "^1.1.0"
@@ -45870,6 +45933,7 @@
},
"node_modules/serialize-javascript": {
"version": "6.0.1",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
"randombytes": "^2.1.0"
@@ -46924,6 +46988,7 @@
},
"node_modules/terser-webpack-plugin": {
"version": "5.3.9",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/trace-mapping": "^0.3.17",
@@ -46956,6 +47021,7 @@
},
"node_modules/terser-webpack-plugin/node_modules/jest-worker": {
"version": "27.5.1",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*",
@@ -46968,6 +47034,7 @@
},
"node_modules/terser-webpack-plugin/node_modules/supports-color": {
"version": "8.1.1",
"dev": true,
"license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
@@ -47721,6 +47788,7 @@
},
"node_modules/watchpack": {
"version": "2.4.0",
"dev": true,
"license": "MIT",
"dependencies": {
"glob-to-regexp": "^0.4.1",
@@ -47743,6 +47811,7 @@
},
"node_modules/webpack": {
"version": "5.88.2",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/eslint-scope": "^3.7.3",
@@ -47857,6 +47926,7 @@
},
"node_modules/webpack-sources": {
"version": "3.2.3",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10.13.0"

View File

@@ -1,3 +1,14 @@
diff --git a/node_modules/react-native-vector-icons/android/build/.transforms/9469767ddf733a51f4497b9a4a4c145a/results.bin b/node_modules/react-native-vector-icons/android/build/.transforms/9469767ddf733a51f4497b9a4a4c145a/results.bin
new file mode 100644
index 0000000..0d259dd
--- /dev/null
+++ b/node_modules/react-native-vector-icons/android/build/.transforms/9469767ddf733a51f4497b9a4a4c145a/results.bin
@@ -0,0 +1 @@
+o/classes
diff --git a/node_modules/react-native-vector-icons/android/build/.transforms/9469767ddf733a51f4497b9a4a4c145a/transformed/classes/classes.dex b/node_modules/react-native-vector-icons/android/build/.transforms/9469767ddf733a51f4497b9a4a4c145a/transformed/classes/classes.dex
new file mode 100644
index 0000000..d4bdd72
Binary files /dev/null and b/node_modules/react-native-vector-icons/android/build/.transforms/9469767ddf733a51f4497b9a4a4c145a/transformed/classes/classes.dex differ
diff --git a/node_modules/react-native-vector-icons/android/build/.transforms/f1314fc28eaff1170375cbb76465cb24/results.bin b/node_modules/react-native-vector-icons/android/build/.transforms/f1314fc28eaff1170375cbb76465cb24/results.bin
new file mode 100644
index 0000000..0d259dd
@@ -7,8 +18,7 @@ index 0000000..0d259dd
+o/classes
diff --git a/node_modules/react-native-vector-icons/android/build/.transforms/f1314fc28eaff1170375cbb76465cb24/transformed/classes/classes.dex b/node_modules/react-native-vector-icons/android/build/.transforms/f1314fc28eaff1170375cbb76465cb24/transformed/classes/classes.dex
new file mode 100644
index 0000000..d4bdd72
Binary files /dev/null and b/node_modules/react-native-vector-icons/android/build/.transforms/f1314fc28eaff1170375cbb76465cb24/transformed/classes/classes.dex differ
index 0000000..e69de29
diff --git a/node_modules/react-native-vector-icons/android/build/generated/source/buildConfig/debug/com/oblador/vectoricons/BuildConfig.java b/node_modules/react-native-vector-icons/android/build/generated/source/buildConfig/debug/com/oblador/vectoricons/BuildConfig.java
new file mode 100644
index 0000000..52a02e0
@@ -2053,46 +2063,46 @@ index 0000000..5347f17
+int xml rn_dev_preferences 0x0
diff --git a/node_modules/react-native-vector-icons/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties b/node_modules/react-native-vector-icons/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties
new file mode 100644
index 0000000..c671bf3
index 0000000..aca2293
--- /dev/null
+++ b/node_modules/react-native-vector-icons/android/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties
@@ -0,0 +1 @@
+#Mon Oct 02 09:47:12 PKT 2023
+#Thu Nov 23 08:23:53 PKT 2023
diff --git a/node_modules/react-native-vector-icons/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml b/node_modules/react-native-vector-icons/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml
new file mode 100644
index 0000000..08d62cc
index 0000000..c417283
--- /dev/null
+++ b/node_modules/react-native-vector-icons/android/build/intermediates/incremental/debug/packageDebugResources/merger.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merger version="3"><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="main$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/res"/><source path="/Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/build/generated/res/rs/debug"/><source path="/Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/build/generated/res/resValues/debug"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="main" generated-set="main$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/res"/><source path="/Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/build/generated/res/rs/debug"/><source path="/Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/build/generated/res/resValues/debug"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="debug$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/debug/res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="debug" generated-set="debug$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/debug/res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="generated$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"/><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="generated" generated-set="generated$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"/><mergedItems/></merger>
+<merger version="3"><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="main$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/res"/><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/build/generated/res/rs/debug"/><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/build/generated/res/resValues/debug"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="main" generated-set="main$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/res"/><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/build/generated/res/rs/debug"/><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/build/generated/res/resValues/debug"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="debug$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/debug/res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="debug" generated-set="debug$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/debug/res"/></dataSet><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="generated$Generated" generated="true" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"/><dataSet aapt-namespace="http://schemas.android.com/apk/res-auto" config="generated" generated-set="generated$Generated" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"/><mergedItems/></merger>
\ No newline at end of file
diff --git a/node_modules/react-native-vector-icons/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml b/node_modules/react-native-vector-icons/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml
new file mode 100644
index 0000000..12fc555
index 0000000..994a515
--- /dev/null
+++ b/node_modules/react-native-vector-icons/android/build/intermediates/incremental/mergeDebugJniLibFolders/merger.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/jniLibs"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/debug/jniLibs"/></dataSet></merger>
+<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/jniLibs"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/debug/jniLibs"/></dataSet></merger>
\ No newline at end of file
diff --git a/node_modules/react-native-vector-icons/android/build/intermediates/incremental/mergeDebugShaders/merger.xml b/node_modules/react-native-vector-icons/android/build/intermediates/incremental/mergeDebugShaders/merger.xml
new file mode 100644
index 0000000..7d757a3
index 0000000..75b5b1a
--- /dev/null
+++ b/node_modules/react-native-vector-icons/android/build/intermediates/incremental/mergeDebugShaders/merger.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/shaders"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/debug/shaders"/></dataSet></merger>
+<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/shaders"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/debug/shaders"/></dataSet></merger>
\ No newline at end of file
diff --git a/node_modules/react-native-vector-icons/android/build/intermediates/incremental/packageDebugAssets/merger.xml b/node_modules/react-native-vector-icons/android/build/intermediates/incremental/packageDebugAssets/merger.xml
new file mode 100644
index 0000000..ef96fe3
index 0000000..9b07b6e
--- /dev/null
+++ b/node_modules/react-native-vector-icons/android/build/intermediates/incremental/packageDebugAssets/merger.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/assets"/><source path="/Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/build/intermediates/shader_assets/debug/out"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/debug/assets"/></dataSet></merger>
+<merger version="3"><dataSet config="main" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/assets"/><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/build/intermediates/shader_assets/debug/out"/></dataSet><dataSet config="debug" ignore_pattern="!.svn:!.git:!.ds_store:!*.scc:.*:&lt;dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"><source path="/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/debug/assets"/></dataSet></merger>
\ No newline at end of file
diff --git a/node_modules/react-native-vector-icons/android/build/intermediates/javac/debug/classes/com/oblador/vectoricons/BuildConfig.class b/node_modules/react-native-vector-icons/android/build/intermediates/javac/debug/classes/com/oblador/vectoricons/BuildConfig.class
new file mode 100644
@@ -2120,7 +2130,7 @@ index 0000000..78ac5b8
+local
diff --git a/node_modules/react-native-vector-icons/android/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt b/node_modules/react-native-vector-icons/android/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt
new file mode 100644
index 0000000..8462a2c
index 0000000..d91dbc1
--- /dev/null
+++ b/node_modules/react-native-vector-icons/android/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt
@@ -0,0 +1,8 @@
@@ -2129,7 +2139,7 @@ index 0000000..8462a2c
+3 package="com.oblador.vectoricons" >
+4
+5 <uses-sdk android:minSdkVersion="21" />
+5-->/Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
+5-->/Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
+6
+7</manifest>
diff --git a/node_modules/react-native-vector-icons/android/build/intermediates/merged_manifest/debug/AndroidManifest.xml b/node_modules/react-native-vector-icons/android/build/intermediates/merged_manifest/debug/AndroidManifest.xml
@@ -3638,35 +3648,35 @@ index 0000000..873e0a9
+xml rn_dev_preferences
diff --git a/node_modules/react-native-vector-icons/android/build/outputs/logs/manifest-merger-debug-report.txt b/node_modules/react-native-vector-icons/android/build/outputs/logs/manifest-merger-debug-report.txt
new file mode 100644
index 0000000..f4f75c1
index 0000000..3d2b28a
--- /dev/null
+++ b/node_modules/react-native-vector-icons/android/build/outputs/logs/manifest-merger-debug-report.txt
@@ -0,0 +1,25 @@
+-- Merging decision tree log ---
+manifest
+ADDED from /Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml:1:1-2:12
+INJECTED from /Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml:1:1-2:12
+INJECTED from /Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml:1:1-2:12
+ADDED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml:1:1-2:12
+INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml:1:1-2:12
+INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml:1:1-2:12
+ package
+ ADDED from /Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml:1:70-103
+ INJECTED from /Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
+ INJECTED from /Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
+ ADDED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml:1:70-103
+ INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
+ INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
+ xmlns:android
+ ADDED from /Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml:1:11-69
+ ADDED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml:1:11-69
+uses-sdk
+INJECTED from /Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml reason: use-sdk injection requested
+INJECTED from /Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
+INJECTED from /Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
+INJECTED from /Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
+INJECTED from /Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
+INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml reason: use-sdk injection requested
+INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
+INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
+INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
+INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
+ android:targetSdkVersion
+ INJECTED from /Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
+ ADDED from /Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
+ INJECTED from /Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
+ INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
+ ADDED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
+ INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
+ android:minSdkVersion
+ INJECTED from /Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
+ ADDED from /Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
+ INJECTED from /Users/ammarahmed/Repos/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
+ INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
+ ADDED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
+ INJECTED from /Volumes/DataDrive/Projects/apps/notesnook/apps/mobile/node_modules/react-native-vector-icons/android/src/main/AndroidManifest.xml
diff --git a/node_modules/react-native-vector-icons/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin b/node_modules/react-native-vector-icons/android/build/tmp/compileDebugJavaWithJavac/previous-compilation-data.bin
new file mode 100644
index 0000000..26da0e3
@@ -3687,7 +3697,7 @@ index 5485fac..ef3ccb3 100644
generateAssetsTask.dependsOn(fontCopyTask)
}
diff --git a/node_modules/react-native-vector-icons/glyphmaps/MaterialCommunityIcons.json b/node_modules/react-native-vector-icons/glyphmaps/MaterialCommunityIcons.json
index c06a819..13c76cc 100644
index c06a819..42f1a6d 100644
--- a/node_modules/react-native-vector-icons/glyphmaps/MaterialCommunityIcons.json
+++ b/node_modules/react-native-vector-icons/glyphmaps/MaterialCommunityIcons.json
@@ -1,6598 +1 @@
@@ -10290,7 +10300,7 @@ index c06a819..13c76cc 100644
- "blank": 63116
-}
\ No newline at end of file
+{"menu":983900,"lock-open-outline":983872,"key-outline":986582,"pin-off-outline":985392,"pin-outline":985393,"star-off":984273,"star-outline":984274,"link-variant-remove":987393,"link-variant":983865,"bell":983194,"bell-off-outline":985745,"check":983340,"magnify":983881,"plus":984085,"view-list-outline":988299,"view-list":984434,"play":984074,"pause":984036,"notebook-outline":986815,"text-short":985513,"radiobox-marked":984126,"radiobox-blank":984125,"sort-descending":984253,"information":983804,"sort-ascending":984252,"alert":983078,"arrow-right":983124,"bookmark-outline":983235,"checkbox-marked":983346,"checkbox-blank-outline":983345,"unfold-less-horizontal":984398,"minus-circle":983926,"vibrate":984422,"volume-high":984446,"checkbox-blank-circle-outline":983344,"check-circle-outline":984545,"chevron-up":983363,"chevron-down":983360,"calendar":983277,"minus-circle-outline":983927,"close-circle-outline":983386,"qrcode":984114,"text":985512,"cloud":983391,"book-outline":985956,"pound":984099,"clock-plus-outline":989282,"cloud-upload-outline":985982,"export":983559,"message-badge-outline":989506,"square-edit-outline":985356,"content-copy":983439,"delete-restore":985113,"share-variant":984215,"pencil-lock":984046,"sync-off":984296,"content-duplicate":983441,"theme-light-dark":984334,"pencil":984043,"clock-outline":983376,"attachment":983142,"history":983770,"notebook":985134,"bookmark":983232,"delete-outline":985575,"delete":983476,"link":983863,"cloud-upload":983399,"star":984270,"key":983814,"account-outline":983059,"email":983534,"backup-restore":983151,"update":984752,"android":983090,"web":984479,"home-variant-outline":986023,"text-box-multiple-outline":985784,"download":983514,"arrow-left":983117,"dots-horizontal":983512,"chevron-right":983362,"close":983382,"cellphone-key":985422,"message-plus-outline":987323,"email-outline":983536,"shield-lock":985501,"chevron-left":983361,"minus":983924,"crown":983461,"account-cog":988016,"two-factor-authentication":985519,"information-outline":983805,"logout":983875,"autorenew":983146,"sync-alert":984295,"shape":985137,"circle-half":988053,"brightness-6":983263,"note-edit-outline":989058,"format-line-spacing":983672,"format-size":983679,"format-font":984790,"radar":984119,"arrow-decision-outline":985534,"fingerprint":983607,"eye-off-outline":984785,"folder":983627,"lock":983870,"form-textbox":984590,"bell-outline":983196,"bell-ring":983198,"bug":983268,"mail":986811,"file-document":983577,"mastodon":985809,"twitter":984388,"discord":984687,"open-source-initiative":986030,"monitor":983929,"chart-timeline":984686,"cellphone-arrow-down":985557,"alpha-v":985859,"circle-small":985567,"upload":984402,"file-check":983574,"file":983572,"alert-circle-outline":984534,"check-all":983341,"shield-key-outline":986053,"dots-vertical":983513,"emoticon-wink":986232,"sync":984294,"shield":984216,"billboard":987152,"cellphone":983324,"cellphone-lock":985423,"file-lock":983585,"image-multiple":983801,"harddisk":983754,"file-cabinet":985782,"refresh":984144,"emoticon":986216,"palette":984024,"pin":984067,"format-bold":983652,"table":984299,"language-markdown":983892,"gesture-tap-button":987816,"send-lock":985069,"bomb":984721,"file-pdf-box":983590,"language-html5":983837,"clipboard-text-outline":985656,"invert-colors":983809,"select-all":984198,"cog-outline":985275,"arrow-top-right-thick":985542,"checkbox-blank-circle":983343,"note":983962,"drag":983515,"menu-down":983901,"alert-circle":983080,"reload":984147,"card-text":985975,"open-in-new":984012,"eye":983560}
+{"menu":983900,"lock-open-outline":983872,"key-outline":986582,"pin-off-outline":985392,"pin-outline":985393,"star-off":984273,"star-outline":984274,"link-variant-remove":987393,"link-variant":983865,"bell":983194,"bell-off-outline":985745,"check":983340,"magnify":983881,"plus":984085,"view-list-outline":988299,"view-list":984434,"play":984074,"pause":984036,"notebook-outline":986815,"text-short":985513,"radiobox-marked":984126,"radiobox-blank":984125,"sort-descending":984253,"information":983804,"sort-ascending":984252,"alert":983078,"arrow-right":983124,"bookmark-outline":983235,"checkbox-marked":983346,"checkbox-blank-outline":983345,"unfold-less-horizontal":984398,"minus-circle":983926,"vibrate":984422,"volume-high":984446,"checkbox-blank-circle-outline":983344,"check-circle-outline":984545,"chevron-up":983363,"chevron-down":983360,"calendar":983277,"minus-circle-outline":983927,"close-circle-outline":983386,"qrcode":984114,"text":985512,"cloud":983391,"restore":985499,"delete-outline":985575,"link":983863,"square-edit-outline":985356,"pencil":984043,"delete-restore":985113,"delete":983476,"notebook":985134,"attachment":983142,"history":983770,"clock-outline":983376,"content-copy":983439,"share-variant":984215,"pencil-lock":984046,"sync-off":984296,"content-duplicate":983441,"clock-plus-outline":989282,"cloud-upload-outline":985982,"export":983559,"message-badge-outline":989506,"book-outline":985956,"pound":984099,"cloud-upload":983399,"star":984270,"key":983814,"account-outline":983059,"email":983534,"backup-restore":983151,"update":984752,"android":983090,"web":984479,"home-variant-outline":986023,"text-box-multiple-outline":985784,"download":983514,"circle-small":985567,"fingerprint":983607,"upload":984402,"file-check":983574,"form-textbox":984590,"file":983572,"alert-circle-outline":984534,"check-all":983341,"shield-key-outline":986053,"arrow-left":983117,"message-plus-outline":987323,"email-outline":983536,"cellphone-key":985422,"dots-vertical":983513,"close":983382,"chevron-right":983362,"emoticon-wink":986232,"sync":984294,"shield":984216,"billboard":987152,"cellphone":983324,"cellphone-lock":985423,"lock":983870,"file-lock":983585,"image-multiple":983801,"harddisk":983754,"file-cabinet":985782,"refresh":984144,"emoticon":986216,"palette":984024,"pin":984067,"format-bold":983652,"table":984299,"language-markdown":983892,"gesture-tap-button":987816,"send-lock":985069,"bomb":984721,"file-pdf-box":983590,"language-html5":983837,"clipboard-text-outline":985656,"theme-light-dark":984334,"invert-colors":983809,"crown":983461,"select-all":984198,"minus":983924,"information-outline":983805,"cog-outline":985275,"arrow-top-right-thick":985542,"checkbox-blank-circle":983343,"sync-alert":984295,"bookmark":983232,"note":983962,"dots-horizontal":983512,"shield-lock":985501,"chevron-left":983361,"account-cog":988016,"two-factor-authentication":985519,"logout":983875,"autorenew":983146,"shape":985137,"circle-half":988053,"brightness-6":983263,"note-edit-outline":989058,"format-line-spacing":983672,"format-size":983679,"format-font":984790,"radar":984119,"arrow-decision-outline":985534,"eye-off-outline":984785,"folder":983627,"bell-outline":983196,"bell-ring":983198,"bug":983268,"mail":986811,"file-document":983577,"mastodon":985809,"twitter":984388,"discord":984687,"open-source-initiative":986030,"monitor":983929,"chart-timeline":984686,"cellphone-arrow-down":985557,"alpha-v":985859,"alert-circle":983080,"reload":984147,"card-text":985975,"open-in-new":984012,"eye":983560,"drag":983515,"menu-down":983901}
\ No newline at end of file
diff --git a/node_modules/react-native-vector-icons/glyphmaps/MaterialCommunityIcons.old.json b/node_modules/react-native-vector-icons/glyphmaps/MaterialCommunityIcons.old.json
new file mode 100644

View File

@@ -70,7 +70,8 @@ const EXTRA_ICON_NAMES = [
"close-circle-outline",
"qrcode",
"text",
"cloud"
"cloud",
"restore"
];
const __filename = fileURLToPath(import.meta.url);

View File

@@ -59,7 +59,7 @@ export default class Lookup {
)
.selectFrom("notes")
.$if(!!noteIds && noteIds.length > 0, (eb) =>
eb.where("id", "in", noteIds!)
eb.where("notes.id", "in", noteIds!)
)
.$if(!!limit, (eb) => eb.limit(limit!))
.where(isFalse("notes.deleted"))