mirror of
https://github.com/streetwriters/notesnook.git
synced 2025-12-16 19:57:52 +01:00
mobile: support vault notes in tabs
This commit is contained in:
committed by
Abdullah Atta
parent
2ce31fc81c
commit
c33c365b62
@@ -23,7 +23,6 @@ import { InteractionManager, View } from "react-native";
|
|||||||
import Share from "react-native-share";
|
import Share from "react-native-share";
|
||||||
import { notesnook } from "../../../../e2e/test.ids";
|
import { notesnook } from "../../../../e2e/test.ids";
|
||||||
import { db } from "../../../common/database";
|
import { db } from "../../../common/database";
|
||||||
import { editorController } from "../../../screens/editor/tiptap/utils";
|
|
||||||
import BiometricService from "../../../services/biometrics";
|
import BiometricService from "../../../services/biometrics";
|
||||||
import { DDS } from "../../../services/device-detection";
|
import { DDS } from "../../../services/device-detection";
|
||||||
import {
|
import {
|
||||||
@@ -35,7 +34,6 @@ import {
|
|||||||
import Navigation from "../../../services/navigation";
|
import Navigation from "../../../services/navigation";
|
||||||
import { getElevationStyle } from "../../../utils/elevation";
|
import { getElevationStyle } from "../../../utils/elevation";
|
||||||
import {
|
import {
|
||||||
eClearEditor,
|
|
||||||
eCloseActionSheet,
|
eCloseActionSheet,
|
||||||
eCloseVaultDialog,
|
eCloseVaultDialog,
|
||||||
eOnLoadNote,
|
eOnLoadNote,
|
||||||
|
|||||||
@@ -69,17 +69,6 @@ export const openNote = async (
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (await db.vaults.itemExists(note)) {
|
|
||||||
openVault({
|
|
||||||
item: note,
|
|
||||||
novault: true,
|
|
||||||
locked: true,
|
|
||||||
goToEditor: true,
|
|
||||||
title: "Open note",
|
|
||||||
description: "Unlock note to open it in editor."
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (isTrash) {
|
if (isTrash) {
|
||||||
if (!note.contentId) return;
|
if (!note.contentId) return;
|
||||||
|
|
||||||
|
|||||||
@@ -22,18 +22,21 @@ import { View } from "react-native";
|
|||||||
import { useDBItem } from "../../../hooks/use-db-item";
|
import { useDBItem } from "../../../hooks/use-db-item";
|
||||||
import { useTabStore } from "../../../screens/editor/tiptap/use-tab-store";
|
import { useTabStore } from "../../../screens/editor/tiptap/use-tab-store";
|
||||||
import { editorController } from "../../../screens/editor/tiptap/utils";
|
import { editorController } from "../../../screens/editor/tiptap/utils";
|
||||||
import { presentSheet } from "../../../services/event-manager";
|
import { eSendEvent, presentSheet } from "../../../services/event-manager";
|
||||||
import { SIZE } from "../../../utils/size";
|
import { SIZE } from "../../../utils/size";
|
||||||
import { Button } from "../../ui/button";
|
import { Button } from "../../ui/button";
|
||||||
import { IconButton } from "../../ui/icon-button";
|
import { IconButton } from "../../ui/icon-button";
|
||||||
import { PressableButton } from "../../ui/pressable";
|
import { PressableButton } from "../../ui/pressable";
|
||||||
import Heading from "../../ui/typography/heading";
|
import Heading from "../../ui/typography/heading";
|
||||||
import Paragraph from "../../ui/typography/paragraph";
|
import Paragraph from "../../ui/typography/paragraph";
|
||||||
|
import { eUnlockNote } from "../../../utils/events";
|
||||||
|
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
|
||||||
|
|
||||||
type TabItem = {
|
type TabItem = {
|
||||||
id: number;
|
id: number;
|
||||||
noteId?: string;
|
noteId?: string;
|
||||||
previewTab?: boolean;
|
previewTab?: boolean;
|
||||||
|
locked?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const TabItemComponent = (props: {
|
const TabItemComponent = (props: {
|
||||||
@@ -58,6 +61,9 @@ const TabItemComponent = (props: {
|
|||||||
if (!props.isFocused) {
|
if (!props.isFocused) {
|
||||||
useTabStore.getState().focusTab(props.tab.id);
|
useTabStore.getState().focusTab(props.tab.id);
|
||||||
props.close?.();
|
props.close?.();
|
||||||
|
if (props.tab.locked) {
|
||||||
|
eSendEvent(eUnlockNote);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onLongPress={() => {
|
onLongPress={() => {
|
||||||
@@ -70,9 +76,11 @@ const TabItemComponent = (props: {
|
|||||||
style={{
|
style={{
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "flex-start"
|
justifyContent: "flex-start",
|
||||||
|
gap: 10
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
{props.tab.locked ? <Icon size={SIZE.md} name="lock" /> : null}
|
||||||
<Paragraph
|
<Paragraph
|
||||||
color={
|
color={
|
||||||
props.isFocused
|
props.isFocused
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ import {
|
|||||||
eLoginSessionExpired,
|
eLoginSessionExpired,
|
||||||
eOnLoadNote,
|
eOnLoadNote,
|
||||||
eOpenAnnouncementDialog,
|
eOpenAnnouncementDialog,
|
||||||
|
eUnlockNote,
|
||||||
eUserLoggedIn,
|
eUserLoggedIn,
|
||||||
refreshNotesPage
|
refreshNotesPage
|
||||||
} from "../utils/events";
|
} from "../utils/events";
|
||||||
@@ -464,6 +465,27 @@ export const useAppEvents = () => {
|
|||||||
EV.subscribe(EVENTS.uploadCanceled, (data) => {
|
EV.subscribe(EVENTS.uploadCanceled, (data) => {
|
||||||
useAttachmentStore.getState().setUploading(data);
|
useAttachmentStore.getState().setUploading(data);
|
||||||
}),
|
}),
|
||||||
|
EV.subscribe(EVENTS.vaultLocked, async () => {
|
||||||
|
// Lock all notes in all tabs...
|
||||||
|
for (const tab of useTabStore.getState().tabs) {
|
||||||
|
const noteId = useTabStore.getState().getTab(tab.id)?.noteId;
|
||||||
|
if (!noteId) continue;
|
||||||
|
const note = await db.notes.note(noteId);
|
||||||
|
if (note?.locked) {
|
||||||
|
useTabStore.getState().updateTab(tab.id, {
|
||||||
|
locked: true
|
||||||
|
});
|
||||||
|
if (
|
||||||
|
tab.id === useTabStore.getState().currentTab &&
|
||||||
|
note.locked &&
|
||||||
|
!editorState().movedAway
|
||||||
|
) {
|
||||||
|
// Show unlock note screen.
|
||||||
|
eSendEvent(eUnlockNote);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
eSubscribeEvent(eUserLoggedIn, onUserUpdated)
|
eSubscribeEvent(eUserLoggedIn, onUserUpdated)
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import {
|
|||||||
eUnSubscribeEvent
|
eUnSubscribeEvent
|
||||||
} from "../services/event-manager";
|
} from "../services/event-manager";
|
||||||
import { eDBItemUpdate } from "../utils/events";
|
import { eDBItemUpdate } from "../utils/events";
|
||||||
|
import { useSettingStore } from "../stores/use-setting-store";
|
||||||
|
|
||||||
type ItemTypeKey = {
|
type ItemTypeKey = {
|
||||||
note: Note;
|
note: Note;
|
||||||
@@ -94,7 +95,15 @@ export const useDBItem = <T extends keyof ItemTypeKey>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
if (useSettingStore.getState().isAppLoading) {
|
||||||
|
useSettingStore.subscribe((state) => {
|
||||||
|
if (!state.isAppLoading) {
|
||||||
onUpdateItem();
|
onUpdateItem();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
onUpdateItem();
|
||||||
|
}
|
||||||
eSubscribeEvent(eDBItemUpdate, onUpdateItem);
|
eSubscribeEvent(eDBItemUpdate, onUpdateItem);
|
||||||
return () => {
|
return () => {
|
||||||
eUnSubscribeEvent(eDBItemUpdate, onUpdateItem);
|
eUnSubscribeEvent(eDBItemUpdate, onUpdateItem);
|
||||||
|
|||||||
@@ -65,7 +65,8 @@ import {
|
|||||||
eClearEditor,
|
eClearEditor,
|
||||||
eCloseFullscreenEditor,
|
eCloseFullscreenEditor,
|
||||||
eOnLoadNote,
|
eOnLoadNote,
|
||||||
eOpenFullscreenEditor
|
eOpenFullscreenEditor,
|
||||||
|
eUnlockNote
|
||||||
} from "../utils/events";
|
} from "../utils/events";
|
||||||
import { editorRef, tabBarRef } from "../utils/global-refs";
|
import { editorRef, tabBarRef } from "../utils/global-refs";
|
||||||
import { sleep } from "../utils/time";
|
import { sleep } from "../utils/time";
|
||||||
@@ -516,6 +517,12 @@ const onChangeTab = async (obj) => {
|
|||||||
eSendEvent(eOnLoadNote, {
|
eSendEvent(eOnLoadNote, {
|
||||||
newNote: true
|
newNote: true
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
if (
|
||||||
|
useTabStore.getState().getTab(useTabStore.getState().currentTab).locked
|
||||||
|
) {
|
||||||
|
eSendEvent(eUnlockNote);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (obj.from === 2) {
|
if (obj.from === 2) {
|
||||||
|
|||||||
@@ -25,16 +25,31 @@ import React, {
|
|||||||
useEffect,
|
useEffect,
|
||||||
useImperativeHandle,
|
useImperativeHandle,
|
||||||
useLayoutEffect,
|
useLayoutEffect,
|
||||||
useRef
|
useRef,
|
||||||
|
useState
|
||||||
} from "react";
|
} from "react";
|
||||||
import { Platform, ViewStyle } from "react-native";
|
import {
|
||||||
|
Dimensions,
|
||||||
|
Keyboard,
|
||||||
|
Platform,
|
||||||
|
ScrollView,
|
||||||
|
TextInput,
|
||||||
|
View,
|
||||||
|
ViewStyle,
|
||||||
|
useWindowDimensions
|
||||||
|
} from "react-native";
|
||||||
import WebView from "react-native-webview";
|
import WebView from "react-native-webview";
|
||||||
import { ShouldStartLoadRequest } from "react-native-webview/lib/WebViewTypes";
|
import { ShouldStartLoadRequest } from "react-native-webview/lib/WebViewTypes";
|
||||||
import { notesnook } from "../../../e2e/test.ids";
|
import { notesnook } from "../../../e2e/test.ids";
|
||||||
import { db } from "../../common/database";
|
import { db } from "../../common/database";
|
||||||
import { IconButton } from "../../components/ui/icon-button";
|
import { IconButton } from "../../components/ui/icon-button";
|
||||||
import useKeyboard from "../../hooks/use-keyboard";
|
import useKeyboard from "../../hooks/use-keyboard";
|
||||||
import { eSubscribeEvent } from "../../services/event-manager";
|
import {
|
||||||
|
ToastManager,
|
||||||
|
eSendEvent,
|
||||||
|
eSubscribeEvent,
|
||||||
|
openVault
|
||||||
|
} from "../../services/event-manager";
|
||||||
import { getElevationStyle } from "../../utils/elevation";
|
import { getElevationStyle } from "../../utils/elevation";
|
||||||
import { openLinkInBrowser } from "../../utils/functions";
|
import { openLinkInBrowser } from "../../utils/functions";
|
||||||
import EditorOverlay from "./loading";
|
import EditorOverlay from "./loading";
|
||||||
@@ -43,7 +58,18 @@ import { EditorProps, useEditorType } from "./tiptap/types";
|
|||||||
import { useEditor } from "./tiptap/use-editor";
|
import { useEditor } from "./tiptap/use-editor";
|
||||||
import { useEditorEvents } from "./tiptap/use-editor-events";
|
import { useEditorEvents } from "./tiptap/use-editor-events";
|
||||||
import { useTabStore } from "./tiptap/use-tab-store";
|
import { useTabStore } from "./tiptap/use-tab-store";
|
||||||
import { editorController } from "./tiptap/utils";
|
import { editorController, editorState } from "./tiptap/utils";
|
||||||
|
import useGlobalSafeAreaInsets from "../../hooks/use-global-safe-area-insets";
|
||||||
|
import { useThemeColors } from "@notesnook/theme";
|
||||||
|
import { VaultDialog } from "../../components/dialogs/vault";
|
||||||
|
import { Button } from "../../components/ui/button";
|
||||||
|
import Heading from "../../components/ui/typography/heading";
|
||||||
|
import Seperator from "../../components/ui/seperator";
|
||||||
|
import Paragraph from "../../components/ui/typography/paragraph";
|
||||||
|
import { useDBItem } from "../../hooks/use-db-item";
|
||||||
|
import Input from "../../components/ui/input";
|
||||||
|
import BiometicService from "../../services/biometrics";
|
||||||
|
import { eOnLoadNote, eUnlockNote } from "../../utils/events";
|
||||||
|
|
||||||
const style: ViewStyle = {
|
const style: ViewStyle = {
|
||||||
height: "100%",
|
height: "100%",
|
||||||
@@ -163,6 +189,7 @@ const Editor = React.memo(
|
|||||||
/>
|
/>
|
||||||
<EditorOverlay editorId={editorId || ""} editor={editor} />
|
<EditorOverlay editorId={editorId || ""} editor={editor} />
|
||||||
<ReadonlyButton editor={editor} />
|
<ReadonlyButton editor={editor} />
|
||||||
|
<LockOverlay />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -172,6 +199,216 @@ const Editor = React.memo(
|
|||||||
|
|
||||||
export default Editor;
|
export default Editor;
|
||||||
|
|
||||||
|
const LockOverlay = () => {
|
||||||
|
const tab = useTabStore((state) =>
|
||||||
|
state.tabs.find((t) => t.id === state.currentTab)
|
||||||
|
);
|
||||||
|
const { height } = useWindowDimensions();
|
||||||
|
const [item] = useDBItem(tab?.noteId, "note");
|
||||||
|
const isLocked = item?.locked && tab?.locked;
|
||||||
|
const { colors } = useThemeColors();
|
||||||
|
const insets = useGlobalSafeAreaInsets();
|
||||||
|
const password = useRef<string>();
|
||||||
|
const passInputRef = useRef<TextInput>(null);
|
||||||
|
const [biometryEnrolled, setBiometryEnrolled] = useState(false);
|
||||||
|
const [biometryAvailable, setBiometryAvailable] = useState(false);
|
||||||
|
const [enrollBiometrics, setEnrollBiometrics] = useState(false);
|
||||||
|
|
||||||
|
console.log("Tab locked", item?.locked, tab?.locked);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
let biometry = await BiometicService.isBiometryAvailable();
|
||||||
|
let fingerprint = await BiometicService.hasInternetCredentials();
|
||||||
|
setBiometryAvailable(!!biometry);
|
||||||
|
setBiometryEnrolled(!!fingerprint);
|
||||||
|
})();
|
||||||
|
}, [isLocked]);
|
||||||
|
|
||||||
|
const unlockWithBiometrics = async () => {
|
||||||
|
try {
|
||||||
|
if (!item || !tab) return;
|
||||||
|
console.log("Trying to unlock with biometrics...");
|
||||||
|
let credentials = await BiometicService.getCredentials(
|
||||||
|
"Unlock note",
|
||||||
|
"Unlock note to open it in editor. If biometrics are not working, you can enter device pin to unlock vault."
|
||||||
|
);
|
||||||
|
|
||||||
|
if (credentials && credentials?.password) {
|
||||||
|
let note = await db.vault.open(item.id, credentials?.password);
|
||||||
|
eSendEvent(eOnLoadNote, {
|
||||||
|
item: note
|
||||||
|
});
|
||||||
|
useTabStore.getState().updateTab(tab.id, {
|
||||||
|
locked: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const unlock = () => {
|
||||||
|
if (
|
||||||
|
isLocked &&
|
||||||
|
biometryAvailable &&
|
||||||
|
biometryEnrolled &&
|
||||||
|
!editorState().movedAway
|
||||||
|
) {
|
||||||
|
unlockWithBiometrics();
|
||||||
|
} else {
|
||||||
|
console.log("Biometrics unavailable.");
|
||||||
|
if (isLocked && !editorState().movedAway) {
|
||||||
|
setTimeout(() => {
|
||||||
|
passInputRef.current?.focus();
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const sub = eSubscribeEvent(eUnlockNote, unlock);
|
||||||
|
unlock();
|
||||||
|
return () => {
|
||||||
|
sub.unsubscribe();
|
||||||
|
};
|
||||||
|
}, [isLocked, biometryAvailable, biometryEnrolled]);
|
||||||
|
|
||||||
|
const onSubmit = async () => {
|
||||||
|
if (!item || !tab) return;
|
||||||
|
|
||||||
|
if (!password.current || password.current.trim().length === 0) {
|
||||||
|
ToastManager.show({
|
||||||
|
heading: "Password not entered",
|
||||||
|
message: "Enter a password for the vault and try again.",
|
||||||
|
type: "error"
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
let note = await db.vault.open(item.id, password.current);
|
||||||
|
if (enrollBiometrics) {
|
||||||
|
try {
|
||||||
|
await db.vault.unlock(password.current);
|
||||||
|
await BiometicService.storeCredentials(password.current);
|
||||||
|
eSendEvent("vaultUpdated");
|
||||||
|
ToastManager.show({
|
||||||
|
heading: "Biometric unlocking enabled!",
|
||||||
|
message: "Now you can unlock notes in vault with biometrics.",
|
||||||
|
type: "success",
|
||||||
|
context: "global"
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
ToastManager.show({
|
||||||
|
heading: "Incorrect password",
|
||||||
|
message:
|
||||||
|
"Please enter the correct vault password to enable biometrics.",
|
||||||
|
type: "error",
|
||||||
|
context: "local"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
eSendEvent(eOnLoadNote, {
|
||||||
|
item: note
|
||||||
|
});
|
||||||
|
useTabStore.getState().updateTab(tab.id, {
|
||||||
|
locked: false
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
ToastManager.show({
|
||||||
|
heading: "Incorrect password",
|
||||||
|
type: "error",
|
||||||
|
context: "local"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return isLocked ? (
|
||||||
|
<ScrollView
|
||||||
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
height: height,
|
||||||
|
backgroundColor: colors.primary.background,
|
||||||
|
position: "absolute",
|
||||||
|
top: 50 + insets.top,
|
||||||
|
zIndex: 999
|
||||||
|
}}
|
||||||
|
contentContainerStyle={{
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
height: height
|
||||||
|
}}
|
||||||
|
keyboardDismissMode="interactive"
|
||||||
|
keyboardShouldPersistTaps="handled"
|
||||||
|
>
|
||||||
|
<Heading>{item.title}</Heading>
|
||||||
|
<Paragraph>This note is locked.</Paragraph>
|
||||||
|
<Seperator />
|
||||||
|
<Input
|
||||||
|
fwdRef={passInputRef}
|
||||||
|
autoCapitalize="none"
|
||||||
|
testID={notesnook.ids.dialogs.vault.pwd}
|
||||||
|
onChangeText={(value) => {
|
||||||
|
password.current = value;
|
||||||
|
}}
|
||||||
|
wrapperStyle={{
|
||||||
|
width: 300
|
||||||
|
}}
|
||||||
|
marginBottom={10}
|
||||||
|
onSubmit={() => {
|
||||||
|
onSubmit();
|
||||||
|
}}
|
||||||
|
autoComplete="password"
|
||||||
|
returnKeyLabel="Unlock"
|
||||||
|
returnKeyType={"done"}
|
||||||
|
secureTextEntry
|
||||||
|
placeholder="Password"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
title="Unlock note"
|
||||||
|
type="accent"
|
||||||
|
onPress={() => {
|
||||||
|
onSubmit();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{biometryAvailable && !biometryEnrolled ? (
|
||||||
|
<Button
|
||||||
|
title="Enable biometric unlocking"
|
||||||
|
type={enrollBiometrics ? "accent" : "gray"}
|
||||||
|
onPress={() => {
|
||||||
|
setEnrollBiometrics(!enrollBiometrics);
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
marginTop: 10
|
||||||
|
}}
|
||||||
|
icon={
|
||||||
|
enrollBiometrics
|
||||||
|
? "check-circle-outline"
|
||||||
|
: "checkbox-blank-circle-outline"
|
||||||
|
}
|
||||||
|
iconSize={20}
|
||||||
|
/>
|
||||||
|
) : biometryEnrolled && biometryAvailable ? (
|
||||||
|
<IconButton
|
||||||
|
name="fingerprint"
|
||||||
|
type="gray"
|
||||||
|
customStyle={{
|
||||||
|
marginTop: 20
|
||||||
|
}}
|
||||||
|
size={40}
|
||||||
|
onPress={() => {
|
||||||
|
unlockWithBiometrics();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
|
</ScrollView>
|
||||||
|
) : null;
|
||||||
|
};
|
||||||
|
|
||||||
const ReadonlyButton = ({ editor }: { editor: useEditorType }) => {
|
const ReadonlyButton = ({ editor }: { editor: useEditorType }) => {
|
||||||
const readonly = useTabStore(
|
const readonly = useTabStore(
|
||||||
(state) => state.tabs.find((t) => t.id === state.currentTab)?.readonly
|
(state) => state.tabs.find((t) => t.id === state.currentTab)?.readonly
|
||||||
|
|||||||
@@ -91,6 +91,10 @@ import {
|
|||||||
// 8. If app is killed, restore the note in background.
|
// 8. If app is killed, restore the note in background.
|
||||||
// 9. During realtimes sync, tabs not focused will be updated so if focused, they have the latest and updated content loaded.
|
// 9. During realtimes sync, tabs not focused will be updated so if focused, they have the latest and updated content loaded.
|
||||||
|
|
||||||
|
type NoteWithContent = Note & {
|
||||||
|
content?: NoteContent<false>;
|
||||||
|
};
|
||||||
|
|
||||||
export const useEditor = (
|
export const useEditor = (
|
||||||
editorId = "",
|
editorId = "",
|
||||||
readonly?: boolean,
|
readonly?: boolean,
|
||||||
@@ -216,7 +220,8 @@ export const useEditor = (
|
|||||||
resetContent && (await commands.clearContent(tabId));
|
resetContent && (await commands.clearContent(tabId));
|
||||||
resetContent && (await commands.clearTags(tabId));
|
resetContent && (await commands.clearTags(tabId));
|
||||||
useTabStore.getState().updateTab(tabId, {
|
useTabStore.getState().updateTab(tabId, {
|
||||||
noteId: undefined
|
noteId: undefined,
|
||||||
|
locked: false
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[commands, editorSessionHistory, postMessage]
|
[commands, editorSessionHistory, postMessage]
|
||||||
@@ -407,14 +412,21 @@ export const useEditor = (
|
|||||||
} else {
|
} else {
|
||||||
if (!event.item) return;
|
if (!event.item) return;
|
||||||
const item = event.item;
|
const item = event.item;
|
||||||
|
const noteIsLocked =
|
||||||
|
event.item.locked && !(event.item as NoteWithContent).content;
|
||||||
|
|
||||||
|
console.log("noteIsLocked", noteIsLocked);
|
||||||
|
|
||||||
// If note was already opened in a tab, focus that tab.
|
// If note was already opened in a tab, focus that tab.
|
||||||
if (typeof event.tabId !== "number") {
|
if (typeof event.tabId !== "number") {
|
||||||
if (useTabStore.getState().hasTabForNote(event.item.id)) {
|
if (useTabStore.getState().hasTabForNote(event.item.id)) {
|
||||||
const tabId = useTabStore.getState().getTabForNote(event.item.id);
|
const tabId = useTabStore.getState().getTabForNote(event.item.id);
|
||||||
if (typeof tabId === "number") {
|
if (typeof tabId === "number") {
|
||||||
useTabStore.getState().updateTab(tabId, {
|
useTabStore.getState().updateTab(tabId, {
|
||||||
readonly: event.item.readonly || readonly
|
readonly: event.item.readonly || readonly,
|
||||||
|
locked: noteIsLocked
|
||||||
});
|
});
|
||||||
|
console.log(noteIsLocked, "focused tab...");
|
||||||
useTabStore.getState().focusTab(tabId);
|
useTabStore.getState().focusTab(tabId);
|
||||||
}
|
}
|
||||||
console.log("Note already loaded, focusing the tab");
|
console.log("Note already loaded, focusing the tab");
|
||||||
@@ -423,7 +435,8 @@ export const useEditor = (
|
|||||||
// Otherwise we focus the preview tab or create one to open the note in.
|
// Otherwise we focus the preview tab or create one to open the note in.
|
||||||
useTabStore.getState().focusPreviewTab(event.item.id, {
|
useTabStore.getState().focusPreviewTab(event.item.id, {
|
||||||
readonly: event.item.readonly || readonly,
|
readonly: event.item.readonly || readonly,
|
||||||
locked: false
|
locked:
|
||||||
|
event.item.locked && !(event.item as NoteWithContent).content
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -446,7 +459,9 @@ export const useEditor = (
|
|||||||
state.current.movedAway = false;
|
state.current.movedAway = false;
|
||||||
state.current.currentlyEditing = true;
|
state.current.currentlyEditing = true;
|
||||||
|
|
||||||
|
if (!noteIsLocked) {
|
||||||
await loadContent(item);
|
await loadContent(item);
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
currentNotes.current[item.id] &&
|
currentNotes.current[item.id] &&
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ export type TabStore = {
|
|||||||
) => void;
|
) => void;
|
||||||
removeTab: (index: number) => void;
|
removeTab: (index: number) => void;
|
||||||
moveTab: (index: number, toIndex: number) => void;
|
moveTab: (index: number, toIndex: number) => void;
|
||||||
newTab: (noteId?: string, previewTab?: boolean) => void;
|
newTab: (options?: Omit<Partial<TabItem>, "id">) => void;
|
||||||
focusTab: (id: number) => void;
|
focusTab: (id: number) => void;
|
||||||
getNoteIdForTab: (id: number) => string | undefined;
|
getNoteIdForTab: (id: number) => string | undefined;
|
||||||
getTabForNote: (noteId: string) => number | undefined;
|
getTabForNote: (noteId: string) => number | undefined;
|
||||||
@@ -148,12 +148,17 @@ export const useTabStore = create<TabStore>(
|
|||||||
options: Omit<Partial<TabItem>, "id" | "noteId">
|
options: Omit<Partial<TabItem>, "id" | "noteId">
|
||||||
) => {
|
) => {
|
||||||
const index = get().tabs.findIndex((t) => t.previewTab);
|
const index = get().tabs.findIndex((t) => t.previewTab);
|
||||||
if (index === -1) return get().newTab(noteId, true);
|
if (index === -1)
|
||||||
|
return get().newTab({
|
||||||
|
noteId,
|
||||||
|
previewTab: true,
|
||||||
|
...options
|
||||||
|
});
|
||||||
const tabs = [...get().tabs];
|
const tabs = [...get().tabs];
|
||||||
tabs[index] = {
|
tabs[index] = {
|
||||||
...tabs[index],
|
...tabs[index],
|
||||||
previewTab: true,
|
|
||||||
...options,
|
...options,
|
||||||
|
previewTab: true,
|
||||||
noteId: noteId
|
noteId: noteId
|
||||||
};
|
};
|
||||||
console.log("focus preview", noteId);
|
console.log("focus preview", noteId);
|
||||||
@@ -183,14 +188,13 @@ export const useTabStore = create<TabStore>(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
newTab: (noteId?: string, previewTab?: boolean) => {
|
newTab: (options) => {
|
||||||
const id = getId(get().tabs.length, get().tabs);
|
const id = getId(get().tabs.length, get().tabs);
|
||||||
const nextTabs = [
|
const nextTabs = [
|
||||||
...get().tabs,
|
...get().tabs,
|
||||||
{
|
{
|
||||||
id: id,
|
id: id,
|
||||||
noteId,
|
...options
|
||||||
previewTab: previewTab
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
set({
|
set({
|
||||||
|
|||||||
@@ -167,3 +167,4 @@ export const eOnRefreshSearch = "612";
|
|||||||
export const eOpenAppLockPasswordDialog = "613";
|
export const eOpenAppLockPasswordDialog = "613";
|
||||||
export const eCloseAppLocKPasswordDailog = "614";
|
export const eCloseAppLocKPasswordDailog = "614";
|
||||||
export const eEditorTabFocused = "613";
|
export const eEditorTabFocused = "613";
|
||||||
|
export const eUnlockNote = "614";
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ mergedConfig.resolver = {
|
|||||||
resolveRequest: (context, moduleName, platform) => {
|
resolveRequest: (context, moduleName, platform) => {
|
||||||
if (moduleName === "node:crypto") {
|
if (moduleName === "node:crypto") {
|
||||||
return {
|
return {
|
||||||
type: 'empty'
|
type:"empty"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (moduleName ==='react') {
|
if (moduleName ==='react') {
|
||||||
|
|||||||
429
apps/mobile/package-lock.json
generated
429
apps/mobile/package-lock.json
generated
@@ -19,6 +19,7 @@
|
|||||||
"@notesnook/editor": "file:../../packages/editor",
|
"@notesnook/editor": "file:../../packages/editor",
|
||||||
"@notesnook/editor-mobile": "file:../../packages/editor-mobile",
|
"@notesnook/editor-mobile": "file:../../packages/editor-mobile",
|
||||||
"@notesnook/logger": "file:../../packages/logger",
|
"@notesnook/logger": "file:../../packages/logger",
|
||||||
|
"@notesnook/theme": "file:../../packages/theme",
|
||||||
"@notesnook/themes-server": "file:../../servers/themes",
|
"@notesnook/themes-server": "file:../../servers/themes",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-native": "0.72.0"
|
"react-native": "0.72.0"
|
||||||
@@ -32962,6 +32963,10 @@
|
|||||||
"resolved": "native",
|
"resolved": "native",
|
||||||
"link": true
|
"link": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@notesnook/theme": {
|
||||||
|
"resolved": "../../packages/theme",
|
||||||
|
"link": true
|
||||||
|
},
|
||||||
"node_modules/@notesnook/themes-server": {
|
"node_modules/@notesnook/themes-server": {
|
||||||
"resolved": "../../servers/themes",
|
"resolved": "../../servers/themes",
|
||||||
"link": true
|
"link": true
|
||||||
@@ -78964,6 +78969,430 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@notesnook/theme": {
|
||||||
|
"version": "file:../../packages/theme",
|
||||||
|
"requires": {
|
||||||
|
"@emotion/react": "11.11.1",
|
||||||
|
"@theme-ui/color": "^0.16.1",
|
||||||
|
"@theme-ui/components": "^0.16.1",
|
||||||
|
"@theme-ui/core": "^0.16.1",
|
||||||
|
"@trpc/server": "^10.31.0",
|
||||||
|
"@types/react": "^18.2.39",
|
||||||
|
"@types/tinycolor2": "^1.4.3",
|
||||||
|
"isomorphic-fetch": "^3.0.0",
|
||||||
|
"react": "18.2.0",
|
||||||
|
"tinycolor2": "^1.6.0",
|
||||||
|
"ts-json-schema-generator": "^1.2.0",
|
||||||
|
"zustand": "4.4.7"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@babel/runtime": {
|
||||||
|
"version": "7.22.6",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"regenerator-runtime": "^0.13.11"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@emotion/is-prop-valid": {
|
||||||
|
"version": "0.8.8",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@emotion/memoize": "0.7.4"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@emotion/memoize": {
|
||||||
|
"version": "0.7.4",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@styled-system/background": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@styled-system/core": "^5.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@styled-system/border": {
|
||||||
|
"version": "5.1.5",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@styled-system/core": "^5.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@styled-system/color": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@styled-system/core": "^5.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@styled-system/core": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"object-assign": "^4.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@styled-system/css": {
|
||||||
|
"version": "5.1.5",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"@styled-system/flexbox": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@styled-system/core": "^5.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@styled-system/grid": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@styled-system/core": "^5.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@styled-system/layout": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@styled-system/core": "^5.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@styled-system/position": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@styled-system/core": "^5.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@styled-system/shadow": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@styled-system/core": "^5.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@styled-system/should-forward-prop": {
|
||||||
|
"version": "5.1.5",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@emotion/is-prop-valid": "^0.8.1",
|
||||||
|
"@emotion/memoize": "^0.7.1",
|
||||||
|
"styled-system": "^5.1.5"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@emotion/memoize": {
|
||||||
|
"version": "0.7.5",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@styled-system/space": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@styled-system/core": "^5.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@styled-system/typography": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@styled-system/core": "^5.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@styled-system/variant": {
|
||||||
|
"version": "5.1.5",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@styled-system/core": "^5.1.2",
|
||||||
|
"@styled-system/css": "^5.1.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@theme-ui/color": {
|
||||||
|
"version": "0.16.0",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@theme-ui/css": "^0.16.0",
|
||||||
|
"polished": "^4.0.5"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@theme-ui/css": {
|
||||||
|
"version": "0.16.0",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"csstype": "^3.0.10"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@theme-ui/components": {
|
||||||
|
"version": "0.14.7",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@styled-system/color": "^5.1.2",
|
||||||
|
"@styled-system/should-forward-prop": "^5.1.2",
|
||||||
|
"@styled-system/space": "^5.1.2",
|
||||||
|
"@theme-ui/css": "0.14.7",
|
||||||
|
"@types/styled-system": "^5.1.13"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@theme-ui/core": {
|
||||||
|
"version": "0.14.7",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@theme-ui/css": "0.14.7",
|
||||||
|
"@theme-ui/parse-props": "0.14.7",
|
||||||
|
"deepmerge": "^4.2.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@theme-ui/css": {
|
||||||
|
"version": "0.14.7",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"csstype": "^3.0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@theme-ui/parse-props": {
|
||||||
|
"version": "0.14.7",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@theme-ui/css": "0.14.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@trpc/server": {
|
||||||
|
"version": "10.38.3",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"@types/json-schema": {
|
||||||
|
"version": "7.0.12",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"@types/prop-types": {
|
||||||
|
"version": "15.7.5",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"@types/react": {
|
||||||
|
"version": "17.0.2",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/prop-types": "*",
|
||||||
|
"csstype": "^3.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@types/styled-system": {
|
||||||
|
"version": "5.1.16",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"csstype": "^3.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@types/tinycolor2": {
|
||||||
|
"version": "1.4.3",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"balanced-match": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"commander": {
|
||||||
|
"version": "9.5.0",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"csstype": {
|
||||||
|
"version": "3.1.1",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"deepmerge": {
|
||||||
|
"version": "4.2.2",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"fs.realpath": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"inflight": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"once": "^1.3.0",
|
||||||
|
"wrappy": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"inherits": {
|
||||||
|
"version": "2.0.4",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"isomorphic-fetch": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"node-fetch": "^2.6.1",
|
||||||
|
"whatwg-fetch": "^3.4.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"js-tokens": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"json5": {
|
||||||
|
"version": "2.2.3",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"loose-envify": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"js-tokens": "^3.0.0 || ^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node-fetch": {
|
||||||
|
"version": "2.6.12",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"whatwg-url": "^5.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"normalize-path": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"object-assign": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"once": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"wrappy": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"polished": {
|
||||||
|
"version": "4.2.2",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.17.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"react": {
|
||||||
|
"version": "17.0.2",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"loose-envify": "^1.1.0",
|
||||||
|
"object-assign": "^4.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"regenerator-runtime": {
|
||||||
|
"version": "0.13.11",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"safe-stable-stringify": {
|
||||||
|
"version": "2.4.3",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"styled-system": {
|
||||||
|
"version": "5.1.5",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@styled-system/background": "^5.1.2",
|
||||||
|
"@styled-system/border": "^5.1.5",
|
||||||
|
"@styled-system/color": "^5.1.2",
|
||||||
|
"@styled-system/core": "^5.1.2",
|
||||||
|
"@styled-system/flexbox": "^5.1.2",
|
||||||
|
"@styled-system/grid": "^5.1.2",
|
||||||
|
"@styled-system/layout": "^5.1.2",
|
||||||
|
"@styled-system/position": "^5.1.2",
|
||||||
|
"@styled-system/shadow": "^5.1.2",
|
||||||
|
"@styled-system/space": "^5.1.2",
|
||||||
|
"@styled-system/typography": "^5.1.2",
|
||||||
|
"@styled-system/variant": "^5.1.5",
|
||||||
|
"object-assign": "^4.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tr46": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"ts-json-schema-generator": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/json-schema": "^7.0.11",
|
||||||
|
"commander": "^9.4.1",
|
||||||
|
"glob": "^8.0.3",
|
||||||
|
"json5": "^2.2.1",
|
||||||
|
"normalize-path": "^3.0.0",
|
||||||
|
"safe-stable-stringify": "^2.4.1",
|
||||||
|
"typescript": "~4.9.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"brace-expansion": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"balanced-match": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"glob": {
|
||||||
|
"version": "8.1.0",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"fs.realpath": "^1.0.0",
|
||||||
|
"inflight": "^1.0.4",
|
||||||
|
"inherits": "2",
|
||||||
|
"minimatch": "^5.0.1",
|
||||||
|
"once": "^1.3.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minimatch": {
|
||||||
|
"version": "5.1.6",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"brace-expansion": "^2.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"typescript": {
|
||||||
|
"version": "4.9.5",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"use-sync-external-store": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
|
"webidl-conversions": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"whatwg-fetch": {
|
||||||
|
"version": "3.6.2",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"whatwg-url": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"tr46": "~0.0.3",
|
||||||
|
"webidl-conversions": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"wrappy": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"zustand": {
|
||||||
|
"version": "4.3.8",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"use-sync-external-store": "1.2.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"@notesnook/themes-server": {
|
"@notesnook/themes-server": {
|
||||||
"version": "file:../../servers/themes",
|
"version": "file:../../servers/themes",
|
||||||
"requires": {
|
"requires": {
|
||||||
|
|||||||
22
packages/editor-mobile/package-lock.json
generated
22
packages/editor-mobile/package-lock.json
generated
@@ -4360,7 +4360,7 @@
|
|||||||
"version": "15.7.11",
|
"version": "15.7.11",
|
||||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz",
|
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz",
|
||||||
"integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==",
|
"integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==",
|
||||||
"devOptional": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/q": {
|
"node_modules/@types/q": {
|
||||||
"version": "1.5.8",
|
"version": "1.5.8",
|
||||||
@@ -4384,7 +4384,7 @@
|
|||||||
"version": "18.2.39",
|
"version": "18.2.39",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.39.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.39.tgz",
|
||||||
"integrity": "sha512-Oiw+ppED6IremMInLV4HXGbfbG6GyziY3kqAwJYOR0PNbkYDmLWQA3a95EhdSmamsvbkJN96ZNN+YD+fGjzSBA==",
|
"integrity": "sha512-Oiw+ppED6IremMInLV4HXGbfbG6GyziY3kqAwJYOR0PNbkYDmLWQA3a95EhdSmamsvbkJN96ZNN+YD+fGjzSBA==",
|
||||||
"devOptional": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/prop-types": "*",
|
"@types/prop-types": "*",
|
||||||
"@types/scheduler": "*",
|
"@types/scheduler": "*",
|
||||||
@@ -4419,7 +4419,7 @@
|
|||||||
"version": "0.16.8",
|
"version": "0.16.8",
|
||||||
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz",
|
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz",
|
||||||
"integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==",
|
"integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==",
|
||||||
"devOptional": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/semver": {
|
"node_modules/@types/semver": {
|
||||||
"version": "7.5.6",
|
"version": "7.5.6",
|
||||||
@@ -9715,7 +9715,7 @@
|
|||||||
"version": "9.0.21",
|
"version": "9.0.21",
|
||||||
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz",
|
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz",
|
||||||
"integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==",
|
"integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==",
|
||||||
"devOptional": true,
|
"dev": true,
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
"url": "https://opencollective.com/immer"
|
"url": "https://opencollective.com/immer"
|
||||||
@@ -17776,20 +17776,6 @@
|
|||||||
"is-typedarray": "^1.0.0"
|
"is-typedarray": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typescript": {
|
|
||||||
"version": "4.9.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
|
|
||||||
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
|
|
||||||
"dev": true,
|
|
||||||
"peer": true,
|
|
||||||
"bin": {
|
|
||||||
"tsc": "bin/tsc",
|
|
||||||
"tsserver": "bin/tsserver"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=4.2.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/unbox-primitive": {
|
"node_modules/unbox-primitive": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ import Header from "./header";
|
|||||||
import StatusBar from "./statusbar";
|
import StatusBar from "./statusbar";
|
||||||
import Tags from "./tags";
|
import Tags from "./tags";
|
||||||
import Title from "./title";
|
import Title from "./title";
|
||||||
|
import FingerprintIcon from "mdi-react/FingerprintIcon";
|
||||||
|
|
||||||
globalThis.toBlobURL = toBlobURL as typeof globalThis.toBlobURL;
|
globalThis.toBlobURL = toBlobURL as typeof globalThis.toBlobURL;
|
||||||
|
|
||||||
@@ -322,7 +323,8 @@ const Tiptap = ({ settings }: { settings: Settings }) => {
|
|||||||
style={{
|
style={{
|
||||||
overflowY: "scroll",
|
overflowY: "scroll",
|
||||||
height: "100%",
|
height: "100%",
|
||||||
display: "block"
|
display: "block",
|
||||||
|
position: "relative"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{settings.noHeader ? null : (
|
{settings.noHeader ? null : (
|
||||||
@@ -341,14 +343,14 @@ const Tiptap = ({ settings }: { settings: Settings }) => {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{controller.loading ? (
|
{controller.loading || tab.locked ? (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
height: "100%",
|
|
||||||
width: "100%",
|
width: "100%",
|
||||||
|
height: "95%",
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
zIndex: 999,
|
zIndex: 999,
|
||||||
backgroundColor: "white",
|
backgroundColor: colors.primary.background,
|
||||||
paddingRight: 12,
|
paddingRight: 12,
|
||||||
paddingLeft: 12,
|
paddingLeft: 12,
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@@ -411,7 +413,7 @@ const Tiptap = ({ settings }: { settings: Settings }) => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{!layout ? null : (
|
{!layout || tab.locked ? null : (
|
||||||
<EmotionEditorToolbarTheme>
|
<EmotionEditorToolbarTheme>
|
||||||
<Toolbar
|
<Toolbar
|
||||||
className="theme-scope-editorToolbar"
|
className="theme-scope-editorToolbar"
|
||||||
|
|||||||
@@ -22,15 +22,16 @@ import { createJSONStorage, persist } from "zustand/middleware";
|
|||||||
|
|
||||||
globalThis.editorControllers = {};
|
globalThis.editorControllers = {};
|
||||||
globalThis.editors = {};
|
globalThis.editors = {};
|
||||||
global.editorTags = {};
|
globalThis.editorTags = {};
|
||||||
global.editorTitles = {};
|
globalThis.editorTitles = {};
|
||||||
global.statusBars = {};
|
globalThis.statusBars = {};
|
||||||
|
|
||||||
export type TabItem = {
|
export type TabItem = {
|
||||||
id: number;
|
id: number;
|
||||||
noteId?: string;
|
noteId?: string;
|
||||||
previewTab?: boolean;
|
previewTab?: boolean;
|
||||||
readonly?: boolean;
|
readonly?: boolean;
|
||||||
|
locked?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
type NoteState = {
|
type NoteState = {
|
||||||
|
|||||||
Reference in New Issue
Block a user