@inditextech/weave-sdk 0.14.3 → 0.16.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/dist/sdk.cjs CHANGED
@@ -15506,6 +15506,7 @@ var WeaveStore = class {
15506
15506
  this.instance = instance;
15507
15507
  this.logger = this.instance.getChildLogger(this.getName());
15508
15508
  this.instance.getMainLogger().info(`Store with name [${this.getName()}] registered`);
15509
+ this.instance.emitEvent("onRoomLoaded", this.isRoomLoaded);
15509
15510
  return this;
15510
15511
  }
15511
15512
  getUser() {
@@ -15530,8 +15531,7 @@ var WeaveStore = class {
15530
15531
  return JSON.parse(JSON.stringify(this.state, void 0, 2));
15531
15532
  }
15532
15533
  setup() {
15533
- const config = this.instance.getConfiguration();
15534
- config.callbacks?.onRoomLoaded?.(this.isRoomLoaded);
15534
+ this.isRoomLoaded = false;
15535
15535
  this.instance.emitEvent("onRoomLoaded", this.isRoomLoaded);
15536
15536
  if (this.supportsUndoManager) {
15537
15537
  const weaveStateValues = (0, __syncedstore_core.getYjsValue)(
@@ -15552,7 +15552,6 @@ var WeaveStore = class {
15552
15552
  redoStackLength: this.undoManager.redoStack.length,
15553
15553
  undoStackLength: this.undoManager.undoStack.length
15554
15554
  };
15555
- config.callbacks?.onUndoManagerStatusChange?.(change);
15556
15555
  this.instance.emitEvent("onUndoManagerStatusChange", change);
15557
15556
  });
15558
15557
  this.undoManager.on("stack-item-popped", () => {
@@ -15562,14 +15561,12 @@ var WeaveStore = class {
15562
15561
  redoStackLength: this.undoManager.redoStack.length,
15563
15562
  undoStackLength: this.undoManager.undoStack.length
15564
15563
  };
15565
- config.callbacks?.onUndoManagerStatusChange?.(change);
15566
15564
  this.instance.emitEvent("onUndoManagerStatusChange", change);
15567
15565
  });
15568
15566
  }
15569
15567
  }
15570
15568
  (0, __syncedstore_core.observeDeep)(this.getState(), () => {
15571
15569
  const newState = JSON.parse(JSON.stringify(this.getState()));
15572
- config.callbacks?.onStateChange?.(newState);
15573
15570
  this.instance.emitEvent("onStateChange", newState);
15574
15571
  const nodesSelectionPlugin = this.instance.getPlugin("nodesSelection");
15575
15572
  if (this.isRoomLoaded && nodesSelectionPlugin && nodesSelectionPlugin.getSelectedNodes().length === 1) {
@@ -15583,7 +15580,6 @@ var WeaveStore = class {
15583
15580
  if (!this.isRoomLoaded && !(0, import_lodash.isEmpty)(this.state.weave)) {
15584
15581
  this.instance.setupRenderer();
15585
15582
  this.isRoomLoaded = true;
15586
- config.callbacks?.onRoomLoaded?.(this.isRoomLoaded);
15587
15583
  this.instance.emitEvent("onRoomLoaded", this.isRoomLoaded);
15588
15584
  }
15589
15585
  if (this.isRoomLoaded && !(0, import_lodash.isEmpty)(this.state.weave)) this.instance.render();
@@ -15765,7 +15761,7 @@ function clearContainerTargets(instance) {
15765
15761
  for (const container of getContainers) container.fire(__inditextech_weave_types.WEAVE_NODE_CUSTOM_EVENTS.onTargetLeave, { bubbles: true });
15766
15762
  }
15767
15763
  function checkIfOverContainer(instance, node) {
15768
- const nodesIntersected = instance.pointIntersectsContainerElement();
15764
+ const nodesIntersected = instance.pointIntersectsContainerElement(node.getParent());
15769
15765
  let nodeActualContainer = node.getParent();
15770
15766
  if (nodeActualContainer?.getAttrs().nodeId) nodeActualContainer = instance.getStage().findOne(`#${nodeActualContainer.getAttrs().nodeId}`);
15771
15767
  let layerToMove = void 0;
@@ -15795,6 +15791,12 @@ function moveNodeToContainer(instance, node) {
15795
15791
  return layerToMove;
15796
15792
  }
15797
15793
 
15794
+ //#endregion
15795
+ //#region src/plugins/users-selection/constants.ts
15796
+ const WEAVE_USERS_SELECTION_KEY = "usersSelection";
15797
+ const WEAVE_USERS_SELECTION_LAYER_ID = "usersPointersLayer";
15798
+ const WEAVE_USER_SELECTION_KEY = "userSelection";
15799
+
15798
15800
  //#endregion
15799
15801
  //#region src/plugins/nodes-selection/nodes-selection.ts
15800
15802
  var WeaveNodesSelectionPlugin = class extends WeavePlugin {
@@ -15959,6 +15961,8 @@ var WeaveNodesSelectionPlugin = class extends WeavePlugin {
15959
15961
  node: nodeHandler.serialize(node)
15960
15962
  };
15961
15963
  });
15964
+ const usersSelectionPlugin = this.instance.getPlugin(WEAVE_USERS_SELECTION_KEY);
15965
+ if (usersSelectionPlugin) usersSelectionPlugin.sendSelectionAwarenessInfo(this.tr);
15962
15966
  this.instance.emitEvent("onNodesChange", selectedNodes);
15963
15967
  }
15964
15968
  removeSelectedNodes() {
@@ -17135,7 +17139,7 @@ var WeaveTargetingManager = class {
17135
17139
  this.logger = this.instance.getChildLogger("targeting-manager");
17136
17140
  this.logger.debug("Targeting manager created");
17137
17141
  }
17138
- pointIntersectsContainerElement(point) {
17142
+ pointIntersectsContainerElement(actualLayer, point) {
17139
17143
  const stage = this.instance.getStage();
17140
17144
  const relativeMousePointer = point ? point : stage.getPointerPosition() ?? {
17141
17145
  x: 0,
@@ -17147,11 +17151,11 @@ var WeaveTargetingManager = class {
17147
17151
  if (node.getAttrs().nodeId) {
17148
17152
  const parent = stage.findOne(`#${node.getAttrs().nodeId}`);
17149
17153
  intersectedNode = parent;
17150
- break;
17154
+ continue;
17151
17155
  }
17152
- if (node.getAttrs().containerId) {
17156
+ if (node.getAttrs().containerId && node.getAttrs().id !== actualLayer?.getAttrs().id) {
17153
17157
  intersectedNode = node;
17154
- break;
17158
+ continue;
17155
17159
  }
17156
17160
  }
17157
17161
  return intersectedNode;
@@ -17916,7 +17920,7 @@ var WeaveRegisterManager = class {
17916
17920
 
17917
17921
  //#endregion
17918
17922
  //#region package.json
17919
- var version = "0.14.3";
17923
+ var version = "0.16.0";
17920
17924
 
17921
17925
  //#endregion
17922
17926
  //#region src/managers/setup.ts
@@ -18035,7 +18039,6 @@ var WeaveActionsManager = class {
18035
18039
  return this.activeAction;
18036
18040
  }
18037
18041
  triggerAction(actionName, params) {
18038
- const config = this.instance.getConfiguration();
18039
18042
  const actionsHandlers = this.instance.getActionsHandlers();
18040
18043
  if (!actionsHandlers[actionName]) {
18041
18044
  const msg = `Action handler with name [${actionName}] not registered`;
@@ -18045,7 +18048,6 @@ var WeaveActionsManager = class {
18045
18048
  if (typeof this.activeAction !== "undefined") this.cancelAction(this.activeAction);
18046
18049
  this.activeAction = actionName;
18047
18050
  const payload = actionsHandlers[actionName].trigger(this.cancelActionCallback(actionName), params);
18048
- config.callbacks?.onActiveActionChange?.(this.activeAction);
18049
18051
  this.instance.emitEvent("onActiveActionChange", this.activeAction);
18050
18052
  return payload;
18051
18053
  }
@@ -18080,7 +18082,6 @@ var WeaveActionsManager = class {
18080
18082
  return actionsHandlers[actionName].getProps?.();
18081
18083
  }
18082
18084
  cancelAction(actionName) {
18083
- const config = this.instance.getConfiguration();
18084
18085
  const actionsHandlers = this.instance.getActionsHandlers();
18085
18086
  if (!actionsHandlers[actionName]) {
18086
18087
  const msg = `Action handler with name [${actionName}] not registered`;
@@ -18089,7 +18090,6 @@ var WeaveActionsManager = class {
18089
18090
  }
18090
18091
  this.activeAction = void 0;
18091
18092
  actionsHandlers[actionName].cleanup?.();
18092
- config.callbacks?.onActiveActionChange?.(this.activeAction);
18093
18093
  this.instance.emitEvent("onActiveActionChange", this.activeAction);
18094
18094
  }
18095
18095
  cancelActionCallback(actionName) {
@@ -18313,7 +18313,6 @@ var Weave = class extends Emittery {
18313
18313
  this.setupManager.setupActions();
18314
18314
  this.moduleLogger.info("Instance started");
18315
18315
  this.status = __inditextech_weave_types.WEAVE_INSTANCE_STATUS.RUNNING;
18316
- this.getConfiguration().callbacks?.onInstanceStatus?.(this.status);
18317
18316
  this.emitEvent("onInstanceStatus", this.status);
18318
18317
  });
18319
18318
  }
@@ -18328,15 +18327,14 @@ var Weave = class extends Emittery {
18328
18327
  }
18329
18328
  async start() {
18330
18329
  this.moduleLogger.info("Start instance");
18330
+ this.emitEvent("onRoomLoaded", false);
18331
18331
  this.status = __inditextech_weave_types.WEAVE_INSTANCE_STATUS.STARTING;
18332
- this.getConfiguration().callbacks?.onInstanceStatus?.(this.status);
18333
18332
  this.emitEvent("onInstanceStatus", this.status);
18334
18333
  this.registerManager.registerNodesHandlers();
18335
18334
  this.registerManager.registerPlugins();
18336
18335
  this.registerManager.registerActionsHandlers();
18337
18336
  this.storeManager.registerStore(this.config.store);
18338
18337
  this.status = __inditextech_weave_types.WEAVE_INSTANCE_STATUS.LOADING_FONTS;
18339
- this.getConfiguration().callbacks?.onInstanceStatus?.(this.status);
18340
18338
  this.emitEvent("onInstanceStatus", this.status);
18341
18339
  await this.fontsManager.loadFonts();
18342
18340
  this.setupManager.setupLog();
@@ -18345,6 +18343,17 @@ var Weave = class extends Emittery {
18345
18343
  store.setup();
18346
18344
  store.connect();
18347
18345
  }
18346
+ destroy() {
18347
+ this.moduleLogger.info(`Destroying the instance`);
18348
+ this.clearListeners();
18349
+ this.status = __inditextech_weave_types.WEAVE_INSTANCE_STATUS.IDLE;
18350
+ this.emitEvent("onInstanceStatus", this.status);
18351
+ const store = this.storeManager.getStore();
18352
+ store.disconnect();
18353
+ const stage = this.getStage();
18354
+ if (stage) stage.destroy();
18355
+ this.moduleLogger.info(`Instance destroyed`);
18356
+ }
18348
18357
  getId() {
18349
18358
  return this.id;
18350
18359
  }
@@ -18459,13 +18468,11 @@ var Weave = class extends Emittery {
18459
18468
  update(newState) {
18460
18469
  this.getStore().setState(newState);
18461
18470
  this.renderer.render(() => {
18462
- this.config.callbacks?.onRender?.();
18463
18471
  this.emitEvent("onRender", {});
18464
18472
  });
18465
18473
  }
18466
18474
  render() {
18467
18475
  this.renderer.render(() => {
18468
- this.config.callbacks?.onRender?.();
18469
18476
  this.emitEvent("onRender", {});
18470
18477
  });
18471
18478
  }
@@ -18519,8 +18526,8 @@ var Weave = class extends Emittery {
18519
18526
  unGroup(group) {
18520
18527
  this.groupsManager.unGroup(group);
18521
18528
  }
18522
- pointIntersectsContainerElement(point) {
18523
- return this.targetingManager.pointIntersectsContainerElement(point);
18529
+ pointIntersectsContainerElement(actualLayer, point) {
18530
+ return this.targetingManager.pointIntersectsContainerElement(actualLayer, point);
18524
18531
  }
18525
18532
  getMousePointer(point) {
18526
18533
  return this.targetingManager.getMousePointer(point);
@@ -21616,27 +21623,223 @@ var WeaveConnectedUsersPlugin = class extends WeavePlugin {
21616
21623
  }
21617
21624
  };
21618
21625
 
21626
+ //#endregion
21627
+ //#region src/plugins/users-selection/users-selection.ts
21628
+ var WeaveUsersSelectionPlugin = class extends WeavePlugin {
21629
+ constructor(params) {
21630
+ super();
21631
+ const { config } = params;
21632
+ this.config = config;
21633
+ this.usersSelection = {};
21634
+ }
21635
+ getName() {
21636
+ return WEAVE_USERS_SELECTION_KEY;
21637
+ }
21638
+ getLayerName() {
21639
+ return WEAVE_USERS_SELECTION_LAYER_ID;
21640
+ }
21641
+ initLayer() {
21642
+ const stage = this.instance.getStage();
21643
+ const layer = new konva.default.Layer({
21644
+ id: this.getLayerName(),
21645
+ listening: false
21646
+ });
21647
+ stage.add(layer);
21648
+ }
21649
+ onRender() {
21650
+ this.renderSelectors();
21651
+ }
21652
+ getLayer() {
21653
+ const stage = this.instance.getStage();
21654
+ return stage.findOne(`#${WEAVE_USERS_SELECTION_LAYER_ID}`);
21655
+ }
21656
+ onInit() {
21657
+ this.instance.addEventListener("onAwarenessChange", (changes) => {
21658
+ const selfUser = this.config.getUser();
21659
+ const allActiveUsers = [];
21660
+ for (const change of changes) {
21661
+ if (!change[WEAVE_USER_SELECTION_KEY]) continue;
21662
+ if (change[WEAVE_USER_SELECTION_KEY] && selfUser.name !== change[WEAVE_USER_SELECTION_KEY].user) {
21663
+ const userSelection = change[WEAVE_USER_SELECTION_KEY];
21664
+ allActiveUsers.push(userSelection.user);
21665
+ this.usersSelection[userSelection.user] = {
21666
+ oldNodes: this.usersSelection[userSelection.user]?.actualNodes ?? {
21667
+ user: userSelection.user,
21668
+ nodes: []
21669
+ },
21670
+ actualNodes: userSelection
21671
+ };
21672
+ }
21673
+ }
21674
+ const allActiveUsersSelections = Object.keys(this.usersSelection).map((userSelectionKey) => {
21675
+ const selectionInfo = this.usersSelection[userSelectionKey];
21676
+ return selectionInfo.actualNodes.user;
21677
+ });
21678
+ const inactiveSelections = import_lodash.default.differenceWith(allActiveUsersSelections, allActiveUsers, import_lodash.default.isEqual);
21679
+ const selectionsLayer = this.getLayer();
21680
+ for (const inactiveSelection of inactiveSelections) {
21681
+ const userPointerNode = selectionsLayer?.findOne(`#${inactiveSelection}`);
21682
+ if (userPointerNode) userPointerNode.destroy();
21683
+ delete this.usersSelection[inactiveSelection];
21684
+ }
21685
+ this.renderSelectors();
21686
+ });
21687
+ this.renderSelectors();
21688
+ }
21689
+ sendSelectionAwarenessInfo(tr) {
21690
+ const userInfo = this.config.getUser();
21691
+ const store = this.instance.getStore();
21692
+ store.setAwarenessInfo(WEAVE_USER_SELECTION_KEY, {
21693
+ user: userInfo.name,
21694
+ nodes: tr.nodes().map((node) => node.getAttrs().id)
21695
+ });
21696
+ }
21697
+ removeSelectionAwarenessInfo() {
21698
+ const store = this.instance.getStore();
21699
+ store.setAwarenessInfo(WEAVE_USER_SELECTION_KEY, void 0);
21700
+ }
21701
+ stringToColor(str) {
21702
+ let hash = 0;
21703
+ str.split("").forEach((char) => {
21704
+ hash = char.charCodeAt(0) + ((hash << 5) - hash);
21705
+ });
21706
+ let color = "#";
21707
+ for (let i = 0; i < 3; i++) {
21708
+ const value = hash >> i * 8 & 255;
21709
+ color += value.toString(16).padStart(2, "0");
21710
+ }
21711
+ return color;
21712
+ }
21713
+ getSelectedNodesRect(nodes) {
21714
+ const stage = this.instance.getStage();
21715
+ const maxPoint = {
21716
+ x: -Infinity,
21717
+ y: -Infinity
21718
+ };
21719
+ const minPoint = {
21720
+ x: Infinity,
21721
+ y: Infinity
21722
+ };
21723
+ for (const nodeId of nodes) {
21724
+ const node = stage.findOne(`#${nodeId}`);
21725
+ if (node) {
21726
+ const nodeRect = node.getClientRect({
21727
+ relativeTo: stage,
21728
+ skipStroke: true
21729
+ });
21730
+ if (nodeRect.x < minPoint.x) minPoint.x = nodeRect.x;
21731
+ if (nodeRect.y < minPoint.y) minPoint.y = nodeRect.y;
21732
+ if (nodeRect.x + nodeRect.width > maxPoint.x) maxPoint.x = nodeRect.x + nodeRect.width;
21733
+ if (nodeRect.y + nodeRect.height > maxPoint.y) maxPoint.y = nodeRect.y + nodeRect.height;
21734
+ }
21735
+ }
21736
+ return {
21737
+ x: minPoint.x,
21738
+ y: minPoint.y,
21739
+ width: Math.abs(maxPoint.x - minPoint.x) * stage.scaleX(),
21740
+ height: Math.abs(maxPoint.y - minPoint.y) * stage.scaleY()
21741
+ };
21742
+ }
21743
+ renderSelectors() {
21744
+ const stage = this.instance.getStage();
21745
+ const selectorsLayer = this.getLayer();
21746
+ if (!this.enabled) return;
21747
+ const selectors = selectorsLayer?.find(".selector") ?? [];
21748
+ for (const selector of selectors) selector.destroy();
21749
+ for (const userPointerKey of Object.keys(this.usersSelection)) {
21750
+ const userSelector = this.usersSelection[userPointerKey];
21751
+ const userSelectorNode = selectorsLayer?.findOne(`#selector_${userSelector.actualNodes.user}`);
21752
+ if (!userSelectorNode) {
21753
+ const selectionRect = this.getSelectedNodesRect(userSelector.actualNodes.nodes);
21754
+ const userSelectorNode$1 = new konva.default.Group({
21755
+ name: "selector",
21756
+ id: `selector_${userSelector.actualNodes.user}`,
21757
+ x: selectionRect.x,
21758
+ y: selectionRect.y,
21759
+ width: selectionRect.width / stage.scaleX(),
21760
+ height: selectionRect.height / stage.scaleY(),
21761
+ listening: false
21762
+ });
21763
+ const userSelectorRect$1 = new konva.default.Rect({
21764
+ x: 0,
21765
+ y: 0,
21766
+ id: `selector_${userSelector.actualNodes.user}_rect`,
21767
+ width: selectionRect.width / stage.scaleX(),
21768
+ height: selectionRect.height / stage.scaleY(),
21769
+ fill: "transparent",
21770
+ stroke: this.stringToColor(userSelector.actualNodes.user),
21771
+ strokeWidth: 3,
21772
+ strokeScaleEnabled: false
21773
+ });
21774
+ userSelectorNode$1.add(userSelectorRect$1);
21775
+ selectorsLayer?.add(userSelectorNode$1);
21776
+ continue;
21777
+ }
21778
+ const userSelectorRect = selectorsLayer?.findOne(`#selector_${userSelector.actualNodes.user}_rect`);
21779
+ if (userSelectorRect) {
21780
+ const selectionRect = this.getSelectedNodesRect(userSelector.actualNodes.nodes);
21781
+ userSelectorNode.setAttrs({
21782
+ x: selectionRect.x,
21783
+ y: selectionRect.y,
21784
+ width: selectionRect.width,
21785
+ height: selectionRect.height,
21786
+ scale: 1
21787
+ });
21788
+ userSelectorRect.setAttrs({
21789
+ x: 0,
21790
+ y: 0,
21791
+ width: selectionRect.width,
21792
+ height: selectionRect.height
21793
+ });
21794
+ }
21795
+ }
21796
+ }
21797
+ enable() {
21798
+ this.getLayer()?.show();
21799
+ this.enabled = true;
21800
+ }
21801
+ disable() {
21802
+ this.getLayer()?.hide();
21803
+ this.enabled = false;
21804
+ }
21805
+ };
21806
+
21619
21807
  //#endregion
21620
21808
  //#region src/plugins/users-pointers/constants.ts
21621
21809
  const WEAVE_USERS_POINTERS_KEY = "usersPointers";
21622
21810
  const WEAVE_USERS_POINTERS_LAYER_ID = "usersPointersLayer";
21623
21811
  const WEAVE_USER_POINTER_KEY = "userPointer";
21812
+ const WEAVE_DEFAULT_USER_INFO_FUNCTION = () => ({
21813
+ name: "Unknown",
21814
+ email: "unknown@domain.com"
21815
+ });
21816
+ const WEAVE_USER_POINTERS_DEFAULT_PROPS = {
21817
+ separation: 8,
21818
+ pointer: {
21819
+ circleRadius: 4,
21820
+ circleStrokeWidth: 0
21821
+ },
21822
+ name: {
21823
+ fontFamily: "Arial",
21824
+ fontSize: 10,
21825
+ backgroundCornerRadius: 0,
21826
+ backgroundPaddingX: 8,
21827
+ backgroundPaddingY: 4
21828
+ }
21829
+ };
21624
21830
 
21625
21831
  //#endregion
21626
21832
  //#region src/plugins/users-pointers/users-pointers.ts
21627
21833
  var WeaveUsersPointersPlugin = class extends WeavePlugin {
21628
- userPointerCircleRadius = 4;
21629
- userPointerSeparation = 8;
21630
- userPointerCircleStrokeWidth = 1;
21631
- userPointerNameFontSize = 10;
21632
- userPointerBackgroundCornerRadius = 4;
21633
- userPointerBackgroundPaddingX = 4;
21634
- userPointerBackgroundPaddingY = 8;
21635
21834
  constructor(params) {
21636
21835
  super();
21637
21836
  const { config } = params;
21638
- this.usersPointers = {};
21639
21837
  this.config = config;
21838
+ this.uiConfig = {
21839
+ ...WEAVE_USER_POINTERS_DEFAULT_PROPS,
21840
+ ...this.config.ui
21841
+ };
21842
+ this.usersPointers = {};
21640
21843
  }
21641
21844
  getName() {
21642
21845
  return WEAVE_USERS_POINTERS_KEY;
@@ -21687,7 +21890,7 @@ var WeaveUsersPointersPlugin = class extends WeavePlugin {
21687
21890
  const inactivePointers = import_lodash.default.differenceWith(allActiveUsersPointers, allActiveUsers, import_lodash.default.isEqual);
21688
21891
  const pointersLayer = this.getLayer();
21689
21892
  for (const inactivePointer of inactivePointers) {
21690
- const userPointerNode = pointersLayer?.findOne(`#${inactivePointer}`);
21893
+ const userPointerNode = pointersLayer?.findOne(`#pointer_${inactivePointer}`);
21691
21894
  if (userPointerNode) userPointerNode.destroy();
21692
21895
  delete this.usersPointers[inactivePointer];
21693
21896
  }
@@ -21715,17 +21918,25 @@ var WeaveUsersPointersPlugin = class extends WeavePlugin {
21715
21918
  });
21716
21919
  this.renderPointers();
21717
21920
  }
21718
- stringToColour(str) {
21921
+ getContrastTextColor(hex) {
21922
+ const cleaned = hex.replace(/^#/, "");
21923
+ const r = parseInt(cleaned.slice(0, 2), 16);
21924
+ const g = parseInt(cleaned.slice(2, 4), 16);
21925
+ const b = parseInt(cleaned.slice(4, 6), 16);
21926
+ const luminance = (.299 * r + .587 * g + .114 * b) / 255;
21927
+ return luminance > .5 ? "black" : "white";
21928
+ }
21929
+ stringToColor(str) {
21719
21930
  let hash = 0;
21720
21931
  str.split("").forEach((char) => {
21721
21932
  hash = char.charCodeAt(0) + ((hash << 5) - hash);
21722
21933
  });
21723
- let colour = "#";
21934
+ let color = "#";
21724
21935
  for (let i = 0; i < 3; i++) {
21725
21936
  const value = hash >> i * 8 & 255;
21726
- colour += value.toString(16).padStart(2, "0");
21937
+ color += value.toString(16).padStart(2, "0");
21727
21938
  }
21728
- return colour;
21939
+ return color;
21729
21940
  }
21730
21941
  renderPointers() {
21731
21942
  const stage = this.instance.getStage();
@@ -21733,52 +21944,61 @@ var WeaveUsersPointersPlugin = class extends WeavePlugin {
21733
21944
  if (!this.enabled) return;
21734
21945
  for (const userPointerKey of Object.keys(this.usersPointers)) {
21735
21946
  const userPointer = this.usersPointers[userPointerKey];
21736
- const userPointerNode = pointersLayer?.findOne(`#${userPointer.actualPos.user}`);
21947
+ const userPointerNode = pointersLayer?.findOne(`#pointer_${userPointer.actualPos.user}`);
21737
21948
  if (!userPointerNode) {
21738
21949
  const userPointerNode$1 = new konva.default.Group({
21739
21950
  name: "pointer",
21740
- id: userPointer.actualPos.user,
21951
+ id: `pointer_${userPointer.actualPos.user}`,
21741
21952
  x: userPointer.actualPos.x,
21742
21953
  y: userPointer.actualPos.y,
21743
21954
  opacity: 1,
21744
21955
  listening: false
21745
21956
  });
21746
- const userPointNode$1 = new konva.default.Circle({
21747
- id: "userPoint",
21957
+ const { separation, pointer: { circleRadius, circleStrokeWidth }, name: { fontFamily, fontSize, backgroundCornerRadius, backgroundPaddingX, backgroundPaddingY } } = this.uiConfig;
21958
+ const userColor = this.stringToColor(userPointer.actualPos.user);
21959
+ const userContrastColor = this.getContrastTextColor(userColor);
21960
+ const userPointNode = new konva.default.Circle({
21961
+ id: `pointer_${userPointer.actualPos.user}_userPoint`,
21748
21962
  x: 0,
21749
21963
  y: 0,
21750
- radius: this.userPointerCircleRadius / stage.scaleX(),
21751
- fill: this.stringToColour(userPointer.actualPos.user),
21964
+ radius: circleRadius,
21965
+ fill: userColor,
21752
21966
  stroke: "black",
21753
- strokeWidth: this.userPointerCircleStrokeWidth / stage.scaleX(),
21967
+ strokeWidth: circleStrokeWidth,
21968
+ strokeScaleEnabled: false,
21754
21969
  listening: false
21755
21970
  });
21756
21971
  const userNameNode = new konva.default.Text({
21757
- id: "userPointName",
21758
- x: (this.userPointerSeparation + this.userPointerBackgroundPaddingX) / stage.scaleX(),
21759
- y: 0 / stage.scaleX(),
21760
- height: userPointNode$1.height() * 2 / stage.scaleX(),
21761
- text: userPointer.actualPos.user,
21762
- fontSize: this.userPointerNameFontSize / stage.scaleX(),
21763
- fontFamily: "NotoSansMono, monospace",
21764
- fill: "black",
21765
- align: "left",
21972
+ id: `pointer_${userPointer.actualPos.user}_userPointName`,
21973
+ x: separation,
21974
+ y: -circleRadius * 2 + backgroundPaddingY,
21975
+ text: userPointer.actualPos.user.trim(),
21976
+ fontSize,
21977
+ fontFamily,
21978
+ lineHeight: .9,
21979
+ fill: userContrastColor,
21980
+ align: "center",
21766
21981
  verticalAlign: "middle",
21767
- listening: false
21982
+ listening: false,
21983
+ strokeScaleEnabled: false,
21984
+ ellipsis: true
21768
21985
  });
21986
+ const textWidth = userNameNode.getTextWidth();
21987
+ const textHeight = userNameNode.getTextHeight();
21988
+ userNameNode.width(textWidth + backgroundPaddingX * 2);
21989
+ userNameNode.height(textHeight + backgroundPaddingY * 2);
21769
21990
  const userNameBackground = new konva.default.Rect({
21770
- id: "userPointRect",
21771
- x: this.userPointerSeparation / stage.scaleX(),
21772
- y: -this.userPointerBackgroundPaddingY / stage.scaleX(),
21773
- width: (userNameNode.width() + this.userPointerBackgroundPaddingX * 2) / stage.scaleX(),
21774
- height: (userNameNode.height() + this.userPointerBackgroundPaddingY * 2) / stage.scaleX(),
21775
- cornerRadius: this.userPointerBackgroundCornerRadius / stage.scaleX(),
21776
- fill: "rgba(0,0,0,0.2)",
21777
- strokeWidth: 0,
21991
+ id: `pointer_${userPointer.actualPos.user}_userPointRect`,
21992
+ x: separation,
21993
+ y: -backgroundPaddingY,
21994
+ width: textWidth + backgroundPaddingX * 2,
21995
+ height: textHeight + backgroundPaddingY * 2,
21996
+ cornerRadius: backgroundCornerRadius,
21997
+ fill: userColor,
21778
21998
  listening: false
21779
21999
  });
21780
- userPointNode$1.setAttrs({ y: userNameBackground.y() + userNameBackground.height() / 2 });
21781
- userPointerNode$1.add(userPointNode$1);
22000
+ userPointNode.setAttrs({ y: userNameBackground.y() + userNameBackground.height() / 2 });
22001
+ userPointerNode$1.add(userPointNode);
21782
22002
  userPointerNode$1.add(userNameBackground);
21783
22003
  userPointerNode$1.add(userNameNode);
21784
22004
  pointersLayer?.add(userPointerNode$1);
@@ -21793,27 +22013,8 @@ var WeaveUsersPointersPlugin = class extends WeavePlugin {
21793
22013
  y: userPointer.actualPos.y
21794
22014
  };
21795
22015
  const hasChanged = !import_lodash.default.isEqual(actualPos, oldPos);
21796
- const userPointNode = userPointerNode.getChildren((node) => node.getAttrs().id === "userPoint");
21797
- userPointNode[0]?.setAttrs({
21798
- radius: this.userPointerCircleRadius / stage.scaleX(),
21799
- strokeWidth: this.userPointerCircleStrokeWidth / stage.scaleX()
21800
- });
21801
- const userPointNodeText = userPointerNode.getChildren((node) => node.getAttrs().id === "userPointName");
21802
- userPointNodeText[0]?.setAttrs({
21803
- x: (this.userPointerSeparation + this.userPointerBackgroundPaddingX) / stage.scaleX(),
21804
- y: 0 / stage.scaleX(),
21805
- height: userPointNode[0]?.height(),
21806
- fontSize: this.userPointerNameFontSize / stage.scaleX()
21807
- });
21808
- const userPointNodeBackground = userPointerNode.getChildren((node) => node.getAttrs().id === "userPointRect");
21809
- userPointNodeBackground[0]?.setAttrs({
21810
- x: this.userPointerSeparation / stage.scaleX(),
21811
- y: -this.userPointerBackgroundPaddingY / stage.scaleX(),
21812
- cornerRadius: this.userPointerBackgroundCornerRadius / stage.scaleX(),
21813
- width: userPointNodeText[0]?.width() + this.userPointerBackgroundPaddingX * 2,
21814
- height: userPointNodeText[0]?.height() + this.userPointerBackgroundPaddingY * 2
21815
- });
21816
- userPointNode[0]?.setAttrs({ y: userPointNodeBackground[0]?.y() + userPointNodeBackground[0]?.height() / 2 });
22016
+ userPointerNode.scaleX(1 / stage.scaleX());
22017
+ userPointerNode.scaleY(1 / stage.scaleY());
21817
22018
  if (hasChanged) userPointerNode.setAttrs({
21818
22019
  x: userPointer.actualPos.x,
21819
22020
  y: userPointer.actualPos.y,
@@ -22249,6 +22450,7 @@ exports.SELECTION_TOOL_STATE = SELECTION_TOOL_STATE
22249
22450
  exports.TEXT_TOOL_ACTION_NAME = TEXT_TOOL_ACTION_NAME
22250
22451
  exports.TEXT_TOOL_STATE = TEXT_TOOL_STATE
22251
22452
  exports.WEAVE_COPY_PASTE_NODES_KEY = WEAVE_COPY_PASTE_NODES_KEY
22453
+ exports.WEAVE_DEFAULT_USER_INFO_FUNCTION = WEAVE_DEFAULT_USER_INFO_FUNCTION
22252
22454
  exports.WEAVE_FRAME_NODE_DEFAULT_CONFIG = WEAVE_FRAME_NODE_DEFAULT_CONFIG
22253
22455
  exports.WEAVE_FRAME_NODE_DEFAULT_PROPS = WEAVE_FRAME_NODE_DEFAULT_PROPS
22254
22456
  exports.WEAVE_FRAME_NODE_SIZES = WEAVE_FRAME_NODE_SIZES
@@ -22266,6 +22468,13 @@ exports.WEAVE_NODES_SELECTION_KEY = WEAVE_NODES_SELECTION_KEY
22266
22468
  exports.WEAVE_NODES_SELECTION_LAYER_ID = WEAVE_NODES_SELECTION_LAYER_ID
22267
22469
  exports.WEAVE_NODES_SNAPPING_KEY = WEAVE_NODES_SNAPPING_KEY
22268
22470
  exports.WEAVE_STAGE_GRID_KEY = WEAVE_STAGE_GRID_KEY
22471
+ exports.WEAVE_USERS_POINTERS_KEY = WEAVE_USERS_POINTERS_KEY
22472
+ exports.WEAVE_USERS_POINTERS_LAYER_ID = WEAVE_USERS_POINTERS_LAYER_ID
22473
+ exports.WEAVE_USERS_SELECTION_KEY = WEAVE_USERS_SELECTION_KEY
22474
+ exports.WEAVE_USERS_SELECTION_LAYER_ID = WEAVE_USERS_SELECTION_LAYER_ID
22475
+ exports.WEAVE_USER_POINTERS_DEFAULT_PROPS = WEAVE_USER_POINTERS_DEFAULT_PROPS
22476
+ exports.WEAVE_USER_POINTER_KEY = WEAVE_USER_POINTER_KEY
22477
+ exports.WEAVE_USER_SELECTION_KEY = WEAVE_USER_SELECTION_KEY
22269
22478
  exports.Weave = Weave
22270
22479
  exports.WeaveAction = WeaveAction
22271
22480
  exports.WeaveBrushToolAction = WeaveBrushToolAction
@@ -22302,6 +22511,7 @@ exports.WeaveStore = WeaveStore
22302
22511
  exports.WeaveTextNode = WeaveTextNode
22303
22512
  exports.WeaveTextToolAction = WeaveTextToolAction
22304
22513
  exports.WeaveUsersPointersPlugin = WeaveUsersPointersPlugin
22514
+ exports.WeaveUsersSelectionPlugin = WeaveUsersSelectionPlugin
22305
22515
  exports.WeaveZoomInToolAction = WeaveZoomInToolAction
22306
22516
  exports.WeaveZoomOutToolAction = WeaveZoomOutToolAction
22307
22517
  exports.checkIfOverContainer = checkIfOverContainer