kritzel-stencil 0.1.76 → 0.1.78
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/dist/cjs/{index-Dc7LOVhs.js → index-BRZ6e6oa.js} +1 -1
- package/dist/cjs/index.cjs.js +2 -330
- package/dist/cjs/kritzel-active-users_42.cjs.entry.js +88 -50
- package/dist/cjs/kritzel-brush-style.cjs.entry.js +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/stencil.cjs.js +2 -2
- package/dist/cjs/{workspace.migrations-DkmVO6dE.js → workspace.migrations-sUPrO23c.js} +378 -13
- package/dist/collection/classes/objects/selection-group.class.js +2 -0
- package/dist/collection/collection-manifest.json +1 -1
- package/dist/collection/components/core/kritzel-awareness-cursors/kritzel-awareness-cursors.css +6 -1
- package/dist/collection/components/core/kritzel-awareness-cursors/kritzel-awareness-cursors.js +5 -2
- package/dist/collection/components/core/kritzel-editor/kritzel-editor.css +2 -0
- package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +16 -6
- package/dist/collection/components/core/kritzel-engine/kritzel-engine.css +21 -0
- package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +24 -10
- package/dist/collection/components/ui/kritzel-login-dialog/kritzel-login-dialog.css +3 -0
- package/dist/collection/components/ui/kritzel-utility-panel/kritzel-utility-panel.css +1 -0
- package/dist/collection/configs/default-engine-config.js +1 -0
- package/dist/collection/constants/version.js +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/kritzel-active-users.js +1 -1
- package/dist/components/kritzel-avatar.js +1 -1
- package/dist/components/kritzel-awareness-cursors.js +1 -1
- package/dist/components/kritzel-back-to-content.js +1 -1
- package/dist/components/kritzel-brush-style.js +1 -1
- package/dist/components/kritzel-button.js +1 -1
- package/dist/components/kritzel-color-palette.js +1 -1
- package/dist/components/kritzel-color.js +1 -1
- package/dist/components/kritzel-context-menu.js +1 -1
- package/dist/components/kritzel-controls.js +1 -1
- package/dist/components/kritzel-current-user-dialog.js +1 -1
- package/dist/components/kritzel-current-user.js +1 -1
- package/dist/components/kritzel-cursor-trail.js +1 -1
- package/dist/components/kritzel-dialog.js +1 -1
- package/dist/components/kritzel-dropdown.js +1 -1
- package/dist/components/kritzel-editor.js +1 -1
- package/dist/components/kritzel-engine.js +1 -1
- package/dist/components/kritzel-export.js +1 -1
- package/dist/components/kritzel-font-family.js +1 -1
- package/dist/components/kritzel-font-size.js +1 -1
- package/dist/components/kritzel-font.js +1 -1
- package/dist/components/kritzel-icon.js +1 -1
- package/dist/components/kritzel-input.js +1 -1
- package/dist/components/kritzel-line-endings.js +1 -1
- package/dist/components/kritzel-login-dialog.js +1 -1
- package/dist/components/kritzel-master-detail.js +1 -1
- package/dist/components/kritzel-menu-item.js +1 -1
- package/dist/components/kritzel-menu.js +1 -1
- package/dist/components/kritzel-more-menu.js +1 -1
- package/dist/components/kritzel-numeric-input.js +1 -1
- package/dist/components/kritzel-opacity-slider.js +1 -1
- package/dist/components/kritzel-pill-tabs.js +1 -1
- package/dist/components/kritzel-portal.js +1 -1
- package/dist/components/kritzel-settings.js +1 -1
- package/dist/components/kritzel-shape-fill.js +1 -1
- package/dist/components/kritzel-share-dialog.js +1 -1
- package/dist/components/kritzel-slide-toggle.js +1 -1
- package/dist/components/kritzel-split-button.js +1 -1
- package/dist/components/kritzel-stroke-size.js +1 -1
- package/dist/components/kritzel-tool-config.js +1 -1
- package/dist/components/kritzel-tooltip.js +1 -1
- package/dist/components/kritzel-utility-panel.js +1 -1
- package/dist/components/kritzel-workspace-manager.js +1 -1
- package/dist/components/{p-Dt-J69xt.js → p-53di1Zko.js} +1 -1
- package/dist/components/{p-DS0xx1eT.js → p-6NFl6EB2.js} +1 -1
- package/dist/components/{p-DSzQ6H2j.js → p-76W5pG2O.js} +1 -1
- package/dist/components/{p-DRbG92F9.js → p-BLsH_Oi0.js} +1 -1
- package/dist/components/p-Ban3OlgZ.js +9 -0
- package/dist/components/{p-CUkKKbnu.js → p-BrZ_gL8Q.js} +1 -1
- package/dist/components/{p-kj9wbLY8.js → p-BuI6Gkzg.js} +1 -1
- package/dist/components/{p-BeFUNGEI.js → p-BueaqfA2.js} +1 -1
- package/dist/components/{p-BiByyU2C.js → p-C2l9mZ1P.js} +1 -1
- package/dist/components/{p-CsR4owzk.js → p-C4fKLlrd.js} +1 -1
- package/dist/components/{p-BA0ayKqO.js → p-CBslLN3-.js} +1 -1
- package/dist/components/p-CHY71o5B.js +1 -0
- package/dist/components/{p-KQzWumjB.js → p-CI9Nbh-x.js} +1 -1
- package/dist/components/{p-CsoDfhD5.js → p-CN8IxBlU.js} +1 -1
- package/dist/components/{p-2OYw6GJ7.js → p-CWMFGEe0.js} +1 -1
- package/dist/components/{p-Dj_Qjga5.js → p-CYh7yV-K.js} +1 -1
- package/dist/components/{p-xM-_OeRO.js → p-Ck1dhpUQ.js} +1 -1
- package/dist/components/{p-b4gyXoju.js → p-Cns7qSKS.js} +1 -1
- package/dist/components/{p-C69Stayh.js → p-D14QNK3X.js} +1 -1
- package/dist/components/{p-iRL0wQHQ.js → p-D3pNw-SV.js} +1 -1
- package/dist/components/{p-BEJQ2kP7.js → p-D5IhryUR.js} +1 -1
- package/dist/components/{p-CZhyKp-f.js → p-D7yzmu1l.js} +1 -1
- package/dist/components/{p-HLbqRJGs.js → p-DDKjsXCe.js} +1 -1
- package/dist/components/{p-TyR-YTXm.js → p-DV7Z_qfa.js} +1 -1
- package/dist/components/{p-ByR0VXeU.js → p-DWsCbu01.js} +1 -1
- package/dist/components/{p-31FVoNWR.js → p-DaGZEV0R.js} +1 -1
- package/dist/components/{p-Da46jw3N.js → p-DkWWzVg8.js} +1 -1
- package/dist/components/{p-D1O7DxL4.js → p-Dr3-pKVg.js} +1 -1
- package/dist/components/{p-JdNoaqqb.js → p-Dte67BWd.js} +1 -1
- package/dist/components/{p-CHmi1QWx.js → p-DxzDda_J.js} +1 -1
- package/dist/components/{p-CAIGuV2J.js → p-KJ4dHzrS.js} +1 -1
- package/dist/components/{p-BiouZo1q.js → p-Lhyh6KeB.js} +1 -1
- package/dist/components/{p-CFhp1W9F.js → p-Md9Y-b3d.js} +1 -1
- package/dist/components/{p-C1uR_ZNW.js → p-ZC5YELQJ.js} +1 -1
- package/dist/components/{p-C7SBI_0T.js → p-ZQ2bKafG.js} +1 -1
- package/dist/components/{p-0kShCfeb.js → p-_QEHfsIk.js} +1 -1
- package/dist/components/{p-DXjuuVq9.js → p-gtQlsorg.js} +1 -1
- package/dist/components/{p-GYI7sDxr.js → p-l_YGO7RB.js} +1 -1
- package/dist/components/{p-DvIEvoZu.js → p-m1nVDC3G.js} +1 -1
- package/dist/components/{p-7o2FWtFx.js → p-pCC6t6BH.js} +1 -1
- package/dist/components/p-pGzF7PUB.js +1 -0
- package/dist/esm/{index-MV-81ybv.js → index-BbOHefEf.js} +1 -1
- package/dist/esm/index.js +2 -331
- package/dist/esm/kritzel-active-users_42.entry.js +88 -50
- package/dist/esm/kritzel-brush-style.entry.js +1 -1
- package/dist/esm/loader.js +2 -2
- package/dist/esm/stencil.js +3 -3
- package/dist/esm/{workspace.migrations-D48_Bqvh.js → workspace.migrations-NhRgr2_H.js} +378 -12
- package/dist/stencil/index.esm.js +1 -1
- package/dist/stencil/p-4a4b38e4.entry.js +9 -0
- package/dist/stencil/{p-fc21e29c.entry.js → p-98238bf9.entry.js} +1 -1
- package/dist/stencil/p-NhRgr2_H.js +1 -0
- package/dist/stencil/stencil.esm.js +1 -1
- package/dist/types/classes/objects/selection-group.class.d.ts +1 -0
- package/dist/types/components.d.ts +4 -2
- package/dist/types/constants/version.d.ts +1 -1
- package/dist/types/interfaces/engine-state.interface.d.ts +1 -0
- package/package.json +2 -2
- package/dist/components/p-CJ2eHeoV.js +0 -1
- package/dist/components/p-jdYmu4SA.js +0 -9
- package/dist/components/p-xNwOWoiT.js +0 -1
- package/dist/stencil/p-775a7246.entry.js +0 -9
- package/dist/stencil/p-D48_Bqvh.js +0 -1
- /package/dist/components/{p-pebXO4LU.js → p-CGGiwvWZ.js} +0 -0
- /package/dist/stencil/{p-MV-81ybv.js → p-BbOHefEf.js} +0 -0
|
@@ -5054,7 +5054,8 @@ class ReplaceStep extends Step {
|
|
|
5054
5054
|
return new ReplaceStep(this.from, this.from + this.slice.size, doc.slice(this.from, this.to));
|
|
5055
5055
|
}
|
|
5056
5056
|
map(mapping) {
|
|
5057
|
-
let
|
|
5057
|
+
let to = mapping.mapResult(this.to, -1);
|
|
5058
|
+
let from = this.from == this.to && ReplaceStep.MAP_BIAS < 0 ? to : mapping.mapResult(this.from, 1);
|
|
5058
5059
|
if (from.deletedAcross && to.deletedAcross)
|
|
5059
5060
|
return null;
|
|
5060
5061
|
return new ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice, this.structure);
|
|
@@ -5093,6 +5094,15 @@ class ReplaceStep extends Step {
|
|
|
5093
5094
|
return new ReplaceStep(json.from, json.to, Slice.fromJSON(schema, json.slice), !!json.structure);
|
|
5094
5095
|
}
|
|
5095
5096
|
}
|
|
5097
|
+
/**
|
|
5098
|
+
By default, for backwards compatibility, an inserting step
|
|
5099
|
+
mapped over an insertion at that same position fill move after
|
|
5100
|
+
the inserted content. In a collaborative editing situation, that
|
|
5101
|
+
can make redone insertions appear in unexpected places. You can
|
|
5102
|
+
set this to -1 to make such mapping keep the step before the
|
|
5103
|
+
insertion instead.
|
|
5104
|
+
*/
|
|
5105
|
+
ReplaceStep.MAP_BIAS = 1;
|
|
5096
5106
|
Step.jsonID("replace", ReplaceStep);
|
|
5097
5107
|
/**
|
|
5098
5108
|
Replace a part of the document with a slice of content, but
|
|
@@ -6010,6 +6020,26 @@ function replaceRangeWith(tr, from, to, node) {
|
|
|
6010
6020
|
}
|
|
6011
6021
|
function deleteRange(tr, from, to) {
|
|
6012
6022
|
let $from = tr.doc.resolve(from), $to = tr.doc.resolve(to);
|
|
6023
|
+
// When the deleted range spans from the start of one textblock to
|
|
6024
|
+
// the start of another one, move out of the start of both blocks.
|
|
6025
|
+
if ($from.parent.isTextblock && $to.parent.isTextblock && $from.start() != $to.start() &&
|
|
6026
|
+
$from.parentOffset == 0 && $to.parentOffset == 0) {
|
|
6027
|
+
let shared = $from.sharedDepth(to), isolated = false;
|
|
6028
|
+
for (let d = $from.depth; d > shared; d--)
|
|
6029
|
+
if ($from.node(d).type.spec.isolating)
|
|
6030
|
+
isolated = true;
|
|
6031
|
+
for (let d = $to.depth; d > shared; d--)
|
|
6032
|
+
if ($to.node(d).type.spec.isolating)
|
|
6033
|
+
isolated = true;
|
|
6034
|
+
if (!isolated) {
|
|
6035
|
+
for (let d = $from.depth; d > 0 && from == $from.start(d); d--)
|
|
6036
|
+
from = $from.before(d);
|
|
6037
|
+
for (let d = $to.depth; d > 0 && to == $to.start(d); d--)
|
|
6038
|
+
to = $to.before(d);
|
|
6039
|
+
$from = tr.doc.resolve(from);
|
|
6040
|
+
$to = tr.doc.resolve(to);
|
|
6041
|
+
}
|
|
6042
|
+
}
|
|
6013
6043
|
let covered = coveredDepths($from, $to);
|
|
6014
6044
|
for (let i = 0; i < covered.length; i++) {
|
|
6015
6045
|
let depth = covered[i], last = i == covered.length - 1;
|
|
@@ -10778,8 +10808,8 @@ class MouseDown {
|
|
|
10778
10808
|
this.target = targetDesc && targetDesc.nodeDOM.nodeType == 1 ? targetDesc.nodeDOM : null;
|
|
10779
10809
|
let { selection } = view.state;
|
|
10780
10810
|
if (event.button == 0 &&
|
|
10781
|
-
targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false ||
|
|
10782
|
-
|
|
10811
|
+
(targetNode.type.spec.draggable && targetNode.type.spec.selectable !== false ||
|
|
10812
|
+
selection instanceof NodeSelection && selection.from <= targetPos && selection.to > targetPos))
|
|
10783
10813
|
this.mightDrag = {
|
|
10784
10814
|
node: targetNode,
|
|
10785
10815
|
pos: targetPos,
|
|
@@ -11128,8 +11158,9 @@ class Dragging {
|
|
|
11128
11158
|
}
|
|
11129
11159
|
const dragCopyModifier = mac$3 ? "altKey" : "ctrlKey";
|
|
11130
11160
|
function dragMoves(view, event) {
|
|
11131
|
-
let
|
|
11132
|
-
|
|
11161
|
+
let copy;
|
|
11162
|
+
view.someProp("dragCopies", test => { copy = copy || test(event); });
|
|
11163
|
+
return copy != null ? !copy : !event[dragCopyModifier];
|
|
11133
11164
|
}
|
|
11134
11165
|
handlers.dragstart = (view, _event) => {
|
|
11135
11166
|
let event = _event;
|
|
@@ -11156,7 +11187,7 @@ handlers.dragstart = (view, _event) => {
|
|
|
11156
11187
|
if (!event.dataTransfer.files.length || !chrome || chrome_version > 120)
|
|
11157
11188
|
event.dataTransfer.clearData();
|
|
11158
11189
|
event.dataTransfer.setData(brokenClipboardAPI ? "Text" : "text/html", dom.innerHTML);
|
|
11159
|
-
// See https://
|
|
11190
|
+
// See https://code.haverbeke.berlin/prosemirror/prosemirror/issues/1156
|
|
11160
11191
|
event.dataTransfer.effectAllowed = "copyMove";
|
|
11161
11192
|
if (!brokenClipboardAPI)
|
|
11162
11193
|
event.dataTransfer.setData("text/plain", text);
|
|
@@ -12155,8 +12186,13 @@ class DOMObserver {
|
|
|
12155
12186
|
for (let node of added)
|
|
12156
12187
|
if (node.nodeName == "BR" && node.parentNode) {
|
|
12157
12188
|
let after = node.nextSibling;
|
|
12158
|
-
|
|
12159
|
-
|
|
12189
|
+
while (after && after.nodeType == 1) {
|
|
12190
|
+
if (after.contentEditable == "false") {
|
|
12191
|
+
node.parentNode.removeChild(node);
|
|
12192
|
+
break;
|
|
12193
|
+
}
|
|
12194
|
+
after = after.firstChild;
|
|
12195
|
+
}
|
|
12160
12196
|
}
|
|
12161
12197
|
}
|
|
12162
12198
|
else if (gecko && added.length) {
|
|
@@ -12776,7 +12812,7 @@ class EditorView {
|
|
|
12776
12812
|
this.pluginViews = [];
|
|
12777
12813
|
/**
|
|
12778
12814
|
Holds `true` when a hack node is needed in Firefox to prevent the
|
|
12779
|
-
[space is eaten issue](https://
|
|
12815
|
+
[space is eaten issue](https://code.haverbeke.berlin/prosemirror/prosemirror/issues/651)
|
|
12780
12816
|
@internal
|
|
12781
12817
|
*/
|
|
12782
12818
|
this.requiresGeckoHackNode = false;
|
|
@@ -12994,12 +13030,12 @@ class EditorView {
|
|
|
12994
13030
|
}
|
|
12995
13031
|
updateDraggedNode(dragging, prev) {
|
|
12996
13032
|
let sel = dragging.node, found = -1;
|
|
12997
|
-
if (this.state.doc.nodeAt(sel.from) == sel.node) {
|
|
13033
|
+
if (sel.from < this.state.doc.content.size && this.state.doc.nodeAt(sel.from) == sel.node) {
|
|
12998
13034
|
found = sel.from;
|
|
12999
13035
|
}
|
|
13000
13036
|
else {
|
|
13001
13037
|
let movedPos = sel.from + (this.state.doc.content.size - prev.doc.content.size);
|
|
13002
|
-
let moved = movedPos > 0 && this.state.doc.nodeAt(movedPos);
|
|
13038
|
+
let moved = movedPos > 0 && movedPos < this.state.doc.content.size && this.state.doc.nodeAt(movedPos);
|
|
13003
13039
|
if (moved == sel.node)
|
|
13004
13040
|
found = movedPos;
|
|
13005
13041
|
}
|
|
@@ -18492,6 +18528,7 @@ class KritzelSelectionGroup extends KritzelBaseObject {
|
|
|
18492
18528
|
snapshotHeight = 0;
|
|
18493
18529
|
snapshotTranslateX = 0;
|
|
18494
18530
|
snapshotTranslateY = 0;
|
|
18531
|
+
clientId;
|
|
18495
18532
|
minX;
|
|
18496
18533
|
maxX;
|
|
18497
18534
|
minY;
|
|
@@ -18564,6 +18601,7 @@ class KritzelSelectionGroup extends KritzelBaseObject {
|
|
|
18564
18601
|
object.id = object.generateId();
|
|
18565
18602
|
object.workspaceId = core.store.state.activeWorkspace.id;
|
|
18566
18603
|
object.userId = core.user?.id;
|
|
18604
|
+
object.clientId = core.store.state.objects?.localClientId ?? undefined;
|
|
18567
18605
|
object.scale = core.store.state.scale;
|
|
18568
18606
|
object.zIndex = 99999;
|
|
18569
18607
|
// Initialize styling with theme-aware defaults
|
|
@@ -25224,6 +25262,334 @@ class HocuspocusProvider extends EventEmitter {
|
|
|
25224
25262
|
}
|
|
25225
25263
|
}
|
|
25226
25264
|
|
|
25265
|
+
/**
|
|
25266
|
+
* Hocuspocus sync provider for real-time collaboration
|
|
25267
|
+
* Supports multiplexing - multiple documents can share the same WebSocket connection
|
|
25268
|
+
*/
|
|
25269
|
+
class HocuspocusSyncProvider {
|
|
25270
|
+
type = 'network';
|
|
25271
|
+
provider;
|
|
25272
|
+
isConnected = false;
|
|
25273
|
+
isSynced = false;
|
|
25274
|
+
usesSharedSocket = false;
|
|
25275
|
+
isDestroyed = false;
|
|
25276
|
+
connectTimeout = null;
|
|
25277
|
+
pendingConnectReject = null;
|
|
25278
|
+
connectionTimeoutMs;
|
|
25279
|
+
_connectionStatus = 'disconnected';
|
|
25280
|
+
visibilityHandler = null;
|
|
25281
|
+
onlineHandler = null;
|
|
25282
|
+
get awareness() {
|
|
25283
|
+
return this.provider.awareness;
|
|
25284
|
+
}
|
|
25285
|
+
get connectionStatus() {
|
|
25286
|
+
return this._connectionStatus;
|
|
25287
|
+
}
|
|
25288
|
+
// Static shared WebSocket instance for multiplexing
|
|
25289
|
+
static sharedWebSocketProvider = null;
|
|
25290
|
+
constructor(docName, doc, options) {
|
|
25291
|
+
const name = options?.name || docName;
|
|
25292
|
+
const url = options?.url || 'ws://localhost:1234';
|
|
25293
|
+
this.connectionTimeoutMs = options?.connectionTimeout ?? 10000;
|
|
25294
|
+
// Use provided websocketProvider or the static shared one
|
|
25295
|
+
const websocketProvider = options?.websocketProvider || HocuspocusSyncProvider.sharedWebSocketProvider;
|
|
25296
|
+
// Build reconnect config from options
|
|
25297
|
+
const reconnectConfig = {};
|
|
25298
|
+
if (options?.delay !== undefined)
|
|
25299
|
+
reconnectConfig.delay = options.delay;
|
|
25300
|
+
if (options?.factor !== undefined)
|
|
25301
|
+
reconnectConfig.factor = options.factor;
|
|
25302
|
+
if (options?.maxAttempts !== undefined)
|
|
25303
|
+
reconnectConfig.maxAttempts = options.maxAttempts;
|
|
25304
|
+
if (options?.minDelay !== undefined)
|
|
25305
|
+
reconnectConfig.minDelay = options.minDelay;
|
|
25306
|
+
if (options?.maxDelay !== undefined)
|
|
25307
|
+
reconnectConfig.maxDelay = options.maxDelay;
|
|
25308
|
+
const onConnect = () => {
|
|
25309
|
+
if (this.isDestroyed) {
|
|
25310
|
+
return;
|
|
25311
|
+
}
|
|
25312
|
+
this.isConnected = true;
|
|
25313
|
+
this._connectionStatus = 'connected';
|
|
25314
|
+
if (!options?.quiet) {
|
|
25315
|
+
console.info(`Hocuspocus connected: ${name}`);
|
|
25316
|
+
}
|
|
25317
|
+
if (options?.onConnect) {
|
|
25318
|
+
options.onConnect();
|
|
25319
|
+
}
|
|
25320
|
+
};
|
|
25321
|
+
const onDisconnect = () => {
|
|
25322
|
+
if (this.isDestroyed) {
|
|
25323
|
+
return;
|
|
25324
|
+
}
|
|
25325
|
+
this.isConnected = false;
|
|
25326
|
+
this.isSynced = false;
|
|
25327
|
+
this._connectionStatus = 'disconnected';
|
|
25328
|
+
if (!options?.quiet) {
|
|
25329
|
+
console.info(`Hocuspocus disconnected: ${name}`);
|
|
25330
|
+
}
|
|
25331
|
+
if (options?.onDisconnect) {
|
|
25332
|
+
options.onDisconnect();
|
|
25333
|
+
}
|
|
25334
|
+
};
|
|
25335
|
+
const onSynced = () => {
|
|
25336
|
+
if (this.isDestroyed) {
|
|
25337
|
+
return;
|
|
25338
|
+
}
|
|
25339
|
+
this.isSynced = true;
|
|
25340
|
+
this._connectionStatus = 'synced';
|
|
25341
|
+
if (!options?.quiet) {
|
|
25342
|
+
console.info(`Hocuspocus synced: ${name}`);
|
|
25343
|
+
}
|
|
25344
|
+
if (options?.onSynced) {
|
|
25345
|
+
options.onSynced();
|
|
25346
|
+
}
|
|
25347
|
+
};
|
|
25348
|
+
const onStatus = (data) => {
|
|
25349
|
+
if (this.isDestroyed) {
|
|
25350
|
+
return;
|
|
25351
|
+
}
|
|
25352
|
+
if (data.status === 'connecting') {
|
|
25353
|
+
this._connectionStatus = 'connecting';
|
|
25354
|
+
}
|
|
25355
|
+
if (options?.onStatus) {
|
|
25356
|
+
options.onStatus(data);
|
|
25357
|
+
}
|
|
25358
|
+
};
|
|
25359
|
+
if (websocketProvider) {
|
|
25360
|
+
// Multiplexing mode - use shared WebSocket connection
|
|
25361
|
+
this.usesSharedSocket = true;
|
|
25362
|
+
const config = {
|
|
25363
|
+
websocketProvider,
|
|
25364
|
+
name,
|
|
25365
|
+
document: doc,
|
|
25366
|
+
token: options?.token || null,
|
|
25367
|
+
onStatus,
|
|
25368
|
+
onConnect,
|
|
25369
|
+
onDisconnect,
|
|
25370
|
+
onSynced,
|
|
25371
|
+
...reconnectConfig,
|
|
25372
|
+
};
|
|
25373
|
+
// Add optional settings
|
|
25374
|
+
if (options?.forceSyncInterval !== undefined) {
|
|
25375
|
+
config.forceSyncInterval = options.forceSyncInterval;
|
|
25376
|
+
}
|
|
25377
|
+
if (options?.onAuthenticationFailed) {
|
|
25378
|
+
config.onAuthenticationFailed = options.onAuthenticationFailed;
|
|
25379
|
+
}
|
|
25380
|
+
this.provider = new HocuspocusProvider(config);
|
|
25381
|
+
// Must call attach() explicitly when using shared socket
|
|
25382
|
+
this.provider.attach();
|
|
25383
|
+
if (!options?.quiet) {
|
|
25384
|
+
console.info(`Hocuspocus Provider initialized (multiplexed): ${name}`);
|
|
25385
|
+
}
|
|
25386
|
+
}
|
|
25387
|
+
else {
|
|
25388
|
+
// Standalone mode - create own WebSocket connection
|
|
25389
|
+
this.usesSharedSocket = false;
|
|
25390
|
+
const config = {
|
|
25391
|
+
url,
|
|
25392
|
+
name,
|
|
25393
|
+
document: doc,
|
|
25394
|
+
token: options?.token || null,
|
|
25395
|
+
autoConnect: false,
|
|
25396
|
+
onStatus,
|
|
25397
|
+
onConnect,
|
|
25398
|
+
onDisconnect,
|
|
25399
|
+
onSynced,
|
|
25400
|
+
...reconnectConfig,
|
|
25401
|
+
};
|
|
25402
|
+
// Add optional settings
|
|
25403
|
+
if (options?.forceSyncInterval !== undefined) {
|
|
25404
|
+
config.forceSyncInterval = options.forceSyncInterval;
|
|
25405
|
+
}
|
|
25406
|
+
if (options?.onAuthenticationFailed) {
|
|
25407
|
+
config.onAuthenticationFailed = options.onAuthenticationFailed;
|
|
25408
|
+
}
|
|
25409
|
+
if (options?.WebSocketPolyfill) {
|
|
25410
|
+
config.WebSocketPolyfill = options.WebSocketPolyfill;
|
|
25411
|
+
}
|
|
25412
|
+
this.provider = new HocuspocusProvider(config);
|
|
25413
|
+
if (!options?.quiet) {
|
|
25414
|
+
console.info(`Hocuspocus Provider initialized: ${url}/${name}`);
|
|
25415
|
+
}
|
|
25416
|
+
}
|
|
25417
|
+
this.setupBrowserEventListeners();
|
|
25418
|
+
}
|
|
25419
|
+
setupBrowserEventListeners() {
|
|
25420
|
+
if (typeof document !== 'undefined') {
|
|
25421
|
+
this.visibilityHandler = () => {
|
|
25422
|
+
if (document.visibilityState === 'visible' && !this.isConnected && !this.isDestroyed) {
|
|
25423
|
+
this.provider.connect();
|
|
25424
|
+
}
|
|
25425
|
+
};
|
|
25426
|
+
document.addEventListener('visibilitychange', this.visibilityHandler);
|
|
25427
|
+
}
|
|
25428
|
+
if (typeof window !== 'undefined') {
|
|
25429
|
+
this.onlineHandler = () => {
|
|
25430
|
+
if (!this.isConnected && !this.isDestroyed) {
|
|
25431
|
+
this.provider.connect();
|
|
25432
|
+
}
|
|
25433
|
+
};
|
|
25434
|
+
window.addEventListener('online', this.onlineHandler);
|
|
25435
|
+
}
|
|
25436
|
+
}
|
|
25437
|
+
removeBrowserEventListeners() {
|
|
25438
|
+
if (this.visibilityHandler && typeof document !== 'undefined') {
|
|
25439
|
+
document.removeEventListener('visibilitychange', this.visibilityHandler);
|
|
25440
|
+
this.visibilityHandler = null;
|
|
25441
|
+
}
|
|
25442
|
+
if (this.onlineHandler && typeof window !== 'undefined') {
|
|
25443
|
+
window.removeEventListener('online', this.onlineHandler);
|
|
25444
|
+
this.onlineHandler = null;
|
|
25445
|
+
}
|
|
25446
|
+
}
|
|
25447
|
+
/**
|
|
25448
|
+
* Create a shared WebSocket connection for multiplexing
|
|
25449
|
+
* Call this once to create a shared connection that multiple providers can use
|
|
25450
|
+
*/
|
|
25451
|
+
static createSharedWebSocket(options) {
|
|
25452
|
+
if (HocuspocusSyncProvider.sharedWebSocketProvider) {
|
|
25453
|
+
console.warn('Shared WebSocket already exists. Returning existing instance.');
|
|
25454
|
+
return HocuspocusSyncProvider.sharedWebSocketProvider;
|
|
25455
|
+
}
|
|
25456
|
+
const config = {
|
|
25457
|
+
url: options.url,
|
|
25458
|
+
};
|
|
25459
|
+
if (options.WebSocketPolyfill) {
|
|
25460
|
+
config.WebSocketPolyfill = options.WebSocketPolyfill;
|
|
25461
|
+
}
|
|
25462
|
+
if (options.onConnect) {
|
|
25463
|
+
config.onConnect = options.onConnect;
|
|
25464
|
+
}
|
|
25465
|
+
if (options.onDisconnect) {
|
|
25466
|
+
config.onDisconnect = options.onDisconnect;
|
|
25467
|
+
}
|
|
25468
|
+
if (options.onStatus) {
|
|
25469
|
+
config.onStatus = options.onStatus;
|
|
25470
|
+
}
|
|
25471
|
+
HocuspocusSyncProvider.sharedWebSocketProvider = new HocuspocusProviderWebsocket(config);
|
|
25472
|
+
console.info(`Shared Hocuspocus WebSocket created: ${options.url}`);
|
|
25473
|
+
return HocuspocusSyncProvider.sharedWebSocketProvider;
|
|
25474
|
+
}
|
|
25475
|
+
/**
|
|
25476
|
+
* Destroy the shared WebSocket connection
|
|
25477
|
+
* Call this when you're done with all multiplexed providers
|
|
25478
|
+
*/
|
|
25479
|
+
static destroySharedWebSocket() {
|
|
25480
|
+
if (HocuspocusSyncProvider.sharedWebSocketProvider) {
|
|
25481
|
+
HocuspocusSyncProvider.sharedWebSocketProvider.destroy();
|
|
25482
|
+
HocuspocusSyncProvider.sharedWebSocketProvider = null;
|
|
25483
|
+
console.info('Shared Hocuspocus WebSocket destroyed');
|
|
25484
|
+
}
|
|
25485
|
+
}
|
|
25486
|
+
/**
|
|
25487
|
+
* Get the shared WebSocket provider instance (if it exists)
|
|
25488
|
+
*/
|
|
25489
|
+
static getSharedWebSocket() {
|
|
25490
|
+
return HocuspocusSyncProvider.sharedWebSocketProvider;
|
|
25491
|
+
}
|
|
25492
|
+
/**
|
|
25493
|
+
* Static factory method for creating HocuspocusSyncProvider with configuration options
|
|
25494
|
+
* Returns a ProviderFactory that can be used in sync configuration
|
|
25495
|
+
*/
|
|
25496
|
+
static with(options) {
|
|
25497
|
+
return {
|
|
25498
|
+
create: (docName, doc, runtimeOptions) => {
|
|
25499
|
+
const mergedOptions = runtimeOptions ? { ...options, ...runtimeOptions } : options;
|
|
25500
|
+
return new HocuspocusSyncProvider(docName, doc, mergedOptions);
|
|
25501
|
+
},
|
|
25502
|
+
};
|
|
25503
|
+
}
|
|
25504
|
+
async connect() {
|
|
25505
|
+
if (this.isSynced || this.isDestroyed) {
|
|
25506
|
+
return;
|
|
25507
|
+
}
|
|
25508
|
+
this._connectionStatus = 'connecting';
|
|
25509
|
+
return new Promise((resolve, reject) => {
|
|
25510
|
+
// Store reject function so we can cancel the connection if destroyed
|
|
25511
|
+
this.pendingConnectReject = reject;
|
|
25512
|
+
this.connectTimeout = setTimeout(() => {
|
|
25513
|
+
this.pendingConnectReject = null;
|
|
25514
|
+
this.connectTimeout = null;
|
|
25515
|
+
reject(new Error('Hocuspocus connection timeout'));
|
|
25516
|
+
}, this.connectionTimeoutMs);
|
|
25517
|
+
const syncHandler = () => {
|
|
25518
|
+
if (this.connectTimeout) {
|
|
25519
|
+
clearTimeout(this.connectTimeout);
|
|
25520
|
+
this.connectTimeout = null;
|
|
25521
|
+
}
|
|
25522
|
+
this.pendingConnectReject = null;
|
|
25523
|
+
this.provider.off('synced', syncHandler);
|
|
25524
|
+
if (!this.isDestroyed) {
|
|
25525
|
+
resolve();
|
|
25526
|
+
}
|
|
25527
|
+
};
|
|
25528
|
+
this.provider.on('synced', syncHandler);
|
|
25529
|
+
// If already synced, resolve immediately
|
|
25530
|
+
if (this.provider.isSynced) {
|
|
25531
|
+
if (this.connectTimeout) {
|
|
25532
|
+
clearTimeout(this.connectTimeout);
|
|
25533
|
+
this.connectTimeout = null;
|
|
25534
|
+
}
|
|
25535
|
+
this.pendingConnectReject = null;
|
|
25536
|
+
this.provider.off('synced', syncHandler);
|
|
25537
|
+
resolve();
|
|
25538
|
+
return;
|
|
25539
|
+
}
|
|
25540
|
+
// Connect if not already connected (standalone mode only)
|
|
25541
|
+
if (!this.isConnected && !this.usesSharedSocket) {
|
|
25542
|
+
this.provider.connect();
|
|
25543
|
+
}
|
|
25544
|
+
});
|
|
25545
|
+
}
|
|
25546
|
+
async reconnect() {
|
|
25547
|
+
this.disconnect();
|
|
25548
|
+
return this.connect();
|
|
25549
|
+
}
|
|
25550
|
+
disconnect() {
|
|
25551
|
+
// Cancel any pending connection attempt
|
|
25552
|
+
if (this.connectTimeout) {
|
|
25553
|
+
clearTimeout(this.connectTimeout);
|
|
25554
|
+
this.connectTimeout = null;
|
|
25555
|
+
}
|
|
25556
|
+
if (this.pendingConnectReject) {
|
|
25557
|
+
this.pendingConnectReject = null; // Don't reject, just abandon the promise
|
|
25558
|
+
}
|
|
25559
|
+
if (this.provider) {
|
|
25560
|
+
if (this.usesSharedSocket) {
|
|
25561
|
+
// Detach from shared socket instead of disconnecting
|
|
25562
|
+
this.provider.detach();
|
|
25563
|
+
}
|
|
25564
|
+
else {
|
|
25565
|
+
this.provider.disconnect();
|
|
25566
|
+
}
|
|
25567
|
+
}
|
|
25568
|
+
this.isConnected = false;
|
|
25569
|
+
this.isSynced = false;
|
|
25570
|
+
this._connectionStatus = 'disconnected';
|
|
25571
|
+
}
|
|
25572
|
+
destroy() {
|
|
25573
|
+
// Mark as destroyed first to prevent any callbacks from doing work
|
|
25574
|
+
this.isDestroyed = true;
|
|
25575
|
+
// Cancel any pending connection attempt
|
|
25576
|
+
if (this.connectTimeout) {
|
|
25577
|
+
clearTimeout(this.connectTimeout);
|
|
25578
|
+
this.connectTimeout = null;
|
|
25579
|
+
}
|
|
25580
|
+
if (this.pendingConnectReject) {
|
|
25581
|
+
this.pendingConnectReject = null; // Don't reject, just abandon the promise
|
|
25582
|
+
}
|
|
25583
|
+
this.removeBrowserEventListeners();
|
|
25584
|
+
if (this.provider) {
|
|
25585
|
+
this.provider.destroy();
|
|
25586
|
+
}
|
|
25587
|
+
this.isConnected = false;
|
|
25588
|
+
this.isSynced = false;
|
|
25589
|
+
this._connectionStatus = 'disconnected';
|
|
25590
|
+
}
|
|
25591
|
+
}
|
|
25592
|
+
|
|
25227
25593
|
/** Current version of the workspace export format */
|
|
25228
25594
|
const WORKSPACE_EXPORT_VERSION = '1.2.0';
|
|
25229
25595
|
/**
|
|
@@ -26882,8 +27248,7 @@ exports.DEFAULT_BRUSH_CONFIG = DEFAULT_BRUSH_CONFIG;
|
|
|
26882
27248
|
exports.DEFAULT_COLOR_PALETTE = DEFAULT_COLOR_PALETTE;
|
|
26883
27249
|
exports.DEFAULT_LINE_TOOL_CONFIG = DEFAULT_LINE_TOOL_CONFIG;
|
|
26884
27250
|
exports.DEFAULT_TEXT_CONFIG = DEFAULT_TEXT_CONFIG;
|
|
26885
|
-
exports.
|
|
26886
|
-
exports.HocuspocusProviderWebsocket = HocuspocusProviderWebsocket;
|
|
27251
|
+
exports.HocuspocusSyncProvider = HocuspocusSyncProvider;
|
|
26887
27252
|
exports.IndexedDBSyncProvider = IndexedDBSyncProvider;
|
|
26888
27253
|
exports.KritzelAnchorManager = KritzelAnchorManager;
|
|
26889
27254
|
exports.KritzelBaseHandler = KritzelBaseHandler;
|
|
@@ -20,6 +20,7 @@ export class KritzelSelectionGroup extends KritzelBaseObject {
|
|
|
20
20
|
snapshotHeight = 0;
|
|
21
21
|
snapshotTranslateX = 0;
|
|
22
22
|
snapshotTranslateY = 0;
|
|
23
|
+
clientId;
|
|
23
24
|
minX;
|
|
24
25
|
maxX;
|
|
25
26
|
minY;
|
|
@@ -92,6 +93,7 @@ export class KritzelSelectionGroup extends KritzelBaseObject {
|
|
|
92
93
|
object.id = object.generateId();
|
|
93
94
|
object.workspaceId = core.store.state.activeWorkspace.id;
|
|
94
95
|
object.userId = core.user?.id;
|
|
96
|
+
object.clientId = core.store.state.objects?.localClientId ?? undefined;
|
|
95
97
|
object.scale = core.store.state.scale;
|
|
96
98
|
object.zIndex = 99999;
|
|
97
99
|
// Initialize styling with theme-aware defaults
|
package/dist/collection/components/core/kritzel-awareness-cursors/kritzel-awareness-cursors.css
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
width: 100vw;
|
|
7
7
|
height: 100vh;
|
|
8
8
|
pointer-events: none;
|
|
9
|
-
z-index:
|
|
9
|
+
z-index: 1;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
.awareness-cursor {
|
|
@@ -74,6 +74,11 @@
|
|
|
74
74
|
.edge-arrow {
|
|
75
75
|
position: absolute;
|
|
76
76
|
filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.3));
|
|
77
|
+
transition: opacity 300ms ease;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.edge-arrow.stale {
|
|
81
|
+
opacity: 0;
|
|
77
82
|
}
|
|
78
83
|
|
|
79
84
|
.edge-label {
|
package/dist/collection/components/core/kritzel-awareness-cursors/kritzel-awareness-cursors.js
CHANGED
|
@@ -78,6 +78,9 @@ export class KritzelAwarenessCursors {
|
|
|
78
78
|
updated.delete(clientId);
|
|
79
79
|
changed = true;
|
|
80
80
|
}
|
|
81
|
+
else if (!changed && now - cursor.lastCursorMove > STALE_THRESHOLD_MS) {
|
|
82
|
+
changed = true;
|
|
83
|
+
}
|
|
81
84
|
}
|
|
82
85
|
if (changed) {
|
|
83
86
|
this.remoteCursors = updated;
|
|
@@ -182,7 +185,7 @@ export class KritzelAwarenessCursors {
|
|
|
182
185
|
void _ty;
|
|
183
186
|
void this.objectVersion;
|
|
184
187
|
const cursors = Array.from(this.remoteCursors.values());
|
|
185
|
-
return (h(Host, { key: '
|
|
188
|
+
return (h(Host, { key: '5a28def6e024249c4309c087502cde9f219f5421' }, cursors.map(remoteCursor => {
|
|
186
189
|
if (!remoteCursor.cursor)
|
|
187
190
|
return null;
|
|
188
191
|
// When a remote user is actively drawing, derive cursor position from
|
|
@@ -258,7 +261,7 @@ export class KritzelAwarenessCursors {
|
|
|
258
261
|
const displayName = this.getUserDisplayName(cursor.user);
|
|
259
262
|
return (h("div", { key: `edge-${cursor.clientId}`, class: { 'edge-indicator': true, stale, 'tracking-object': trackingObject }, style: {
|
|
260
263
|
transform: `translate(${clamped.x}px, ${clamped.y}px)`,
|
|
261
|
-
} }, h("svg", { class:
|
|
264
|
+
} }, h("svg", { class: { 'edge-arrow': true, stale }, width: "16", height: "16", viewBox: "0 0 16 16", style: { transform: `rotate(${arrowDeg}deg)` } }, h("path", { d: "M8 1L14 13H2L8 1Z", fill: color, stroke: "#ffffff", "stroke-width": "1.5", "stroke-linejoin": "round" })), h("span", { class: "edge-label", style: {
|
|
262
265
|
backgroundColor: color,
|
|
263
266
|
transform: `translate(${labelX}px, ${labelY}px)`,
|
|
264
267
|
} }, displayName)));
|
|
@@ -34,6 +34,7 @@ kritzel-controls.keyboard-open {
|
|
|
34
34
|
display: flex;
|
|
35
35
|
align-items: flex-start;
|
|
36
36
|
gap: 8px;
|
|
37
|
+
z-index: 10000;
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
.top-right-buttons {
|
|
@@ -43,6 +44,7 @@ kritzel-controls.keyboard-open {
|
|
|
43
44
|
display: flex;
|
|
44
45
|
align-items: center;
|
|
45
46
|
gap: 8px;
|
|
47
|
+
z-index: 10000;
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
.top-right-button {
|
|
@@ -16,7 +16,7 @@ import { DEFAULT_SHAPE_CONFIG } from "../../../configs/default-shape-tool.config
|
|
|
16
16
|
import { ABSOLUTE_SCALE_MAX, ABSOLUTE_SCALE_MIN } from "../../../constants/engine.constants";
|
|
17
17
|
import { KritzelKeyboardHelper } from "../../../helpers/keyboard.helper";
|
|
18
18
|
import { KritzelDevicesHelper } from "../../../helpers/devices.helper";
|
|
19
|
-
import { IndexedDBSyncProvider } from "../../..";
|
|
19
|
+
import { HocuspocusSyncProvider, IndexedDBSyncProvider } from "../../..";
|
|
20
20
|
import { KritzelSelectionGroup } from "../../../classes/objects/selection-group.class";
|
|
21
21
|
import { KritzelSelectionBox } from "../../../classes/objects/selection-box.class";
|
|
22
22
|
export class KritzelEditor {
|
|
@@ -180,10 +180,19 @@ export class KritzelEditor {
|
|
|
180
180
|
isControlsVisible = true;
|
|
181
181
|
isUtilityPanelVisible = true;
|
|
182
182
|
syncConfig = {
|
|
183
|
-
|
|
183
|
+
appStateId: 'kritzel-app-test',
|
|
184
|
+
providers: [HocuspocusSyncProvider, IndexedDBSyncProvider]
|
|
184
185
|
};
|
|
185
186
|
/** Optional login configuration. When provided, a "Sign in" button is shown that opens a login dialog with the configured providers. */
|
|
186
|
-
loginConfig
|
|
187
|
+
loginConfig = {
|
|
188
|
+
providers: [
|
|
189
|
+
{
|
|
190
|
+
label: 'Sign in with Google',
|
|
191
|
+
icon: 'google',
|
|
192
|
+
name: 'Google',
|
|
193
|
+
}
|
|
194
|
+
]
|
|
195
|
+
};
|
|
187
196
|
/** Optional unique identifier for namespacing storage keys across multiple editor instances. */
|
|
188
197
|
editorId;
|
|
189
198
|
/** Optional workspace ID to set as active. If provided, the editor will automatically activate the workspace with this ID. */
|
|
@@ -697,7 +706,7 @@ export class KritzelEditor {
|
|
|
697
706
|
const isLoggedIn = this.isLoggedIn;
|
|
698
707
|
const shouldShowCurrentUser = isLoggedIn;
|
|
699
708
|
const shouldShowLoginButton = !!this.loginConfig && !isLoggedIn;
|
|
700
|
-
return (h(Host, { key: '
|
|
709
|
+
return (h(Host, { key: '6dbc3a8c64dd097ba82e46341b3fb97cbd0194db' }, h("div", { key: '26ceb62f59ad830fd651a1712f57e5d711e7c6f4', class: "top-left-buttons" }, h("kritzel-workspace-manager", { key: 'afb4f5b87c5dc0a673444fb27930e43994df4e02', workspaces: this.workspaces, activeWorkspace: this.activeWorkspace, onWorkspaceChange: event => (this.activeWorkspace = event.detail), onIsWorkspaceManagerReady: () => (this.isWorkspaceManagerReady = true) }), h("kritzel-back-to-content", { key: 'f3c0f31841cb819917c3277852bc9b5ce291c09a', visible: this.isBackToContentButtonVisible, onBackToContent: () => this.backToContent() })), h("kritzel-engine", { key: '8a9e57132e6b74ec812ee516dc7f0d5fc6c8a2e1', ref: el => (this.engineRef = el), workspace: this.activeWorkspace, activeWorkspaceId: this.activeWorkspaceId, editorId: this.editorId, syncConfig: this.syncConfig, user: this.user, scaleMax: this.scaleMax, lockDrawingScale: this.lockDrawingScale, scaleMin: this.scaleMin, viewportBoundaryLeft: this.viewportBoundaryLeft, viewportBoundaryRight: this.viewportBoundaryRight, viewportBoundaryTop: this.viewportBoundaryTop, viewportBoundaryBottom: this.viewportBoundaryBottom, wheelEnabled: this.wheelEnabled, theme: this.currentTheme, debugInfo: this.debugInfo, globalContextMenuItems: this.globalContextMenuItems, objectContextMenuItems: this.objectContextMenuItems, onIsEngineReady: event => this.onEngineReady(event), onWorkspacesChange: event => this.handleWorkspacesChange(event), onActiveWorkspaceChange: event => this.handleActiveWorkspaceChange(event), onObjectsChange: event => this.handleObjectsChange(event), onObjectsAdded: event => this.handleObjectsAdded(event), onObjectsRemoved: event => this.handleObjectsRemoved(event), onObjectsUpdated: event => this.handleObjectsUpdated(event), onUndoStateChange: event => this.handleUndoStateChange(event), onObjectsInViewportChange: event => this.handleObjectsInViewportChange(event), onViewportChange: event => this.handleViewportChange(event), onAwarenessChange: event => this.handleAwarenessChange(event) }), h("kritzel-controls", { key: '6caadf512a0208fecdb18b6d68b17daa522161a3', class: { 'keyboard-open': this.isVirtualKeyboardOpen }, style: { display: this.isControlsVisible ? 'flex' : 'none' }, ref: el => (this.controlsRef = el), controls: this.controls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState, theme: this.currentTheme, onIsControlsReady: () => (this.isControlsReady = true) }), h("div", { key: 'e27e5f3965be2fd15c83b91470ef87c4031dd7a2', class: "top-right-buttons" }, h("kritzel-settings", { key: '57f8e75287402aecbb7740d46dfa15839de2169f', ref: el => (this.settingsRef = el), shortcuts: this.shortcuts, editorId: this.editorId, onSettingsChange: event => this.handleSettingsChange(event) }), h("kritzel-export", { key: '5ccf176d4fe1221c5d7597bd1c8537cf3324d3ee', ref: el => (this.exportRef = el), workspaceName: this.activeWorkspace?.name || 'workspace', onExportPng: () => this.engineRef.exportViewportAsPng(), onExportSvg: () => this.engineRef.exportViewportAsSvg(), onExportJson: event => this.engineRef.downloadAsJson(event.detail) }), h("kritzel-active-users", { key: '44a334b808706e11163e89b91074ca4ea8ab4b18', users: this.activeUsers }), shouldShowCurrentUser && h("kritzel-current-user", { key: 'bcb3c966e630b1a8fc4ccd438fc8fbb11cd2b167', user: this.user }), shouldShowLoginButton && h("kritzel-button", { key: 'f1957e56257b7c565311e41b770579f7e2bb910d', onButtonClick: () => this.loginDialogRef?.open() }, "Sign in"), h("kritzel-more-menu", { key: 'd8c1d1b51cf87725d68aaf4457b88828986a40dc', items: this.moreMenuItems }), h("kritzel-share-dialog", { key: 'f5840e7f56cf6897ec28b0f28d9b204037bf3348', ref: el => (this.shareDialogRef = el), isPublic: this.currentIsPublic, workspaceId: this.activeWorkspace?.id, onToggleIsPublic: this.handleToggleIsPublic }), this.loginConfig && (h("kritzel-login-dialog", { key: 'cfdcc3d5e7a5e29b0a352f0d4423ae79195dbf69', ref: el => (this.loginDialogRef = el), providers: this.loginConfig.providers, dialogTitle: this.loginConfig.title, subtitle: this.loginConfig.subtitle, onProviderLogin: this.handleProviderLogin })))));
|
|
701
710
|
}
|
|
702
711
|
static get is() { return "kritzel-editor"; }
|
|
703
712
|
static get originalStyleUrls() {
|
|
@@ -1106,7 +1115,7 @@ export class KritzelEditor {
|
|
|
1106
1115
|
},
|
|
1107
1116
|
"getter": false,
|
|
1108
1117
|
"setter": false,
|
|
1109
|
-
"defaultValue": "{\r\n providers: [IndexedDBSyncProvider]\r\n }"
|
|
1118
|
+
"defaultValue": "{\r\n appStateId: 'kritzel-app-test',\r\n providers: [HocuspocusSyncProvider, IndexedDBSyncProvider]\r\n }"
|
|
1110
1119
|
},
|
|
1111
1120
|
"loginConfig": {
|
|
1112
1121
|
"type": "unknown",
|
|
@@ -1130,7 +1139,8 @@ export class KritzelEditor {
|
|
|
1130
1139
|
"text": "Optional login configuration. When provided, a \"Sign in\" button is shown that opens a login dialog with the configured providers."
|
|
1131
1140
|
},
|
|
1132
1141
|
"getter": false,
|
|
1133
|
-
"setter": false
|
|
1142
|
+
"setter": false,
|
|
1143
|
+
"defaultValue": "{\r\n providers: [\r\n {\r\n label: 'Sign in with Google',\r\n icon: 'google',\r\n name: 'Google',\r\n }\r\n ]\r\n }"
|
|
1134
1144
|
},
|
|
1135
1145
|
"editorId": {
|
|
1136
1146
|
"type": "string",
|