From 7df1037e3fc98e8a1986af3b166506dde4120ccd Mon Sep 17 00:00:00 2001 From: Ammar Ahmed Date: Mon, 3 Feb 2025 15:38:17 +0500 Subject: [PATCH] mobile: fix realtime sync editor updates in tabs --- .../app/screens/editor/tiptap/use-editor.ts | 72 +++++++++++++------ .../android/app/src/main/AndroidManifest.xml | 1 + .../editor-mobile/src/components/editor.tsx | 29 +++++--- 3 files changed, 72 insertions(+), 30 deletions(-) diff --git a/apps/mobile/app/screens/editor/tiptap/use-editor.ts b/apps/mobile/app/screens/editor/tiptap/use-editor.ts index f902df3fc..7c6c4b56f 100644 --- a/apps/mobile/app/screens/editor/tiptap/use-editor.ts +++ b/apps/mobile/app/screens/editor/tiptap/use-editor.ts @@ -738,35 +738,37 @@ export const useEditor = ( lock.current = true; // Handle this case where note was locked on another device and synced. - const locked = note + let locked = note ? await db.vaults.itemExists(note as ItemReference) : false; + if (data.type === "tiptap") { + locked = data.locked; + } + useTabStore.getState().forEachNoteTab(noteId, async (tab) => { const tabId = tab.id; + let didUnlock = false; + if (note) { if (!locked && tab?.session?.noteLocked) { - // Note lock removed. - if (tab.session?.locked) { - if (useTabStore.getState().currentTab === tabId) { - eSendEvent(eOnLoadNote, { - item: note - }); - } else { - useTabStore.getState().updateTab(tabId, { - session: { - locked: false, - noteLocked: false - } - }); + if (tab?.session?.noteLocked || tab?.session?.locked) { + if (useTabStore.getState().currentTab !== tabId) { localTabState.current?.set(tabId, { editedAt: 0 }); } + + didUnlock = true; + useTabStore.getState().updateTab(tabId, { + session: { + locked: false, + noteLocked: false + } + }); } } else if (!tab?.session?.noteLocked && locked) { - // Note lock added. useTabStore.getState().updateTab(tabId, { session: { locked: true, @@ -782,18 +784,24 @@ export const useEditor = ( }); } - if (currentNotes.current[noteId]?.title !== note.title) { + if ( + currentNotes.current[noteId]?.title !== note.title || + didUnlock + ) { postMessage(NativeEvents.title, note.title, tabId); } commands.setTags(note); - if (currentNotes.current[noteId]?.dateEdited !== note.dateEdited) { + if ( + currentNotes.current[noteId]?.dateEdited !== note.dateEdited || + didUnlock + ) { commands.setStatus( getFormattedDate(note.dateEdited, "date-time"), strings.saved(), tabId as string ); } - if (tab.session?.readonly !== note.readonly) { + if (tab.session?.readonly !== note.readonly || didUnlock) { useTabStore.getState().updateTab(tabId, { session: { readonly: note.readonly @@ -803,7 +811,10 @@ export const useEditor = ( } if (data.type === "tiptap" && note && !isLocal) { - if (lastContentChangeTime.current[noteId] >= data.dateModified) { + if ( + lastContentChangeTime.current[noteId] >= data.dateModified && + !didUnlock + ) { return; } @@ -823,18 +834,35 @@ export const useEditor = ( } else { await postMessage( NativeEvents.updatehtml, - decryptedContent.data, + { + data: decryptedContent.data, + selection: tab.session?.selection, + scrollTop: tab.session?.scrollTop + }, tabId ); currentContents.current[note.id] = decryptedContent; } } else { const _nextContent = data.data; - if (_nextContent === currentContents.current[note.id]?.data) { + if ( + _nextContent === currentContents.current[note.id]?.data && + !didUnlock + ) { return; } + lastContentChangeTime.current[note.id] = note.dateEdited; - await postMessage(NativeEvents.updatehtml, _nextContent, tabId); + console.log(tab.session?.selection); + await postMessage( + NativeEvents.updatehtml, + { + data: _nextContent, + selection: tab.session?.selection, + scrollTop: tab.session?.scrollTop + }, + tabId + ); if (!isEncryptedContent(data)) { currentContents.current[note.id] = data as UnencryptedContentItem; diff --git a/apps/mobile/native/android/app/src/main/AndroidManifest.xml b/apps/mobile/native/android/app/src/main/AndroidManifest.xml index bce821538..595aefdd9 100644 --- a/apps/mobile/native/android/app/src/main/AndroidManifest.xml +++ b/apps/mobile/native/android/app/src/main/AndroidManifest.xml @@ -60,6 +60,7 @@ android:theme="@style/BootTheme" android:largeHeap="true" android:supportsRtl="false" + android:networkSecurityConfig="@xml/network_security_config" tools:replace="android:supportsRtl"> diff --git a/packages/editor-mobile/src/components/editor.tsx b/packages/editor-mobile/src/components/editor.tsx index 5849f5945..ef9b3ba90 100644 --- a/packages/editor-mobile/src/components/editor.tsx +++ b/packages/editor-mobile/src/components/editor.tsx @@ -205,9 +205,18 @@ const Tiptap = ({ if (tabRef.current.session?.noteId) { clearTimeout(noteStateUpdateTimer.current); noteStateUpdateTimer.current = setTimeout(() => { - const { to, from } = - editors[tabRef.current?.id]?.state.selection || {}; - }, 500); + post( + EditorEvents.saveScroll, + { + selection: { + to: editors[tabRef.current.id]?.state.selection.to, + from: editors[tabRef.current.id]?.state.selection.from + } + }, + tabRef.current.id, + tabRef.current.session?.noteId + ); + }, 300); } }, onCreate() { @@ -547,7 +556,7 @@ const Tiptap = ({ )} - {controller.loading || tab.session?.locked ? ( + {controller.loading || tab.session?.noteLocked ? (
- {tab.session?.locked ? ( + {tab.session?.noteLocked ? ( <>