microboard-temp 0.3.1 → 0.4.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/cjs/browser.js +333 -485
- package/dist/cjs/index.js +333 -485
- package/dist/cjs/node.js +333 -485
- package/dist/esm/browser.js +333 -485
- package/dist/esm/index.js +333 -485
- package/dist/esm/node.js +333 -485
- package/dist/types/Board.d.ts +2 -2
- package/dist/types/Items/Image/ImageHelpers.d.ts +0 -6
- package/dist/types/Settings.d.ts +5 -0
- package/dist/types/SpatialIndex/SpacialIndex.d.ts +3 -4
- 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
|
-
|
|
40158
|
-
}
|
|
40159
|
-
super.onRemove();
|
|
40160
|
-
}
|
|
40161
|
-
}
|
|
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());
|
|
40325
|
+
conf.hooks.beforeMediaRemove([storageId], this.board.getBoardId());
|
|
40427
40326
|
}
|
|
40428
40327
|
super.onRemove();
|
|
40429
40328
|
}
|
|
40430
40329
|
}
|
|
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
|
}
|
|
@@ -55125,7 +54973,7 @@ function handleAudioGenerate(response, board) {
|
|
|
55125
54973
|
}
|
|
55126
54974
|
function handleImageGenerate(response, board) {
|
|
55127
54975
|
if (response.status === "completed" && response.base64) {
|
|
55128
|
-
prepareImage(response.base64,
|
|
54976
|
+
prepareImage(response.base64, null, board.getBoardId()).then((imageData) => {
|
|
55129
54977
|
const placeholderId = board.aiImagePlaceholder?.getId();
|
|
55130
54978
|
if (placeholderId) {
|
|
55131
54979
|
const placeholderNode = board.items.getById(placeholderId);
|