Skip to content

Commit db17a4a

Browse files
committed
Updates to comment location
1 parent 31af857 commit db17a4a

File tree

2 files changed

+17
-13
lines changed

2 files changed

+17
-13
lines changed

src/prosemirror/plugins/comments.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -152,17 +152,24 @@ function reducer(tr: Transaction, state: CommentState): CommentState {
152152
});
153153
const action = tr.getMeta(key) as (CommentAction & { docId?: string }) | undefined;
154154
const { selectedComment } = state;
155+
// The docId might be updated by the action (unlikely)
155156
const docId = action?.docId ?? state.docId;
157+
if (tr.getMeta('addToHistory') === false) {
158+
// This is used in `prosemirror-collab`, other clients should not change our decoration state
159+
// This early exits with only updating the mapped decorations
160+
return { docId, selectedComment, decorations: nextDecorations };
161+
}
156162
if (!action) {
157163
// Check if we are in a comment!
158164
const around = decorations.find(tr.selection.from, tr.selection.to);
159-
if (around.length === 0) {
165+
if (around.length === 0 || !tr.selection.empty) {
160166
// We are not in a comment, and the action to select does not exist
161167
const hasSelectedComment = selectors.selectedSidenote(store.getState(), docId);
162168
if (hasSelectedComment) store.dispatch(actions.deselectSidenote(docId));
163169
const selected = updateSelectedDecorations(nextDecorations, null, tr.doc);
164170
return { docId, selectedComment: null, decorations: selected };
165171
}
172+
// Otherwise, send a select action to sidenotes as we change state.selection!
166173
const { id, domId } = around[0].spec as DecorationSpec;
167174
const isSelected = selectors.isSidenoteSelected(store.getState(), docId, id);
168175
if (!isSelected) store.dispatch(actions.selectAnchor(docId, domId));

src/prosemirror/plugins/selection.tsx

+9-12
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,15 @@ import { opts } from '../../connect';
99
class SelectionControl {
1010
dom: HTMLDivElement;
1111

12-
constructor(view: EditorView, stateKey: string) {
12+
constructor(view: EditorView, stateKey: any) {
1313
this.dom = document.createElement('div');
1414
this.dom.className = 'selection-control';
1515
ReactDOM.render(
1616
<Card style={{ borderRadius: '50%' }}>
1717
<IconButton
1818
color="primary"
19-
aria-label="add comment"
20-
onClick={() => {
21-
opts.addComment(stateKey, view);
22-
}}
19+
aria-label="Add Comment"
20+
onClick={() => opts.addComment(stateKey, view)}
2321
>
2422
<CommentIcon />
2523
</IconButton>
@@ -31,27 +29,26 @@ class SelectionControl {
3129
}
3230

3331
update(view: EditorView, lastState: EditorState | null) {
34-
const { state } = view;
35-
if (lastState && lastState.selection.eq?.(state.selection)) return;
32+
const { selection } = view.state;
33+
if (lastState?.selection.eq?.(selection)) return;
3634

3735
// Hide the tooltip if the selection is empty
38-
if (state.selection.empty) {
36+
if (selection.empty) {
3937
this.dom.style.display = 'none';
4038
return;
4139
}
4240

4341
// Otherwise, reposition it and update its content
4442
this.dom.style.display = '';
45-
const { from, to } = state.selection;
43+
// Use the first place you put the anchor, so the selection doesn't jump around
44+
const { anchor } = selection;
4645
// These are in screen coordinates
47-
const start = view.coordsAtPos(from);
46+
const start = view.coordsAtPos(anchor);
4847
// The box in which the tooltip is positioned, to use as base
4948
if (!this.dom.offsetParent) {
5049
return;
5150
}
5251
const box = this.dom.offsetParent.getBoundingClientRect();
53-
// Find a center-ish x position from the selection endpoints (when
54-
// crossing lines, end may be more to the left)
5552
this.dom.style.bottom = `${box.bottom - start.top - 30}px`;
5653
}
5754

0 commit comments

Comments
 (0)