microboard-temp 0.1.5 → 0.1.7
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-entry.js → browser.js} +808 -448
- package/dist/cjs/index.js +803 -443
- package/dist/cjs/{node-entry.js → node.js} +808 -448
- package/dist/esm/{browser-entry.js → browser.js} +3371 -3011
- package/dist/esm/index.js +3370 -3010
- package/dist/esm/{node-entry.js → node.js} +3371 -3011
- package/dist/types/Items/Video/index.d.ts +3 -1
- package/dist/types/Items/index.d.ts +11 -6
- package/dist/types/Keyboard/index.d.ts +1 -1
- package/dist/types/Presence/index.d.ts +2 -0
- package/dist/types/Selection/index.d.ts +1 -0
- package/package.json +15 -14
- package/dist/index.js +0 -46565
- /package/dist/types/{browser-entry.d.ts → browser.d.ts} +0 -0
- /package/dist/types/{node-entry.d.ts → node.d.ts} +0 -0
|
@@ -2206,18 +2206,23 @@ var require_browser2 = __commonJS((exports2) => {
|
|
|
2206
2206
|
};
|
|
2207
2207
|
});
|
|
2208
2208
|
|
|
2209
|
-
// src/browser
|
|
2210
|
-
var
|
|
2211
|
-
__export(
|
|
2209
|
+
// src/browser.ts
|
|
2210
|
+
var exports_browser = {};
|
|
2211
|
+
__export(exports_browser, {
|
|
2212
2212
|
validateRichTextData: () => validateRichTextData,
|
|
2213
2213
|
validateItemsMap: () => validateItemsMap,
|
|
2214
|
+
uploadVideoToStorage: () => uploadVideoToStorage,
|
|
2215
|
+
uploadVideo: () => uploadVideo,
|
|
2214
2216
|
translateElementBy: () => translateElementBy,
|
|
2215
2217
|
toFiniteNumber: () => toFiniteNumber,
|
|
2216
2218
|
tempStorage: () => tempStorage2,
|
|
2217
2219
|
tagByType: () => tagByType,
|
|
2218
2220
|
sha256: () => sha256,
|
|
2219
2221
|
scaleElementBy: () => scaleElementBy,
|
|
2222
|
+
rgbToRgba: () => rgbToRgba,
|
|
2220
2223
|
resetElementScale: () => resetElementScale,
|
|
2224
|
+
quickAddItem: () => quickAddItem,
|
|
2225
|
+
prepareVideo: () => prepareVideo,
|
|
2221
2226
|
positionRelatively: () => positionRelatively,
|
|
2222
2227
|
positionAbsolutely: () => positionAbsolutely,
|
|
2223
2228
|
parsersHTML: () => parsersHTML,
|
|
@@ -2231,17 +2236,26 @@ __export(exports_browser_entry, {
|
|
|
2231
2236
|
isHotkeyPushed: () => isHotkeyPushed,
|
|
2232
2237
|
isFiniteNumber: () => isFiniteNumber,
|
|
2233
2238
|
isControlCharacter: () => isControlCharacter,
|
|
2239
|
+
getYouTubeVideoPreview: () => getYouTubeVideoPreview,
|
|
2240
|
+
getYouTubeThumbnail: () => getYouTubeThumbnail,
|
|
2241
|
+
getVideoMetadata: () => getVideoMetadata,
|
|
2234
2242
|
getTranslationFromHTML: () => getTranslationFromHTML,
|
|
2235
2243
|
getScaleFromHTML: () => getScaleFromHTML,
|
|
2236
2244
|
getRandomNumber: () => getRandomNumber,
|
|
2245
|
+
getQuickAddButtons: () => getQuickAddButtons,
|
|
2237
2246
|
getHotkeyLabel: () => getHotkeyLabel,
|
|
2247
|
+
getControlPointData: () => getControlPointData,
|
|
2238
2248
|
forceNumberIntoInterval: () => forceNumberIntoInterval,
|
|
2239
2249
|
fileTosha256: () => fileTosha256,
|
|
2240
2250
|
decodeHtml: () => decodeHtml,
|
|
2241
2251
|
cursors: () => defaultCursors,
|
|
2252
|
+
createVideoItem: () => createVideoItem,
|
|
2242
2253
|
createEvents: () => createEvents,
|
|
2243
2254
|
conf: () => conf,
|
|
2244
2255
|
checkHotkeys: () => checkHotkeys,
|
|
2256
|
+
catmullRomInterpolate: () => catmullRomInterpolate,
|
|
2257
|
+
captureFrame: () => captureFrame,
|
|
2258
|
+
VideoItem: () => VideoItem,
|
|
2245
2259
|
Transformation: () => Transformation,
|
|
2246
2260
|
Tools: () => Tools,
|
|
2247
2261
|
SubjectOperation: () => SubjectOperation,
|
|
@@ -2267,7 +2281,8 @@ __export(exports_browser_entry, {
|
|
|
2267
2281
|
Items: () => Items,
|
|
2268
2282
|
Frame: () => Frame,
|
|
2269
2283
|
ExportQuality: () => ExportQuality,
|
|
2270
|
-
Events: () =>
|
|
2284
|
+
Events: () => Events2,
|
|
2285
|
+
DefaultTransformationData: () => DefaultTransformationData,
|
|
2271
2286
|
CubicBezier: () => CubicBezier,
|
|
2272
2287
|
ConnectorData: () => ConnectorData2,
|
|
2273
2288
|
Connector: () => Connector,
|
|
@@ -2279,7 +2294,7 @@ __export(exports_browser_entry, {
|
|
|
2279
2294
|
Board: () => Board,
|
|
2280
2295
|
Arc: () => Arc
|
|
2281
2296
|
});
|
|
2282
|
-
module.exports = __toCommonJS(
|
|
2297
|
+
module.exports = __toCommonJS(exports_browser);
|
|
2283
2298
|
|
|
2284
2299
|
// src/BoardCommand.ts
|
|
2285
2300
|
class BoardCommand {
|
|
@@ -30309,6 +30324,791 @@ class Frame {
|
|
|
30309
30324
|
return this.text;
|
|
30310
30325
|
}
|
|
30311
30326
|
}
|
|
30327
|
+
// src/Items/Video/VideoCommand.ts
|
|
30328
|
+
class VideoCommand {
|
|
30329
|
+
videos;
|
|
30330
|
+
operation;
|
|
30331
|
+
constructor(videos, operation) {
|
|
30332
|
+
this.videos = videos;
|
|
30333
|
+
this.operation = operation;
|
|
30334
|
+
}
|
|
30335
|
+
apply() {
|
|
30336
|
+
for (const video of this.videos) {
|
|
30337
|
+
video.apply(this.operation);
|
|
30338
|
+
}
|
|
30339
|
+
}
|
|
30340
|
+
revert() {}
|
|
30341
|
+
}
|
|
30342
|
+
|
|
30343
|
+
// src/Items/Video/Video.ts
|
|
30344
|
+
var VIDEO_ICON_SRC = "data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 22 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M15 0C15.2652 0 15.5196 0.105357 15.7071 0.292893C15.8946 0.48043 16 0.734784 16 1V5.2L21.213 1.55C21.288 1.49746 21.3759 1.4665 21.4672 1.4605C21.5586 1.4545 21.6498 1.4737 21.731 1.51599C21.8122 1.55829 21.8802 1.62206 21.9276 1.70035C21.9751 1.77865 22.0001 1.86846 22 1.96V14.04C22.0001 14.1315 21.9751 14.2214 21.9276 14.2996C21.8802 14.3779 21.8122 14.4417 21.731 14.484C21.6498 14.5263 21.5586 14.5455 21.4672 14.5395C21.3759 14.5335 21.288 14.5025 21.213 14.45L16 10.8V15C16 15.2652 15.8946 15.5196 15.7071 15.7071C15.5196 15.8946 15.2652 16 15 16H1C0.734784 16 0.48043 15.8946 0.292893 15.7071C0.105357 15.5196 0 15.2652 0 15V1C0 0.734784 0.105357 0.48043 0.292893 0.292893C0.48043 0.105357 0.734784 0 1 0H15ZM14 2H2V14H14V2ZM6.4 4.829C6.47611 4.82879 6.55069 4.8503 6.615 4.891L10.97 7.663C11.0266 7.69917 11.0731 7.749 11.1054 7.80789C11.1376 7.86679 11.1545 7.93285 11.1545 8C11.1545 8.06715 11.1376 8.13321 11.1054 8.19211C11.0731 8.251 11.0266 8.30083 10.97 8.337L6.615 11.11C6.55434 11.1487 6.48438 11.1703 6.41248 11.1725C6.34059 11.1748 6.26941 11.1576 6.20646 11.1228C6.14351 11.088 6.0911 11.0368 6.05477 10.9747C6.01844 10.9127 5.99951 10.8419 6 10.77V5.23C6 5.009 6.18 4.83 6.4 4.83V4.829ZM20 4.84L16 7.64V8.358L20 11.158V4.84Z' fill='%23FFFFFF'/%3E%3C/svg%3E";
|
|
30345
|
+
var videoIcon = conf.documentFactory.createElement("img");
|
|
30346
|
+
videoIcon.src = VIDEO_ICON_SRC;
|
|
30347
|
+
var createPlaceholderImage = (width, height) => {
|
|
30348
|
+
const canvas = conf.documentFactory.createElement("canvas");
|
|
30349
|
+
canvas.width = width;
|
|
30350
|
+
canvas.height = height;
|
|
30351
|
+
const ctx = canvas.getContext("2d");
|
|
30352
|
+
if (ctx) {
|
|
30353
|
+
ctx.fillStyle = "rgba(229, 229, 234, 1)";
|
|
30354
|
+
ctx.fillRect(0, 0, width, height);
|
|
30355
|
+
const iconSize = Math.min(width, height) * 0.3;
|
|
30356
|
+
const iconX = (width - iconSize) / 2;
|
|
30357
|
+
const iconY = (height - iconSize) / 2;
|
|
30358
|
+
ctx.drawImage(videoIcon, iconX, iconY, iconSize * 1.375, iconSize);
|
|
30359
|
+
}
|
|
30360
|
+
const image = new Image;
|
|
30361
|
+
image.src = canvas.toDataURL();
|
|
30362
|
+
return image;
|
|
30363
|
+
};
|
|
30364
|
+
|
|
30365
|
+
class VideoItem extends Mbr {
|
|
30366
|
+
events;
|
|
30367
|
+
id;
|
|
30368
|
+
extension;
|
|
30369
|
+
itemType = "Video";
|
|
30370
|
+
parent = "Board";
|
|
30371
|
+
preview;
|
|
30372
|
+
transformation;
|
|
30373
|
+
linkTo;
|
|
30374
|
+
subject = new Subject;
|
|
30375
|
+
loadCallbacks = [];
|
|
30376
|
+
beforeLoadCallbacks = [];
|
|
30377
|
+
transformationRenderBlock = undefined;
|
|
30378
|
+
url = "";
|
|
30379
|
+
previewUrl = "";
|
|
30380
|
+
isStorageUrl = false;
|
|
30381
|
+
videoDimension;
|
|
30382
|
+
board;
|
|
30383
|
+
isPlaying = false;
|
|
30384
|
+
shouldShowControls = false;
|
|
30385
|
+
playBtnMbr = new Mbr;
|
|
30386
|
+
currentTime = 0;
|
|
30387
|
+
constructor({ url, videoDimension, previewUrl }, board, events2, id = "", extension2 = "mp4") {
|
|
30388
|
+
super();
|
|
30389
|
+
this.events = events2;
|
|
30390
|
+
this.id = id;
|
|
30391
|
+
this.extension = extension2;
|
|
30392
|
+
this.isStorageUrl = !conf.getYouTubeId(url);
|
|
30393
|
+
this.preview = createPlaceholderImage(videoDimension.width, videoDimension.height);
|
|
30394
|
+
this.linkTo = new LinkTo(this.id, events2);
|
|
30395
|
+
this.board = board;
|
|
30396
|
+
if (previewUrl) {
|
|
30397
|
+
this.previewUrl = previewUrl;
|
|
30398
|
+
this.setPreview(this.preview, previewUrl);
|
|
30399
|
+
}
|
|
30400
|
+
this.preview.onload = this.onLoad;
|
|
30401
|
+
this.preview.onerror = this.onError;
|
|
30402
|
+
if (url) {
|
|
30403
|
+
this.setUrl(url);
|
|
30404
|
+
}
|
|
30405
|
+
this.videoDimension = videoDimension;
|
|
30406
|
+
this.transformation = new Transformation(id, events2);
|
|
30407
|
+
this.linkTo.subject.subscribe(() => {
|
|
30408
|
+
this.updateMbr();
|
|
30409
|
+
this.subject.publish(this);
|
|
30410
|
+
});
|
|
30411
|
+
this.transformation.subject.subscribe(this.onTransform);
|
|
30412
|
+
}
|
|
30413
|
+
setCurrentTime(time2) {
|
|
30414
|
+
this.currentTime = time2;
|
|
30415
|
+
}
|
|
30416
|
+
getCurrentTime() {
|
|
30417
|
+
return this.currentTime;
|
|
30418
|
+
}
|
|
30419
|
+
onTransform = () => {
|
|
30420
|
+
this.updateMbr();
|
|
30421
|
+
this.subject.publish(this);
|
|
30422
|
+
};
|
|
30423
|
+
doOnceBeforeOnLoad = (callback) => {
|
|
30424
|
+
this.loadCallbacks.push(callback);
|
|
30425
|
+
};
|
|
30426
|
+
doOnceOnLoad = (callback) => {
|
|
30427
|
+
this.loadCallbacks.push(callback);
|
|
30428
|
+
};
|
|
30429
|
+
getStorageId() {
|
|
30430
|
+
return this.url.split("/").pop();
|
|
30431
|
+
}
|
|
30432
|
+
getIsStorageUrl() {
|
|
30433
|
+
return this.isStorageUrl;
|
|
30434
|
+
}
|
|
30435
|
+
setVideoData({ previewUrl, url }) {
|
|
30436
|
+
this.emit({
|
|
30437
|
+
class: "Video",
|
|
30438
|
+
item: [this.id],
|
|
30439
|
+
method: "updateVideoData",
|
|
30440
|
+
data: { previewUrl, url, videoDimension: this.videoDimension }
|
|
30441
|
+
});
|
|
30442
|
+
}
|
|
30443
|
+
applyVideoData({ previewUrl = "", url = "" }) {
|
|
30444
|
+
this.previewUrl = previewUrl;
|
|
30445
|
+
this.setPreview(this.preview, previewUrl);
|
|
30446
|
+
this.setUrl(url);
|
|
30447
|
+
}
|
|
30448
|
+
setIsPlaying(isPlaying) {
|
|
30449
|
+
this.isPlaying = isPlaying;
|
|
30450
|
+
this.subject.publish(this);
|
|
30451
|
+
}
|
|
30452
|
+
getIsPlaying() {
|
|
30453
|
+
return this.isPlaying;
|
|
30454
|
+
}
|
|
30455
|
+
setShouldShowControls(shouldShowControls) {
|
|
30456
|
+
this.shouldShowControls = shouldShowControls;
|
|
30457
|
+
this.subject.publish(this);
|
|
30458
|
+
}
|
|
30459
|
+
getShouldShowControls() {
|
|
30460
|
+
return this.shouldShowControls;
|
|
30461
|
+
}
|
|
30462
|
+
getPlayBtnMbr() {
|
|
30463
|
+
return this.playBtnMbr;
|
|
30464
|
+
}
|
|
30465
|
+
setUrl(url) {
|
|
30466
|
+
if (this.isStorageUrl) {
|
|
30467
|
+
try {
|
|
30468
|
+
const newUrl = new URL(url);
|
|
30469
|
+
this.url = `${window.location.origin}${newUrl.pathname}`;
|
|
30470
|
+
} catch (_) {}
|
|
30471
|
+
} else {
|
|
30472
|
+
this.url = url;
|
|
30473
|
+
}
|
|
30474
|
+
}
|
|
30475
|
+
setPreview(image, previewUrl) {
|
|
30476
|
+
if (this.isStorageUrl) {
|
|
30477
|
+
try {
|
|
30478
|
+
const newUrl = new URL(previewUrl);
|
|
30479
|
+
image.src = `${window.location.origin}${newUrl.pathname}`;
|
|
30480
|
+
} catch (_) {}
|
|
30481
|
+
} else {
|
|
30482
|
+
image.src = previewUrl;
|
|
30483
|
+
}
|
|
30484
|
+
image.onload = () => {
|
|
30485
|
+
this.preview = image;
|
|
30486
|
+
};
|
|
30487
|
+
}
|
|
30488
|
+
setPreviewImage(image) {
|
|
30489
|
+
this.preview = image;
|
|
30490
|
+
this.preview.onload = this.onLoad;
|
|
30491
|
+
this.preview.onerror = () => {
|
|
30492
|
+
const defaultPreview = new Image;
|
|
30493
|
+
defaultPreview.src = this.getPreviewUrl();
|
|
30494
|
+
this.preview = defaultPreview;
|
|
30495
|
+
this.preview.onload = this.onLoad;
|
|
30496
|
+
this.preview.onerror = this.onError;
|
|
30497
|
+
this.subject.publish(this);
|
|
30498
|
+
};
|
|
30499
|
+
this.subject.publish(this);
|
|
30500
|
+
}
|
|
30501
|
+
getPreviewUrl() {
|
|
30502
|
+
return this.previewUrl;
|
|
30503
|
+
}
|
|
30504
|
+
getUrl() {
|
|
30505
|
+
return this.url;
|
|
30506
|
+
}
|
|
30507
|
+
onLoad = async () => {
|
|
30508
|
+
this.shootBeforeLoadCallbacks();
|
|
30509
|
+
this.updateMbr();
|
|
30510
|
+
this.subject.publish(this);
|
|
30511
|
+
this.shootLoadCallbacks();
|
|
30512
|
+
};
|
|
30513
|
+
onError = (_error) => {
|
|
30514
|
+
this.preview = createPlaceholderImage(this.videoDimension.width, this.videoDimension.height);
|
|
30515
|
+
this.updateMbr();
|
|
30516
|
+
this.subject.publish(this);
|
|
30517
|
+
this.shootLoadCallbacks();
|
|
30518
|
+
};
|
|
30519
|
+
updateMbr() {
|
|
30520
|
+
const { translateX, translateY, scaleX, scaleY } = this.transformation.matrix;
|
|
30521
|
+
this.left = translateX;
|
|
30522
|
+
this.top = translateY;
|
|
30523
|
+
this.right = this.left + this.videoDimension.width * scaleX;
|
|
30524
|
+
this.bottom = this.top + this.videoDimension.height * scaleY;
|
|
30525
|
+
const playBtnSize = 50;
|
|
30526
|
+
const scaledPlayBtn = playBtnSize * this.transformation.matrix.scaleX;
|
|
30527
|
+
this.playBtnMbr = new Mbr(this.left + this.getWidth() / 2 - scaledPlayBtn / 2, this.top + this.getHeight() / 2 - scaledPlayBtn / 2, this.right - this.getWidth() / 2 + scaledPlayBtn / 2, this.bottom - this.getHeight() / 2 + scaledPlayBtn / 2);
|
|
30528
|
+
}
|
|
30529
|
+
render(context) {
|
|
30530
|
+
if (this.transformationRenderBlock || !this.preview.complete) {
|
|
30531
|
+
return;
|
|
30532
|
+
}
|
|
30533
|
+
const ctx = context.ctx;
|
|
30534
|
+
if (this.isPlaying) {
|
|
30535
|
+
ctx.save();
|
|
30536
|
+
ctx.globalCompositeOperation = "destination-out";
|
|
30537
|
+
ctx.fillRect(this.left, this.top, this.getWidth(), this.getHeight());
|
|
30538
|
+
ctx.restore();
|
|
30539
|
+
return;
|
|
30540
|
+
}
|
|
30541
|
+
ctx.save();
|
|
30542
|
+
this.transformation.matrix.applyToContext(ctx);
|
|
30543
|
+
ctx.drawImage(this.preview, 0, 0);
|
|
30544
|
+
if (this.shouldShowControls && this.previewUrl) {
|
|
30545
|
+
ctx.restore();
|
|
30546
|
+
ctx.fillStyle = "rgba(0, 0, 0, 0.5)";
|
|
30547
|
+
ctx.fillRect(this.left, this.top, this.getWidth(), this.getHeight());
|
|
30548
|
+
const playBtnSize = this.playBtnMbr.getWidth();
|
|
30549
|
+
const left = this.playBtnMbr.left;
|
|
30550
|
+
const top = this.playBtnMbr.top;
|
|
30551
|
+
ctx.fillStyle = "white";
|
|
30552
|
+
ctx.beginPath();
|
|
30553
|
+
ctx.moveTo(left, top);
|
|
30554
|
+
ctx.lineTo(left + playBtnSize, top + playBtnSize / 2);
|
|
30555
|
+
ctx.lineTo(left, top + playBtnSize);
|
|
30556
|
+
ctx.closePath();
|
|
30557
|
+
ctx.fill();
|
|
30558
|
+
}
|
|
30559
|
+
ctx.restore();
|
|
30560
|
+
}
|
|
30561
|
+
renderHTML(documentFactory) {
|
|
30562
|
+
const div = documentFactory.createElement("video-item");
|
|
30563
|
+
const { translateX, translateY, scaleX, scaleY } = this.transformation.matrix;
|
|
30564
|
+
const transform = `translate(${translateX}px, ${translateY}px) scale(${scaleX}, ${scaleY})`;
|
|
30565
|
+
div.style.backgroundImage = this.previewUrl ? `url(${this.previewUrl})` : `url(${createPlaceholderImage(this.videoDimension.width, this.videoDimension.height).src})`;
|
|
30566
|
+
div.id = this.getId();
|
|
30567
|
+
div.style.width = `${this.videoDimension.width}px`;
|
|
30568
|
+
div.style.height = `${this.videoDimension.height}px`;
|
|
30569
|
+
div.style.transformOrigin = "top left";
|
|
30570
|
+
div.style.transform = transform;
|
|
30571
|
+
div.style.position = "absolute";
|
|
30572
|
+
div.style.backgroundSize = "cover";
|
|
30573
|
+
div.setAttribute("video-url", this.getUrl());
|
|
30574
|
+
div.setAttribute("preview-url", this.getPreviewUrl());
|
|
30575
|
+
div.setAttribute("extension", this.extension);
|
|
30576
|
+
div.setAttribute("is-storage-url", this.isStorageUrl ? "1" : "");
|
|
30577
|
+
div.setAttribute("data-link-to", "");
|
|
30578
|
+
return div;
|
|
30579
|
+
}
|
|
30580
|
+
serialize() {
|
|
30581
|
+
return {
|
|
30582
|
+
itemType: "Video",
|
|
30583
|
+
url: this.url,
|
|
30584
|
+
videoDimension: this.videoDimension,
|
|
30585
|
+
transformation: this.transformation.serialize(),
|
|
30586
|
+
isStorageUrl: this.isStorageUrl,
|
|
30587
|
+
previewUrl: this.previewUrl,
|
|
30588
|
+
extension: this.extension
|
|
30589
|
+
};
|
|
30590
|
+
}
|
|
30591
|
+
deserialize(data) {
|
|
30592
|
+
if (data.transformation) {
|
|
30593
|
+
this.transformation.deserialize(data.transformation);
|
|
30594
|
+
}
|
|
30595
|
+
if (data.isStorageUrl) {
|
|
30596
|
+
this.isStorageUrl = data.isStorageUrl;
|
|
30597
|
+
}
|
|
30598
|
+
if (data.url) {
|
|
30599
|
+
this.setUrl(data.url);
|
|
30600
|
+
}
|
|
30601
|
+
if (data.extension) {
|
|
30602
|
+
this.extension = data.extension;
|
|
30603
|
+
}
|
|
30604
|
+
this.preview = createPlaceholderImage(data.videoDimension?.width || 100, data.videoDimension?.height || 100);
|
|
30605
|
+
const storageImage = new Image;
|
|
30606
|
+
storageImage.onload = () => {
|
|
30607
|
+
this.onLoad();
|
|
30608
|
+
};
|
|
30609
|
+
storageImage.onerror = this.onError;
|
|
30610
|
+
if (data.previewUrl) {
|
|
30611
|
+
this.setPreview(storageImage, data.previewUrl);
|
|
30612
|
+
}
|
|
30613
|
+
return this;
|
|
30614
|
+
}
|
|
30615
|
+
apply(op) {
|
|
30616
|
+
switch (op.class) {
|
|
30617
|
+
case "Transformation":
|
|
30618
|
+
this.transformation.apply(op);
|
|
30619
|
+
break;
|
|
30620
|
+
case "LinkTo":
|
|
30621
|
+
this.linkTo.apply(op);
|
|
30622
|
+
break;
|
|
30623
|
+
case "Video":
|
|
30624
|
+
if (op.method === "updateVideoData") {
|
|
30625
|
+
this.applyVideoData({
|
|
30626
|
+
url: op.data.url,
|
|
30627
|
+
previewUrl: op.data.previewUrl
|
|
30628
|
+
});
|
|
30629
|
+
}
|
|
30630
|
+
this.subject.publish(this);
|
|
30631
|
+
break;
|
|
30632
|
+
}
|
|
30633
|
+
}
|
|
30634
|
+
emit(operation) {
|
|
30635
|
+
if (this.events) {
|
|
30636
|
+
const command = new VideoCommand([this], operation);
|
|
30637
|
+
command.apply();
|
|
30638
|
+
this.events.emit(operation, command);
|
|
30639
|
+
} else {
|
|
30640
|
+
this.apply(operation);
|
|
30641
|
+
}
|
|
30642
|
+
}
|
|
30643
|
+
setId(id) {
|
|
30644
|
+
this.id = id;
|
|
30645
|
+
this.transformation.setId(id);
|
|
30646
|
+
return this;
|
|
30647
|
+
}
|
|
30648
|
+
getId() {
|
|
30649
|
+
return this.id;
|
|
30650
|
+
}
|
|
30651
|
+
shootLoadCallbacks() {
|
|
30652
|
+
while (this.loadCallbacks.length > 0) {
|
|
30653
|
+
this.loadCallbacks.shift()(this);
|
|
30654
|
+
}
|
|
30655
|
+
}
|
|
30656
|
+
shootBeforeLoadCallbacks() {
|
|
30657
|
+
while (this.beforeLoadCallbacks.length > 0) {
|
|
30658
|
+
this.beforeLoadCallbacks.shift()(this);
|
|
30659
|
+
}
|
|
30660
|
+
}
|
|
30661
|
+
getPath() {
|
|
30662
|
+
const { left, top, right, bottom } = this.getMbr();
|
|
30663
|
+
const leftTop = new Point(left, top);
|
|
30664
|
+
const rightTop = new Point(right, top);
|
|
30665
|
+
const rightBottom = new Point(right, bottom);
|
|
30666
|
+
const leftBottom = new Point(left, bottom);
|
|
30667
|
+
return new Path([
|
|
30668
|
+
new Line(leftTop, rightTop),
|
|
30669
|
+
new Line(rightTop, rightBottom),
|
|
30670
|
+
new Line(rightBottom, leftBottom),
|
|
30671
|
+
new Line(leftBottom, leftTop)
|
|
30672
|
+
], true);
|
|
30673
|
+
}
|
|
30674
|
+
getSnapAnchorPoints() {
|
|
30675
|
+
const mbr = this.getMbr();
|
|
30676
|
+
const width = mbr.getWidth();
|
|
30677
|
+
const height = mbr.getHeight();
|
|
30678
|
+
return [
|
|
30679
|
+
new Point(mbr.left + width / 2, mbr.top),
|
|
30680
|
+
new Point(mbr.left + width / 2, mbr.bottom),
|
|
30681
|
+
new Point(mbr.left, mbr.top + height / 2),
|
|
30682
|
+
new Point(mbr.right, mbr.top + height / 2)
|
|
30683
|
+
];
|
|
30684
|
+
}
|
|
30685
|
+
isClosed() {
|
|
30686
|
+
return true;
|
|
30687
|
+
}
|
|
30688
|
+
getRichText() {
|
|
30689
|
+
return null;
|
|
30690
|
+
}
|
|
30691
|
+
getLinkTo() {
|
|
30692
|
+
return;
|
|
30693
|
+
}
|
|
30694
|
+
download() {
|
|
30695
|
+
if (this.isStorageUrl) {
|
|
30696
|
+
const linkElem = document.createElement("a");
|
|
30697
|
+
linkElem.href = this.url;
|
|
30698
|
+
linkElem.setAttribute("download", `${this.board.getBoardId()}.${this.extension}`);
|
|
30699
|
+
linkElem.click();
|
|
30700
|
+
}
|
|
30701
|
+
}
|
|
30702
|
+
}
|
|
30703
|
+
// src/Items/Image/calculatePosition.ts
|
|
30704
|
+
function calculatePosition(boardImage, board) {
|
|
30705
|
+
const viewportMbr = board.camera.getMbr();
|
|
30706
|
+
const viewportWidth = viewportMbr.getWidth();
|
|
30707
|
+
const viewportHeight = viewportMbr.getHeight();
|
|
30708
|
+
const centerPoint = viewportMbr.getCenter();
|
|
30709
|
+
const imageWidth = boardImage.getWidth();
|
|
30710
|
+
const imageHeight = boardImage.getHeight();
|
|
30711
|
+
const prevDimensions = tempStorage2.getImageDimensions();
|
|
30712
|
+
if (prevDimensions) {
|
|
30713
|
+
const scaleX2 = prevDimensions.width / imageWidth;
|
|
30714
|
+
const scaleY2 = prevDimensions.height / imageHeight;
|
|
30715
|
+
const finalScale2 = Math.min(scaleX2, scaleY2);
|
|
30716
|
+
return {
|
|
30717
|
+
scaleX: finalScale2,
|
|
30718
|
+
scaleY: finalScale2,
|
|
30719
|
+
translateX: centerPoint.x - imageWidth * finalScale2 / 2,
|
|
30720
|
+
translateY: centerPoint.y - imageHeight * finalScale2 / 2
|
|
30721
|
+
};
|
|
30722
|
+
}
|
|
30723
|
+
const margin = viewportHeight * 0.05;
|
|
30724
|
+
const viewportWidthWithMargin = viewportWidth - 2 * margin;
|
|
30725
|
+
const viewportHeightWithMargin = viewportHeight - 2 * margin;
|
|
30726
|
+
const scaleX = viewportWidthWithMargin / imageWidth;
|
|
30727
|
+
const scaleY = viewportHeightWithMargin / imageHeight;
|
|
30728
|
+
const scaleToFit = Math.min(scaleX, scaleY);
|
|
30729
|
+
const finalScale = scaleToFit;
|
|
30730
|
+
const scaledImageWidth = imageWidth * finalScale;
|
|
30731
|
+
const scaledImageHeight = imageHeight * finalScale;
|
|
30732
|
+
tempStorage2.setImageDimensions({
|
|
30733
|
+
width: scaledImageWidth,
|
|
30734
|
+
height: scaledImageHeight
|
|
30735
|
+
});
|
|
30736
|
+
const scaledImageCenterX = scaledImageWidth / 2;
|
|
30737
|
+
const scaledImageCenterY = scaledImageHeight / 2;
|
|
30738
|
+
const translateX = centerPoint.x - scaledImageCenterX;
|
|
30739
|
+
const translateY = centerPoint.y - scaledImageCenterY;
|
|
30740
|
+
return { scaleX: finalScale, scaleY: finalScale, translateX, translateY };
|
|
30741
|
+
}
|
|
30742
|
+
|
|
30743
|
+
// src/sha256.ts
|
|
30744
|
+
async function sha256(message) {
|
|
30745
|
+
const msgBuffer = new TextEncoder().encode(message);
|
|
30746
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", msgBuffer);
|
|
30747
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
30748
|
+
const hashHex = hashArray.map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
30749
|
+
return hashHex;
|
|
30750
|
+
}
|
|
30751
|
+
async function fileTosha256(file) {
|
|
30752
|
+
const buffer = await file.arrayBuffer();
|
|
30753
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", buffer);
|
|
30754
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
30755
|
+
return hashArray.map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
30756
|
+
}
|
|
30757
|
+
|
|
30758
|
+
// src/Items/Image/ImageHelpers.ts
|
|
30759
|
+
var catchErrorResponse = async (response, mediaType) => {
|
|
30760
|
+
if (response.status === 403) {
|
|
30761
|
+
const data = await response.json();
|
|
30762
|
+
let errorBody = conf.i18n.t("toolsPanel.addMedia.limitReached.bodyWithoutLimit");
|
|
30763
|
+
if (!data.isOwnerRequest) {
|
|
30764
|
+
errorBody = conf.i18n.t("toolsPanel.addMedia.limitReached.bodyOwner");
|
|
30765
|
+
} else if (data.currentUsage && data.storageLimit) {
|
|
30766
|
+
errorBody = conf.i18n.t(`toolsPanel.addMedia.limitReached.body.${parseInt(data.storageLimit) < 1e5 ? "basic" : "plus"}`);
|
|
30767
|
+
}
|
|
30768
|
+
conf.notify({
|
|
30769
|
+
variant: "warning",
|
|
30770
|
+
header: conf.i18n.t("toolsPanel.addMedia.limitReached.header"),
|
|
30771
|
+
body: errorBody,
|
|
30772
|
+
button: data.isOwnerRequest && data.storageLimit <= 100 ? {
|
|
30773
|
+
text: conf.i18n.t("toolsPanel.addMedia.upgradeToPlus"),
|
|
30774
|
+
onClick: () => conf.openModal("USER_PLAN_MODAL_ID")
|
|
30775
|
+
} : undefined,
|
|
30776
|
+
duration: 8000
|
|
30777
|
+
});
|
|
30778
|
+
} else if (response.status === 413) {
|
|
30779
|
+
const data = await response.json();
|
|
30780
|
+
let errorBody = conf.i18n.t("toolsPanel.addMedia.tooLarge.bodyWithoutLimit");
|
|
30781
|
+
let isBasicPlan = false;
|
|
30782
|
+
if (data.fileSizeLimit && data.fileSize) {
|
|
30783
|
+
if (mediaType === "image") {
|
|
30784
|
+
isBasicPlan = parseInt(data.fileSizeLimit) < 20;
|
|
30785
|
+
errorBody = conf.i18n.t(`toolsPanel.addMedia.tooLarge.imageBody.${isBasicPlan ? "basic" : "plus"}`);
|
|
30786
|
+
} else {
|
|
30787
|
+
isBasicPlan = parseInt(data.fileSizeLimit) < 1000;
|
|
30788
|
+
errorBody = conf.i18n.t(`toolsPanel.addMedia.tooLarge.audioOrVideoBody.${isBasicPlan ? "basic" : "plus"}`);
|
|
30789
|
+
}
|
|
30790
|
+
}
|
|
30791
|
+
conf.notify({
|
|
30792
|
+
variant: "warning",
|
|
30793
|
+
header: conf.i18n.t("toolsPanel.addMedia.tooLarge.header"),
|
|
30794
|
+
body: errorBody,
|
|
30795
|
+
button: isBasicPlan ? {
|
|
30796
|
+
text: conf.i18n.t("toolsPanel.addMedia.upgradeToPlus"),
|
|
30797
|
+
onClick: () => conf.openModal("USER_PLAN_MODAL_ID")
|
|
30798
|
+
} : undefined,
|
|
30799
|
+
duration: 4000
|
|
30800
|
+
});
|
|
30801
|
+
} else if (response.status === 401) {
|
|
30802
|
+
conf.openModal("MEDIA_UNAVAILABLE_MODAL_ID");
|
|
30803
|
+
} else if (response.status === 415) {
|
|
30804
|
+
conf.notify({
|
|
30805
|
+
variant: "warning",
|
|
30806
|
+
header: conf.i18n.t("toolsPanel.addMedia.unsupportedFormat.header"),
|
|
30807
|
+
body: conf.i18n.t("toolsPanel.addMedia.unsupportedFormat.body"),
|
|
30808
|
+
duration: 4000
|
|
30809
|
+
});
|
|
30810
|
+
} else {
|
|
30811
|
+
conf.notify({
|
|
30812
|
+
variant: "error",
|
|
30813
|
+
header: conf.i18n.t("toolsPanel.addMedia.unhandled.header"),
|
|
30814
|
+
body: conf.i18n.t("toolsPanel.addMedia.unhandled.body"),
|
|
30815
|
+
duration: 4000
|
|
30816
|
+
});
|
|
30817
|
+
}
|
|
30818
|
+
throw new Error(`HTTP status: ${response.status}`);
|
|
30819
|
+
};
|
|
30820
|
+
var catchDuplicateErrorResponse = async (response) => {
|
|
30821
|
+
if (response.status === 403) {
|
|
30822
|
+
conf.notify({
|
|
30823
|
+
variant: "warning",
|
|
30824
|
+
header: conf.i18n.t("toolsPanel.addMedia.limitReached.header"),
|
|
30825
|
+
body: conf.i18n.t("toolsPanel.addMedia.limitReached.duplicateBody"),
|
|
30826
|
+
duration: 4000
|
|
30827
|
+
});
|
|
30828
|
+
} else {
|
|
30829
|
+
conf.notify({
|
|
30830
|
+
variant: "error",
|
|
30831
|
+
header: conf.i18n.t("toolsPanel.addMedia.unhandled.header"),
|
|
30832
|
+
body: conf.i18n.t("toolsPanel.addMedia.unhandled.body"),
|
|
30833
|
+
duration: 4000
|
|
30834
|
+
});
|
|
30835
|
+
}
|
|
30836
|
+
throw new Error(`HTTP status: ${response.status}`);
|
|
30837
|
+
};
|
|
30838
|
+
var deleteMedia = async (mediaIds, boardId) => {
|
|
30839
|
+
fetch(`${window?.location.origin}/api/v1/media/usage/${boardId}`, {
|
|
30840
|
+
method: "POST",
|
|
30841
|
+
headers: {
|
|
30842
|
+
"content-type": "application/json"
|
|
30843
|
+
},
|
|
30844
|
+
body: JSON.stringify({ mediaIds, shouldIncrease: false })
|
|
30845
|
+
}).catch((error) => {
|
|
30846
|
+
console.error("Media storage error:", error);
|
|
30847
|
+
});
|
|
30848
|
+
};
|
|
30849
|
+
var updateMediaUsage = async (mediaIds, boardId) => {
|
|
30850
|
+
try {
|
|
30851
|
+
const response = await fetch(`${window?.location.origin}/api/v1/media/usage/${boardId}`, {
|
|
30852
|
+
method: "POST",
|
|
30853
|
+
headers: {
|
|
30854
|
+
"Content-Type": "application/json"
|
|
30855
|
+
},
|
|
30856
|
+
body: JSON.stringify({ mediaIds, shouldIncrease: true })
|
|
30857
|
+
});
|
|
30858
|
+
if (response.status !== 200) {
|
|
30859
|
+
await catchDuplicateErrorResponse(response);
|
|
30860
|
+
return false;
|
|
30861
|
+
}
|
|
30862
|
+
return true;
|
|
30863
|
+
} catch (error) {
|
|
30864
|
+
console.error("Media storage error:", error);
|
|
30865
|
+
return false;
|
|
30866
|
+
}
|
|
30867
|
+
};
|
|
30868
|
+
var uploadToTheStorage = async (hash, dataURL, accessToken, boardId) => {
|
|
30869
|
+
return new Promise((resolve, reject) => {
|
|
30870
|
+
const base64String = dataURL.split(",")[1];
|
|
30871
|
+
const mimeType = dataURL.split(",")[0].split(":")[1].split(";")[0];
|
|
30872
|
+
const binaryString = window.atob(base64String);
|
|
30873
|
+
const bytes = Uint8Array.from(binaryString, (char) => char.charCodeAt(0));
|
|
30874
|
+
const blob = new Blob([bytes], { type: mimeType });
|
|
30875
|
+
fetch(`${window?.location.origin}/api/v1/media/image/${boardId}`, {
|
|
30876
|
+
method: "POST",
|
|
30877
|
+
headers: {
|
|
30878
|
+
"Content-Type": mimeType,
|
|
30879
|
+
"X-Image-Id": hash,
|
|
30880
|
+
Authorization: `Bearer ${accessToken}`
|
|
30881
|
+
},
|
|
30882
|
+
body: blob
|
|
30883
|
+
}).then(async (response) => {
|
|
30884
|
+
if (response.status !== 200) {
|
|
30885
|
+
return catchErrorResponse(response, "image");
|
|
30886
|
+
}
|
|
30887
|
+
return response.json();
|
|
30888
|
+
}).then((data) => {
|
|
30889
|
+
resolve(data.src);
|
|
30890
|
+
}).catch((error) => {
|
|
30891
|
+
console.error("Media storage error:", error);
|
|
30892
|
+
reject(error);
|
|
30893
|
+
});
|
|
30894
|
+
});
|
|
30895
|
+
};
|
|
30896
|
+
var resizeAndConvertToPng = async (inp) => {
|
|
30897
|
+
return new Promise((resolve, reject) => {
|
|
30898
|
+
if (typeof inp !== "string") {
|
|
30899
|
+
return reject("Can't process such input");
|
|
30900
|
+
}
|
|
30901
|
+
const base64String = inp;
|
|
30902
|
+
const image = new Image;
|
|
30903
|
+
image.src = base64String;
|
|
30904
|
+
image.onerror = () => {
|
|
30905
|
+
return reject("Failed to load image");
|
|
30906
|
+
};
|
|
30907
|
+
if (base64String.startsWith("data:image/svg+xml")) {
|
|
30908
|
+
image.onload = async () => {
|
|
30909
|
+
const parser = conf.getDOMParser();
|
|
30910
|
+
const svgDoc = parser.parseFromString(atob(base64String.split(",")[1]), "image/svg+xml");
|
|
30911
|
+
const svgElement = svgDoc.documentElement;
|
|
30912
|
+
svgElement.removeAttribute("width");
|
|
30913
|
+
svgElement.removeAttribute("height");
|
|
30914
|
+
if (!svgElement.getAttribute("viewBox")) {
|
|
30915
|
+
svgElement.setAttribute("viewBox", `0 0 ${image.width} ${image.height}`);
|
|
30916
|
+
}
|
|
30917
|
+
svgElement.setAttribute("width", `${image.width}`);
|
|
30918
|
+
svgElement.setAttribute("height", `${image.height}`);
|
|
30919
|
+
svgElement.setAttribute("preserveAspectRatio", "xMidYMid meet");
|
|
30920
|
+
const newSvgString = new XMLSerializer().serializeToString(svgElement);
|
|
30921
|
+
const newBase64 = `data:image/svg+xml;base64,${btoa(newSvgString)}`;
|
|
30922
|
+
sha256(newBase64).then((hash) => {
|
|
30923
|
+
resolve({
|
|
30924
|
+
dataURL: newBase64,
|
|
30925
|
+
width: image.width,
|
|
30926
|
+
height: image.height,
|
|
30927
|
+
hash: `${hash}.svg`
|
|
30928
|
+
});
|
|
30929
|
+
}).catch(() => {
|
|
30930
|
+
return reject(new Error("Failed to generate hash"));
|
|
30931
|
+
});
|
|
30932
|
+
};
|
|
30933
|
+
} else {
|
|
30934
|
+
image.onload = async () => {
|
|
30935
|
+
const canvas = document.createElement("canvas");
|
|
30936
|
+
const context = canvas.getContext("2d");
|
|
30937
|
+
if (!context) {
|
|
30938
|
+
return reject("Failed to get canvas context");
|
|
30939
|
+
}
|
|
30940
|
+
const { width, height } = image;
|
|
30941
|
+
const scale = 1920 / Math.max(width, height);
|
|
30942
|
+
const canvasWidth = width > 1920 || height > 1920 ? width * scale : width;
|
|
30943
|
+
const canvasHeight = width > 1920 || height > 1920 ? height * scale : height;
|
|
30944
|
+
canvas.width = canvasWidth;
|
|
30945
|
+
canvas.height = canvasHeight;
|
|
30946
|
+
context.drawImage(image, 0, 0, canvasWidth, canvasHeight);
|
|
30947
|
+
const dataURL = canvas.toDataURL("image/webp");
|
|
30948
|
+
sha256(dataURL).then((hash) => {
|
|
30949
|
+
resolve({
|
|
30950
|
+
dataURL,
|
|
30951
|
+
width: canvasWidth,
|
|
30952
|
+
height: canvasHeight,
|
|
30953
|
+
hash
|
|
30954
|
+
});
|
|
30955
|
+
}).catch(() => {
|
|
30956
|
+
return reject(new Error("Failed to generate hash"));
|
|
30957
|
+
});
|
|
30958
|
+
};
|
|
30959
|
+
}
|
|
30960
|
+
});
|
|
30961
|
+
};
|
|
30962
|
+
var prepareImage = (inp, accessToken, boardId) => resizeAndConvertToPng(inp).then(({ width, height, dataURL, hash }) => {
|
|
30963
|
+
return uploadToTheStorage(hash, dataURL, accessToken, boardId).then((src) => {
|
|
30964
|
+
return {
|
|
30965
|
+
imageDimension: { width, height },
|
|
30966
|
+
base64: dataURL,
|
|
30967
|
+
storageLink: src
|
|
30968
|
+
};
|
|
30969
|
+
});
|
|
30970
|
+
});
|
|
30971
|
+
|
|
30972
|
+
// src/Items/Video/VideoHelpers.ts
|
|
30973
|
+
var uploadVideoToStorage = async (hash, videoBlob, accessToken, boardId) => {
|
|
30974
|
+
return new Promise((resolve, reject) => {
|
|
30975
|
+
fetch(`${window.location.origin}/api/v1/media/video/${boardId}`, {
|
|
30976
|
+
method: "POST",
|
|
30977
|
+
headers: {
|
|
30978
|
+
"Content-Type": videoBlob.type,
|
|
30979
|
+
"x-video-id": hash,
|
|
30980
|
+
Authorization: `Bearer ${accessToken}`
|
|
30981
|
+
},
|
|
30982
|
+
body: videoBlob
|
|
30983
|
+
}).then(async (response) => {
|
|
30984
|
+
if (response.status !== 200) {
|
|
30985
|
+
return catchErrorResponse(response, "video");
|
|
30986
|
+
}
|
|
30987
|
+
return response.json();
|
|
30988
|
+
}).then((data) => {
|
|
30989
|
+
resolve(data.src);
|
|
30990
|
+
}).catch((error) => {
|
|
30991
|
+
console.error("Media storage error:", error);
|
|
30992
|
+
reject(error);
|
|
30993
|
+
});
|
|
30994
|
+
});
|
|
30995
|
+
};
|
|
30996
|
+
var getVideoMetadata = (file) => {
|
|
30997
|
+
return new Promise((resolve, reject) => {
|
|
30998
|
+
const video = document.createElement("video");
|
|
30999
|
+
video.preload = "metadata";
|
|
31000
|
+
video.onloadedmetadata = () => {
|
|
31001
|
+
const { videoWidth: width, videoHeight: height } = video;
|
|
31002
|
+
URL.revokeObjectURL(video.src);
|
|
31003
|
+
resolve({ width, height });
|
|
31004
|
+
};
|
|
31005
|
+
video.onerror = () => {
|
|
31006
|
+
URL.revokeObjectURL(video.src);
|
|
31007
|
+
reject(new Error("Failed to load video metadata"));
|
|
31008
|
+
};
|
|
31009
|
+
video.src = URL.createObjectURL(file);
|
|
31010
|
+
});
|
|
31011
|
+
};
|
|
31012
|
+
var createVideoItem = (board, extension2, videoData, onLoadCb) => {
|
|
31013
|
+
const video = new VideoItem(videoData, board, board.events, "", extension2);
|
|
31014
|
+
video.doOnceBeforeOnLoad(() => {
|
|
31015
|
+
const { scaleX, scaleY, translateX, translateY } = calculatePosition(video, board);
|
|
31016
|
+
video.transformation.applyTranslateTo(translateX, translateY);
|
|
31017
|
+
video.transformation.applyScaleTo(scaleX, scaleY);
|
|
31018
|
+
video.updateMbr();
|
|
31019
|
+
const boardVideo = board.add(video);
|
|
31020
|
+
board.selection.removeAll();
|
|
31021
|
+
board.selection.add(boardVideo);
|
|
31022
|
+
onLoadCb(boardVideo);
|
|
31023
|
+
});
|
|
31024
|
+
};
|
|
31025
|
+
var prepareVideo = (file, accessToken, boardId) => {
|
|
31026
|
+
return new Promise((resolve, reject) => {
|
|
31027
|
+
const video = document.createElement("video");
|
|
31028
|
+
video.src = URL.createObjectURL(file);
|
|
31029
|
+
video.onloadedmetadata = () => {
|
|
31030
|
+
video.onseeked = () => {
|
|
31031
|
+
video.onseeked = null;
|
|
31032
|
+
prepareImage(captureFrame(0.1, video)?.src, accessToken, boardId).then((imageData) => {
|
|
31033
|
+
fileTosha256(file).then((hash) => {
|
|
31034
|
+
uploadVideoToStorage(hash, file, accessToken, boardId).then((url) => {
|
|
31035
|
+
resolve({
|
|
31036
|
+
url,
|
|
31037
|
+
previewUrl: imageData.storageLink
|
|
31038
|
+
});
|
|
31039
|
+
}).catch(reject);
|
|
31040
|
+
}).catch(() => {
|
|
31041
|
+
reject(new Error("Failed to generate hash"));
|
|
31042
|
+
});
|
|
31043
|
+
}).catch(() => reject(new Error("Failed to load video preview")));
|
|
31044
|
+
};
|
|
31045
|
+
video.currentTime = 0.1;
|
|
31046
|
+
};
|
|
31047
|
+
video.onerror = () => {
|
|
31048
|
+
reject(new Error("Failed to load video"));
|
|
31049
|
+
};
|
|
31050
|
+
});
|
|
31051
|
+
};
|
|
31052
|
+
var getYouTubeVideoPreview = (youtubeUrl) => {
|
|
31053
|
+
return new Promise((resolve, reject) => {
|
|
31054
|
+
const preview = document.createElement("img");
|
|
31055
|
+
preview.src = youtubeUrl;
|
|
31056
|
+
preview.onload = () => {
|
|
31057
|
+
resolve(preview);
|
|
31058
|
+
};
|
|
31059
|
+
preview.onerror = () => {
|
|
31060
|
+
reject(new Error("Failed to load preview"));
|
|
31061
|
+
};
|
|
31062
|
+
});
|
|
31063
|
+
};
|
|
31064
|
+
var getYouTubeThumbnail = (videoId, quality = "maxres") => {
|
|
31065
|
+
const qualities = {
|
|
31066
|
+
maxres: "maxresdefault",
|
|
31067
|
+
sd: "sddefault",
|
|
31068
|
+
hq: "hqdefault",
|
|
31069
|
+
mq: "mqdefault",
|
|
31070
|
+
default: "default"
|
|
31071
|
+
};
|
|
31072
|
+
return `https://img.youtube.com/vi/${videoId}/${qualities[quality]}.jpg`;
|
|
31073
|
+
};
|
|
31074
|
+
var captureFrame = (frameTime, video) => {
|
|
31075
|
+
video.currentTime = frameTime;
|
|
31076
|
+
const canvas = document.createElement("canvas");
|
|
31077
|
+
canvas.width = video.videoWidth;
|
|
31078
|
+
canvas.height = video.videoHeight;
|
|
31079
|
+
const ctx = canvas.getContext("2d");
|
|
31080
|
+
if (ctx) {
|
|
31081
|
+
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
|
|
31082
|
+
const frame = new Image;
|
|
31083
|
+
frame.src = canvas.toDataURL();
|
|
31084
|
+
return frame;
|
|
31085
|
+
} else {
|
|
31086
|
+
return null;
|
|
31087
|
+
}
|
|
31088
|
+
};
|
|
31089
|
+
// src/Items/Video/uploadVideo.ts
|
|
31090
|
+
function uploadVideo(file, board, notify2, extension2, accessToken) {
|
|
31091
|
+
getVideoMetadata(file).then((dimension) => {
|
|
31092
|
+
const onLoadCb = (videoItem) => {
|
|
31093
|
+
const notificationId = notify2({
|
|
31094
|
+
variant: "info",
|
|
31095
|
+
header: conf.i18n.t("toolsPanel.addMedia.loading"),
|
|
31096
|
+
body: "",
|
|
31097
|
+
duration: 1e5,
|
|
31098
|
+
loader: "MediaLoader"
|
|
31099
|
+
});
|
|
31100
|
+
prepareVideo(file, accessToken, board.getBoardId()).then((urls) => {
|
|
31101
|
+
videoItem.setVideoData(urls);
|
|
31102
|
+
}).catch((er) => {
|
|
31103
|
+
board.remove(videoItem);
|
|
31104
|
+
console.error("Could not create video:", er);
|
|
31105
|
+
}).finally(() => conf.disMissNotification(notificationId));
|
|
31106
|
+
};
|
|
31107
|
+
createVideoItem(board, extension2, { videoDimension: dimension }, onLoadCb);
|
|
31108
|
+
}).catch((er) => {
|
|
31109
|
+
console.error("Could not create video:", er);
|
|
31110
|
+
});
|
|
31111
|
+
}
|
|
30312
31112
|
// src/Items/Comment/CommentCommand.ts
|
|
30313
31113
|
class CommentCommand {
|
|
30314
31114
|
comment;
|
|
@@ -31599,70 +32399,6 @@ class AudioItem extends Mbr {
|
|
|
31599
32399
|
}
|
|
31600
32400
|
}
|
|
31601
32401
|
}
|
|
31602
|
-
// src/sha256.ts
|
|
31603
|
-
async function sha256(message) {
|
|
31604
|
-
const msgBuffer = new TextEncoder().encode(message);
|
|
31605
|
-
const hashBuffer = await crypto.subtle.digest("SHA-256", msgBuffer);
|
|
31606
|
-
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
31607
|
-
const hashHex = hashArray.map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
31608
|
-
return hashHex;
|
|
31609
|
-
}
|
|
31610
|
-
async function fileTosha256(file) {
|
|
31611
|
-
const buffer = await file.arrayBuffer();
|
|
31612
|
-
const hashBuffer = await crypto.subtle.digest("SHA-256", buffer);
|
|
31613
|
-
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
31614
|
-
return hashArray.map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
31615
|
-
}
|
|
31616
|
-
|
|
31617
|
-
// src/Items/Image/ImageHelpers.ts
|
|
31618
|
-
var catchDuplicateErrorResponse = async (response) => {
|
|
31619
|
-
if (response.status === 403) {
|
|
31620
|
-
conf.notify({
|
|
31621
|
-
variant: "warning",
|
|
31622
|
-
header: conf.i18n.t("toolsPanel.addMedia.limitReached.header"),
|
|
31623
|
-
body: conf.i18n.t("toolsPanel.addMedia.limitReached.duplicateBody"),
|
|
31624
|
-
duration: 4000
|
|
31625
|
-
});
|
|
31626
|
-
} else {
|
|
31627
|
-
conf.notify({
|
|
31628
|
-
variant: "error",
|
|
31629
|
-
header: conf.i18n.t("toolsPanel.addMedia.unhandled.header"),
|
|
31630
|
-
body: conf.i18n.t("toolsPanel.addMedia.unhandled.body"),
|
|
31631
|
-
duration: 4000
|
|
31632
|
-
});
|
|
31633
|
-
}
|
|
31634
|
-
throw new Error(`HTTP status: ${response.status}`);
|
|
31635
|
-
};
|
|
31636
|
-
var deleteMedia = async (mediaIds, boardId) => {
|
|
31637
|
-
fetch(`${window?.location.origin}/api/v1/media/usage/${boardId}`, {
|
|
31638
|
-
method: "POST",
|
|
31639
|
-
headers: {
|
|
31640
|
-
"content-type": "application/json"
|
|
31641
|
-
},
|
|
31642
|
-
body: JSON.stringify({ mediaIds, shouldIncrease: false })
|
|
31643
|
-
}).catch((error) => {
|
|
31644
|
-
console.error("Media storage error:", error);
|
|
31645
|
-
});
|
|
31646
|
-
};
|
|
31647
|
-
var updateMediaUsage = async (mediaIds, boardId) => {
|
|
31648
|
-
try {
|
|
31649
|
-
const response = await fetch(`${window?.location.origin}/api/v1/media/usage/${boardId}`, {
|
|
31650
|
-
method: "POST",
|
|
31651
|
-
headers: {
|
|
31652
|
-
"Content-Type": "application/json"
|
|
31653
|
-
},
|
|
31654
|
-
body: JSON.stringify({ mediaIds, shouldIncrease: true })
|
|
31655
|
-
});
|
|
31656
|
-
if (response.status !== 200) {
|
|
31657
|
-
await catchDuplicateErrorResponse(response);
|
|
31658
|
-
return false;
|
|
31659
|
-
}
|
|
31660
|
-
return true;
|
|
31661
|
-
} catch (error) {
|
|
31662
|
-
console.error("Media storage error:", error);
|
|
31663
|
-
return false;
|
|
31664
|
-
}
|
|
31665
|
-
};
|
|
31666
32402
|
// src/Items/Drawing/DrawingCommand.ts
|
|
31667
32403
|
class DrawingCommand {
|
|
31668
32404
|
item;
|
|
@@ -33515,382 +34251,6 @@ class Sticker {
|
|
|
33515
34251
|
return this.linkTo.link;
|
|
33516
34252
|
}
|
|
33517
34253
|
}
|
|
33518
|
-
// src/Items/Video/VideoCommand.ts
|
|
33519
|
-
class VideoCommand {
|
|
33520
|
-
videos;
|
|
33521
|
-
operation;
|
|
33522
|
-
constructor(videos, operation) {
|
|
33523
|
-
this.videos = videos;
|
|
33524
|
-
this.operation = operation;
|
|
33525
|
-
}
|
|
33526
|
-
apply() {
|
|
33527
|
-
for (const video of this.videos) {
|
|
33528
|
-
video.apply(this.operation);
|
|
33529
|
-
}
|
|
33530
|
-
}
|
|
33531
|
-
revert() {}
|
|
33532
|
-
}
|
|
33533
|
-
|
|
33534
|
-
// src/Items/Video/Video.ts
|
|
33535
|
-
var VIDEO_ICON_SRC = "data:image/svg+xml;charset=utf-8,%3Csvg viewBox='0 0 22 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M15 0C15.2652 0 15.5196 0.105357 15.7071 0.292893C15.8946 0.48043 16 0.734784 16 1V5.2L21.213 1.55C21.288 1.49746 21.3759 1.4665 21.4672 1.4605C21.5586 1.4545 21.6498 1.4737 21.731 1.51599C21.8122 1.55829 21.8802 1.62206 21.9276 1.70035C21.9751 1.77865 22.0001 1.86846 22 1.96V14.04C22.0001 14.1315 21.9751 14.2214 21.9276 14.2996C21.8802 14.3779 21.8122 14.4417 21.731 14.484C21.6498 14.5263 21.5586 14.5455 21.4672 14.5395C21.3759 14.5335 21.288 14.5025 21.213 14.45L16 10.8V15C16 15.2652 15.8946 15.5196 15.7071 15.7071C15.5196 15.8946 15.2652 16 15 16H1C0.734784 16 0.48043 15.8946 0.292893 15.7071C0.105357 15.5196 0 15.2652 0 15V1C0 0.734784 0.105357 0.48043 0.292893 0.292893C0.48043 0.105357 0.734784 0 1 0H15ZM14 2H2V14H14V2ZM6.4 4.829C6.47611 4.82879 6.55069 4.8503 6.615 4.891L10.97 7.663C11.0266 7.69917 11.0731 7.749 11.1054 7.80789C11.1376 7.86679 11.1545 7.93285 11.1545 8C11.1545 8.06715 11.1376 8.13321 11.1054 8.19211C11.0731 8.251 11.0266 8.30083 10.97 8.337L6.615 11.11C6.55434 11.1487 6.48438 11.1703 6.41248 11.1725C6.34059 11.1748 6.26941 11.1576 6.20646 11.1228C6.14351 11.088 6.0911 11.0368 6.05477 10.9747C6.01844 10.9127 5.99951 10.8419 6 10.77V5.23C6 5.009 6.18 4.83 6.4 4.83V4.829ZM20 4.84L16 7.64V8.358L20 11.158V4.84Z' fill='%23FFFFFF'/%3E%3C/svg%3E";
|
|
33536
|
-
var videoIcon = conf.documentFactory.createElement("img");
|
|
33537
|
-
videoIcon.src = VIDEO_ICON_SRC;
|
|
33538
|
-
var createPlaceholderImage = (width2, height2) => {
|
|
33539
|
-
const canvas = conf.documentFactory.createElement("canvas");
|
|
33540
|
-
canvas.width = width2;
|
|
33541
|
-
canvas.height = height2;
|
|
33542
|
-
const ctx = canvas.getContext("2d");
|
|
33543
|
-
if (ctx) {
|
|
33544
|
-
ctx.fillStyle = "rgba(229, 229, 234, 1)";
|
|
33545
|
-
ctx.fillRect(0, 0, width2, height2);
|
|
33546
|
-
const iconSize = Math.min(width2, height2) * 0.3;
|
|
33547
|
-
const iconX = (width2 - iconSize) / 2;
|
|
33548
|
-
const iconY = (height2 - iconSize) / 2;
|
|
33549
|
-
ctx.drawImage(videoIcon, iconX, iconY, iconSize * 1.375, iconSize);
|
|
33550
|
-
}
|
|
33551
|
-
const image = new Image;
|
|
33552
|
-
image.src = canvas.toDataURL();
|
|
33553
|
-
return image;
|
|
33554
|
-
};
|
|
33555
|
-
|
|
33556
|
-
class VideoItem extends Mbr {
|
|
33557
|
-
events;
|
|
33558
|
-
id;
|
|
33559
|
-
extension;
|
|
33560
|
-
itemType = "Video";
|
|
33561
|
-
parent = "Board";
|
|
33562
|
-
preview;
|
|
33563
|
-
transformation;
|
|
33564
|
-
linkTo;
|
|
33565
|
-
subject = new Subject;
|
|
33566
|
-
loadCallbacks = [];
|
|
33567
|
-
beforeLoadCallbacks = [];
|
|
33568
|
-
transformationRenderBlock = undefined;
|
|
33569
|
-
url = "";
|
|
33570
|
-
previewUrl = "";
|
|
33571
|
-
isStorageUrl = false;
|
|
33572
|
-
videoDimension;
|
|
33573
|
-
board;
|
|
33574
|
-
isPlaying = false;
|
|
33575
|
-
shouldShowControls = false;
|
|
33576
|
-
playBtnMbr = new Mbr;
|
|
33577
|
-
currentTime = 0;
|
|
33578
|
-
constructor({ url, videoDimension, previewUrl }, board, events2, id = "", extension2 = "mp4") {
|
|
33579
|
-
super();
|
|
33580
|
-
this.events = events2;
|
|
33581
|
-
this.id = id;
|
|
33582
|
-
this.extension = extension2;
|
|
33583
|
-
this.isStorageUrl = !conf.getYouTubeId(url);
|
|
33584
|
-
this.preview = createPlaceholderImage(videoDimension.width, videoDimension.height);
|
|
33585
|
-
this.linkTo = new LinkTo(this.id, events2);
|
|
33586
|
-
this.board = board;
|
|
33587
|
-
if (previewUrl) {
|
|
33588
|
-
this.previewUrl = previewUrl;
|
|
33589
|
-
this.setPreview(this.preview, previewUrl);
|
|
33590
|
-
}
|
|
33591
|
-
this.preview.onload = this.onLoad;
|
|
33592
|
-
this.preview.onerror = this.onError;
|
|
33593
|
-
if (url) {
|
|
33594
|
-
this.setUrl(url);
|
|
33595
|
-
}
|
|
33596
|
-
this.videoDimension = videoDimension;
|
|
33597
|
-
this.transformation = new Transformation(id, events2);
|
|
33598
|
-
this.linkTo.subject.subscribe(() => {
|
|
33599
|
-
this.updateMbr();
|
|
33600
|
-
this.subject.publish(this);
|
|
33601
|
-
});
|
|
33602
|
-
this.transformation.subject.subscribe(this.onTransform);
|
|
33603
|
-
}
|
|
33604
|
-
setCurrentTime(time2) {
|
|
33605
|
-
this.currentTime = time2;
|
|
33606
|
-
}
|
|
33607
|
-
getCurrentTime() {
|
|
33608
|
-
return this.currentTime;
|
|
33609
|
-
}
|
|
33610
|
-
onTransform = () => {
|
|
33611
|
-
this.updateMbr();
|
|
33612
|
-
this.subject.publish(this);
|
|
33613
|
-
};
|
|
33614
|
-
doOnceBeforeOnLoad = (callback) => {
|
|
33615
|
-
this.loadCallbacks.push(callback);
|
|
33616
|
-
};
|
|
33617
|
-
doOnceOnLoad = (callback) => {
|
|
33618
|
-
this.loadCallbacks.push(callback);
|
|
33619
|
-
};
|
|
33620
|
-
getStorageId() {
|
|
33621
|
-
return this.url.split("/").pop();
|
|
33622
|
-
}
|
|
33623
|
-
getIsStorageUrl() {
|
|
33624
|
-
return this.isStorageUrl;
|
|
33625
|
-
}
|
|
33626
|
-
setVideoData({ previewUrl, url }) {
|
|
33627
|
-
this.emit({
|
|
33628
|
-
class: "Video",
|
|
33629
|
-
item: [this.id],
|
|
33630
|
-
method: "updateVideoData",
|
|
33631
|
-
data: { previewUrl, url, videoDimension: this.videoDimension }
|
|
33632
|
-
});
|
|
33633
|
-
}
|
|
33634
|
-
applyVideoData({ previewUrl = "", url = "" }) {
|
|
33635
|
-
this.previewUrl = previewUrl;
|
|
33636
|
-
this.setPreview(this.preview, previewUrl);
|
|
33637
|
-
this.setUrl(url);
|
|
33638
|
-
}
|
|
33639
|
-
setIsPlaying(isPlaying) {
|
|
33640
|
-
this.isPlaying = isPlaying;
|
|
33641
|
-
this.subject.publish(this);
|
|
33642
|
-
}
|
|
33643
|
-
getIsPlaying() {
|
|
33644
|
-
return this.isPlaying;
|
|
33645
|
-
}
|
|
33646
|
-
setShouldShowControls(shouldShowControls) {
|
|
33647
|
-
this.shouldShowControls = shouldShowControls;
|
|
33648
|
-
this.subject.publish(this);
|
|
33649
|
-
}
|
|
33650
|
-
getShouldShowControls() {
|
|
33651
|
-
return this.shouldShowControls;
|
|
33652
|
-
}
|
|
33653
|
-
getPlayBtnMbr() {
|
|
33654
|
-
return this.playBtnMbr;
|
|
33655
|
-
}
|
|
33656
|
-
setUrl(url) {
|
|
33657
|
-
if (this.isStorageUrl) {
|
|
33658
|
-
try {
|
|
33659
|
-
const newUrl = new URL(url);
|
|
33660
|
-
this.url = `${window.location.origin}${newUrl.pathname}`;
|
|
33661
|
-
} catch (_) {}
|
|
33662
|
-
} else {
|
|
33663
|
-
this.url = url;
|
|
33664
|
-
}
|
|
33665
|
-
}
|
|
33666
|
-
setPreview(image, previewUrl) {
|
|
33667
|
-
if (this.isStorageUrl) {
|
|
33668
|
-
try {
|
|
33669
|
-
const newUrl = new URL(previewUrl);
|
|
33670
|
-
image.src = `${window.location.origin}${newUrl.pathname}`;
|
|
33671
|
-
} catch (_) {}
|
|
33672
|
-
} else {
|
|
33673
|
-
image.src = previewUrl;
|
|
33674
|
-
}
|
|
33675
|
-
image.onload = () => {
|
|
33676
|
-
this.preview = image;
|
|
33677
|
-
};
|
|
33678
|
-
}
|
|
33679
|
-
setPreviewImage(image) {
|
|
33680
|
-
this.preview = image;
|
|
33681
|
-
this.preview.onload = this.onLoad;
|
|
33682
|
-
this.preview.onerror = () => {
|
|
33683
|
-
const defaultPreview = new Image;
|
|
33684
|
-
defaultPreview.src = this.getPreviewUrl();
|
|
33685
|
-
this.preview = defaultPreview;
|
|
33686
|
-
this.preview.onload = this.onLoad;
|
|
33687
|
-
this.preview.onerror = this.onError;
|
|
33688
|
-
this.subject.publish(this);
|
|
33689
|
-
};
|
|
33690
|
-
this.subject.publish(this);
|
|
33691
|
-
}
|
|
33692
|
-
getPreviewUrl() {
|
|
33693
|
-
return this.previewUrl;
|
|
33694
|
-
}
|
|
33695
|
-
getUrl() {
|
|
33696
|
-
return this.url;
|
|
33697
|
-
}
|
|
33698
|
-
onLoad = async () => {
|
|
33699
|
-
this.shootBeforeLoadCallbacks();
|
|
33700
|
-
this.updateMbr();
|
|
33701
|
-
this.subject.publish(this);
|
|
33702
|
-
this.shootLoadCallbacks();
|
|
33703
|
-
};
|
|
33704
|
-
onError = (_error) => {
|
|
33705
|
-
this.preview = createPlaceholderImage(this.videoDimension.width, this.videoDimension.height);
|
|
33706
|
-
this.updateMbr();
|
|
33707
|
-
this.subject.publish(this);
|
|
33708
|
-
this.shootLoadCallbacks();
|
|
33709
|
-
};
|
|
33710
|
-
updateMbr() {
|
|
33711
|
-
const { translateX, translateY, scaleX, scaleY } = this.transformation.matrix;
|
|
33712
|
-
this.left = translateX;
|
|
33713
|
-
this.top = translateY;
|
|
33714
|
-
this.right = this.left + this.videoDimension.width * scaleX;
|
|
33715
|
-
this.bottom = this.top + this.videoDimension.height * scaleY;
|
|
33716
|
-
const playBtnSize = 50;
|
|
33717
|
-
const scaledPlayBtn = playBtnSize * this.transformation.matrix.scaleX;
|
|
33718
|
-
this.playBtnMbr = new Mbr(this.left + this.getWidth() / 2 - scaledPlayBtn / 2, this.top + this.getHeight() / 2 - scaledPlayBtn / 2, this.right - this.getWidth() / 2 + scaledPlayBtn / 2, this.bottom - this.getHeight() / 2 + scaledPlayBtn / 2);
|
|
33719
|
-
}
|
|
33720
|
-
render(context) {
|
|
33721
|
-
if (this.transformationRenderBlock || !this.preview.complete) {
|
|
33722
|
-
return;
|
|
33723
|
-
}
|
|
33724
|
-
const ctx = context.ctx;
|
|
33725
|
-
if (this.isPlaying) {
|
|
33726
|
-
ctx.save();
|
|
33727
|
-
ctx.globalCompositeOperation = "destination-out";
|
|
33728
|
-
ctx.fillRect(this.left, this.top, this.getWidth(), this.getHeight());
|
|
33729
|
-
ctx.restore();
|
|
33730
|
-
return;
|
|
33731
|
-
}
|
|
33732
|
-
ctx.save();
|
|
33733
|
-
this.transformation.matrix.applyToContext(ctx);
|
|
33734
|
-
ctx.drawImage(this.preview, 0, 0);
|
|
33735
|
-
if (this.shouldShowControls && this.previewUrl) {
|
|
33736
|
-
ctx.restore();
|
|
33737
|
-
ctx.fillStyle = "rgba(0, 0, 0, 0.5)";
|
|
33738
|
-
ctx.fillRect(this.left, this.top, this.getWidth(), this.getHeight());
|
|
33739
|
-
const playBtnSize = this.playBtnMbr.getWidth();
|
|
33740
|
-
const left = this.playBtnMbr.left;
|
|
33741
|
-
const top = this.playBtnMbr.top;
|
|
33742
|
-
ctx.fillStyle = "white";
|
|
33743
|
-
ctx.beginPath();
|
|
33744
|
-
ctx.moveTo(left, top);
|
|
33745
|
-
ctx.lineTo(left + playBtnSize, top + playBtnSize / 2);
|
|
33746
|
-
ctx.lineTo(left, top + playBtnSize);
|
|
33747
|
-
ctx.closePath();
|
|
33748
|
-
ctx.fill();
|
|
33749
|
-
}
|
|
33750
|
-
ctx.restore();
|
|
33751
|
-
}
|
|
33752
|
-
renderHTML(documentFactory) {
|
|
33753
|
-
const div = documentFactory.createElement("video-item");
|
|
33754
|
-
const { translateX, translateY, scaleX, scaleY } = this.transformation.matrix;
|
|
33755
|
-
const transform = `translate(${translateX}px, ${translateY}px) scale(${scaleX}, ${scaleY})`;
|
|
33756
|
-
div.style.backgroundImage = this.previewUrl ? `url(${this.previewUrl})` : `url(${createPlaceholderImage(this.videoDimension.width, this.videoDimension.height).src})`;
|
|
33757
|
-
div.id = this.getId();
|
|
33758
|
-
div.style.width = `${this.videoDimension.width}px`;
|
|
33759
|
-
div.style.height = `${this.videoDimension.height}px`;
|
|
33760
|
-
div.style.transformOrigin = "top left";
|
|
33761
|
-
div.style.transform = transform;
|
|
33762
|
-
div.style.position = "absolute";
|
|
33763
|
-
div.style.backgroundSize = "cover";
|
|
33764
|
-
div.setAttribute("video-url", this.getUrl());
|
|
33765
|
-
div.setAttribute("preview-url", this.getPreviewUrl());
|
|
33766
|
-
div.setAttribute("extension", this.extension);
|
|
33767
|
-
div.setAttribute("is-storage-url", this.isStorageUrl ? "1" : "");
|
|
33768
|
-
div.setAttribute("data-link-to", "");
|
|
33769
|
-
return div;
|
|
33770
|
-
}
|
|
33771
|
-
serialize() {
|
|
33772
|
-
return {
|
|
33773
|
-
itemType: "Video",
|
|
33774
|
-
url: this.url,
|
|
33775
|
-
videoDimension: this.videoDimension,
|
|
33776
|
-
transformation: this.transformation.serialize(),
|
|
33777
|
-
isStorageUrl: this.isStorageUrl,
|
|
33778
|
-
previewUrl: this.previewUrl,
|
|
33779
|
-
extension: this.extension
|
|
33780
|
-
};
|
|
33781
|
-
}
|
|
33782
|
-
deserialize(data) {
|
|
33783
|
-
if (data.transformation) {
|
|
33784
|
-
this.transformation.deserialize(data.transformation);
|
|
33785
|
-
}
|
|
33786
|
-
if (data.isStorageUrl) {
|
|
33787
|
-
this.isStorageUrl = data.isStorageUrl;
|
|
33788
|
-
}
|
|
33789
|
-
if (data.url) {
|
|
33790
|
-
this.setUrl(data.url);
|
|
33791
|
-
}
|
|
33792
|
-
if (data.extension) {
|
|
33793
|
-
this.extension = data.extension;
|
|
33794
|
-
}
|
|
33795
|
-
this.preview = createPlaceholderImage(data.videoDimension?.width || 100, data.videoDimension?.height || 100);
|
|
33796
|
-
const storageImage = new Image;
|
|
33797
|
-
storageImage.onload = () => {
|
|
33798
|
-
this.onLoad();
|
|
33799
|
-
};
|
|
33800
|
-
storageImage.onerror = this.onError;
|
|
33801
|
-
if (data.previewUrl) {
|
|
33802
|
-
this.setPreview(storageImage, data.previewUrl);
|
|
33803
|
-
}
|
|
33804
|
-
return this;
|
|
33805
|
-
}
|
|
33806
|
-
apply(op) {
|
|
33807
|
-
switch (op.class) {
|
|
33808
|
-
case "Transformation":
|
|
33809
|
-
this.transformation.apply(op);
|
|
33810
|
-
break;
|
|
33811
|
-
case "LinkTo":
|
|
33812
|
-
this.linkTo.apply(op);
|
|
33813
|
-
break;
|
|
33814
|
-
case "Video":
|
|
33815
|
-
if (op.method === "updateVideoData") {
|
|
33816
|
-
this.applyVideoData({
|
|
33817
|
-
url: op.data.url,
|
|
33818
|
-
previewUrl: op.data.previewUrl
|
|
33819
|
-
});
|
|
33820
|
-
}
|
|
33821
|
-
this.subject.publish(this);
|
|
33822
|
-
break;
|
|
33823
|
-
}
|
|
33824
|
-
}
|
|
33825
|
-
emit(operation) {
|
|
33826
|
-
if (this.events) {
|
|
33827
|
-
const command = new VideoCommand([this], operation);
|
|
33828
|
-
command.apply();
|
|
33829
|
-
this.events.emit(operation, command);
|
|
33830
|
-
} else {
|
|
33831
|
-
this.apply(operation);
|
|
33832
|
-
}
|
|
33833
|
-
}
|
|
33834
|
-
setId(id) {
|
|
33835
|
-
this.id = id;
|
|
33836
|
-
this.transformation.setId(id);
|
|
33837
|
-
return this;
|
|
33838
|
-
}
|
|
33839
|
-
getId() {
|
|
33840
|
-
return this.id;
|
|
33841
|
-
}
|
|
33842
|
-
shootLoadCallbacks() {
|
|
33843
|
-
while (this.loadCallbacks.length > 0) {
|
|
33844
|
-
this.loadCallbacks.shift()(this);
|
|
33845
|
-
}
|
|
33846
|
-
}
|
|
33847
|
-
shootBeforeLoadCallbacks() {
|
|
33848
|
-
while (this.beforeLoadCallbacks.length > 0) {
|
|
33849
|
-
this.beforeLoadCallbacks.shift()(this);
|
|
33850
|
-
}
|
|
33851
|
-
}
|
|
33852
|
-
getPath() {
|
|
33853
|
-
const { left, top, right, bottom } = this.getMbr();
|
|
33854
|
-
const leftTop = new Point(left, top);
|
|
33855
|
-
const rightTop = new Point(right, top);
|
|
33856
|
-
const rightBottom = new Point(right, bottom);
|
|
33857
|
-
const leftBottom = new Point(left, bottom);
|
|
33858
|
-
return new Path([
|
|
33859
|
-
new Line(leftTop, rightTop),
|
|
33860
|
-
new Line(rightTop, rightBottom),
|
|
33861
|
-
new Line(rightBottom, leftBottom),
|
|
33862
|
-
new Line(leftBottom, leftTop)
|
|
33863
|
-
], true);
|
|
33864
|
-
}
|
|
33865
|
-
getSnapAnchorPoints() {
|
|
33866
|
-
const mbr = this.getMbr();
|
|
33867
|
-
const width2 = mbr.getWidth();
|
|
33868
|
-
const height2 = mbr.getHeight();
|
|
33869
|
-
return [
|
|
33870
|
-
new Point(mbr.left + width2 / 2, mbr.top),
|
|
33871
|
-
new Point(mbr.left + width2 / 2, mbr.bottom),
|
|
33872
|
-
new Point(mbr.left, mbr.top + height2 / 2),
|
|
33873
|
-
new Point(mbr.right, mbr.top + height2 / 2)
|
|
33874
|
-
];
|
|
33875
|
-
}
|
|
33876
|
-
isClosed() {
|
|
33877
|
-
return true;
|
|
33878
|
-
}
|
|
33879
|
-
getRichText() {
|
|
33880
|
-
return null;
|
|
33881
|
-
}
|
|
33882
|
-
getLinkTo() {
|
|
33883
|
-
return;
|
|
33884
|
-
}
|
|
33885
|
-
download() {
|
|
33886
|
-
if (this.isStorageUrl) {
|
|
33887
|
-
const linkElem = document.createElement("a");
|
|
33888
|
-
linkElem.href = this.url;
|
|
33889
|
-
linkElem.setAttribute("download", `${this.board.getBoardId()}.${this.extension}`);
|
|
33890
|
-
linkElem.click();
|
|
33891
|
-
}
|
|
33892
|
-
}
|
|
33893
|
-
}
|
|
33894
34254
|
// src/itemFactories.ts
|
|
33895
34255
|
var itemFactories = {
|
|
33896
34256
|
Sticker: createSticker,
|
|
@@ -46564,7 +46924,7 @@ function createEventsLog(board) {
|
|
|
46564
46924
|
return new EventsLog(board);
|
|
46565
46925
|
}
|
|
46566
46926
|
// src/Events/Events.ts
|
|
46567
|
-
class
|
|
46927
|
+
class Events2 {
|
|
46568
46928
|
subject;
|
|
46569
46929
|
log;
|
|
46570
46930
|
board;
|
|
@@ -46690,7 +47050,7 @@ class Events {
|
|
|
46690
47050
|
}
|
|
46691
47051
|
}
|
|
46692
47052
|
function createEvents(board, connection, lastIndex) {
|
|
46693
|
-
return new
|
|
47053
|
+
return new Events2(board, connection, lastIndex);
|
|
46694
47054
|
}
|
|
46695
47055
|
// src/api/getMeasureCtx.ts
|
|
46696
47056
|
function getMeasureCtx() {
|
|
@@ -49845,5 +50205,5 @@ function initBrowserSettings() {
|
|
|
49845
50205
|
return conf;
|
|
49846
50206
|
}
|
|
49847
50207
|
|
|
49848
|
-
// src/browser
|
|
50208
|
+
// src/browser.ts
|
|
49849
50209
|
initBrowserSettings();
|