@sequent-org/moodboard 1.4.12 → 1.4.14

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sequent-org/moodboard",
3
- "version": "1.4.12",
3
+ "version": "1.4.14",
4
4
  "type": "module",
5
5
  "description": "Interactive moodboard",
6
6
  "main": "./src/index.js",
@@ -40,6 +40,49 @@ export class KeyboardClipboardImagePaste {
40
40
  }
41
41
  }
42
42
 
43
+ async handleFileUpload(file, fileName) {
44
+ try {
45
+ if (!(this.core && this.core.fileUploadService)) {
46
+ alert('Сервис загрузки файлов недоступен. Файл не добавлен.');
47
+ return;
48
+ }
49
+
50
+ const uploadResult = await this.core.fileUploadService.uploadFile(file, fileName);
51
+ const world = this.core?.pixi?.worldLayer || this.core?.pixi?.app?.stage;
52
+ const view = this.core?.pixi?.app?.view;
53
+ const s = world?.scale?.x || 1;
54
+ const hasCursor = Number.isFinite(this.core?._cursor?.x) && Number.isFinite(this.core?._cursor?.y);
55
+
56
+ const screenX = hasCursor ? this.core._cursor.x : (view?.clientWidth || 0) / 2;
57
+ const screenY = hasCursor ? this.core._cursor.y : (view?.clientHeight || 0) / 2;
58
+ const worldX = (screenX - (world?.x || 0)) / s;
59
+ const worldY = (screenY - (world?.y || 0)) / s;
60
+
61
+ const width = 120;
62
+ const height = 140;
63
+ this.eventBus.emit(Events.UI.ToolbarAction, {
64
+ type: 'file',
65
+ id: 'file',
66
+ position: {
67
+ x: Math.round(worldX - width / 2),
68
+ y: Math.round(worldY - height / 2)
69
+ },
70
+ properties: {
71
+ fileName: uploadResult.name,
72
+ fileSize: uploadResult.size,
73
+ mimeType: uploadResult.mimeType,
74
+ formattedSize: uploadResult.formattedSize,
75
+ src: uploadResult.src,
76
+ width,
77
+ height
78
+ }
79
+ });
80
+ } catch (error) {
81
+ console.error('Ошибка загрузки файла:', error);
82
+ alert('Ошибка загрузки файла на сервер. Файл не добавлен.');
83
+ }
84
+ }
85
+
43
86
  createPasteHandler() {
44
87
  return async (e) => {
45
88
  try {
@@ -59,6 +102,21 @@ export class KeyboardClipboardImagePaste {
59
102
  }
60
103
  if (handled) return;
61
104
 
105
+ // Windows/desktop clipboard providers may expose pasted files as items
106
+ // with generic type like "Files" and empty clipboardData.files.
107
+ for (const item of items) {
108
+ if (!item || typeof item.getAsFile !== 'function') continue;
109
+ const fileFromItem = item.getAsFile();
110
+ if (!fileFromItem) continue;
111
+ e.preventDefault();
112
+ if (fileFromItem.type && fileFromItem.type.startsWith('image/')) {
113
+ await this.handleImageFileUpload(fileFromItem, fileFromItem.name || 'clipboard-image.png');
114
+ } else {
115
+ await this.handleFileUpload(fileFromItem, fileFromItem.name || 'clipboard-file');
116
+ }
117
+ return;
118
+ }
119
+
62
120
  const files = cd.files ? Array.from(cd.files) : [];
63
121
  const imgFile = files.find(f => f.type && f.type.startsWith('image/'));
64
122
  if (imgFile) {
@@ -66,6 +124,12 @@ export class KeyboardClipboardImagePaste {
66
124
  await this.handleImageFileUpload(imgFile, imgFile.name || 'clipboard-image.png');
67
125
  return;
68
126
  }
127
+ const plainFile = files.find(f => !(f.type && f.type.startsWith('image/')));
128
+ if (plainFile) {
129
+ e.preventDefault();
130
+ await this.handleFileUpload(plainFile, plainFile.name || 'clipboard-file');
131
+ return;
132
+ }
69
133
 
70
134
  const html = cd.getData && cd.getData('text/html');
71
135
  if (html && html.includes('<img')) {