microboard-temp 0.3.2 → 0.4.1
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/browser.js +341 -488
- package/dist/cjs/index.js +341 -488
- package/dist/cjs/node.js +341 -488
- package/dist/esm/browser.js +341 -488
- package/dist/esm/index.js +341 -488
- package/dist/esm/node.js +341 -488
- package/dist/types/Items/Image/ImageHelpers.d.ts +0 -6
- package/dist/types/Settings.d.ts +5 -0
- package/package.json +1 -1
package/dist/cjs/browser.js
CHANGED
|
@@ -627,12 +627,10 @@ var require_escape_html = __commonJS((exports2, module2) => {
|
|
|
627
627
|
var exports_browser = {};
|
|
628
628
|
__export(exports_browser, {
|
|
629
629
|
validateRichTextData: () => validateRichTextData,
|
|
630
|
-
validateMediaFile: () => validateMediaFile,
|
|
631
630
|
validateItemsMap: () => validateItemsMap,
|
|
632
631
|
uploadVideoToStorage: () => uploadVideoToStorage,
|
|
633
632
|
uploadToTheStorage: () => uploadToTheStorage,
|
|
634
633
|
updateRects: () => updateRects,
|
|
635
|
-
updateMediaUsage: () => updateMediaUsage,
|
|
636
634
|
translateElementBy: () => translateElementBy,
|
|
637
635
|
transformHtmlOrTextToMarkdown: () => transformHtmlOrTextToMarkdown,
|
|
638
636
|
toRelativePoint: () => toRelativePoint,
|
|
@@ -681,7 +679,6 @@ __export(exports_browser, {
|
|
|
681
679
|
forceNumberIntoInterval: () => forceNumberIntoInterval,
|
|
682
680
|
fileTosha256: () => fileTosha256,
|
|
683
681
|
exportBoardSnapshot: () => exportBoardSnapshot,
|
|
684
|
-
deleteMedia: () => deleteMedia,
|
|
685
682
|
decodeHtml: () => decodeHtml,
|
|
686
683
|
cursors: () => defaultCursors,
|
|
687
684
|
createVideoItem: () => createVideoItem,
|
|
@@ -689,8 +686,6 @@ __export(exports_browser, {
|
|
|
689
686
|
conf: () => conf,
|
|
690
687
|
checkHotkeys: () => checkHotkeys,
|
|
691
688
|
catmullRomInterpolate: () => catmullRomInterpolate,
|
|
692
|
-
catchErrorResponse: () => catchErrorResponse,
|
|
693
|
-
catchDuplicateErrorResponse: () => catchDuplicateErrorResponse,
|
|
694
689
|
captureFrame: () => captureFrame,
|
|
695
690
|
calculatePosition: () => calculatePosition,
|
|
696
691
|
calculateAudioPosition: () => calculateAudioPosition,
|
|
@@ -6724,6 +6719,11 @@ var conf = {
|
|
|
6724
6719
|
getDOMParser: undefined,
|
|
6725
6720
|
measureCtx: undefined,
|
|
6726
6721
|
i18n: instance,
|
|
6722
|
+
hooks: {
|
|
6723
|
+
beforeMediaUpload: async (...args) => false,
|
|
6724
|
+
beforeMediaRemove: async (...args) => false,
|
|
6725
|
+
onUploadMediaError: async (...args) => false
|
|
6726
|
+
},
|
|
6727
6727
|
openModal: () => {},
|
|
6728
6728
|
notify: () => "",
|
|
6729
6729
|
disMissNotification: () => {},
|
|
@@ -39172,7 +39172,7 @@ class VideoItem extends BaseItem {
|
|
|
39172
39172
|
onRemove() {
|
|
39173
39173
|
const storageId = this.getStorageId();
|
|
39174
39174
|
if (storageId) {
|
|
39175
|
-
|
|
39175
|
+
conf.hooks.beforeMediaRemove([storageId], this.board.getBoardId());
|
|
39176
39176
|
}
|
|
39177
39177
|
super.onRemove();
|
|
39178
39178
|
}
|
|
@@ -39233,158 +39233,6 @@ async function fileTosha256(file) {
|
|
|
39233
39233
|
}
|
|
39234
39234
|
|
|
39235
39235
|
// src/Items/Image/ImageHelpers.ts
|
|
39236
|
-
var catchErrorResponse = async (response, mediaType) => {
|
|
39237
|
-
if (response.status === 403) {
|
|
39238
|
-
const data = await response.json();
|
|
39239
|
-
let errorBody = conf.i18n.t("toolsPanel.addMedia.limitReached.bodyWithoutLimit");
|
|
39240
|
-
if (!data.isOwnerRequest) {
|
|
39241
|
-
errorBody = conf.i18n.t("toolsPanel.addMedia.limitReached.bodyOwner");
|
|
39242
|
-
} else if (data.currentUsage && data.storageLimit) {
|
|
39243
|
-
errorBody = conf.i18n.t(`toolsPanel.addMedia.limitReached.body.${parseInt(data.storageLimit) < 1e5 ? "basic" : "plus"}`);
|
|
39244
|
-
}
|
|
39245
|
-
conf.notify({
|
|
39246
|
-
variant: "warning",
|
|
39247
|
-
header: conf.i18n.t("toolsPanel.addMedia.limitReached.header"),
|
|
39248
|
-
body: errorBody,
|
|
39249
|
-
button: data.isOwnerRequest && data.storageLimit <= 100 ? {
|
|
39250
|
-
text: conf.i18n.t("toolsPanel.addMedia.upgradeToPlus"),
|
|
39251
|
-
onClick: () => conf.openModal("USER_PLAN_MODAL_ID")
|
|
39252
|
-
} : undefined,
|
|
39253
|
-
duration: 8000
|
|
39254
|
-
});
|
|
39255
|
-
} else if (response.status === 413) {
|
|
39256
|
-
const data = await response.json();
|
|
39257
|
-
let errorBody = conf.i18n.t("toolsPanel.addMedia.tooLarge.bodyWithoutLimit");
|
|
39258
|
-
let isBasicPlan = false;
|
|
39259
|
-
if (data.fileSizeLimit && data.fileSize) {
|
|
39260
|
-
if (mediaType === "image") {
|
|
39261
|
-
isBasicPlan = parseInt(data.fileSizeLimit) < 20;
|
|
39262
|
-
errorBody = conf.i18n.t(`toolsPanel.addMedia.tooLarge.imageBody.${isBasicPlan ? "basic" : "plus"}`);
|
|
39263
|
-
} else {
|
|
39264
|
-
isBasicPlan = parseInt(data.fileSizeLimit) < 1000;
|
|
39265
|
-
errorBody = conf.i18n.t(`toolsPanel.addMedia.tooLarge.audioOrVideoBody.${isBasicPlan ? "basic" : "plus"}`);
|
|
39266
|
-
}
|
|
39267
|
-
}
|
|
39268
|
-
conf.notify({
|
|
39269
|
-
variant: "warning",
|
|
39270
|
-
header: conf.i18n.t("toolsPanel.addMedia.tooLarge.header"),
|
|
39271
|
-
body: errorBody,
|
|
39272
|
-
button: isBasicPlan ? {
|
|
39273
|
-
text: conf.i18n.t("toolsPanel.addMedia.upgradeToPlus"),
|
|
39274
|
-
onClick: () => conf.openModal("USER_PLAN_MODAL_ID")
|
|
39275
|
-
} : undefined,
|
|
39276
|
-
duration: 4000
|
|
39277
|
-
});
|
|
39278
|
-
} else if (response.status === 401) {
|
|
39279
|
-
conf.openModal("MEDIA_UNAVAILABLE_MODAL_ID");
|
|
39280
|
-
} else if (response.status === 415) {
|
|
39281
|
-
conf.notify({
|
|
39282
|
-
variant: "warning",
|
|
39283
|
-
header: conf.i18n.t("toolsPanel.addMedia.unsupportedFormat.header"),
|
|
39284
|
-
body: conf.i18n.t("toolsPanel.addMedia.unsupportedFormat.body"),
|
|
39285
|
-
duration: 4000
|
|
39286
|
-
});
|
|
39287
|
-
} else {
|
|
39288
|
-
conf.notify({
|
|
39289
|
-
variant: "error",
|
|
39290
|
-
header: conf.i18n.t("toolsPanel.addMedia.unhandled.header"),
|
|
39291
|
-
body: conf.i18n.t("toolsPanel.addMedia.unhandled.body"),
|
|
39292
|
-
duration: 4000
|
|
39293
|
-
});
|
|
39294
|
-
}
|
|
39295
|
-
throw new Error(`HTTP status: ${response.status}`);
|
|
39296
|
-
};
|
|
39297
|
-
var catchDuplicateErrorResponse = async (response) => {
|
|
39298
|
-
if (response.status === 403) {
|
|
39299
|
-
conf.notify({
|
|
39300
|
-
variant: "warning",
|
|
39301
|
-
header: conf.i18n.t("toolsPanel.addMedia.limitReached.header"),
|
|
39302
|
-
body: conf.i18n.t("toolsPanel.addMedia.limitReached.duplicateBody"),
|
|
39303
|
-
duration: 4000
|
|
39304
|
-
});
|
|
39305
|
-
} else {
|
|
39306
|
-
conf.notify({
|
|
39307
|
-
variant: "error",
|
|
39308
|
-
header: conf.i18n.t("toolsPanel.addMedia.unhandled.header"),
|
|
39309
|
-
body: conf.i18n.t("toolsPanel.addMedia.unhandled.body"),
|
|
39310
|
-
duration: 4000
|
|
39311
|
-
});
|
|
39312
|
-
}
|
|
39313
|
-
throw new Error(`HTTP status: ${response.status}`);
|
|
39314
|
-
};
|
|
39315
|
-
var validateMediaFile = (file, account2) => {
|
|
39316
|
-
const fileExtension = file.name.split(".").pop()?.toLowerCase() || "";
|
|
39317
|
-
if (!file.type.startsWith("image") && !conf.AUDIO_FORMATS.includes(fileExtension) && !conf.VIDEO_FORMATS.includes(fileExtension)) {
|
|
39318
|
-
conf.notify({
|
|
39319
|
-
variant: "warning",
|
|
39320
|
-
header: conf.i18n.t("toolsPanel.addMedia.unsupportedFormat.header"),
|
|
39321
|
-
body: conf.i18n.t("toolsPanel.addMedia.unsupportedFormat.body"),
|
|
39322
|
-
duration: 4000
|
|
39323
|
-
});
|
|
39324
|
-
return false;
|
|
39325
|
-
}
|
|
39326
|
-
const isBasicPlan = account2.billingInfo?.plan.name === "basic";
|
|
39327
|
-
let errorBody = conf.i18n.t(`toolsPanel.addMedia.tooLarge.imageBody.${isBasicPlan ? "basic" : "plus"}`);
|
|
39328
|
-
if (conf.AUDIO_FORMATS.includes(fileExtension) || conf.VIDEO_FORMATS.includes(fileExtension)) {
|
|
39329
|
-
errorBody = conf.i18n.t(`toolsPanel.addMedia.tooLarge.audioOrVideoBody.${isBasicPlan ? "basic" : "plus"}`);
|
|
39330
|
-
if (file.size / 1024 ** 2 > (account2.billingInfo?.storage.maxMediaSize || Infinity)) {
|
|
39331
|
-
conf.notify({
|
|
39332
|
-
variant: "warning",
|
|
39333
|
-
header: conf.i18n.t("toolsPanel.addMedia.tooLarge.header"),
|
|
39334
|
-
body: errorBody,
|
|
39335
|
-
button: isBasicPlan ? {
|
|
39336
|
-
text: conf.i18n.t("toolsPanel.addMedia.upgradeToPlus"),
|
|
39337
|
-
onClick: () => conf.openModal("USER_PLAN_MODAL_ID")
|
|
39338
|
-
} : undefined,
|
|
39339
|
-
duration: 4000
|
|
39340
|
-
});
|
|
39341
|
-
return false;
|
|
39342
|
-
}
|
|
39343
|
-
} else if (file.size / 1024 ** 2 > (account2.billingInfo?.storage.maxImageSize || Infinity)) {
|
|
39344
|
-
conf.notify({
|
|
39345
|
-
variant: "warning",
|
|
39346
|
-
header: conf.i18n.t("toolsPanel.addMedia.tooLarge.header"),
|
|
39347
|
-
body: errorBody,
|
|
39348
|
-
button: isBasicPlan ? {
|
|
39349
|
-
text: conf.i18n.t("toolsPanel.addMedia.upgradeToPlus"),
|
|
39350
|
-
onClick: () => conf.openModal("USER_PLAN_MODAL_ID")
|
|
39351
|
-
} : undefined,
|
|
39352
|
-
duration: 4000
|
|
39353
|
-
});
|
|
39354
|
-
return false;
|
|
39355
|
-
}
|
|
39356
|
-
return true;
|
|
39357
|
-
};
|
|
39358
|
-
var deleteMedia = async (mediaIds, boardId) => {
|
|
39359
|
-
fetch(`${window?.location.origin}/api/v1/media/usage/${boardId}`, {
|
|
39360
|
-
method: "POST",
|
|
39361
|
-
headers: {
|
|
39362
|
-
"content-type": "application/json"
|
|
39363
|
-
},
|
|
39364
|
-
body: JSON.stringify({ mediaIds, shouldIncrease: false })
|
|
39365
|
-
}).catch((error) => {
|
|
39366
|
-
console.error("Media storage error:", error);
|
|
39367
|
-
});
|
|
39368
|
-
};
|
|
39369
|
-
var updateMediaUsage = async (mediaIds, boardId) => {
|
|
39370
|
-
try {
|
|
39371
|
-
const response = await fetch(`${window?.location.origin}/api/v1/media/usage/${boardId}`, {
|
|
39372
|
-
method: "POST",
|
|
39373
|
-
headers: {
|
|
39374
|
-
"Content-Type": "application/json"
|
|
39375
|
-
},
|
|
39376
|
-
body: JSON.stringify({ mediaIds, shouldIncrease: true })
|
|
39377
|
-
});
|
|
39378
|
-
if (response.status !== 200) {
|
|
39379
|
-
await catchDuplicateErrorResponse(response);
|
|
39380
|
-
return false;
|
|
39381
|
-
}
|
|
39382
|
-
return true;
|
|
39383
|
-
} catch (error) {
|
|
39384
|
-
console.error("Media storage error:", error);
|
|
39385
|
-
return false;
|
|
39386
|
-
}
|
|
39387
|
-
};
|
|
39388
39236
|
var uploadToTheStorage = async (hash, dataURL, accessToken, boardId) => {
|
|
39389
39237
|
return new Promise((resolve2, reject) => {
|
|
39390
39238
|
const base64String = dataURL.split(",")[1];
|
|
@@ -39402,7 +39250,7 @@ var uploadToTheStorage = async (hash, dataURL, accessToken, boardId) => {
|
|
|
39402
39250
|
body: blob
|
|
39403
39251
|
}).then(async (response) => {
|
|
39404
39252
|
if (response.status !== 200) {
|
|
39405
|
-
return
|
|
39253
|
+
return conf.hooks.onUploadMediaError(response, "image");
|
|
39406
39254
|
}
|
|
39407
39255
|
return response.json();
|
|
39408
39256
|
}).then((data) => {
|
|
@@ -39502,7 +39350,7 @@ var uploadVideoToStorage = async (hash, videoBlob, accessToken, boardId) => {
|
|
|
39502
39350
|
body: videoBlob
|
|
39503
39351
|
}).then(async (response) => {
|
|
39504
39352
|
if (response.status !== 200) {
|
|
39505
|
-
return
|
|
39353
|
+
return conf.hooks.onUploadMediaError(response, "video");
|
|
39506
39354
|
}
|
|
39507
39355
|
return response.json();
|
|
39508
39356
|
}).then((data) => {
|
|
@@ -39606,6 +39454,326 @@ var captureFrame = (frameTime, video) => {
|
|
|
39606
39454
|
return null;
|
|
39607
39455
|
}
|
|
39608
39456
|
};
|
|
39457
|
+
// src/Items/Audio/Audio.ts
|
|
39458
|
+
class AudioItem extends BaseItem {
|
|
39459
|
+
events;
|
|
39460
|
+
extension;
|
|
39461
|
+
itemType = "Audio";
|
|
39462
|
+
parent = "Board";
|
|
39463
|
+
transformation;
|
|
39464
|
+
linkTo;
|
|
39465
|
+
subject = new Subject;
|
|
39466
|
+
loadCallbacks = [];
|
|
39467
|
+
beforeLoadCallbacks = [];
|
|
39468
|
+
transformationRenderBlock = undefined;
|
|
39469
|
+
url = "";
|
|
39470
|
+
isPlaying = false;
|
|
39471
|
+
currentTime = 0;
|
|
39472
|
+
isStorageUrl = true;
|
|
39473
|
+
constructor(board, isStorageUrl, url, events, id = "", extension2) {
|
|
39474
|
+
super(board, id);
|
|
39475
|
+
this.events = events;
|
|
39476
|
+
this.extension = extension2;
|
|
39477
|
+
this.linkTo = new LinkTo(this.id, events);
|
|
39478
|
+
this.board = board;
|
|
39479
|
+
this.isStorageUrl = isStorageUrl;
|
|
39480
|
+
if (url) {
|
|
39481
|
+
this.applyUrl(url);
|
|
39482
|
+
}
|
|
39483
|
+
this.transformation = new Transformation(id, events);
|
|
39484
|
+
this.linkTo.subject.subscribe(() => {
|
|
39485
|
+
this.updateMbr();
|
|
39486
|
+
this.subject.publish(this);
|
|
39487
|
+
});
|
|
39488
|
+
this.transformation.subject.subscribe(this.onTransform);
|
|
39489
|
+
this.right = this.left + conf.AUDIO_DIMENSIONS.width;
|
|
39490
|
+
this.bottom = this.top + conf.AUDIO_DIMENSIONS.height;
|
|
39491
|
+
this.shouldUseCustomRender = true;
|
|
39492
|
+
}
|
|
39493
|
+
setCurrentTime(time) {
|
|
39494
|
+
this.currentTime = time;
|
|
39495
|
+
}
|
|
39496
|
+
getCurrentTime() {
|
|
39497
|
+
return this.currentTime;
|
|
39498
|
+
}
|
|
39499
|
+
getIsStorageUrl() {
|
|
39500
|
+
return this.isStorageUrl;
|
|
39501
|
+
}
|
|
39502
|
+
onTransform = () => {
|
|
39503
|
+
this.updateMbr();
|
|
39504
|
+
this.subject.publish(this);
|
|
39505
|
+
};
|
|
39506
|
+
doOnceBeforeOnLoad = (callback) => {
|
|
39507
|
+
this.loadCallbacks.push(callback);
|
|
39508
|
+
};
|
|
39509
|
+
doOnceOnLoad = (callback) => {
|
|
39510
|
+
this.loadCallbacks.push(callback);
|
|
39511
|
+
};
|
|
39512
|
+
setIsPlaying(isPlaying) {
|
|
39513
|
+
this.isPlaying = isPlaying;
|
|
39514
|
+
this.shouldRenderOutsideViewRect = isPlaying;
|
|
39515
|
+
this.subject.publish(this);
|
|
39516
|
+
}
|
|
39517
|
+
getIsPlaying() {
|
|
39518
|
+
return this.isPlaying;
|
|
39519
|
+
}
|
|
39520
|
+
applyUrl(url) {
|
|
39521
|
+
if (this.isStorageUrl) {
|
|
39522
|
+
try {
|
|
39523
|
+
const newUrl = new URL(url);
|
|
39524
|
+
this.url = `${window.location.origin}${newUrl.pathname}`;
|
|
39525
|
+
} catch (_) {}
|
|
39526
|
+
} else {
|
|
39527
|
+
this.url = url;
|
|
39528
|
+
}
|
|
39529
|
+
}
|
|
39530
|
+
setUrl(url) {
|
|
39531
|
+
this.emit({
|
|
39532
|
+
class: "Audio",
|
|
39533
|
+
method: "setUrl",
|
|
39534
|
+
item: [this.getId()],
|
|
39535
|
+
url
|
|
39536
|
+
});
|
|
39537
|
+
}
|
|
39538
|
+
getStorageId() {
|
|
39539
|
+
if (!this.isStorageUrl) {
|
|
39540
|
+
return;
|
|
39541
|
+
}
|
|
39542
|
+
return this.url.split("/").pop();
|
|
39543
|
+
}
|
|
39544
|
+
getUrl() {
|
|
39545
|
+
return this.url;
|
|
39546
|
+
}
|
|
39547
|
+
onLoad = async () => {
|
|
39548
|
+
this.shootBeforeLoadCallbacks();
|
|
39549
|
+
this.updateMbr();
|
|
39550
|
+
this.subject.publish(this);
|
|
39551
|
+
this.shootLoadCallbacks();
|
|
39552
|
+
};
|
|
39553
|
+
onError = (_error) => {
|
|
39554
|
+
this.updateMbr();
|
|
39555
|
+
this.subject.publish(this);
|
|
39556
|
+
this.shootLoadCallbacks();
|
|
39557
|
+
};
|
|
39558
|
+
updateMbr() {
|
|
39559
|
+
const { translateX, translateY, scaleX, scaleY } = this.transformation.matrix;
|
|
39560
|
+
this.left = translateX;
|
|
39561
|
+
this.top = translateY;
|
|
39562
|
+
this.right = this.left + conf.AUDIO_DIMENSIONS.width * scaleX;
|
|
39563
|
+
this.bottom = this.top + conf.AUDIO_DIMENSIONS.height * scaleY;
|
|
39564
|
+
}
|
|
39565
|
+
render(context) {
|
|
39566
|
+
if (this.transformationRenderBlock) {
|
|
39567
|
+
return;
|
|
39568
|
+
}
|
|
39569
|
+
const ctx = context.ctx;
|
|
39570
|
+
const radius = 12 * this.transformation.getScale().x;
|
|
39571
|
+
ctx.save();
|
|
39572
|
+
ctx.globalCompositeOperation = "destination-out";
|
|
39573
|
+
ctx.beginPath();
|
|
39574
|
+
ctx.moveTo(this.left + radius, this.top);
|
|
39575
|
+
ctx.lineTo(this.left + this.getWidth() - radius, this.top);
|
|
39576
|
+
ctx.quadraticCurveTo(this.left + this.getWidth(), this.top, this.left + this.getWidth(), this.top + radius);
|
|
39577
|
+
ctx.lineTo(this.left + this.getWidth(), this.top + this.getHeight() - radius);
|
|
39578
|
+
ctx.quadraticCurveTo(this.left + this.getWidth(), this.top + this.getHeight(), this.left + this.getWidth() - radius, this.top + this.getHeight());
|
|
39579
|
+
ctx.lineTo(this.left + radius, this.top + this.getHeight());
|
|
39580
|
+
ctx.quadraticCurveTo(this.left, this.top + this.getHeight(), this.left, this.top + this.getHeight() - radius);
|
|
39581
|
+
ctx.lineTo(this.left, this.top + radius);
|
|
39582
|
+
ctx.quadraticCurveTo(this.left, this.top, this.left + radius, this.top);
|
|
39583
|
+
ctx.closePath();
|
|
39584
|
+
ctx.fill();
|
|
39585
|
+
ctx.restore();
|
|
39586
|
+
}
|
|
39587
|
+
renderHTML(documentFactory) {
|
|
39588
|
+
const div = documentFactory.createElement("audio-item");
|
|
39589
|
+
const { translateX, translateY, scaleX, scaleY } = this.transformation.matrix;
|
|
39590
|
+
const transform = `translate(${translateX}px, ${translateY}px) scale(${scaleX}, ${scaleY})`;
|
|
39591
|
+
div.id = this.getId();
|
|
39592
|
+
div.style.width = `${conf.AUDIO_DIMENSIONS.width}px`;
|
|
39593
|
+
div.style.height = `${conf.AUDIO_DIMENSIONS.height}px`;
|
|
39594
|
+
div.style.transformOrigin = "top left";
|
|
39595
|
+
div.style.transform = transform;
|
|
39596
|
+
div.style.position = "absolute";
|
|
39597
|
+
div.setAttribute("audio-url", this.getUrl());
|
|
39598
|
+
if (this.extension) {
|
|
39599
|
+
div.setAttribute("extension", this.extension);
|
|
39600
|
+
}
|
|
39601
|
+
if (this.isStorageUrl) {
|
|
39602
|
+
div.setAttribute("is-storage-url", "true");
|
|
39603
|
+
}
|
|
39604
|
+
div.setAttribute("data-link-to", "");
|
|
39605
|
+
return div;
|
|
39606
|
+
}
|
|
39607
|
+
serialize() {
|
|
39608
|
+
return {
|
|
39609
|
+
itemType: "Audio",
|
|
39610
|
+
url: this.url,
|
|
39611
|
+
transformation: this.transformation.serialize(),
|
|
39612
|
+
isStorageUrl: this.isStorageUrl,
|
|
39613
|
+
extension: this.extension
|
|
39614
|
+
};
|
|
39615
|
+
}
|
|
39616
|
+
deserialize(data) {
|
|
39617
|
+
if (data.isStorageUrl) {
|
|
39618
|
+
this.isStorageUrl = data.isStorageUrl;
|
|
39619
|
+
}
|
|
39620
|
+
if (data.transformation) {
|
|
39621
|
+
this.transformation.deserialize(data.transformation);
|
|
39622
|
+
}
|
|
39623
|
+
if (data.url) {
|
|
39624
|
+
this.setUrl(data.url);
|
|
39625
|
+
}
|
|
39626
|
+
if (data.extension) {
|
|
39627
|
+
this.extension = data.extension;
|
|
39628
|
+
}
|
|
39629
|
+
return this;
|
|
39630
|
+
}
|
|
39631
|
+
apply(op) {
|
|
39632
|
+
switch (op.class) {
|
|
39633
|
+
case "Transformation":
|
|
39634
|
+
this.transformation.apply(op);
|
|
39635
|
+
break;
|
|
39636
|
+
case "LinkTo":
|
|
39637
|
+
this.linkTo.apply(op);
|
|
39638
|
+
break;
|
|
39639
|
+
case "Audio":
|
|
39640
|
+
if (op.method === "setUrl") {
|
|
39641
|
+
this.applyUrl(op.url);
|
|
39642
|
+
}
|
|
39643
|
+
this.subject.publish(this);
|
|
39644
|
+
break;
|
|
39645
|
+
}
|
|
39646
|
+
}
|
|
39647
|
+
emit(operation) {
|
|
39648
|
+
if (this.events) {
|
|
39649
|
+
const command = new AudioCommand([this], operation);
|
|
39650
|
+
command.apply();
|
|
39651
|
+
this.events.emit(operation, command);
|
|
39652
|
+
} else {
|
|
39653
|
+
this.apply(operation);
|
|
39654
|
+
}
|
|
39655
|
+
}
|
|
39656
|
+
setId(id) {
|
|
39657
|
+
this.id = id;
|
|
39658
|
+
this.transformation.setId(id);
|
|
39659
|
+
return this;
|
|
39660
|
+
}
|
|
39661
|
+
getId() {
|
|
39662
|
+
return this.id;
|
|
39663
|
+
}
|
|
39664
|
+
shootLoadCallbacks() {
|
|
39665
|
+
while (this.loadCallbacks.length > 0) {
|
|
39666
|
+
this.loadCallbacks.shift()(this);
|
|
39667
|
+
}
|
|
39668
|
+
}
|
|
39669
|
+
shootBeforeLoadCallbacks() {
|
|
39670
|
+
while (this.beforeLoadCallbacks.length > 0) {
|
|
39671
|
+
this.beforeLoadCallbacks.shift()(this);
|
|
39672
|
+
}
|
|
39673
|
+
}
|
|
39674
|
+
getPath() {
|
|
39675
|
+
const { left, top, right, bottom } = this.getMbr();
|
|
39676
|
+
const leftTop = new Point(left, top);
|
|
39677
|
+
const rightTop = new Point(right, top);
|
|
39678
|
+
const rightBottom = new Point(right, bottom);
|
|
39679
|
+
const leftBottom = new Point(left, bottom);
|
|
39680
|
+
return new Path([
|
|
39681
|
+
new Line(leftTop, rightTop),
|
|
39682
|
+
new Line(rightTop, rightBottom),
|
|
39683
|
+
new Line(rightBottom, leftBottom),
|
|
39684
|
+
new Line(leftBottom, leftTop)
|
|
39685
|
+
], true);
|
|
39686
|
+
}
|
|
39687
|
+
getSnapAnchorPoints() {
|
|
39688
|
+
const mbr = this.getMbr();
|
|
39689
|
+
const width2 = mbr.getWidth();
|
|
39690
|
+
const height2 = mbr.getHeight();
|
|
39691
|
+
return [
|
|
39692
|
+
new Point(mbr.left + width2 / 2, mbr.top),
|
|
39693
|
+
new Point(mbr.left + width2 / 2, mbr.bottom),
|
|
39694
|
+
new Point(mbr.left, mbr.top + height2 / 2),
|
|
39695
|
+
new Point(mbr.right, mbr.top + height2 / 2)
|
|
39696
|
+
];
|
|
39697
|
+
}
|
|
39698
|
+
isClosed() {
|
|
39699
|
+
return true;
|
|
39700
|
+
}
|
|
39701
|
+
getRichText() {
|
|
39702
|
+
return null;
|
|
39703
|
+
}
|
|
39704
|
+
getLinkTo() {
|
|
39705
|
+
return;
|
|
39706
|
+
}
|
|
39707
|
+
getExtension() {
|
|
39708
|
+
return this.extension;
|
|
39709
|
+
}
|
|
39710
|
+
download() {
|
|
39711
|
+
if (this.extension) {
|
|
39712
|
+
const linkElem = conf.documentFactory.createElement("a");
|
|
39713
|
+
linkElem.href = this.url;
|
|
39714
|
+
linkElem.setAttribute("download", `${this.board.getBoardId()}.${this.extension}`);
|
|
39715
|
+
linkElem.click();
|
|
39716
|
+
}
|
|
39717
|
+
}
|
|
39718
|
+
onRemove() {
|
|
39719
|
+
const storageId = this.getStorageId();
|
|
39720
|
+
if (storageId) {
|
|
39721
|
+
conf.hooks.beforeMediaRemove([storageId], this.board.getBoardId());
|
|
39722
|
+
}
|
|
39723
|
+
super.onRemove();
|
|
39724
|
+
}
|
|
39725
|
+
}
|
|
39726
|
+
// src/Items/Audio/AudioHelpers.ts
|
|
39727
|
+
var uploadAudioToStorage = async (hash, audioBlob, accessToken, boardId) => {
|
|
39728
|
+
return new Promise((resolve2, reject) => {
|
|
39729
|
+
fetch(`${window.location.origin}/api/v1/media/audio/${boardId}`, {
|
|
39730
|
+
method: "POST",
|
|
39731
|
+
headers: {
|
|
39732
|
+
"Content-Type": audioBlob.type,
|
|
39733
|
+
"x-audio-id": hash,
|
|
39734
|
+
Authorization: `Bearer ${accessToken}`
|
|
39735
|
+
},
|
|
39736
|
+
body: audioBlob
|
|
39737
|
+
}).then(async (response) => {
|
|
39738
|
+
if (response.status !== 200) {
|
|
39739
|
+
return conf.hooks.onUploadMediaError(response, "audio");
|
|
39740
|
+
}
|
|
39741
|
+
return response.json();
|
|
39742
|
+
}).then((data) => {
|
|
39743
|
+
console.log(data);
|
|
39744
|
+
resolve2(data.src);
|
|
39745
|
+
}).catch((error) => {
|
|
39746
|
+
console.error("Media storage error:", error);
|
|
39747
|
+
reject(error);
|
|
39748
|
+
});
|
|
39749
|
+
});
|
|
39750
|
+
};
|
|
39751
|
+
var prepareAudio = (file, accessToken, boardId) => {
|
|
39752
|
+
return new Promise((resolve2, reject) => {
|
|
39753
|
+
const audio = document.createElement("audio");
|
|
39754
|
+
audio.src = URL.createObjectURL(file);
|
|
39755
|
+
audio.onloadedmetadata = () => {
|
|
39756
|
+
fileTosha256(file).then((hash) => {
|
|
39757
|
+
uploadAudioToStorage(hash, file, accessToken, boardId).then((url) => {
|
|
39758
|
+
resolve2(url);
|
|
39759
|
+
}).catch(reject);
|
|
39760
|
+
}).catch(() => {
|
|
39761
|
+
reject(new Error("Failed to generate hash"));
|
|
39762
|
+
});
|
|
39763
|
+
};
|
|
39764
|
+
audio.onerror = () => {
|
|
39765
|
+
reject(new Error("Failed to load audio"));
|
|
39766
|
+
};
|
|
39767
|
+
});
|
|
39768
|
+
};
|
|
39769
|
+
var calculateAudioPosition = (board, audioItem) => {
|
|
39770
|
+
const cameraMbr = board.camera.getMbr();
|
|
39771
|
+
const cameraWidth = cameraMbr.getWidth();
|
|
39772
|
+
const translateX = cameraMbr.left + cameraWidth * 0.34;
|
|
39773
|
+
const translateY = cameraMbr.getCenter().y - audioItem.getHeight() / 2;
|
|
39774
|
+
const scale = cameraWidth * 0.32 / audioItem.getWidth();
|
|
39775
|
+
return new Matrix2(translateX, translateY, scale, scale);
|
|
39776
|
+
};
|
|
39609
39777
|
// src/Items/Placeholder/Placeholder.ts
|
|
39610
39778
|
var PlaceholderImg = `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
39611
39779
|
<path d="M5 11.1L7 9.1L12.5 14.6L16 11.1L19 14.1V5H5V11.1ZM4 3H20C20.2652 3 20.5196 3.10536 20.7071 3.29289C20.8946 3.48043 21 3.73478 21 4V20C21 20.2652 20.8946 20.5196 20.7071 20.7071C20.5196 20.8946 20.2652 21 20 21H4C3.73478 21 3.48043 20.8946 3.29289 20.7071C3.10536 20.5196 3 20.2652 3 20V4C3 3.73478 3.10536 3.48043 3.29289 3.29289C3.48043 3.10536 3.73478 3 4 3ZM15.5 10C15.1022 10 14.7206 9.84196 14.4393 9.56066C14.158 9.27936 14 8.89782 14 8.5C14 8.10218 14.158 7.72064 14.4393 7.43934C14.7206 7.15804 15.1022 7 15.5 7C15.8978 7 16.2794 7.15804 16.5607 7.43934C16.842 7.72064 17 8.10218 17 8.5C17 8.89782 16.842 9.27936 16.5607 9.56066C16.2794 9.84196 15.8978 10 15.5 10Z" fill="white" fill-opacity="0.6"/>
|
|
@@ -40154,331 +40322,11 @@ class ImageItem extends BaseItem {
|
|
|
40154
40322
|
onRemove() {
|
|
40155
40323
|
const storageId = this.getStorageId();
|
|
40156
40324
|
if (storageId) {
|
|
40157
|
-
|
|
40325
|
+
conf.hooks.beforeMediaRemove([storageId], this.board.getBoardId());
|
|
40158
40326
|
}
|
|
40159
40327
|
super.onRemove();
|
|
40160
40328
|
}
|
|
40161
40329
|
}
|
|
40162
|
-
// src/Items/Audio/Audio.ts
|
|
40163
|
-
class AudioItem extends BaseItem {
|
|
40164
|
-
events;
|
|
40165
|
-
extension;
|
|
40166
|
-
itemType = "Audio";
|
|
40167
|
-
parent = "Board";
|
|
40168
|
-
transformation;
|
|
40169
|
-
linkTo;
|
|
40170
|
-
subject = new Subject;
|
|
40171
|
-
loadCallbacks = [];
|
|
40172
|
-
beforeLoadCallbacks = [];
|
|
40173
|
-
transformationRenderBlock = undefined;
|
|
40174
|
-
url = "";
|
|
40175
|
-
isPlaying = false;
|
|
40176
|
-
currentTime = 0;
|
|
40177
|
-
isStorageUrl = true;
|
|
40178
|
-
constructor(board, isStorageUrl, url, events, id = "", extension2) {
|
|
40179
|
-
super(board, id);
|
|
40180
|
-
this.events = events;
|
|
40181
|
-
this.extension = extension2;
|
|
40182
|
-
this.linkTo = new LinkTo(this.id, events);
|
|
40183
|
-
this.board = board;
|
|
40184
|
-
this.isStorageUrl = isStorageUrl;
|
|
40185
|
-
if (url) {
|
|
40186
|
-
this.applyUrl(url);
|
|
40187
|
-
}
|
|
40188
|
-
this.transformation = new Transformation(id, events);
|
|
40189
|
-
this.linkTo.subject.subscribe(() => {
|
|
40190
|
-
this.updateMbr();
|
|
40191
|
-
this.subject.publish(this);
|
|
40192
|
-
});
|
|
40193
|
-
this.transformation.subject.subscribe(this.onTransform);
|
|
40194
|
-
this.right = this.left + conf.AUDIO_DIMENSIONS.width;
|
|
40195
|
-
this.bottom = this.top + conf.AUDIO_DIMENSIONS.height;
|
|
40196
|
-
this.shouldUseCustomRender = true;
|
|
40197
|
-
}
|
|
40198
|
-
setCurrentTime(time) {
|
|
40199
|
-
this.currentTime = time;
|
|
40200
|
-
}
|
|
40201
|
-
getCurrentTime() {
|
|
40202
|
-
return this.currentTime;
|
|
40203
|
-
}
|
|
40204
|
-
getIsStorageUrl() {
|
|
40205
|
-
return this.isStorageUrl;
|
|
40206
|
-
}
|
|
40207
|
-
onTransform = () => {
|
|
40208
|
-
this.updateMbr();
|
|
40209
|
-
this.subject.publish(this);
|
|
40210
|
-
};
|
|
40211
|
-
doOnceBeforeOnLoad = (callback) => {
|
|
40212
|
-
this.loadCallbacks.push(callback);
|
|
40213
|
-
};
|
|
40214
|
-
doOnceOnLoad = (callback) => {
|
|
40215
|
-
this.loadCallbacks.push(callback);
|
|
40216
|
-
};
|
|
40217
|
-
setIsPlaying(isPlaying) {
|
|
40218
|
-
this.isPlaying = isPlaying;
|
|
40219
|
-
this.shouldRenderOutsideViewRect = isPlaying;
|
|
40220
|
-
this.subject.publish(this);
|
|
40221
|
-
}
|
|
40222
|
-
getIsPlaying() {
|
|
40223
|
-
return this.isPlaying;
|
|
40224
|
-
}
|
|
40225
|
-
applyUrl(url) {
|
|
40226
|
-
if (this.isStorageUrl) {
|
|
40227
|
-
try {
|
|
40228
|
-
const newUrl = new URL(url);
|
|
40229
|
-
this.url = `${window.location.origin}${newUrl.pathname}`;
|
|
40230
|
-
} catch (_) {}
|
|
40231
|
-
} else {
|
|
40232
|
-
this.url = url;
|
|
40233
|
-
}
|
|
40234
|
-
}
|
|
40235
|
-
setUrl(url) {
|
|
40236
|
-
this.emit({
|
|
40237
|
-
class: "Audio",
|
|
40238
|
-
method: "setUrl",
|
|
40239
|
-
item: [this.getId()],
|
|
40240
|
-
url
|
|
40241
|
-
});
|
|
40242
|
-
}
|
|
40243
|
-
getStorageId() {
|
|
40244
|
-
if (!this.isStorageUrl) {
|
|
40245
|
-
return;
|
|
40246
|
-
}
|
|
40247
|
-
return this.url.split("/").pop();
|
|
40248
|
-
}
|
|
40249
|
-
getUrl() {
|
|
40250
|
-
return this.url;
|
|
40251
|
-
}
|
|
40252
|
-
onLoad = async () => {
|
|
40253
|
-
this.shootBeforeLoadCallbacks();
|
|
40254
|
-
this.updateMbr();
|
|
40255
|
-
this.subject.publish(this);
|
|
40256
|
-
this.shootLoadCallbacks();
|
|
40257
|
-
};
|
|
40258
|
-
onError = (_error) => {
|
|
40259
|
-
this.updateMbr();
|
|
40260
|
-
this.subject.publish(this);
|
|
40261
|
-
this.shootLoadCallbacks();
|
|
40262
|
-
};
|
|
40263
|
-
updateMbr() {
|
|
40264
|
-
const { translateX, translateY, scaleX, scaleY } = this.transformation.matrix;
|
|
40265
|
-
this.left = translateX;
|
|
40266
|
-
this.top = translateY;
|
|
40267
|
-
this.right = this.left + conf.AUDIO_DIMENSIONS.width * scaleX;
|
|
40268
|
-
this.bottom = this.top + conf.AUDIO_DIMENSIONS.height * scaleY;
|
|
40269
|
-
}
|
|
40270
|
-
render(context) {
|
|
40271
|
-
if (this.transformationRenderBlock) {
|
|
40272
|
-
return;
|
|
40273
|
-
}
|
|
40274
|
-
const ctx = context.ctx;
|
|
40275
|
-
const radius = 12 * this.transformation.getScale().x;
|
|
40276
|
-
ctx.save();
|
|
40277
|
-
ctx.globalCompositeOperation = "destination-out";
|
|
40278
|
-
ctx.beginPath();
|
|
40279
|
-
ctx.moveTo(this.left + radius, this.top);
|
|
40280
|
-
ctx.lineTo(this.left + this.getWidth() - radius, this.top);
|
|
40281
|
-
ctx.quadraticCurveTo(this.left + this.getWidth(), this.top, this.left + this.getWidth(), this.top + radius);
|
|
40282
|
-
ctx.lineTo(this.left + this.getWidth(), this.top + this.getHeight() - radius);
|
|
40283
|
-
ctx.quadraticCurveTo(this.left + this.getWidth(), this.top + this.getHeight(), this.left + this.getWidth() - radius, this.top + this.getHeight());
|
|
40284
|
-
ctx.lineTo(this.left + radius, this.top + this.getHeight());
|
|
40285
|
-
ctx.quadraticCurveTo(this.left, this.top + this.getHeight(), this.left, this.top + this.getHeight() - radius);
|
|
40286
|
-
ctx.lineTo(this.left, this.top + radius);
|
|
40287
|
-
ctx.quadraticCurveTo(this.left, this.top, this.left + radius, this.top);
|
|
40288
|
-
ctx.closePath();
|
|
40289
|
-
ctx.fill();
|
|
40290
|
-
ctx.restore();
|
|
40291
|
-
}
|
|
40292
|
-
renderHTML(documentFactory) {
|
|
40293
|
-
const div = documentFactory.createElement("audio-item");
|
|
40294
|
-
const { translateX, translateY, scaleX, scaleY } = this.transformation.matrix;
|
|
40295
|
-
const transform = `translate(${translateX}px, ${translateY}px) scale(${scaleX}, ${scaleY})`;
|
|
40296
|
-
div.id = this.getId();
|
|
40297
|
-
div.style.width = `${conf.AUDIO_DIMENSIONS.width}px`;
|
|
40298
|
-
div.style.height = `${conf.AUDIO_DIMENSIONS.height}px`;
|
|
40299
|
-
div.style.transformOrigin = "top left";
|
|
40300
|
-
div.style.transform = transform;
|
|
40301
|
-
div.style.position = "absolute";
|
|
40302
|
-
div.setAttribute("audio-url", this.getUrl());
|
|
40303
|
-
if (this.extension) {
|
|
40304
|
-
div.setAttribute("extension", this.extension);
|
|
40305
|
-
}
|
|
40306
|
-
if (this.isStorageUrl) {
|
|
40307
|
-
div.setAttribute("is-storage-url", "true");
|
|
40308
|
-
}
|
|
40309
|
-
div.setAttribute("data-link-to", "");
|
|
40310
|
-
return div;
|
|
40311
|
-
}
|
|
40312
|
-
serialize() {
|
|
40313
|
-
return {
|
|
40314
|
-
itemType: "Audio",
|
|
40315
|
-
url: this.url,
|
|
40316
|
-
transformation: this.transformation.serialize(),
|
|
40317
|
-
isStorageUrl: this.isStorageUrl,
|
|
40318
|
-
extension: this.extension
|
|
40319
|
-
};
|
|
40320
|
-
}
|
|
40321
|
-
deserialize(data) {
|
|
40322
|
-
if (data.isStorageUrl) {
|
|
40323
|
-
this.isStorageUrl = data.isStorageUrl;
|
|
40324
|
-
}
|
|
40325
|
-
if (data.transformation) {
|
|
40326
|
-
this.transformation.deserialize(data.transformation);
|
|
40327
|
-
}
|
|
40328
|
-
if (data.url) {
|
|
40329
|
-
this.setUrl(data.url);
|
|
40330
|
-
}
|
|
40331
|
-
if (data.extension) {
|
|
40332
|
-
this.extension = data.extension;
|
|
40333
|
-
}
|
|
40334
|
-
return this;
|
|
40335
|
-
}
|
|
40336
|
-
apply(op) {
|
|
40337
|
-
switch (op.class) {
|
|
40338
|
-
case "Transformation":
|
|
40339
|
-
this.transformation.apply(op);
|
|
40340
|
-
break;
|
|
40341
|
-
case "LinkTo":
|
|
40342
|
-
this.linkTo.apply(op);
|
|
40343
|
-
break;
|
|
40344
|
-
case "Audio":
|
|
40345
|
-
if (op.method === "setUrl") {
|
|
40346
|
-
this.applyUrl(op.url);
|
|
40347
|
-
}
|
|
40348
|
-
this.subject.publish(this);
|
|
40349
|
-
break;
|
|
40350
|
-
}
|
|
40351
|
-
}
|
|
40352
|
-
emit(operation) {
|
|
40353
|
-
if (this.events) {
|
|
40354
|
-
const command = new AudioCommand([this], operation);
|
|
40355
|
-
command.apply();
|
|
40356
|
-
this.events.emit(operation, command);
|
|
40357
|
-
} else {
|
|
40358
|
-
this.apply(operation);
|
|
40359
|
-
}
|
|
40360
|
-
}
|
|
40361
|
-
setId(id) {
|
|
40362
|
-
this.id = id;
|
|
40363
|
-
this.transformation.setId(id);
|
|
40364
|
-
return this;
|
|
40365
|
-
}
|
|
40366
|
-
getId() {
|
|
40367
|
-
return this.id;
|
|
40368
|
-
}
|
|
40369
|
-
shootLoadCallbacks() {
|
|
40370
|
-
while (this.loadCallbacks.length > 0) {
|
|
40371
|
-
this.loadCallbacks.shift()(this);
|
|
40372
|
-
}
|
|
40373
|
-
}
|
|
40374
|
-
shootBeforeLoadCallbacks() {
|
|
40375
|
-
while (this.beforeLoadCallbacks.length > 0) {
|
|
40376
|
-
this.beforeLoadCallbacks.shift()(this);
|
|
40377
|
-
}
|
|
40378
|
-
}
|
|
40379
|
-
getPath() {
|
|
40380
|
-
const { left, top, right, bottom } = this.getMbr();
|
|
40381
|
-
const leftTop = new Point(left, top);
|
|
40382
|
-
const rightTop = new Point(right, top);
|
|
40383
|
-
const rightBottom = new Point(right, bottom);
|
|
40384
|
-
const leftBottom = new Point(left, bottom);
|
|
40385
|
-
return new Path([
|
|
40386
|
-
new Line(leftTop, rightTop),
|
|
40387
|
-
new Line(rightTop, rightBottom),
|
|
40388
|
-
new Line(rightBottom, leftBottom),
|
|
40389
|
-
new Line(leftBottom, leftTop)
|
|
40390
|
-
], true);
|
|
40391
|
-
}
|
|
40392
|
-
getSnapAnchorPoints() {
|
|
40393
|
-
const mbr = this.getMbr();
|
|
40394
|
-
const width2 = mbr.getWidth();
|
|
40395
|
-
const height2 = mbr.getHeight();
|
|
40396
|
-
return [
|
|
40397
|
-
new Point(mbr.left + width2 / 2, mbr.top),
|
|
40398
|
-
new Point(mbr.left + width2 / 2, mbr.bottom),
|
|
40399
|
-
new Point(mbr.left, mbr.top + height2 / 2),
|
|
40400
|
-
new Point(mbr.right, mbr.top + height2 / 2)
|
|
40401
|
-
];
|
|
40402
|
-
}
|
|
40403
|
-
isClosed() {
|
|
40404
|
-
return true;
|
|
40405
|
-
}
|
|
40406
|
-
getRichText() {
|
|
40407
|
-
return null;
|
|
40408
|
-
}
|
|
40409
|
-
getLinkTo() {
|
|
40410
|
-
return;
|
|
40411
|
-
}
|
|
40412
|
-
getExtension() {
|
|
40413
|
-
return this.extension;
|
|
40414
|
-
}
|
|
40415
|
-
download() {
|
|
40416
|
-
if (this.extension) {
|
|
40417
|
-
const linkElem = conf.documentFactory.createElement("a");
|
|
40418
|
-
linkElem.href = this.url;
|
|
40419
|
-
linkElem.setAttribute("download", `${this.board.getBoardId()}.${this.extension}`);
|
|
40420
|
-
linkElem.click();
|
|
40421
|
-
}
|
|
40422
|
-
}
|
|
40423
|
-
onRemove() {
|
|
40424
|
-
const storageId = this.getStorageId();
|
|
40425
|
-
if (storageId) {
|
|
40426
|
-
deleteMedia([storageId], this.board.getBoardId());
|
|
40427
|
-
}
|
|
40428
|
-
super.onRemove();
|
|
40429
|
-
}
|
|
40430
|
-
}
|
|
40431
|
-
// src/Items/Audio/AudioHelpers.ts
|
|
40432
|
-
var uploadAudioToStorage = async (hash, audioBlob, accessToken, boardId) => {
|
|
40433
|
-
return new Promise((resolve2, reject) => {
|
|
40434
|
-
fetch(`${window.location.origin}/api/v1/media/audio/${boardId}`, {
|
|
40435
|
-
method: "POST",
|
|
40436
|
-
headers: {
|
|
40437
|
-
"Content-Type": audioBlob.type,
|
|
40438
|
-
"x-audio-id": hash,
|
|
40439
|
-
Authorization: `Bearer ${accessToken}`
|
|
40440
|
-
},
|
|
40441
|
-
body: audioBlob
|
|
40442
|
-
}).then(async (response) => {
|
|
40443
|
-
if (response.status !== 200) {
|
|
40444
|
-
return catchErrorResponse(response, "audio");
|
|
40445
|
-
}
|
|
40446
|
-
return response.json();
|
|
40447
|
-
}).then((data) => {
|
|
40448
|
-
console.log(data);
|
|
40449
|
-
resolve2(data.src);
|
|
40450
|
-
}).catch((error) => {
|
|
40451
|
-
console.error("Media storage error:", error);
|
|
40452
|
-
reject(error);
|
|
40453
|
-
});
|
|
40454
|
-
});
|
|
40455
|
-
};
|
|
40456
|
-
var prepareAudio = (file, accessToken, boardId) => {
|
|
40457
|
-
return new Promise((resolve2, reject) => {
|
|
40458
|
-
const audio = document.createElement("audio");
|
|
40459
|
-
audio.src = URL.createObjectURL(file);
|
|
40460
|
-
audio.onloadedmetadata = () => {
|
|
40461
|
-
fileTosha256(file).then((hash) => {
|
|
40462
|
-
uploadAudioToStorage(hash, file, accessToken, boardId).then((url) => {
|
|
40463
|
-
resolve2(url);
|
|
40464
|
-
}).catch(reject);
|
|
40465
|
-
}).catch(() => {
|
|
40466
|
-
reject(new Error("Failed to generate hash"));
|
|
40467
|
-
});
|
|
40468
|
-
};
|
|
40469
|
-
audio.onerror = () => {
|
|
40470
|
-
reject(new Error("Failed to load audio"));
|
|
40471
|
-
};
|
|
40472
|
-
});
|
|
40473
|
-
};
|
|
40474
|
-
var calculateAudioPosition = (board, audioItem) => {
|
|
40475
|
-
const cameraMbr = board.camera.getMbr();
|
|
40476
|
-
const cameraWidth = cameraMbr.getWidth();
|
|
40477
|
-
const translateX = cameraMbr.left + cameraWidth * 0.34;
|
|
40478
|
-
const translateY = cameraMbr.getCenter().y - audioItem.getHeight() / 2;
|
|
40479
|
-
const scale = cameraWidth * 0.32 / audioItem.getWidth();
|
|
40480
|
-
return new Matrix2(translateX, translateY, scale, scale);
|
|
40481
|
-
};
|
|
40482
40330
|
// src/isSafari.ts
|
|
40483
40331
|
function isSafari() {
|
|
40484
40332
|
if (typeof navigator === "undefined") {
|
|
@@ -51893,7 +51741,7 @@ class BoardSelection {
|
|
|
51893
51741
|
const connectors = itemIds.flatMap((id) => {
|
|
51894
51742
|
return this.board.items.getLinkedConnectorsById(id);
|
|
51895
51743
|
}).map((connector) => connector.getId());
|
|
51896
|
-
|
|
51744
|
+
conf.hooks.beforeMediaRemove(this.getMediaStorageIds(), this.board.getBoardId());
|
|
51897
51745
|
this.emit({
|
|
51898
51746
|
class: "Board",
|
|
51899
51747
|
method: "remove",
|
|
@@ -51931,7 +51779,7 @@ class BoardSelection {
|
|
|
51931
51779
|
}
|
|
51932
51780
|
async duplicate() {
|
|
51933
51781
|
const mediaIds = this.getMediaStorageIds();
|
|
51934
|
-
const canDuplicate = mediaIds.length ? await
|
|
51782
|
+
const canDuplicate = mediaIds.length ? await conf.hooks.beforeMediaUpload(mediaIds, this.board.getBoardId()) : true;
|
|
51935
51783
|
if (!canDuplicate) {
|
|
51936
51784
|
return;
|
|
51937
51785
|
}
|
|
@@ -52812,7 +52660,7 @@ class Board {
|
|
|
52812
52660
|
newMap[newItemId] = itemData;
|
|
52813
52661
|
}
|
|
52814
52662
|
if (shouldUpdateMediaUsage) {
|
|
52815
|
-
const canDuplicate = mediaStorageIds.length ? await
|
|
52663
|
+
const canDuplicate = mediaStorageIds.length ? await conf.hooks.beforeMediaUpload(mediaStorageIds, this.getBoardId()) : true;
|
|
52816
52664
|
if (!canDuplicate) {
|
|
52817
52665
|
return;
|
|
52818
52666
|
}
|
|
@@ -52831,7 +52679,9 @@ class Board {
|
|
|
52831
52679
|
return;
|
|
52832
52680
|
}
|
|
52833
52681
|
removeVoidComments() {
|
|
52834
|
-
const voidComments = this.items.listAll().filter((item) =>
|
|
52682
|
+
const voidComments = this.items.listAll().filter((item) => {
|
|
52683
|
+
return item instanceof Comment2 && !item.getThread().length;
|
|
52684
|
+
});
|
|
52835
52685
|
if (voidComments) {
|
|
52836
52686
|
for (const comment2 of voidComments) {
|
|
52837
52687
|
this.remove(comment2);
|
|
@@ -52844,7 +52694,7 @@ class Board {
|
|
|
52844
52694
|
return [];
|
|
52845
52695
|
}
|
|
52846
52696
|
const parentItem = this.items.findById(parentId);
|
|
52847
|
-
if (!parentItem || parentItem
|
|
52697
|
+
if (!parentItem || !(parentItem instanceof AINode)) {
|
|
52848
52698
|
return [];
|
|
52849
52699
|
}
|
|
52850
52700
|
return [parentItem, ...this.getParentAINodes(parentItem)];
|
|
@@ -52955,7 +52805,10 @@ class Board {
|
|
|
52955
52805
|
applyPasteOperation(itemsMap) {
|
|
52956
52806
|
const items = [];
|
|
52957
52807
|
const sortedItemsMap = Object.entries(itemsMap).sort(([, dataA], [, dataB]) => {
|
|
52958
|
-
|
|
52808
|
+
if ("zIndex" in dataA && "zIndex" in dataB) {
|
|
52809
|
+
return dataA.zIndex - dataB.zIndex;
|
|
52810
|
+
}
|
|
52811
|
+
return 0;
|
|
52959
52812
|
});
|
|
52960
52813
|
const pasteItem = (itemId, data) => {
|
|
52961
52814
|
if (!data) {
|
|
@@ -55125,7 +54978,7 @@ function handleAudioGenerate(response, board) {
|
|
|
55125
54978
|
}
|
|
55126
54979
|
function handleImageGenerate(response, board) {
|
|
55127
54980
|
if (response.status === "completed" && response.base64) {
|
|
55128
|
-
prepareImage(response.base64,
|
|
54981
|
+
prepareImage(response.base64, null, board.getBoardId()).then((imageData) => {
|
|
55129
54982
|
const placeholderId = board.aiImagePlaceholder?.getId();
|
|
55130
54983
|
if (placeholderId) {
|
|
55131
54984
|
const placeholderNode = board.items.getById(placeholderId);
|