quoin-editor 2.0.4 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +110 -0
- package/MIGRATION.md +1 -1
- package/README.md +14 -13
- package/dist/ai.cjs +124 -94
- package/dist/ai.d.cts +7 -0
- package/dist/ai.d.ts +7 -0
- package/dist/ai.js +50 -20
- package/dist/ai.js.map +1 -1
- package/dist/catalogue.cjs +28 -26
- package/dist/catalogue.js +19 -17
- package/dist/catalogue.js.map +1 -1
- package/dist/{chunk-JGEDJYIV.cjs → chunk-2FUWXPPC.cjs} +92 -98
- package/dist/{chunk-NHNW5DK3.js → chunk-3F76QQ65.js} +6 -6
- package/dist/{chunk-NHNW5DK3.js.map → chunk-3F76QQ65.js.map} +1 -1
- package/dist/{chunk-DBOZFNWU.js → chunk-3QYFAAQR.js} +3 -3
- package/dist/{chunk-DBOZFNWU.js.map → chunk-3QYFAAQR.js.map} +1 -1
- package/dist/{chunk-I7X7B3WD.cjs → chunk-4JDRDPLC.cjs} +17 -8
- package/dist/{chunk-EBSDPHPS.cjs → chunk-4UFWFV43.cjs} +1060 -719
- package/dist/{chunk-LM3DHROX.cjs → chunk-5AUIA4B3.cjs} +2 -2
- package/dist/{chunk-3INFNIGN.cjs → chunk-5H3BB5VJ.cjs} +131 -78
- package/dist/{chunk-DJU25PFC.cjs → chunk-5L2NSIHZ.cjs} +11 -11
- package/dist/{chunk-W376L2GM.js → chunk-6Y7JAWYY.js} +8 -8
- package/dist/chunk-6Y7JAWYY.js.map +1 -0
- package/dist/{chunk-UDBLZILE.js → chunk-ATKDXQEY.js} +12 -7
- package/dist/{chunk-UDBLZILE.js.map → chunk-ATKDXQEY.js.map} +1 -1
- package/dist/{chunk-A2IQHMIH.js → chunk-BE2SYPK5.js} +49 -54
- package/dist/chunk-BE2SYPK5.js.map +1 -0
- package/dist/{chunk-PURYVDC3.cjs → chunk-CFICD2JP.cjs} +21 -16
- package/dist/{chunk-3HW3WRYC.cjs → chunk-CSIUXYRU.cjs} +2 -2
- package/dist/{chunk-N7BSFDDM.cjs → chunk-DBKL524I.cjs} +23 -23
- package/dist/{chunk-XE3IYW5B.js → chunk-DEFYFIWW.js} +90 -37
- package/dist/chunk-DEFYFIWW.js.map +1 -0
- package/dist/{chunk-7E43TURF.cjs → chunk-ECI3PSMS.cjs} +7 -7
- package/dist/{chunk-4G645EYO.js → chunk-F73QEF7E.js} +5 -5
- package/dist/{chunk-4G645EYO.js.map → chunk-F73QEF7E.js.map} +1 -1
- package/dist/{chunk-KHRVCTQQ.cjs → chunk-FUT7XLMP.cjs} +61 -74
- package/dist/{chunk-7J63427U.cjs → chunk-GQSBOBOM.cjs} +375 -320
- package/dist/{chunk-LU3T3JB4.js → chunk-HPNSQWRD.js} +15 -28
- package/dist/chunk-HPNSQWRD.js.map +1 -0
- package/dist/{chunk-7Y4B7NHO.js → chunk-I34BFOLL.js} +18 -11
- package/dist/chunk-I34BFOLL.js.map +1 -0
- package/dist/{chunk-AJT54OMZ.js → chunk-IFRXEFQH.js} +9 -15
- package/dist/chunk-IFRXEFQH.js.map +1 -0
- package/dist/{chunk-YYW33WUL.cjs → chunk-K3XWVRL4.cjs} +8 -8
- package/dist/{chunk-LSI4RMTY.js → chunk-L5L6YNLT.js} +3 -3
- package/dist/{chunk-LSI4RMTY.js.map → chunk-L5L6YNLT.js.map} +1 -1
- package/dist/{chunk-2BPXVQBP.js → chunk-MO4UMXMT.js} +238 -86
- package/dist/chunk-MO4UMXMT.js.map +1 -0
- package/dist/{chunk-2QKFRKOP.cjs → chunk-N25EH2GZ.cjs} +351 -205
- package/dist/{chunk-CSPCDVCT.js → chunk-NCV2ML25.js} +3 -3
- package/dist/{chunk-CSPCDVCT.js.map → chunk-NCV2ML25.js.map} +1 -1
- package/dist/{chunk-NUQ64S5B.cjs → chunk-OJSKSQTL.cjs} +26 -26
- package/dist/chunk-PIWMU4BV.js +9 -0
- package/dist/chunk-PIWMU4BV.js.map +1 -0
- package/dist/chunk-QFGWSFOI.cjs +10 -0
- package/dist/{chunk-GPTJYWGS.js → chunk-RNBLVGWY.js} +3 -3
- package/dist/{chunk-GPTJYWGS.js.map → chunk-RNBLVGWY.js.map} +1 -1
- package/dist/{chunk-5RBMZGKV.js → chunk-TL2MJOWM.js} +325 -57
- package/dist/chunk-TL2MJOWM.js.map +1 -0
- package/dist/{chunk-YEDPBYO5.cjs → chunk-UDQ52EEC.cjs} +4 -4
- package/dist/{chunk-EIWPJWY3.js → chunk-UE2NQPNG.js} +5 -5
- package/dist/{chunk-EIWPJWY3.js.map → chunk-UE2NQPNG.js.map} +1 -1
- package/dist/{chunk-BE2YHZXA.cjs → chunk-ULV3SCYP.cjs} +26 -15
- package/dist/{chunk-WDBFGX3U.cjs → chunk-VTTMJGWP.cjs} +72 -77
- package/dist/{chunk-556PFYES.js → chunk-WK4UGDZN.js} +290 -235
- package/dist/chunk-WK4UGDZN.js.map +1 -0
- package/dist/{chunk-JZF6UQH5.cjs → chunk-WMKA37NJ.cjs} +12 -12
- package/dist/{chunk-F2ZK6Z52.js → chunk-Y26F2X4E.js} +3 -3
- package/dist/{chunk-F2ZK6Z52.js.map → chunk-Y26F2X4E.js.map} +1 -1
- package/dist/{chunk-FK7EBZPX.cjs → chunk-Z5EEDCRI.cjs} +549 -276
- package/dist/{chunk-G6NBQYMM.js → chunk-ZGFZRVQA.js} +817 -478
- package/dist/chunk-ZGFZRVQA.js.map +1 -0
- package/dist/{chunk-QLVX7MPS.js → chunk-ZQF45LA4.js} +19 -8
- package/dist/chunk-ZQF45LA4.js.map +1 -0
- package/dist/comments.cjs +127 -65
- package/dist/comments.d.cts +35 -2
- package/dist/comments.d.ts +35 -2
- package/dist/comments.js +73 -12
- package/dist/comments.js.map +1 -1
- package/dist/{diagram-extension-22x_njXB.d.ts → diagram-extension-BMlh8GCw.d.ts} +1 -1
- package/dist/{diagram-extension-C_FSkoj9.d.cts → diagram-extension-gmndUpti.d.cts} +1 -1
- package/dist/diagram.cjs +10 -9
- package/dist/diagram.d.cts +2 -2
- package/dist/diagram.d.ts +2 -2
- package/dist/diagram.js +7 -6
- package/dist/diff.cjs +25 -25
- package/dist/diff.js +3 -3
- package/dist/docx.cjs +31 -30
- package/dist/docx.js +5 -4
- package/dist/docx.js.map +1 -1
- package/dist/embed.cjs +10 -9
- package/dist/embed.js +8 -7
- package/dist/{emoji-extension-Dk5IQLZf.d.cts → emoji-extension-DD9CQTQj.d.cts} +1 -1
- package/dist/{emoji-extension-C832oGeT.d.ts → emoji-extension-U_PWZ2fX.d.ts} +1 -1
- package/dist/emoji.cjs +10 -9
- package/dist/emoji.d.cts +2 -2
- package/dist/emoji.d.ts +2 -2
- package/dist/emoji.js +7 -6
- package/dist/engine.cjs +58 -58
- package/dist/engine.d.cts +3 -3
- package/dist/engine.d.ts +3 -3
- package/dist/engine.js +3 -3
- package/dist/{find-extension-DmK9_N81.d.ts → find-extension-BGlqooZi.d.ts} +1 -1
- package/dist/{find-extension-BfruAPLi.d.cts → find-extension-BPnAJ8bY.d.cts} +1 -1
- package/dist/find.cjs +11 -10
- package/dist/find.d.cts +1 -1
- package/dist/find.d.ts +1 -1
- package/dist/find.js +7 -6
- package/dist/headless.cjs +70 -69
- package/dist/headless.d.cts +33 -10
- package/dist/headless.d.ts +33 -10
- package/dist/headless.js +5 -4
- package/dist/highlight.cjs +7 -6
- package/dist/highlight.js +6 -5
- package/dist/highlight.js.map +1 -1
- package/dist/{index-3fYvwqUZ.d.cts → index-DN7vRKFw.d.cts} +1 -1
- package/dist/{index-CgxnzCO5.d.ts → index-DyIYI3PM.d.ts} +1 -1
- package/dist/index.cjs +82 -81
- package/dist/index.d.cts +19 -12
- package/dist/index.d.ts +19 -12
- package/dist/index.js +6 -5
- package/dist/{labels-CiCxj2jP.d.cts → labels-BJORhN93.d.ts} +10 -5
- package/dist/{labels-BhRJYo46.d.ts → labels-CVYJ2-1X.d.cts} +10 -5
- package/dist/locale-ar.cjs +10 -0
- package/dist/locale-ar.d.cts +1 -1
- package/dist/locale-ar.d.ts +1 -1
- package/dist/locale-ar.js +10 -0
- package/dist/locale-ar.js.map +1 -1
- package/dist/locale-de.cjs +4 -0
- package/dist/locale-de.d.cts +1 -1
- package/dist/locale-de.d.ts +1 -1
- package/dist/locale-de.js +4 -0
- package/dist/locale-de.js.map +1 -1
- package/dist/locale-es.cjs +4 -0
- package/dist/locale-es.d.cts +1 -1
- package/dist/locale-es.d.ts +1 -1
- package/dist/locale-es.js +4 -0
- package/dist/locale-es.js.map +1 -1
- package/dist/locale-fr.cjs +4 -0
- package/dist/locale-fr.d.cts +1 -1
- package/dist/locale-fr.d.ts +1 -1
- package/dist/locale-fr.js +4 -0
- package/dist/locale-fr.js.map +1 -1
- package/dist/locale-ja.cjs +4 -0
- package/dist/locale-ja.d.cts +1 -1
- package/dist/locale-ja.d.ts +1 -1
- package/dist/locale-ja.js +4 -0
- package/dist/locale-ja.js.map +1 -1
- package/dist/locale-pt.cjs +4 -0
- package/dist/locale-pt.d.cts +1 -1
- package/dist/locale-pt.d.ts +1 -1
- package/dist/locale-pt.js +4 -0
- package/dist/locale-pt.js.map +1 -1
- package/dist/locale-zh.cjs +4 -0
- package/dist/locale-zh.d.cts +1 -1
- package/dist/locale-zh.d.ts +1 -1
- package/dist/locale-zh.js +4 -0
- package/dist/locale-zh.js.map +1 -1
- package/dist/math.cjs +11 -10
- package/dist/math.js +9 -8
- package/dist/mention.cjs +11 -10
- package/dist/mention.js +9 -8
- package/dist/{node-reveal-DY6bimv3.d.cts → node-reveal-Be7Xa0BL.d.cts} +1 -1
- package/dist/{node-reveal-BnFcnHhz.d.ts → node-reveal-CftIEqF_.d.ts} +1 -1
- package/dist/palette-DuIFHYHc.d.cts +10 -0
- package/dist/palette-DuIFHYHc.d.ts +10 -0
- package/dist/presence.cjs +39 -38
- package/dist/presence.js +8 -7
- package/dist/presence.js.map +1 -1
- package/dist/source.cjs +10 -9
- package/dist/source.d.cts +1 -1
- package/dist/source.d.ts +1 -1
- package/dist/source.js +6 -5
- package/dist/source.js.map +1 -1
- package/dist/{stats-extension-Dmw0Ujxe.d.ts → stats-extension-Bbpr593p.d.ts} +1 -1
- package/dist/{stats-extension-D5HySF0a.d.cts → stats-extension-D7FaeydW.d.cts} +1 -1
- package/dist/stats.cjs +12 -10
- package/dist/stats.d.cts +2 -2
- package/dist/stats.d.ts +2 -2
- package/dist/stats.js +9 -7
- package/dist/styles.css +1 -1
- package/dist/{table-extension-7LkLNK6Q.d.cts → table-extension-DNijjmxV.d.cts} +1 -1
- package/dist/{table-extension-DEpV0DnP.d.ts → table-extension-Dp6FYGPh.d.ts} +1 -1
- package/dist/table.cjs +26 -25
- package/dist/table.d.cts +4 -3
- package/dist/table.d.ts +4 -3
- package/dist/table.js +7 -6
- package/dist/{toc-extension-Dvh37bWQ.d.cts → toc-extension-BGEVAmSY.d.cts} +1 -1
- package/dist/{toc-extension-SVckrFmb.d.ts → toc-extension-DZIe40eV.d.ts} +1 -1
- package/dist/toc.cjs +10 -9
- package/dist/toc.d.cts +2 -2
- package/dist/toc.d.ts +2 -2
- package/dist/toc.js +7 -6
- package/dist/{types-DMuuDBVh.d.ts → types-Byu2a9qk.d.ts} +6 -1
- package/dist/{types-Bzhq5AXj.d.cts → types-DdDlCyyZ.d.cts} +6 -1
- package/dist/view.cjs +4 -4
- package/dist/view.js +2 -2
- package/dist/yjs.cjs +121 -121
- package/dist/yjs.d.cts +2 -2
- package/dist/yjs.d.ts +2 -2
- package/dist/yjs.js +5 -5
- package/package.json +4 -3
- package/dist/chunk-2BPXVQBP.js.map +0 -1
- package/dist/chunk-556PFYES.js.map +0 -1
- package/dist/chunk-5RBMZGKV.js.map +0 -1
- package/dist/chunk-7Y4B7NHO.js.map +0 -1
- package/dist/chunk-A2IQHMIH.js.map +0 -1
- package/dist/chunk-AJT54OMZ.js.map +0 -1
- package/dist/chunk-G6NBQYMM.js.map +0 -1
- package/dist/chunk-LU3T3JB4.js.map +0 -1
- package/dist/chunk-QLVX7MPS.js.map +0 -1
- package/dist/chunk-W376L2GM.js.map +0 -1
- package/dist/chunk-XE3IYW5B.js.map +0 -1
- package/dist/palette-BrX-hEd-.d.cts +0 -4
- package/dist/palette-BrX-hEd-.d.ts +0 -4
package/dist/comments.cjs
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
5
|
-
var
|
|
6
|
-
var
|
|
7
|
-
var
|
|
4
|
+
var chunk5AUIA4B3_cjs = require('./chunk-5AUIA4B3.cjs');
|
|
5
|
+
var chunkCSIUXYRU_cjs = require('./chunk-CSIUXYRU.cjs');
|
|
6
|
+
var chunk4UFWFV43_cjs = require('./chunk-4UFWFV43.cjs');
|
|
7
|
+
var chunkN25EH2GZ_cjs = require('./chunk-N25EH2GZ.cjs');
|
|
8
8
|
var chunkZWTIRGY5_cjs = require('./chunk-ZWTIRGY5.cjs');
|
|
9
9
|
require('./chunk-A6PGQVTR.cjs');
|
|
10
|
-
|
|
11
|
-
require('./chunk-
|
|
12
|
-
|
|
10
|
+
require('./chunk-QFGWSFOI.cjs');
|
|
11
|
+
var chunkZ5EEDCRI_cjs = require('./chunk-Z5EEDCRI.cjs');
|
|
12
|
+
require('./chunk-5L2NSIHZ.cjs');
|
|
13
|
+
var chunk4JDRDPLC_cjs = require('./chunk-4JDRDPLC.cjs');
|
|
13
14
|
var react = require('react');
|
|
14
15
|
var jsxRuntime = require('react/jsx-runtime');
|
|
15
16
|
var DialogPrimitive = require('@radix-ui/react-dialog');
|
|
17
|
+
var reactDirection = require('@radix-ui/react-direction');
|
|
16
18
|
|
|
17
19
|
function _interopNamespace(e) {
|
|
18
20
|
if (e && e.__esModule) return e;
|
|
@@ -40,7 +42,7 @@ function addRegion(anchors, block, region, inline2) {
|
|
|
40
42
|
let position = 0;
|
|
41
43
|
for (const node of inline2) {
|
|
42
44
|
const from = position;
|
|
43
|
-
position +=
|
|
45
|
+
position += chunk4JDRDPLC_cjs.nodeLength(node);
|
|
44
46
|
for (const id of idsOf(node)) {
|
|
45
47
|
const ranges = anchors.get(id) ?? [];
|
|
46
48
|
const last = ranges[ranges.length - 1];
|
|
@@ -67,25 +69,25 @@ function commentAnchors(doc) {
|
|
|
67
69
|
var atomLabel = (node) => node.kind === "atom" ? node.attrs.label ?? "" : "";
|
|
68
70
|
function anchorText(doc, ranges) {
|
|
69
71
|
return ranges.map(({ block, region, from, to }) => {
|
|
70
|
-
const inline2 =
|
|
71
|
-
return
|
|
72
|
+
const inline2 = chunk4JDRDPLC_cjs.blockById(doc, block)?.regions[region] ?? [];
|
|
73
|
+
return chunk4JDRDPLC_cjs.inlineText(chunk4JDRDPLC_cjs.sliceInline(inline2, from, to), atomLabel);
|
|
72
74
|
}).join(" ");
|
|
73
75
|
}
|
|
74
76
|
function commentIdsAt(doc, { block, region, offset }) {
|
|
75
|
-
const inline2 =
|
|
77
|
+
const inline2 = chunk4JDRDPLC_cjs.blockById(doc, block)?.regions[region] ?? [];
|
|
76
78
|
const ids = /* @__PURE__ */ new Set();
|
|
77
79
|
let position = 0;
|
|
78
80
|
for (const node of inline2) {
|
|
79
|
-
const end = position +
|
|
81
|
+
const end = position + chunk4JDRDPLC_cjs.nodeLength(node);
|
|
80
82
|
if (position <= offset && offset <= end && end > position) idsOf(node).forEach((id) => ids.add(id));
|
|
81
83
|
position = end;
|
|
82
84
|
}
|
|
83
85
|
return [...ids].sort();
|
|
84
86
|
}
|
|
85
87
|
function threadRemoval(state, id) {
|
|
86
|
-
const tr = new
|
|
88
|
+
const tr = new chunkZ5EEDCRI_cjs.Transaction(state).setOrigin("command");
|
|
87
89
|
for (const { block, region, from, to } of commentAnchors(state.doc).get(id) ?? []) {
|
|
88
|
-
tr.step(
|
|
90
|
+
tr.step(chunkZ5EEDCRI_cjs.removeMarkStep(block, region, from, to, { type: "comment", attrs: { id } }));
|
|
89
91
|
}
|
|
90
92
|
return tr;
|
|
91
93
|
}
|
|
@@ -96,14 +98,14 @@ function mapPendingRanges(tr, ranges, state) {
|
|
|
96
98
|
const from = tr.mapPos({ block: range.block, region: range.region, offset: range.from }, 1);
|
|
97
99
|
const to = tr.mapPos({ block: range.block, region: range.region, offset: range.to }, -1);
|
|
98
100
|
const { index } = state.doc;
|
|
99
|
-
if (!index.has(from.block) || !index.has(to.block) ||
|
|
100
|
-
return
|
|
101
|
+
if (!index.has(from.block) || !index.has(to.block) || chunkZ5EEDCRI_cjs.comparePos(state.doc, from, to) >= 0) return [];
|
|
102
|
+
return chunkZ5EEDCRI_cjs.markRanges({ ...state, selection: chunkZ5EEDCRI_cjs.textSelection(from, to) });
|
|
101
103
|
});
|
|
102
104
|
}
|
|
103
105
|
|
|
104
106
|
// src/extensions/comments/comments-plugin.ts
|
|
105
107
|
var isEnded = (ended, id, current) => ended.some((thread) => thread.id === id && thread.seen?.resolved === current?.resolved);
|
|
106
|
-
var commentsKey =
|
|
108
|
+
var commentsKey = chunkZ5EEDCRI_cjs.createPluginKey("comments");
|
|
107
109
|
var COMMENTS = "comments";
|
|
108
110
|
var IDLE = { pending: [], active: null, open: null, ended: [] };
|
|
109
111
|
function act(value, action) {
|
|
@@ -156,26 +158,26 @@ var commentsPlugin = {
|
|
|
156
158
|
|
|
157
159
|
// src/extensions/comments/comment-create.ts
|
|
158
160
|
var nextKey = 0;
|
|
159
|
-
var hasCommentableText = (state) => state.selection?.kind === "text" &&
|
|
161
|
+
var hasCommentableText = (state) => state.selection?.kind === "text" && chunkZ5EEDCRI_cjs.markRanges(state).length > 0;
|
|
160
162
|
var requestComment = (state, dispatch) => {
|
|
161
163
|
const { selection } = state;
|
|
162
|
-
if (selection?.kind !== "text" ||
|
|
163
|
-
const ranges =
|
|
164
|
+
if (selection?.kind !== "text" || chunkZ5EEDCRI_cjs.getPluginState(state, commentsKey).pending.length > 0) return false;
|
|
165
|
+
const ranges = chunkZ5EEDCRI_cjs.markRanges(state);
|
|
164
166
|
if (ranges.length === 0) return false;
|
|
165
167
|
if (dispatch === void 0) return true;
|
|
166
168
|
const pending = { key: ++nextKey, ranges, selection };
|
|
167
169
|
const action = { type: "pending", pending };
|
|
168
|
-
dispatch(new
|
|
170
|
+
dispatch(new chunkZ5EEDCRI_cjs.Transaction(state).setMeta(COMMENTS, action).setMeta("addToHistory", false));
|
|
169
171
|
return true;
|
|
170
172
|
};
|
|
171
173
|
function settledTransaction(editor, key, id) {
|
|
172
|
-
const pending =
|
|
174
|
+
const pending = chunkZ5EEDCRI_cjs.getPluginState(editor.state, commentsKey).pending.find((anchor) => anchor.key === key);
|
|
173
175
|
const tr = editor.createTransaction().setOrigin("command");
|
|
174
176
|
const ranges = id === null ? [] : pending?.ranges ?? [];
|
|
175
177
|
for (const { block, region, from, to } of ranges) {
|
|
176
|
-
tr.step(
|
|
178
|
+
tr.step(chunkZ5EEDCRI_cjs.addMarkStep(block, region, from, to, { type: "comment", attrs: { id } }));
|
|
177
179
|
}
|
|
178
|
-
const untouched = pending !== void 0 &&
|
|
180
|
+
const untouched = pending !== void 0 && chunkZ5EEDCRI_cjs.sameSelection(editor.state.selection, pending.selection);
|
|
179
181
|
const open = id !== null && ranges.length > 0 && untouched ? { ids: [id], focus: true } : void 0;
|
|
180
182
|
const action = { type: "settled", key, open };
|
|
181
183
|
return tr.setMeta(COMMENTS, action);
|
|
@@ -186,7 +188,7 @@ function create(editor, pending, onCreate, link) {
|
|
|
186
188
|
if (link.mounts === 0) return;
|
|
187
189
|
const tr = settledTransaction(editor, pending.key, id);
|
|
188
190
|
editor.dispatch(tr);
|
|
189
|
-
if (id === null) link.report(
|
|
191
|
+
if (id === null) link.report(chunk4UFWFV43_cjs.toError(error));
|
|
190
192
|
else if (!tr.docChanged) link.report(new Error(`Comment thread ${id} has no text: it was deleted meanwhile`));
|
|
191
193
|
};
|
|
192
194
|
new Promise((resolve) => resolve(onCreate(input))).then(
|
|
@@ -203,20 +205,20 @@ function watchCreates(editor, onCreate, link) {
|
|
|
203
205
|
|
|
204
206
|
// src/extensions/comments/comment-open.ts
|
|
205
207
|
function openIds(state, threads, ids) {
|
|
206
|
-
const { ended } =
|
|
208
|
+
const { ended } = chunkZ5EEDCRI_cjs.getPluginState(state, commentsKey);
|
|
207
209
|
return ids.filter((id) => {
|
|
208
210
|
const thread = threads.find(id);
|
|
209
211
|
return thread?.resolved === false && !isEnded(ended, id, thread);
|
|
210
212
|
});
|
|
211
213
|
}
|
|
212
214
|
function commentsTransaction(state, action) {
|
|
213
|
-
return new
|
|
215
|
+
return new chunkZ5EEDCRI_cjs.Transaction(state).setMeta(COMMENTS, action).setMeta("addToHistory", false);
|
|
214
216
|
}
|
|
215
217
|
function commentCommand(threads) {
|
|
216
218
|
return (state, dispatch) => {
|
|
217
219
|
if (requestComment(state, dispatch)) return true;
|
|
218
220
|
const { selection } = state;
|
|
219
|
-
if (selection?.kind !== "text" || !
|
|
221
|
+
if (selection?.kind !== "text" || !chunkZ5EEDCRI_cjs.isCollapsed(selection)) return false;
|
|
220
222
|
const ids = openIds(state, threads, commentIdsAt(state.doc, selection.head));
|
|
221
223
|
if (ids.length === 0) return false;
|
|
222
224
|
dispatch?.(commentsTransaction(state, { type: "open", open: { ids, focus: true } }));
|
|
@@ -290,7 +292,7 @@ function place(controller, box, gap) {
|
|
|
290
292
|
root.style.setProperty(HEIGHT, `${bottom}px`);
|
|
291
293
|
}
|
|
292
294
|
function useBlockAligned(controller, box, gap, key) {
|
|
293
|
-
|
|
295
|
+
chunkN25EH2GZ_cjs.useIsomorphicLayoutEffect(() => {
|
|
294
296
|
const element = box.current;
|
|
295
297
|
const view = element?.ownerDocument.defaultView;
|
|
296
298
|
if (!element || !view) return void 0;
|
|
@@ -334,10 +336,10 @@ function CommentMarkers({ env, box, entries, onOpen }) {
|
|
|
334
336
|
"data-rail-item": "",
|
|
335
337
|
"data-block": block,
|
|
336
338
|
"aria-label": env.labels.showComments(ids.length),
|
|
337
|
-
className:
|
|
339
|
+
className: chunk4UFWFV43_cjs.cn("quoin-comments-marker", chunk4UFWFV43_cjs.FOCUS_RING),
|
|
338
340
|
onClick: (event) => onOpen(ids[0], event.currentTarget),
|
|
339
341
|
children: [
|
|
340
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
342
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunk4UFWFV43_cjs.MessageSquare, { "aria-hidden": "true" }),
|
|
341
343
|
ids.length
|
|
342
344
|
]
|
|
343
345
|
},
|
|
@@ -351,7 +353,7 @@ async function called(link, call) {
|
|
|
351
353
|
await call();
|
|
352
354
|
return true;
|
|
353
355
|
} catch (error) {
|
|
354
|
-
link.report(
|
|
356
|
+
link.report(chunk4UFWFV43_cjs.toError(error));
|
|
355
357
|
return false;
|
|
356
358
|
}
|
|
357
359
|
}
|
|
@@ -366,7 +368,7 @@ function sendReply(link, call, id, body) {
|
|
|
366
368
|
}
|
|
367
369
|
var initials = (name) => name.trim().split(/\s+/).slice(0, 2).map((word) => Array.from(word)[0]?.toUpperCase() ?? "").join("");
|
|
368
370
|
function CommentAvatar({ author }) {
|
|
369
|
-
const picture =
|
|
371
|
+
const picture = chunk5AUIA4B3_cjs.webAddress(author.avatarUrl);
|
|
370
372
|
const [failed, setFailed] = react.useState(null);
|
|
371
373
|
if (picture !== null && picture !== failed) {
|
|
372
374
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -444,21 +446,21 @@ function ReplyBox({ env, threadId, first }) {
|
|
|
444
446
|
}
|
|
445
447
|
),
|
|
446
448
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
447
|
-
|
|
449
|
+
chunk4UFWFV43_cjs.Button,
|
|
448
450
|
{
|
|
449
451
|
type: "submit",
|
|
450
452
|
variant: "ghost",
|
|
451
453
|
size: "icon-sm",
|
|
452
454
|
"aria-label": labels.send,
|
|
453
455
|
"aria-disabled": text === "" || sending || void 0,
|
|
454
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
456
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(chunk4UFWFV43_cjs.SendHorizontal, {})
|
|
455
457
|
}
|
|
456
458
|
)
|
|
457
459
|
] });
|
|
458
460
|
}
|
|
459
461
|
function ThreadView({ env, id, thread, onEnded }) {
|
|
460
462
|
const { controller, host, labels, link } = env;
|
|
461
|
-
const readOnly =
|
|
463
|
+
const readOnly = chunkN25EH2GZ_cjs.useReadOnly(controller);
|
|
462
464
|
const [busy, setBusy] = react.useState(false);
|
|
463
465
|
const alive = react.useRef(true);
|
|
464
466
|
const root = react.useRef(null);
|
|
@@ -479,11 +481,11 @@ function ThreadView({ env, id, thread, onEnded }) {
|
|
|
479
481
|
if (ended && stayed) onEnded();
|
|
480
482
|
};
|
|
481
483
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: root, className: "flex flex-col gap-3", children: [
|
|
482
|
-
comments.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "flex flex-col gap-3", children: comments.map((comment) => /* @__PURE__ */ jsxRuntime.jsx(CommentItem, { comment, labels }, comment.id)) }),
|
|
484
|
+
comments.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("ol", { className: "flex list-none flex-col gap-3", children: comments.map((comment) => /* @__PURE__ */ jsxRuntime.jsx(CommentItem, { comment, labels }, comment.id)) }),
|
|
483
485
|
/* @__PURE__ */ jsxRuntime.jsx(ReplyBox, { env, threadId: id, first: comments.length === 0 }),
|
|
484
486
|
!readOnly && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-1", children: [
|
|
485
487
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
486
|
-
|
|
488
|
+
chunk4UFWFV43_cjs.Button,
|
|
487
489
|
{
|
|
488
490
|
type: "button",
|
|
489
491
|
variant: "ghost",
|
|
@@ -494,7 +496,7 @@ function ThreadView({ env, id, thread, onEnded }) {
|
|
|
494
496
|
}
|
|
495
497
|
),
|
|
496
498
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
497
|
-
|
|
499
|
+
chunk4UFWFV43_cjs.Button,
|
|
498
500
|
{
|
|
499
501
|
type: "button",
|
|
500
502
|
variant: "ghost",
|
|
@@ -531,7 +533,7 @@ function ThreadCard({ env, entry, active, expanded, onToggle }) {
|
|
|
531
533
|
ref: header,
|
|
532
534
|
type: "button",
|
|
533
535
|
"aria-expanded": expanded,
|
|
534
|
-
className:
|
|
536
|
+
className: chunk4UFWFV43_cjs.cn("flex w-full flex-col items-start gap-1 rounded-sm text-start", chunk4UFWFV43_cjs.FOCUS_RING),
|
|
535
537
|
onClick: () => onToggle(expanded ? null : thread.id),
|
|
536
538
|
children: [
|
|
537
539
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: removed ? "text-xs text-muted-foreground italic" : "quoin-comments-quote", children: removed ? labels.textRemoved : anchorText2 }),
|
|
@@ -551,7 +553,7 @@ var GAP2 = 8;
|
|
|
551
553
|
var layoutKey = (entries, value) => `${value.active} ${value.open !== null} ${entries.map(({ thread, ranges }) => `${thread.id}:${ranges[0]?.block}`)}`;
|
|
552
554
|
function CommentsRail({ env, box, entries, value, onToggle }) {
|
|
553
555
|
useBlockAligned(env.controller, box, GAP2, layoutKey(entries, value));
|
|
554
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: box, className: "quoin-comments-rail", children: /* @__PURE__ */ jsxRuntime.jsx("ul", { "aria-label": env.labels.comments, children: entries.map((entry) => /* @__PURE__ */ jsxRuntime.jsx("li", { "data-rail-item": "", "data-block": entry.ranges[0]?.block ?? "", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
556
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: box, className: "quoin-comments-rail", children: /* @__PURE__ */ jsxRuntime.jsx("ul", { "aria-label": env.labels.comments, className: "list-none", children: entries.map((entry) => /* @__PURE__ */ jsxRuntime.jsx("li", { "data-rail-item": "", "data-block": entry.ranges[0]?.block ?? "", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
555
557
|
ThreadCard,
|
|
556
558
|
{
|
|
557
559
|
env,
|
|
@@ -565,6 +567,7 @@ function CommentsRail({ env, box, entries, value, onToggle }) {
|
|
|
565
567
|
function CommentsSheet({ env, entries, value, onToggle, onClose, returnFocus }) {
|
|
566
568
|
const { labels } = env;
|
|
567
569
|
const content = react.useRef(null);
|
|
570
|
+
const dir = reactDirection.useDirection();
|
|
568
571
|
const outside = react.useRef(false);
|
|
569
572
|
const focusOpened = (event) => {
|
|
570
573
|
const opened = content.current?.querySelector('[aria-expanded="true"]');
|
|
@@ -584,6 +587,7 @@ function CommentsSheet({ env, entries, value, onToggle, onClose, returnFocus })
|
|
|
584
587
|
DialogPrimitive__namespace.Content,
|
|
585
588
|
{
|
|
586
589
|
ref: content,
|
|
590
|
+
dir,
|
|
587
591
|
"aria-describedby": void 0,
|
|
588
592
|
className: "quoin quoin-comments-sheet",
|
|
589
593
|
onOpenAutoFocus: focusOpened,
|
|
@@ -597,9 +601,9 @@ function CommentsSheet({ env, entries, value, onToggle, onClose, returnFocus })
|
|
|
597
601
|
children: [
|
|
598
602
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
599
603
|
/* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Title, { className: "text-sm font-semibold", children: labels.comments }),
|
|
600
|
-
/* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
604
|
+
/* @__PURE__ */ jsxRuntime.jsx(DialogPrimitive__namespace.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(chunk4UFWFV43_cjs.Button, { type: "button", variant: "ghost", size: "icon-sm", "aria-label": labels.close, children: /* @__PURE__ */ jsxRuntime.jsx(chunk4UFWFV43_cjs.X, {}) }) })
|
|
601
605
|
] }),
|
|
602
|
-
/* @__PURE__ */ jsxRuntime.jsx("ul", { "aria-label": labels.comments, className: "flex flex-col gap-2", children: entries.map((entry) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
606
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { "aria-label": labels.comments, className: "flex list-none flex-col gap-2", children: entries.map((entry) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
603
607
|
ThreadCard,
|
|
604
608
|
{
|
|
605
609
|
env,
|
|
@@ -624,11 +628,11 @@ function railEntries(doc, threads, ended = []) {
|
|
|
624
628
|
const ranges = anchors.get(thread.id) ?? NONE;
|
|
625
629
|
return { thread, ranges, anchorText: anchorText(doc, ranges) };
|
|
626
630
|
});
|
|
627
|
-
const place2 = ({ ranges: [first] }) => first === void 0 ? [Infinity, 0] : [
|
|
631
|
+
const place2 = ({ ranges: [first] }) => first === void 0 ? [Infinity, 0] : [chunk4JDRDPLC_cjs.indexOfBlock(doc, first.block), first.from];
|
|
628
632
|
return entries.map((entry, order) => ({ entry, order, at: place2(entry) })).sort((a, b) => a.at[0] - b.at[0] || a.at[1] - b.at[1] || a.order - b.order).map(({ entry }) => entry);
|
|
629
633
|
}
|
|
630
634
|
function ThreadChooser({ env, choices, onChoose }) {
|
|
631
|
-
return /* @__PURE__ */ jsxRuntime.jsx("ul", { "aria-label": env.labels.threadsHere, className: "flex flex-col gap-1", children: choices.map(({ id, anchorText: anchorText2, preview }) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
635
|
+
return /* @__PURE__ */ jsxRuntime.jsx("ul", { "aria-label": env.labels.threadsHere, className: "flex list-none flex-col gap-1", children: choices.map(({ id, anchorText: anchorText2, preview }) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
632
636
|
"button",
|
|
633
637
|
{
|
|
634
638
|
type: "button",
|
|
@@ -644,22 +648,22 @@ function ThreadChooser({ env, choices, onChoose }) {
|
|
|
644
648
|
var docOf = (state) => state.doc;
|
|
645
649
|
function focusIsOurs(controller, content) {
|
|
646
650
|
const active = content?.ownerDocument.activeElement ?? null;
|
|
647
|
-
return active === null || active === active.ownerDocument.body ||
|
|
651
|
+
return active === null || active === active.ownerDocument.body || chunkCSIUXYRU_cjs.ownsNode(controller, active);
|
|
648
652
|
}
|
|
649
653
|
function ThreadPopover({ env, open, threads, onChoose, onClose }) {
|
|
650
654
|
const { controller, labels } = env;
|
|
651
|
-
const doc =
|
|
655
|
+
const doc = chunkN25EH2GZ_cjs.useEditorState(controller, docOf);
|
|
652
656
|
const anchors = commentAnchors(doc);
|
|
653
657
|
const { ids } = open;
|
|
654
658
|
const first = ids.map((id) => anchors.get(id)?.[0]).find(Boolean);
|
|
655
659
|
const latest = react.useRef(first);
|
|
656
|
-
|
|
660
|
+
chunkN25EH2GZ_cjs.useIsomorphicLayoutEffect(() => {
|
|
657
661
|
if (first) latest.current = first;
|
|
658
662
|
});
|
|
659
663
|
const anchor = react.useMemo(
|
|
660
664
|
() => ({
|
|
661
|
-
current:
|
|
662
|
-
() => latest.current ?
|
|
665
|
+
current: chunk4UFWFV43_cjs.virtualAnchor(
|
|
666
|
+
() => latest.current ? chunk4UFWFV43_cjs.rangeRect(controller, latest.current) : null,
|
|
663
667
|
() => latest.current && controller.registry.get(latest.current.block, latest.current.region)
|
|
664
668
|
)
|
|
665
669
|
}),
|
|
@@ -672,7 +676,7 @@ function ThreadPopover({ env, open, threads, onChoose, onClose }) {
|
|
|
672
676
|
target?.focus();
|
|
673
677
|
}
|
|
674
678
|
};
|
|
675
|
-
|
|
679
|
+
chunkN25EH2GZ_cjs.useIsomorphicLayoutEffect(() => {
|
|
676
680
|
if (open.focus) focusField();
|
|
677
681
|
}, [open]);
|
|
678
682
|
if (first === void 0 && latest.current === void 0) return null;
|
|
@@ -693,7 +697,7 @@ function ThreadPopover({ env, open, threads, onChoose, onClose }) {
|
|
|
693
697
|
};
|
|
694
698
|
const choices = ids.map((id) => ({ id, anchorText: textOf(id), preview: threads.find(id)?.comments[0]?.body ?? "" }));
|
|
695
699
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
696
|
-
|
|
700
|
+
chunk4UFWFV43_cjs.Popover,
|
|
697
701
|
{
|
|
698
702
|
open: true,
|
|
699
703
|
modal: false,
|
|
@@ -701,9 +705,9 @@ function ThreadPopover({ env, open, threads, onChoose, onClose }) {
|
|
|
701
705
|
if (!next) onClose();
|
|
702
706
|
},
|
|
703
707
|
children: [
|
|
704
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
708
|
+
/* @__PURE__ */ jsxRuntime.jsx(chunk4UFWFV43_cjs.PopoverAnchor, { virtualRef: anchor }),
|
|
705
709
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
706
|
-
|
|
710
|
+
chunk4UFWFV43_cjs.PopoverContent,
|
|
707
711
|
{
|
|
708
712
|
ref: content,
|
|
709
713
|
"aria-label": gone ? labels.textRemoved : single ? labels.thread(textOf(ids[0])) : labels.threadsHere,
|
|
@@ -751,7 +755,7 @@ function useAnchorClicks(controller, threads) {
|
|
|
751
755
|
var WIDE_CANVAS = 800;
|
|
752
756
|
function useCanvasWide(box, initial) {
|
|
753
757
|
const [wide, setWide] = react.useState(initial);
|
|
754
|
-
|
|
758
|
+
chunkN25EH2GZ_cjs.useIsomorphicLayoutEffect(() => {
|
|
755
759
|
const canvas = box.current?.parentElement;
|
|
756
760
|
if (!canvas) return void 0;
|
|
757
761
|
const measure = () => setWide(canvas.offsetWidth >= WIDE_CANVAS);
|
|
@@ -765,18 +769,18 @@ function useCanvasWide(box, initial) {
|
|
|
765
769
|
function useThreads(threads) {
|
|
766
770
|
return react.useSyncExternalStore(threads.subscribe, threads.get, threads.get);
|
|
767
771
|
}
|
|
768
|
-
var commentsOf = (state) =>
|
|
772
|
+
var commentsOf = (state) => chunkZ5EEDCRI_cjs.getPluginState(state, commentsKey);
|
|
769
773
|
var docOf2 = (state) => state.doc;
|
|
770
774
|
function CommentsOverlay({ controller, host, labels }) {
|
|
771
|
-
const { onError } =
|
|
775
|
+
const { onError } = chunk4UFWFV43_cjs.useQuoin();
|
|
772
776
|
const link = linkOf(controller.editor);
|
|
773
|
-
|
|
777
|
+
chunkN25EH2GZ_cjs.useIsomorphicLayoutEffect(() => {
|
|
774
778
|
link.report = onError;
|
|
775
779
|
}, [link, onError]);
|
|
776
780
|
useAnchorClicks(controller, host.threads);
|
|
777
781
|
const threads = useThreads(host.threads);
|
|
778
|
-
const value =
|
|
779
|
-
const doc =
|
|
782
|
+
const value = chunkN25EH2GZ_cjs.useEditorState(controller, commentsOf);
|
|
783
|
+
const doc = chunkN25EH2GZ_cjs.useEditorState(controller, docOf2);
|
|
780
784
|
const entries = react.useMemo(() => railEntries(doc, threads, value.ended), [doc, threads, value.ended]);
|
|
781
785
|
const box = react.useRef(null);
|
|
782
786
|
const wide = useCanvasWide(box, host.initialLayout === "wide");
|
|
@@ -836,7 +840,7 @@ var ACTIVE = { class: "quoin-comment-active" };
|
|
|
836
840
|
var inline = (ranges, attrs) => ranges.map((range) => ({ kind: "inline", ...range, attrs }));
|
|
837
841
|
var drawn = /* @__PURE__ */ new WeakMap();
|
|
838
842
|
function commentsDecorations(state) {
|
|
839
|
-
const value =
|
|
843
|
+
const value = chunkZ5EEDCRI_cjs.getPluginState(state, commentsKey);
|
|
840
844
|
const last = drawn.get(value);
|
|
841
845
|
if (last?.doc === state.doc) return last.decorations;
|
|
842
846
|
const active = value.active === null ? [] : commentAnchors(state.doc).get(value.active) ?? [];
|
|
@@ -848,7 +852,7 @@ function commentsDecorations(state) {
|
|
|
848
852
|
// src/extensions/comments/watch-ended.ts
|
|
849
853
|
function watchEnded(editor, threads) {
|
|
850
854
|
return threads.subscribe(() => {
|
|
851
|
-
const { ended } =
|
|
855
|
+
const { ended } = chunkZ5EEDCRI_cjs.getPluginState(editor.state, commentsKey);
|
|
852
856
|
const kept = ended.filter(({ id }) => isEnded(ended, id, threads.find(id)));
|
|
853
857
|
if (kept.length < ended.length) editor.dispatch(commentsTransaction(editor.state, { type: "caught", kept }));
|
|
854
858
|
});
|
|
@@ -856,9 +860,9 @@ function watchEnded(editor, threads) {
|
|
|
856
860
|
var commentItem = (labels) => ({
|
|
857
861
|
id: "comment",
|
|
858
862
|
title: labels.comment,
|
|
859
|
-
icon:
|
|
863
|
+
icon: chunk4UFWFV43_cjs.MessageSquarePlus,
|
|
860
864
|
shortcut: "Mod-Alt-m",
|
|
861
|
-
available: (state) => hasCommentableText(state) &&
|
|
865
|
+
available: (state) => hasCommentableText(state) && chunkZ5EEDCRI_cjs.getPluginState(state, commentsKey).pending.length === 0,
|
|
862
866
|
// Focus goes back to the text first: the button leaves the toolbar while the thread is being asked for.
|
|
863
867
|
run: (controller) => {
|
|
864
868
|
controller.focus();
|
|
@@ -872,7 +876,7 @@ function commentsExtension(options) {
|
|
|
872
876
|
return /* @__PURE__ */ jsxRuntime.jsx(CommentsOverlay, { controller, host, labels });
|
|
873
877
|
}
|
|
874
878
|
const ui = { bubbleItems: [commentItem(labels)], overlays: [Overlay] };
|
|
875
|
-
return
|
|
879
|
+
return chunkZ5EEDCRI_cjs.defineExtension({
|
|
876
880
|
name: "comments",
|
|
877
881
|
plugins: [commentsPlugin],
|
|
878
882
|
decorations: commentsDecorations,
|
|
@@ -919,6 +923,64 @@ function createCommentThreads(initial = NO_THREADS) {
|
|
|
919
923
|
};
|
|
920
924
|
}
|
|
921
925
|
|
|
926
|
+
// src/extensions/comments/shared-threads.ts
|
|
927
|
+
var byTime = (a, b) => (a.createdAt ?? "").localeCompare(b.createdAt ?? "") || a.id.localeCompare(b.id);
|
|
928
|
+
function readThreads(metas, replies) {
|
|
929
|
+
const comments = /* @__PURE__ */ new Map();
|
|
930
|
+
for (const { threadId, ...comment } of [...replies.values()].sort(byTime)) {
|
|
931
|
+
const list = comments.get(threadId);
|
|
932
|
+
if (list === void 0) comments.set(threadId, [comment]);
|
|
933
|
+
else list.push(comment);
|
|
934
|
+
}
|
|
935
|
+
return [...metas.values()].sort(byTime).map(({ id, resolved }) => ({ id, resolved, comments: comments.get(id) ?? [] }));
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
// src/extensions/comments/yjs-comment-threads.ts
|
|
939
|
+
function yjsCommentThreads(doc, options) {
|
|
940
|
+
const { currentUser, field = "comment" } = options;
|
|
941
|
+
const metas = doc.getMap(`${field}-threads`);
|
|
942
|
+
const replies = doc.getMap(`${field}-replies`);
|
|
943
|
+
const threads = createCommentThreads(readThreads(metas, replies));
|
|
944
|
+
const refresh = () => threads.set(readThreads(metas, replies));
|
|
945
|
+
const held = (threadId) => {
|
|
946
|
+
const meta = metas.get(threadId);
|
|
947
|
+
if (meta === void 0) throw new Error(`No comment thread "${threadId}" in the shared document.`);
|
|
948
|
+
return meta;
|
|
949
|
+
};
|
|
950
|
+
return {
|
|
951
|
+
threads,
|
|
952
|
+
async onCreate() {
|
|
953
|
+
const id = chunk4JDRDPLC_cjs.newId();
|
|
954
|
+
metas.set(id, { id, resolved: false, createdAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
955
|
+
return id;
|
|
956
|
+
},
|
|
957
|
+
async onReply(threadId, body) {
|
|
958
|
+
held(threadId);
|
|
959
|
+
const id = chunk4JDRDPLC_cjs.newId();
|
|
960
|
+
replies.set(id, { id, threadId, author: currentUser, body, createdAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
961
|
+
},
|
|
962
|
+
async onResolve(threadId) {
|
|
963
|
+
metas.set(threadId, { ...held(threadId), resolved: true });
|
|
964
|
+
},
|
|
965
|
+
async onDelete(threadId) {
|
|
966
|
+
doc.transact(() => {
|
|
967
|
+
metas.delete(threadId);
|
|
968
|
+
for (const comment of [...replies.values()]) if (comment.threadId === threadId) replies.delete(comment.id);
|
|
969
|
+
});
|
|
970
|
+
},
|
|
971
|
+
listen() {
|
|
972
|
+
refresh();
|
|
973
|
+
metas.observe(refresh);
|
|
974
|
+
replies.observe(refresh);
|
|
975
|
+
return () => {
|
|
976
|
+
metas.unobserve(refresh);
|
|
977
|
+
replies.unobserve(refresh);
|
|
978
|
+
};
|
|
979
|
+
}
|
|
980
|
+
};
|
|
981
|
+
}
|
|
982
|
+
|
|
922
983
|
exports.commentsExtension = commentsExtension;
|
|
923
984
|
exports.createCommentThreads = createCommentThreads;
|
|
924
985
|
exports.englishCommentsLabels = englishCommentsLabels;
|
|
986
|
+
exports.yjsCommentThreads = yjsCommentThreads;
|
package/dist/comments.d.cts
CHANGED
|
@@ -64,5 +64,38 @@ type CommentsOptions = {
|
|
|
64
64
|
*/
|
|
65
65
|
declare function commentsExtension(options: CommentsOptions): Extension;
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
/** The part of a `Y.Map` that comment threads read and write. */
|
|
68
|
+
type YjsCommentsMap<T> = {
|
|
69
|
+
get(key: string): T | undefined;
|
|
70
|
+
has(key: string): boolean;
|
|
71
|
+
set(key: string, value: T): unknown;
|
|
72
|
+
delete(key: string): void;
|
|
73
|
+
values(): Iterable<T>;
|
|
74
|
+
observe(listener: () => void): void;
|
|
75
|
+
unobserve(listener: () => void): void;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/** The part of a `Y.Doc` that `yjsCommentThreads` reads and writes, so that this entry needs no Yjs types. */
|
|
79
|
+
type YjsCommentsDoc = {
|
|
80
|
+
getMap<T>(name: string): YjsCommentsMap<T>;
|
|
81
|
+
transact(change: () => void): unknown;
|
|
82
|
+
};
|
|
83
|
+
type YjsCommentThreadsOptions = {
|
|
84
|
+
/** Who writes the replies sent from this client, as given to `commentsExtension`. */
|
|
85
|
+
currentUser: CommentUser;
|
|
86
|
+
/** What the names of the two shared maps start with: `comment` gives `comment-threads` and `comment-replies`. */
|
|
87
|
+
field?: string;
|
|
88
|
+
};
|
|
89
|
+
type YjsCommentThreads = Pick<CommentsOptions, 'threads' | 'onCreate' | 'onReply' | 'onResolve' | 'onDelete'> & {
|
|
90
|
+
/** Reads the shared maps into `threads`, then follows them until the function it returns is called. */
|
|
91
|
+
listen(): () => void;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Comment threads kept in a Yjs document, so collaborators see each other's: each thread in one shared map and each
|
|
95
|
+
* comment in another, by its own id, so that replies sent at the same time all stay. Hand the store and the four
|
|
96
|
+
* callbacks to `commentsExtension`, and call `listen` while the canvas is mounted.
|
|
97
|
+
*/
|
|
98
|
+
declare function yjsCommentThreads(doc: YjsCommentsDoc, options: YjsCommentThreadsOptions): YjsCommentThreads;
|
|
99
|
+
|
|
100
|
+
export { CommentsLabels, commentsExtension, createCommentThreads, yjsCommentThreads };
|
|
101
|
+
export type { CommentAuthor, CommentThread, CommentThreads, CommentUser, CommentsOptions, ThreadComment, YjsCommentThreads, YjsCommentThreadsOptions, YjsCommentsDoc, YjsCommentsMap };
|
package/dist/comments.d.ts
CHANGED
|
@@ -64,5 +64,38 @@ type CommentsOptions = {
|
|
|
64
64
|
*/
|
|
65
65
|
declare function commentsExtension(options: CommentsOptions): Extension;
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
/** The part of a `Y.Map` that comment threads read and write. */
|
|
68
|
+
type YjsCommentsMap<T> = {
|
|
69
|
+
get(key: string): T | undefined;
|
|
70
|
+
has(key: string): boolean;
|
|
71
|
+
set(key: string, value: T): unknown;
|
|
72
|
+
delete(key: string): void;
|
|
73
|
+
values(): Iterable<T>;
|
|
74
|
+
observe(listener: () => void): void;
|
|
75
|
+
unobserve(listener: () => void): void;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/** The part of a `Y.Doc` that `yjsCommentThreads` reads and writes, so that this entry needs no Yjs types. */
|
|
79
|
+
type YjsCommentsDoc = {
|
|
80
|
+
getMap<T>(name: string): YjsCommentsMap<T>;
|
|
81
|
+
transact(change: () => void): unknown;
|
|
82
|
+
};
|
|
83
|
+
type YjsCommentThreadsOptions = {
|
|
84
|
+
/** Who writes the replies sent from this client, as given to `commentsExtension`. */
|
|
85
|
+
currentUser: CommentUser;
|
|
86
|
+
/** What the names of the two shared maps start with: `comment` gives `comment-threads` and `comment-replies`. */
|
|
87
|
+
field?: string;
|
|
88
|
+
};
|
|
89
|
+
type YjsCommentThreads = Pick<CommentsOptions, 'threads' | 'onCreate' | 'onReply' | 'onResolve' | 'onDelete'> & {
|
|
90
|
+
/** Reads the shared maps into `threads`, then follows them until the function it returns is called. */
|
|
91
|
+
listen(): () => void;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Comment threads kept in a Yjs document, so collaborators see each other's: each thread in one shared map and each
|
|
95
|
+
* comment in another, by its own id, so that replies sent at the same time all stay. Hand the store and the four
|
|
96
|
+
* callbacks to `commentsExtension`, and call `listen` while the canvas is mounted.
|
|
97
|
+
*/
|
|
98
|
+
declare function yjsCommentThreads(doc: YjsCommentsDoc, options: YjsCommentThreadsOptions): YjsCommentThreads;
|
|
99
|
+
|
|
100
|
+
export { CommentsLabels, commentsExtension, createCommentThreads, yjsCommentThreads };
|
|
101
|
+
export type { CommentAuthor, CommentThread, CommentThreads, CommentUser, CommentsOptions, ThreadComment, YjsCommentThreads, YjsCommentThreadsOptions, YjsCommentsDoc, YjsCommentsMap };
|