Skip to content

Commit 79a3ee7

Browse files
committed
Fix: prosemirror cursors, offline-only
1 parent 7f76fa3 commit 79a3ee7

File tree

4 files changed

+25
-23
lines changed

4 files changed

+25
-23
lines changed

applet/src/cross-applet-main.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ export class CrossAppletMain extends LitElement {
6767
>
6868
<syn-context
6969
.store=${new SynStore(
70-
new SynClient(appletClient, "notebooks")
70+
new SynClient(appletClient, "notebooks"),
71+
true
7172
)}
7273
>
7374
<div class="row title" style="align-items: center">

applet/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ function wrapAppletView(
5151
weServices: WeServices,
5252
innerTemplate: TemplateResult
5353
): TemplateResult {
54-
const synStore = new SynStore(new SynClient(client, "notebooks"));
54+
const synStore = new SynStore(new SynClient(client, "notebooks"), true);
5555
return html`
5656
<attachments-context
5757
.store=${new AttachmentsStore(new AttachmentsClient(client, "notebooks"))}
@@ -209,7 +209,7 @@ const applet: WeApplet = {
209209
label: msg("Note"),
210210
icon_src: wrapPathInSvg(mdiNotebook),
211211
async create(attachToHrl: Hrl) {
212-
const synStore = new SynStore(new SynClient(appletClient, "notebooks"));
212+
const synStore = new SynStore(new SynClient(appletClient, "notebooks"), true);
213213

214214
const note = await createNote(synStore, msg(`Note`), attachToHrl, undefined);
215215
const appInfo = await appletClient.appInfo();

ui/src/elements/syn-pm-editor.ts

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,13 @@ import './agent-cursor.js';
1212

1313
// ProseMirror imports
1414
import { EditorView } from 'prosemirror-view';
15-
import { EditorState, Transaction, Plugin, PluginKey, TextSelection } from 'prosemirror-state';
15+
import { EditorState, Plugin, PluginKey, TextSelection } from 'prosemirror-state';
1616
import { Schema, Node as PMNode } from 'prosemirror-model';
1717
import { schema as basicSchema } from 'prosemirror-schema-basic';
1818
import { addListNodes } from 'prosemirror-schema-list';
1919
import { history, undo, redo } from 'prosemirror-history';
2020
import { keymap } from 'prosemirror-keymap';
2121
import { exampleSetup } from 'prosemirror-example-setup';
22-
import { defaultMarkdownParser, defaultMarkdownSerializer } from 'prosemirror-markdown';
2322

2423
import {
2524
AgentSelection,
@@ -758,6 +757,15 @@ export class SynPmEditor extends LitElement {
758757
// console.log('Updating editor from Syn - text changed');
759758
this.isUpdatingFromSyn = true;
760759

760+
// IMPORTANT: Capture the current cursor position BEFORE rebuilding
761+
// We must use the current editor selection, not read from ephemeral state,
762+
// to avoid cursor jumping when multiple users edit simultaneously
763+
const currentSelection = this.view.state.selection;
764+
const currentPmPos = currentSelection.anchor;
765+
766+
// Convert current ProseMirror position to markdown position
767+
const currentMarkdownPos = this.proseMirrorPosToMarkdownPos(currentPmPos);
768+
761769
const lines = stateText.split('\n');
762770
// console.log('Split into lines:', lines.length, 'lines:', JSON.stringify(lines));
763771

@@ -772,23 +780,16 @@ export class SynPmEditor extends LitElement {
772780
newDoc.content
773781
);
774782

775-
// Try to preserve cursor position
776-
const cursors = this._cursors.value;
777-
const myAgentSelection = cursors[encodeHashToBase64(this.slice.myPubKey)];
778-
if (myAgentSelection && state.text.length > 0) {
779-
const position = elemIdToPosition(
780-
myAgentSelection.left,
781-
myAgentSelection.position,
782-
state.text
783-
);
784-
if (position !== null && position !== undefined) {
785-
const docSize = tr.doc.content.size;
786-
const safePos = Math.max(0, Math.min(position, docSize));
787-
try {
788-
tr.setSelection(TextSelection.near(tr.doc.resolve(safePos)));
789-
} catch (e) {
790-
// Selection might be invalid, ignore
791-
}
783+
// Restore cursor position using the captured markdown position
784+
// Convert back from markdown to new ProseMirror position
785+
if (currentMarkdownPos !== null && currentMarkdownPos !== undefined) {
786+
const newPmPos = this.markdownPosToProseMirrorPos(currentMarkdownPos);
787+
const docSize = tr.doc.content.size;
788+
const safePos = Math.max(0, Math.min(newPmPos, docSize));
789+
try {
790+
tr.setSelection(TextSelection.near(tr.doc.resolve(safePos)));
791+
} catch (e) {
792+
// Selection might be invalid, ignore
792793
}
793794
}
794795

ui/src/notebooks-app.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ export class NotebooksApp extends LitElement {
277277

278278
async connectToHolochain() {
279279
const { view, profilesClient, client, weaveClient } = await this.buildClient();
280-
this._synStore = new SynStore(new SynClient(client, "notebooks"));
280+
this._synStore = new SynStore(new SynClient(client, "notebooks"), true);
281281

282282

283283
const appInfo = await this._synStore.client.client.appInfo();

0 commit comments

Comments
 (0)