mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-02-24 04:00:59 +01:00
mobile: fix tabs
This commit is contained in:
committed by
Abdullah Atta
parent
140e343289
commit
329c2e220f
@@ -627,17 +627,10 @@ export const useAppEvents = () => {
|
||||
if (locked) {
|
||||
useTabStore.getState().updateTab(tab.id, {
|
||||
session: {
|
||||
locked: true
|
||||
locked: true,
|
||||
noteLocked: true
|
||||
}
|
||||
});
|
||||
if (
|
||||
tab.id === useTabStore.getState().currentTab &&
|
||||
locked &&
|
||||
!editorState().movedAway
|
||||
) {
|
||||
// Show unlock note screen.
|
||||
eSendEvent(eUnlockNote);
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
@@ -612,14 +612,6 @@ export const useEditorEvents = (
|
||||
break;
|
||||
}
|
||||
case EditorEvents.tabFocused: {
|
||||
console.log(
|
||||
"Focused tab",
|
||||
editorMessage.tabId,
|
||||
editorMessage.noteId,
|
||||
"Content:",
|
||||
editorMessage.value
|
||||
);
|
||||
|
||||
eSendEvent(eEditorTabFocused, editorMessage.tabId);
|
||||
|
||||
if (editorMessage.noteId) {
|
||||
|
||||
@@ -32,9 +32,9 @@ import {
|
||||
isEncryptedContent,
|
||||
isTrashItem
|
||||
} from "@notesnook/core";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { EditorEvents } from "@notesnook/editor-mobile/src/utils/editor-events";
|
||||
import { NativeEvents } from "@notesnook/editor-mobile/src/utils/native-events";
|
||||
import { strings } from "@notesnook/intl";
|
||||
import { useThemeEngineStore } from "@notesnook/theme";
|
||||
import { Mutex } from "async-mutex";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
@@ -500,6 +500,7 @@ export const useEditor = (
|
||||
blockId?: string;
|
||||
session?: TabSessionItem;
|
||||
newTab?: boolean;
|
||||
resetTabState?: boolean;
|
||||
}) => {
|
||||
loadNoteMutex.runExclusive(async () => {
|
||||
if (!event) return;
|
||||
@@ -544,7 +545,15 @@ export const useEditor = (
|
||||
}
|
||||
|
||||
const item = event.item;
|
||||
currentLoadingNoteId.current = item.id;
|
||||
|
||||
// If note is already open in a tab, focus that tab.
|
||||
if (useTabStore.getState().hasTabForNote(item.id)) {
|
||||
const tabId = useTabStore.getState().getTabForNote(item.id);
|
||||
if (tabId !== useTabStore.getState().currentTab) {
|
||||
useTabStore.getState().focusTab(tabId as string);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const isLockedNote = await db.vaults.itemExists(
|
||||
event.item as ItemReference
|
||||
@@ -553,25 +562,24 @@ export const useEditor = (
|
||||
const tabLocked =
|
||||
isLockedNote && !(event.item as NoteWithContent).content;
|
||||
|
||||
let tabId = event.tabId;
|
||||
if (tabId === undefined) tabId = useTabStore.getState().currentTab;
|
||||
const tabId = event.tabId
|
||||
? event.tabId
|
||||
: useTabStore.getState().currentTab;
|
||||
|
||||
// Check if tab needs to be refreshed.
|
||||
if (
|
||||
!event.resetTabState &&
|
||||
tabId &&
|
||||
event.item.id === useTabStore.getState().getNoteIdForTab(tabId) &&
|
||||
!localTabState.current?.needsRefresh(
|
||||
tabId,
|
||||
isLockedNote,
|
||||
item.readonly
|
||||
)
|
||||
) {
|
||||
console.log(
|
||||
"Note is already updated, skipping refresh request on focus"
|
||||
);
|
||||
currentLoadingNoteId.current = undefined;
|
||||
|
||||
commands.setLoading(false, tabId);
|
||||
return;
|
||||
} else {
|
||||
console.log("updating the tab in focus...");
|
||||
localTabState.current?.setEditTime(
|
||||
item.id,
|
||||
localTabState.current?.noteEditedTime[item.id] || item.dateEdited
|
||||
@@ -583,6 +591,9 @@ export const useEditor = (
|
||||
});
|
||||
}
|
||||
|
||||
currentLoadingNoteId.current = item.id;
|
||||
|
||||
// Show loading overlay if note is not already loaded.
|
||||
if (
|
||||
tabId &&
|
||||
(event.item?.id !== useTabStore.getState().getNoteIdForTab(tabId) ||
|
||||
@@ -592,38 +603,35 @@ export const useEditor = (
|
||||
}
|
||||
|
||||
const session: Partial<TabSessionItem> = event.session || {
|
||||
readonly: event.item.readonly,
|
||||
locked: tabLocked,
|
||||
noteLocked: isLockedNote,
|
||||
noteId: event.item.id
|
||||
};
|
||||
|
||||
session.noteLocked = isLockedNote;
|
||||
session.locked = tabLocked;
|
||||
session.readonly = item.readonly;
|
||||
|
||||
const tab = useTabStore.getState().getTab(tabId!);
|
||||
|
||||
if (useTabStore.getState().tabs.length === 0 || event.newTab) {
|
||||
useTabStore.getState().newTab({
|
||||
session: session
|
||||
});
|
||||
console.log("Creating a new tab...");
|
||||
} else {
|
||||
// A new session is created if the note is changed.
|
||||
// If the note is already opened, the session is updated.
|
||||
if (
|
||||
event.item.id !== tab?.session?.noteId &&
|
||||
tab?.session?.noteId
|
||||
!tab?.session ||
|
||||
(event.item.id !== tab?.session?.noteId && tab?.session?.noteId)
|
||||
) {
|
||||
useTabStore.getState().newTabSession(tabId!, session);
|
||||
console.log("Creating a new tab session");
|
||||
} else {
|
||||
console.log("Updating tab session");
|
||||
useTabStore.getState().updateTab(tabId!, {
|
||||
session: session
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (lastTabFocused.current !== tabId) {
|
||||
console.log("Waiting for tab to get focus");
|
||||
return;
|
||||
}
|
||||
if (lastTabFocused.current !== tabId) return;
|
||||
|
||||
if (tabBarRef.current?.page() === 2) {
|
||||
state.current.movedAway = false;
|
||||
@@ -651,8 +659,6 @@ export const useEditor = (
|
||||
await postMessage(NativeEvents.title, item.title, tabId);
|
||||
overlay(false);
|
||||
|
||||
console.log("LOADING NOTE....", item.id, item.title);
|
||||
|
||||
await postMessage(
|
||||
NativeEvents.html,
|
||||
{
|
||||
@@ -699,38 +705,34 @@ export const useEditor = (
|
||||
isLocal?: boolean
|
||||
) => {
|
||||
try {
|
||||
await (async () => {
|
||||
if (SettingsService.get().disableRealtimeSync && !isLocal) return;
|
||||
if (!data) return;
|
||||
if (SettingsService.get().disableRealtimeSync && !isLocal) return;
|
||||
if (!data) return;
|
||||
|
||||
if (isDeleted(data) || isTrashItem(data)) {
|
||||
const tabId = useTabStore.getState().getTabForNote(data.id);
|
||||
if (tabId !== undefined) {
|
||||
await commands.clearContent(tabId);
|
||||
useTabStore.getState().removeTab(tabId);
|
||||
}
|
||||
return;
|
||||
if (isDeleted(data) || isTrashItem(data)) {
|
||||
const tabId = useTabStore.getState().getTabForNote(data.id);
|
||||
if (tabId !== undefined) {
|
||||
await commands.clearContent(tabId);
|
||||
useTabStore.getState().removeTab(tabId);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const noteId =
|
||||
(data as ContentItem).type === "tiptap"
|
||||
? (data as ContentItem).noteId
|
||||
: data.id;
|
||||
const noteId =
|
||||
(data as ContentItem).type === "tiptap"
|
||||
? (data as ContentItem).noteId
|
||||
: data.id;
|
||||
|
||||
if (!useTabStore.getState().hasTabForNote(noteId)) return;
|
||||
const tabId = useTabStore.getState().getTabForNote(noteId) as string;
|
||||
const note = data.type === "note" ? data : await db.notes?.note(noteId);
|
||||
|
||||
const tab = useTabStore.getState().getTab(tabId);
|
||||
lock.current = true;
|
||||
|
||||
const note =
|
||||
data.type === "note" ? data : await db.notes?.note(noteId);
|
||||
// Handle this case where note was locked on another device and synced.
|
||||
const locked = note
|
||||
? await db.vaults.itemExists(note as ItemReference)
|
||||
: false;
|
||||
|
||||
lock.current = true;
|
||||
|
||||
// Handle this case where note was locked on another device and synced.
|
||||
const locked = note
|
||||
? await db.vaults.itemExists(note as ItemReference)
|
||||
: false;
|
||||
useTabStore.getState().forEachNoteTab(noteId, async (tab) => {
|
||||
const tabId = tab.id;
|
||||
|
||||
if (note) {
|
||||
if (!locked && tab?.session?.noteLocked) {
|
||||
@@ -738,8 +740,7 @@ export const useEditor = (
|
||||
if (tab.session?.locked) {
|
||||
if (useTabStore.getState().currentTab === tabId) {
|
||||
eSendEvent(eOnLoadNote, {
|
||||
item: note,
|
||||
forced: true
|
||||
item: note
|
||||
});
|
||||
} else {
|
||||
useTabStore.getState().updateTab(tabId, {
|
||||
@@ -748,7 +749,9 @@ export const useEditor = (
|
||||
noteLocked: false
|
||||
}
|
||||
});
|
||||
commands.setLoading(true, tabId);
|
||||
localTabState.current?.set(tabId, {
|
||||
editedAt: 0
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (!tab?.session?.noteLocked && locked) {
|
||||
@@ -759,10 +762,13 @@ export const useEditor = (
|
||||
noteLocked: true
|
||||
}
|
||||
});
|
||||
commands.clearContent(tabId);
|
||||
if (useTabStore.getState().currentTab !== tabId) {
|
||||
commands.clearContent(tabId);
|
||||
commands.setLoading(true, tabId);
|
||||
}
|
||||
localTabState.current?.set(tabId, {
|
||||
editedAt: 0
|
||||
});
|
||||
}
|
||||
|
||||
if (currentNotes.current[noteId]?.title !== note.title) {
|
||||
@@ -776,12 +782,13 @@ export const useEditor = (
|
||||
tabId as string
|
||||
);
|
||||
}
|
||||
|
||||
useTabStore.getState().updateTab(tabId, {
|
||||
session: {
|
||||
readonly: note.readonly
|
||||
}
|
||||
});
|
||||
if (tab.session?.readonly !== note.readonly) {
|
||||
useTabStore.getState().updateTab(tabId, {
|
||||
session: {
|
||||
readonly: note.readonly
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (data.type === "tiptap" && note && !isLocal) {
|
||||
@@ -792,7 +799,7 @@ export const useEditor = (
|
||||
if (locked && isEncryptedContent(data)) {
|
||||
const decryptedContent = await db.vault?.decryptContent(data);
|
||||
if (!decryptedContent) {
|
||||
useTabStore.getState().updateTab(tabId, {
|
||||
useTabStore.getState().updateTab(tab.id, {
|
||||
session: {
|
||||
locked: true,
|
||||
noteLocked: true
|
||||
@@ -823,7 +830,7 @@ export const useEditor = (
|
||||
}
|
||||
}
|
||||
}
|
||||
})();
|
||||
});
|
||||
} catch (e) {
|
||||
DatabaseLogger.error(e as Error, "Error when applying sync changes");
|
||||
} finally {
|
||||
@@ -980,6 +987,9 @@ export const useEditor = (
|
||||
useTabStore.getState().currentTab!
|
||||
))
|
||||
) {
|
||||
localTabState.current?.set(useTabStore.getState().currentTab!, {
|
||||
editedAt: 0
|
||||
});
|
||||
eSendEvent(eEditorReset, "onReady");
|
||||
return false;
|
||||
} else {
|
||||
@@ -998,6 +1008,10 @@ export const useEditor = (
|
||||
);
|
||||
await commands.setSettings();
|
||||
|
||||
localTabState.current?.set(useTabStore.getState().currentTab!, {
|
||||
editedAt: 0
|
||||
});
|
||||
|
||||
if (!state.current.ready) {
|
||||
state.current.ready = true;
|
||||
}
|
||||
|
||||
@@ -148,7 +148,6 @@ export const tabSessionHistory = new TabSessionHistory({
|
||||
return useTabStore.getState();
|
||||
},
|
||||
set(state) {
|
||||
console.log("Set state", state.canGoBack, state.canGoForward);
|
||||
useTabStore.setState({
|
||||
...state
|
||||
});
|
||||
@@ -217,12 +216,37 @@ export const useTabStore = create<TabStore>(
|
||||
) => {
|
||||
const tabId = _id || (get().currentTab as string);
|
||||
|
||||
const sessionId = tabSessionHistory.add(tabId);
|
||||
const session = {
|
||||
id: sessionId,
|
||||
...options
|
||||
};
|
||||
TabSessionStorage.set(sessionId, session);
|
||||
const sessionHistory = get().tabSessionHistory[tabId];
|
||||
|
||||
let oldSessionId: string | undefined = undefined;
|
||||
if (sessionHistory) {
|
||||
const allSessions = sessionHistory.backStack.concat(
|
||||
sessionHistory.forwardStack
|
||||
);
|
||||
allSessions.forEach((id) => {
|
||||
if (TabSessionStorage.get(id)?.noteId === options?.noteId) {
|
||||
oldSessionId = id;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const sessionId = tabSessionHistory.add(tabId, oldSessionId);
|
||||
|
||||
let session: Partial<TabSessionItem>;
|
||||
|
||||
if (!oldSessionId) {
|
||||
session = {
|
||||
id: sessionId,
|
||||
...options
|
||||
};
|
||||
TabSessionStorage.set(sessionId, session as TabSessionItem);
|
||||
} else {
|
||||
session = {
|
||||
...TabSessionStorage.get(oldSessionId),
|
||||
...options
|
||||
};
|
||||
}
|
||||
|
||||
const index = get().tabs.findIndex((t) => t.id === tabId);
|
||||
if (index == -1) return;
|
||||
const tabs = [...get().tabs];
|
||||
@@ -308,10 +332,9 @@ export const useTabStore = create<TabStore>(
|
||||
|
||||
if (note) {
|
||||
const isLocked = await db.vaults.itemExists(note);
|
||||
if (isLocked && !session?.noteLocked) {
|
||||
session.locked = true;
|
||||
session.noteLocked = true;
|
||||
}
|
||||
session.locked = isLocked;
|
||||
session.noteLocked = isLocked && !session?.noteLocked;
|
||||
|
||||
session.readonly = note.readonly;
|
||||
} else if (session.noteId) {
|
||||
console.log("Failed to load session...");
|
||||
@@ -325,12 +348,12 @@ export const useTabStore = create<TabStore>(
|
||||
});
|
||||
}
|
||||
|
||||
console.log("Loading session", session);
|
||||
eSendEvent(eOnLoadNote, {
|
||||
item: note,
|
||||
newNote: !note,
|
||||
tabId: get().currentTab,
|
||||
session: session
|
||||
session: session,
|
||||
resetTabState: true
|
||||
});
|
||||
|
||||
return true;
|
||||
@@ -418,10 +441,7 @@ export const useTabStore = create<TabStore>(
|
||||
return get().tabs.find((t) => t.id === id)?.session?.noteId;
|
||||
},
|
||||
hasTabForNote: (noteId: string) => {
|
||||
return (
|
||||
typeof get().tabs.find((t) => t.session?.noteId === noteId)?.id ===
|
||||
"number"
|
||||
);
|
||||
return !!get().tabs.find((t) => t.session?.noteId === noteId);
|
||||
},
|
||||
getTabForNote: (noteId: string) => {
|
||||
return get().tabs.find((t) => t.session?.noteId === noteId)?.id;
|
||||
@@ -442,7 +462,7 @@ export const useTabStore = create<TabStore>(
|
||||
}
|
||||
}),
|
||||
{
|
||||
name: "tabs-storage",
|
||||
name: "tabs-storage-v1",
|
||||
getStorage: () => MMKV as unknown as StateStorage,
|
||||
onRehydrateStorage: () => {
|
||||
return (state) => {
|
||||
|
||||
@@ -243,8 +243,10 @@ const Tiptap = ({
|
||||
);
|
||||
setTimeout(() => {
|
||||
editorControllers[tabRef.current.id]?.setLoading(false);
|
||||
restoreNoteSelection(scrollTop, selection);
|
||||
}, 300);
|
||||
setTimeout(() => {
|
||||
restoreNoteSelection(scrollTop, selection);
|
||||
}, 300);
|
||||
}, 1);
|
||||
},
|
||||
[restoreNoteSelection]
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user