@sequent-org/moodboard 1.4.32 → 1.4.34

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.
Files changed (137) hide show
  1. package/package.json +5 -1
  2. package/src/assets/fonts/inter/inter-cyrillic-400-normal.woff2 +0 -0
  3. package/src/assets/fonts/inter/inter-cyrillic-500-normal.woff2 +0 -0
  4. package/src/assets/fonts/inter/inter-latin-400-normal.woff2 +0 -0
  5. package/src/assets/fonts/inter/inter-latin-500-normal.woff2 +0 -0
  6. package/src/assets/icons/attachments.svg +3 -1
  7. package/src/assets/icons/comments.svg +2 -2
  8. package/src/assets/icons/connector.svg +6 -0
  9. package/src/assets/icons/emoji.svg +6 -1
  10. package/src/assets/icons/frame.svg +4 -1
  11. package/src/assets/icons/image.svg +5 -1
  12. package/src/assets/icons/laser.svg +1 -0
  13. package/src/assets/icons/lasso.svg +5 -0
  14. package/src/assets/icons/mindmap.svg +10 -2
  15. package/src/assets/icons/note.svg +4 -1
  16. package/src/assets/icons/pan.svg +5 -2
  17. package/src/assets/icons/pencil.svg +4 -1
  18. package/src/assets/icons/reactions.svg +5 -0
  19. package/src/assets/icons/redo.svg +3 -2
  20. package/src/assets/icons/select.svg +2 -8
  21. package/src/assets/icons/shapes.svg +5 -1
  22. package/src/assets/icons/text-add.svg +15 -1
  23. package/src/assets/icons/undo.svg +3 -2
  24. package/src/assets/reactions/1f44d.svg +20 -0
  25. package/src/assets/reactions/1f44e.svg +20 -0
  26. package/src/assets/reactions/2705.svg +20 -0
  27. package/src/assets/reactions/274c.svg +19 -0
  28. package/src/assets/reactions/2753.svg +20 -0
  29. package/src/assets/reactions/2764.svg +22 -0
  30. package/src/assets/reactions/2b50.svg +19 -0
  31. package/src/assets/reactions/plus-one.svg +25 -0
  32. package/src/core/PixiEngine.js +23 -0
  33. package/src/core/bootstrap/CoreInitializer.js +43 -0
  34. package/src/core/commands/GroupDeleteCommand.js +13 -1
  35. package/src/core/commands/UpdateShapeStyleCommand.js +121 -0
  36. package/src/core/commands/UpdateTextStyleCommand.js +17 -6
  37. package/src/core/commands/index.js +3 -0
  38. package/src/core/events/Events.js +22 -0
  39. package/src/core/flows/LayerAndViewportFlow.js +1 -0
  40. package/src/core/flows/ObjectLifecycleFlow.js +155 -7
  41. package/src/core/index.js +28 -1
  42. package/src/grid/CrossGridZoomPhases.js +3 -3
  43. package/src/initNoBundler.js +1 -1
  44. package/src/moodboard/DataManager.js +28 -0
  45. package/src/moodboard/MoodBoard.js +27 -0
  46. package/src/moodboard/bootstrap/MoodBoardInitializer.js +69 -1
  47. package/src/moodboard/bootstrap/MoodBoardUiFactory.js +22 -4
  48. package/src/moodboard/integration/MoodBoardEventBindings.js +5 -1
  49. package/src/moodboard/integration/MoodBoardLoadApi.js +10 -1
  50. package/src/moodboard/lifecycle/MoodBoardDestroyer.js +9 -0
  51. package/src/objects/ConnectorObject.js +2 -2
  52. package/src/objects/FrameObject.js +119 -59
  53. package/src/objects/ShapeObject.js +49 -74
  54. package/src/objects/shape/ShapeDrawer.js +210 -0
  55. package/src/services/ConnectorBindingResolver.js +112 -0
  56. package/src/services/ConnectorRouter.js +210 -0
  57. package/src/services/ai/ChatSessionController.js +14 -8
  58. package/src/services/comments/CommentService.js +344 -0
  59. package/src/tools/object-tools/CommentTool.js +85 -0
  60. package/src/tools/object-tools/DrawingTool.js +110 -10
  61. package/src/tools/object-tools/LaserPointerTool.js +121 -0
  62. package/src/tools/object-tools/SelectTool.js +25 -1
  63. package/src/tools/object-tools/TextTool.js +6 -1
  64. package/src/tools/object-tools/connector/ConnectorDragController.js +50 -3
  65. package/src/tools/object-tools/connector/connectorGesture.js +33 -19
  66. package/src/tools/object-tools/placement/PlacementInputRouter.js +22 -1
  67. package/src/tools/object-tools/selection/BoxSelectController.js +24 -2
  68. package/src/tools/object-tools/selection/FrameTitleInlineEditorController.js +139 -0
  69. package/src/tools/object-tools/selection/InlineEditorController.js +12 -0
  70. package/src/tools/object-tools/selection/InlineEditorDomFactory.js +36 -0
  71. package/src/tools/object-tools/selection/LassoSelectController.js +125 -0
  72. package/src/tools/object-tools/selection/MindmapInlineEditorController.js +1 -0
  73. package/src/tools/object-tools/selection/SelectInputRouter.js +64 -5
  74. package/src/tools/object-tools/selection/SelectToolLifecycleController.js +11 -1
  75. package/src/tools/object-tools/selection/SelectToolSetup.js +13 -1
  76. package/src/tools/object-tools/selection/TextEditorInteractionController.js +46 -12
  77. package/src/tools/object-tools/selection/TextEditorSyncService.js +1 -0
  78. package/src/tools/object-tools/selection/TextInlineEditorController.js +65 -6
  79. package/src/ui/CommentPopover.js +6 -0
  80. package/src/ui/CommentsBar.js +91 -0
  81. package/src/ui/ConnectorPropertiesPanel.js +150 -0
  82. package/src/ui/ContextMenu.js +25 -0
  83. package/src/ui/DrawingPropertiesPanel.js +362 -0
  84. package/src/ui/FilePropertiesPanel.js +5 -0
  85. package/src/ui/FramePropertiesPanel.js +5 -0
  86. package/src/ui/HtmlTextLayer.js +246 -66
  87. package/src/ui/NotePropertiesPanel.js +6 -0
  88. package/src/ui/ShapePropertiesPanel.js +307 -0
  89. package/src/ui/TextPropertiesPanel.js +100 -1
  90. package/src/ui/Toolbar.js +25 -2
  91. package/src/ui/Topbar.js +2 -2
  92. package/src/ui/animation/HoverLiftController.js +6 -7
  93. package/src/ui/chat/ChatComposer.js +63 -9
  94. package/src/ui/chat/ChatWindow.js +329 -166
  95. package/src/ui/comments/CommentListPanel.js +213 -0
  96. package/src/ui/comments/CommentPinLayer.js +448 -0
  97. package/src/ui/comments/CommentThreadPopover.js +539 -0
  98. package/src/ui/comments/commentFormat.js +32 -0
  99. package/src/ui/connector-properties/ConnectorPropertiesPanelBindings.js +223 -0
  100. package/src/ui/connector-properties/ConnectorPropertiesPanelEventBridge.js +114 -0
  101. package/src/ui/connector-properties/ConnectorPropertiesPanelMapper.js +144 -0
  102. package/src/ui/connector-properties/ConnectorPropertiesPanelRenderer.js +447 -0
  103. package/src/ui/connector-properties/ConnectorPropertiesPanelState.js +61 -0
  104. package/src/ui/connectors/ConnectionAnchorsLayer.js +1 -0
  105. package/src/ui/connectors/ConnectorHandlesLayer.js +321 -0
  106. package/src/ui/connectors/ConnectorLabelLayer.js +334 -0
  107. package/src/ui/connectors/ConnectorLayer.js +264 -57
  108. package/src/ui/handles/HandlesDomRenderer.js +5 -13
  109. package/src/ui/handles/HandlesEventBridge.js +1 -0
  110. package/src/ui/handles/SingleSelectionHandlesController.js +4 -0
  111. package/src/ui/mindmap/MindmapCollapseLayer.js +1 -0
  112. package/src/ui/mindmap/MindmapConnectionLayer.js +1 -0
  113. package/src/ui/mindmap/MindmapHtmlTextLayer.js +6 -0
  114. package/src/ui/shape-properties/ShapePropertiesPanelDom.js +533 -0
  115. package/src/ui/shape-properties/ShapePropertiesPanelSync.js +132 -0
  116. package/src/ui/styles/chat.css +710 -18
  117. package/src/ui/styles/index.css +1 -0
  118. package/src/ui/styles/panels.css +112 -2
  119. package/src/ui/styles/shape-properties-panel.css +250 -0
  120. package/src/ui/styles/toolbar.css +7 -2
  121. package/src/ui/styles/topbar.css +1 -1
  122. package/src/ui/styles/workspace.css +257 -6
  123. package/src/ui/text-properties/TextFormatControls.js +88 -0
  124. package/src/ui/text-properties/TextListRenderer.js +137 -0
  125. package/src/ui/text-properties/TextPropertiesPanelBindings.js +27 -0
  126. package/src/ui/text-properties/TextPropertiesPanelEventBridge.js +3 -1
  127. package/src/ui/text-properties/TextPropertiesPanelMapper.js +56 -0
  128. package/src/ui/text-properties/TextPropertiesPanelRenderer.js +24 -0
  129. package/src/ui/text-properties/TextPropertiesPanelState.js +8 -0
  130. package/src/ui/toolbar/ReactionsPopupController.js +88 -0
  131. package/src/ui/toolbar/ToolbarActionRouter.js +71 -5
  132. package/src/ui/toolbar/ToolbarPopupsController.js +120 -118
  133. package/src/ui/toolbar/ToolbarRenderer.js +9 -1
  134. package/src/ui/toolbar/ToolbarStateController.js +4 -1
  135. package/src/utils/iconLoader.js +17 -16
  136. package/src/utils/markdown.js +14 -0
  137. package/src/utils/richText.js +125 -0
@@ -25,7 +25,12 @@ export class ChatComposer {
25
25
  this._statusBar = refs.statusBar ?? null;
26
26
  this._handlers = handlers;
27
27
  this._listeners = [];
28
- /** @type {File[]} */
28
+ /**
29
+ * Внутреннее хранилище вложений. `sourceObjectId` нужен для дедупа
30
+ * reference-картинок, которые приходят из box-select / клика по объекту:
31
+ * один объект на доске = одно превью в композере.
32
+ * @type {{ file: File, sourceObjectId: string|null }[]}
33
+ */
29
34
  this._attachments = [];
30
35
  }
31
36
 
@@ -42,7 +47,7 @@ export class ChatComposer {
42
47
  });
43
48
  this._on(this._send, 'click', () => {
44
49
  if (this._send.dataset.state === 'streaming') {
45
- this._handlers.onAbort?.();
50
+ if (this._hasContent()) this._submit();
46
51
  } else {
47
52
  this._submit();
48
53
  }
@@ -76,13 +81,54 @@ export class ChatComposer {
76
81
  this._textarea.focus();
77
82
  }
78
83
 
79
- addAttachment(file) {
84
+ /**
85
+ * @param {File} file
86
+ * @param {{ sourceObjectId?: string|null }} [options] — `sourceObjectId`
87
+ * передаётся для reference-картинок с доски; дубликаты по этому id игнорируются.
88
+ */
89
+ addAttachment(file, options = {}) {
80
90
  if (!file) return;
81
- this._attachments.push(file);
91
+ const sourceObjectId = options?.sourceObjectId ?? null;
92
+ if (sourceObjectId && this._attachments.some((entry) => entry.sourceObjectId === sourceObjectId)) {
93
+ return;
94
+ }
95
+ this._attachments.push({ file, sourceObjectId });
82
96
  this._renderAttachmentsPreview();
83
97
  this._refreshSendState();
84
98
  }
85
99
 
100
+ hasAttachmentForObject(sourceObjectId) {
101
+ if (!sourceObjectId) return false;
102
+ return this._attachments.some((entry) => entry.sourceObjectId === sourceObjectId);
103
+ }
104
+
105
+ /**
106
+ * Удаляет превью конкретного объекта доски. Вызывается при снятии фокуса с изображения.
107
+ * @param {string} sourceObjectId
108
+ */
109
+ removeAttachmentForObject(sourceObjectId) {
110
+ if (!sourceObjectId) return;
111
+ const before = this._attachments.length;
112
+ this._attachments = this._attachments.filter((entry) => entry.sourceObjectId !== sourceObjectId);
113
+ if (this._attachments.length !== before) {
114
+ this._renderAttachmentsPreview();
115
+ this._refreshSendState();
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Удаляет все превью, добавленные с доски (sourceObjectId !== null).
121
+ * Файловые вложения (скрепка) не затрагиваются.
122
+ */
123
+ removeAllBoardAttachments() {
124
+ const before = this._attachments.length;
125
+ this._attachments = this._attachments.filter((entry) => entry.sourceObjectId === null);
126
+ if (this._attachments.length !== before) {
127
+ this._renderAttachmentsPreview();
128
+ this._refreshSendState();
129
+ }
130
+ }
131
+
86
132
  destroy() {
87
133
  for (const off of this._listeners) off();
88
134
  this._listeners = [];
@@ -94,11 +140,19 @@ export class ChatComposer {
94
140
  const trimmed = text.trim();
95
141
  const hasAttachments = this._attachments.length > 0;
96
142
  if (!trimmed && !hasAttachments) return;
97
- if (this._send.dataset.state === 'streaming') return;
98
- const attachments = [...this._attachments];
143
+ const attachments = this._attachments.map((entry) => entry.file);
144
+ this._textarea.value = '';
145
+ this._attachments = [];
146
+ this._resizeTextarea();
147
+ if (this._attachmentsPreview) this._renderAttachmentsPreview();
148
+ this._refreshSendState();
99
149
  this._handlers.onSubmit?.(trimmed, attachments);
100
150
  }
101
151
 
152
+ _hasContent() {
153
+ return this._textarea.value.trim().length > 0 || this._attachments.length > 0;
154
+ }
155
+
102
156
  _refreshSendState() {
103
157
  const hasText = this._textarea.value.trim().length > 0;
104
158
  const hasAttachments = this._attachments.length > 0;
@@ -110,7 +164,7 @@ export class ChatComposer {
110
164
  const files = Array.from(this._fileInput.files || []);
111
165
  if (!files.length) return;
112
166
  for (const file of files) {
113
- this._attachments.push(file);
167
+ this._attachments.push({ file, sourceObjectId: null });
114
168
  }
115
169
  this._fileInput.value = '';
116
170
  this._renderAttachmentsPreview();
@@ -134,8 +188,8 @@ export class ChatComposer {
134
188
  inputRow?.classList.add('has-attachments');
135
189
  this._textarea.placeholder = 'Опишите правку, изменение или стилевое направление эталонного изображения';
136
190
  for (let i = 0; i < this._attachments.length; i++) {
137
- const file = this._attachments[i];
138
- const item = this._buildAttachmentItem(file, i);
191
+ const entry = this._attachments[i];
192
+ const item = this._buildAttachmentItem(entry.file, i);
139
193
  container.appendChild(item);
140
194
  }
141
195
  }