@netless/app-presentation 0.1.1 → 0.1.3
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/index.d.ts +42 -10
- package/dist/index.global.js +245 -88
- package/dist/index.js +245 -88
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +245 -88
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -15
- package/src/app-presentation.ts +77 -20
- package/src/preload.ts +154 -53
- package/src/presentation.ts +16 -8
package/dist/index.d.ts
CHANGED
|
@@ -195,17 +195,32 @@ interface ILazyLoadInstance {
|
|
|
195
195
|
toLoadCount: number;
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
+
declare enum ELoadState {
|
|
199
|
+
unloaded = 0,
|
|
200
|
+
loading = 1,
|
|
201
|
+
loaded = 2,
|
|
202
|
+
error = 3
|
|
203
|
+
}
|
|
204
|
+
interface IPreloadMapValue {
|
|
205
|
+
src: string;
|
|
206
|
+
state: ELoadState;
|
|
207
|
+
}
|
|
198
208
|
declare class Preload implements IDisposable {
|
|
199
209
|
readonly pages: PresentationPage[];
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
210
|
+
static maxLinks: number;
|
|
211
|
+
readonly loadingLinks: Map<number, HTMLLinkElement>;
|
|
212
|
+
readonly preloadMap: Map<number, IPreloadMapValue>;
|
|
213
|
+
readonly waitingLoadSet: Set<number>;
|
|
214
|
+
readonly waitinglinks: number[];
|
|
215
|
+
touchIndex: number;
|
|
216
|
+
preloadSize: number;
|
|
206
217
|
constructor(pages: PresentationPage[]);
|
|
207
|
-
touch(index: number):
|
|
208
|
-
|
|
218
|
+
touch(index: number): Promise<ELoadState>;
|
|
219
|
+
private autoTouch;
|
|
220
|
+
private createLink;
|
|
221
|
+
private handler;
|
|
222
|
+
private requestAsyncCallBack;
|
|
223
|
+
private destroyLink;
|
|
209
224
|
dispose(): void;
|
|
210
225
|
}
|
|
211
226
|
|
|
@@ -272,6 +287,7 @@ declare class Presentation implements IDisposable<void> {
|
|
|
272
287
|
showPreview: boolean;
|
|
273
288
|
pageIndex: number;
|
|
274
289
|
previewLazyload: ILazyLoadInstance | null;
|
|
290
|
+
timer: number | null;
|
|
275
291
|
constructor(config: PresentationConfig);
|
|
276
292
|
initialize(): void;
|
|
277
293
|
setDOM(dom: Element | DocumentFragment): void;
|
|
@@ -290,15 +306,31 @@ declare class Presentation implements IDisposable<void> {
|
|
|
290
306
|
declare const __inline: string;
|
|
291
307
|
|
|
292
308
|
type Logger = (...data: any[]) => void;
|
|
309
|
+
interface Viewport {
|
|
310
|
+
readonly x: number;
|
|
311
|
+
readonly y: number;
|
|
312
|
+
readonly width: number;
|
|
313
|
+
readonly height: number;
|
|
314
|
+
}
|
|
293
315
|
interface PresentationAppOptions {
|
|
294
316
|
/** Disables user move / scale the image and whiteboard. */
|
|
295
317
|
disableCameraTransform?: boolean;
|
|
296
318
|
/** Max scale = `maxCameraScale` * default scale. Not working when `disableCameraTransform` is true. Default: 3 */
|
|
297
319
|
maxCameraScale?: number;
|
|
298
|
-
/** Custom logger. Default:
|
|
320
|
+
/** Custom logger. Default: a logger that reports to the whiteboard server. */
|
|
299
321
|
log?: Logger;
|
|
300
322
|
/** Custom thumbnail generator. Default is appending `"?x-oss-process=image/resize,l_50"` to `src`. */
|
|
301
323
|
thumbnail?: (src: string) => string;
|
|
324
|
+
/**
|
|
325
|
+
* Custom viewport to set on the first time the presentation was added. Default is full page.
|
|
326
|
+
* Numbers range in 0 to 1 is considered a ratio to multiply the real page size.
|
|
327
|
+
* Example settings:
|
|
328
|
+
*
|
|
329
|
+
* - Full page: `{ x: 0, y: 0, width: 1, height: 1 }`
|
|
330
|
+
* - Half page: `{ x: 0, y: 0, width: 1, height: 0.5 }`
|
|
331
|
+
* - Absolute top-left area of the page: `{ x: 0, y: 0, width: 100, height: 100 }`
|
|
332
|
+
*/
|
|
333
|
+
viewport?: Viewport | ((page: PresentationPage) => Viewport);
|
|
302
334
|
}
|
|
303
335
|
interface PresentationController {
|
|
304
336
|
readonly app: Presentation;
|
|
@@ -322,7 +354,7 @@ interface PresentationController {
|
|
|
322
354
|
log: Logger;
|
|
323
355
|
}
|
|
324
356
|
|
|
325
|
-
declare const NetlessAppPresentation: NetlessApp<{},
|
|
357
|
+
declare const NetlessAppPresentation: NetlessApp<{}, {}, PresentationAppOptions, PresentationController>;
|
|
326
358
|
type RegisterFn = typeof WindowManager["register"];
|
|
327
359
|
interface InstallOptions {
|
|
328
360
|
/**
|
package/dist/index.global.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
var NetlessAppPresentation = (function (exports) {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
// node_modules/.pnpm/@wopjs+disposable@0.1.
|
|
4
|
+
// node_modules/.pnpm/@wopjs+disposable@0.1.5/node_modules/@wopjs/disposable/dist/index.mjs
|
|
5
5
|
var isAbortable = (disposable) => disposable && disposable.abortable;
|
|
6
|
-
var
|
|
6
|
+
var dispose = (disposable) => {
|
|
7
7
|
try {
|
|
8
|
-
if (disposable
|
|
9
|
-
disposable.dispose
|
|
10
|
-
|
|
11
|
-
disposable
|
|
8
|
+
if (disposable) {
|
|
9
|
+
if (disposable.dispose) {
|
|
10
|
+
disposable.dispose();
|
|
11
|
+
} else if (disposable.constructor && disposable.call && disposable.apply) {
|
|
12
|
+
disposable();
|
|
13
|
+
}
|
|
12
14
|
}
|
|
13
15
|
} catch (e) {
|
|
14
16
|
console.error(e);
|
|
@@ -45,7 +47,7 @@ var NetlessAppPresentation = (function (exports) {
|
|
|
45
47
|
flush(disposable) {
|
|
46
48
|
if (disposable) {
|
|
47
49
|
if (this.remove(disposable)) {
|
|
48
|
-
|
|
50
|
+
dispose(disposable);
|
|
49
51
|
}
|
|
50
52
|
} else {
|
|
51
53
|
this.dispose();
|
|
@@ -54,7 +56,7 @@ var NetlessAppPresentation = (function (exports) {
|
|
|
54
56
|
};
|
|
55
57
|
var disposableStore = (disposables) => {
|
|
56
58
|
const disposableStore2 = () => {
|
|
57
|
-
disposableStore2._d.forEach(
|
|
59
|
+
disposableStore2._d.forEach(dispose);
|
|
58
60
|
disposableStore2._d.clear();
|
|
59
61
|
};
|
|
60
62
|
disposableStore2._d = /* @__PURE__ */ new Set();
|
|
@@ -73,11 +75,9 @@ var NetlessAppPresentation = (function (exports) {
|
|
|
73
75
|
}
|
|
74
76
|
var listen = addEventListener;
|
|
75
77
|
|
|
76
|
-
// node_modules/.pnpm/vanilla-lazyload@
|
|
78
|
+
// node_modules/.pnpm/vanilla-lazyload@18.0.0/node_modules/vanilla-lazyload/dist/lazyload.esm.js
|
|
77
79
|
var runningOnBrowser = typeof window !== "undefined";
|
|
78
80
|
var isBot = runningOnBrowser && !("onscroll" in window) || typeof navigator !== "undefined" && /(gle|ing|ro)bot|crawl|spider/i.test(navigator.userAgent);
|
|
79
|
-
var supportsIntersectionObserver = runningOnBrowser && "IntersectionObserver" in window;
|
|
80
|
-
var supportsClassList = runningOnBrowser && "classList" in document.createElement("p");
|
|
81
81
|
var isHiDpi = runningOnBrowser && window.devicePixelRatio > 1;
|
|
82
82
|
var defaultSettings = {
|
|
83
83
|
elements_selector: ".lazy",
|
|
@@ -189,18 +189,22 @@ var NetlessAppPresentation = (function (exports) {
|
|
|
189
189
|
callback(arg1);
|
|
190
190
|
};
|
|
191
191
|
var addClass = (element, className) => {
|
|
192
|
-
if (
|
|
193
|
-
element.classList.add(className);
|
|
192
|
+
if (!runningOnBrowser) {
|
|
194
193
|
return;
|
|
195
194
|
}
|
|
196
|
-
|
|
195
|
+
if (className === "") {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
element.classList.add(className);
|
|
197
199
|
};
|
|
198
200
|
var removeClass = (element, className) => {
|
|
199
|
-
if (
|
|
200
|
-
element.classList.remove(className);
|
|
201
|
+
if (!runningOnBrowser) {
|
|
201
202
|
return;
|
|
202
203
|
}
|
|
203
|
-
|
|
204
|
+
if (className === "") {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
element.classList.remove(className);
|
|
204
208
|
};
|
|
205
209
|
var addTempImage = (element) => {
|
|
206
210
|
element.llTempImage = document.createElement("IMG");
|
|
@@ -647,7 +651,7 @@ var NetlessAppPresentation = (function (exports) {
|
|
|
647
651
|
observeElements(observer, elementsToObserve);
|
|
648
652
|
};
|
|
649
653
|
var setObserver = (settings, instance) => {
|
|
650
|
-
if (
|
|
654
|
+
if (shouldUseNative(settings)) {
|
|
651
655
|
return;
|
|
652
656
|
}
|
|
653
657
|
instance._observer = new IntersectionObserver((entries) => {
|
|
@@ -696,7 +700,7 @@ var NetlessAppPresentation = (function (exports) {
|
|
|
696
700
|
const settings = this._settings;
|
|
697
701
|
const elementsToLoad = getElementsToLoad(givenNodeset, settings);
|
|
698
702
|
setToLoadCount(this, elementsToLoad.length);
|
|
699
|
-
if (isBot
|
|
703
|
+
if (isBot) {
|
|
700
704
|
this.loadAll(elementsToLoad);
|
|
701
705
|
return;
|
|
702
706
|
}
|
|
@@ -786,66 +790,161 @@ var NetlessAppPresentation = (function (exports) {
|
|
|
786
790
|
}
|
|
787
791
|
|
|
788
792
|
// src/preload.ts
|
|
789
|
-
var
|
|
793
|
+
var _Preload = class _Preload {
|
|
790
794
|
constructor(pages) {
|
|
791
795
|
this.pages = pages;
|
|
792
|
-
this.
|
|
793
|
-
this.
|
|
794
|
-
this.
|
|
795
|
-
this.
|
|
796
|
-
this.
|
|
796
|
+
this.loadingLinks = /* @__PURE__ */ new Map();
|
|
797
|
+
this.preloadMap = /* @__PURE__ */ new Map();
|
|
798
|
+
this.waitingLoadSet = /* @__PURE__ */ new Set();
|
|
799
|
+
this.waitinglinks = [];
|
|
800
|
+
this.touchIndex = 0;
|
|
801
|
+
this.preloadSize = 0;
|
|
802
|
+
this.preloadMap = new Map(pages.map((e, index) => [index, {
|
|
803
|
+
src: e.src,
|
|
804
|
+
state: 0 /* unloaded */
|
|
805
|
+
}]));
|
|
806
|
+
this.waitingLoadSet = new Set(pages.map((e, index) => index));
|
|
807
|
+
this.preloadSize = this.preloadMap.size;
|
|
797
808
|
this.touch(0);
|
|
798
809
|
}
|
|
799
|
-
|
|
800
|
-
|
|
810
|
+
async touch(index) {
|
|
811
|
+
this.touchIndex = index;
|
|
812
|
+
const value = this.preloadMap.get(index);
|
|
813
|
+
let state = 0 /* unloaded */;
|
|
814
|
+
if (value) {
|
|
815
|
+
state = value.state;
|
|
816
|
+
if (value.state === 0 /* unloaded */) {
|
|
817
|
+
if (this.loadingLinks.size) {
|
|
818
|
+
for (const [i, link] of this.loadingLinks) {
|
|
819
|
+
this.destroyLink(i, link);
|
|
820
|
+
this.waitingLoadSet.add(i);
|
|
821
|
+
const v = this.preloadMap.get(i);
|
|
822
|
+
if (v) {
|
|
823
|
+
v.state = 0 /* unloaded */;
|
|
824
|
+
this.preloadMap.set(i, v);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
for (const i of this.waitinglinks) {
|
|
828
|
+
this.waitingLoadSet.add(i);
|
|
829
|
+
}
|
|
830
|
+
this.waitinglinks.length = 0;
|
|
831
|
+
}
|
|
832
|
+
if (this.waitinglinks.includes(index)) {
|
|
833
|
+
this.waitinglinks.splice(this.waitinglinks.indexOf(index), 1);
|
|
834
|
+
}
|
|
835
|
+
state = await new Promise((resolve) => {
|
|
836
|
+
this.waitingLoadSet.delete(index);
|
|
837
|
+
this.createLink(index, resolve);
|
|
838
|
+
});
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
if (this.waitingLoadSet.size) {
|
|
842
|
+
this.requestAsyncCallBack(() => {
|
|
843
|
+
this.autoTouch();
|
|
844
|
+
}, 1e3);
|
|
845
|
+
}
|
|
846
|
+
return state;
|
|
801
847
|
}
|
|
802
|
-
|
|
803
|
-
|
|
848
|
+
autoTouch() {
|
|
849
|
+
this.handler();
|
|
850
|
+
if (this.waitingLoadSet.size === 0) {
|
|
804
851
|
return;
|
|
805
|
-
|
|
806
|
-
|
|
852
|
+
}
|
|
853
|
+
let nextTouchDelay = 1e3;
|
|
854
|
+
this.touchIndex = (this.touchIndex + 1) % this.preloadSize;
|
|
855
|
+
const value = this.preloadMap.get(this.touchIndex);
|
|
856
|
+
if (value) {
|
|
857
|
+
switch (value.state) {
|
|
858
|
+
case 0 /* unloaded */:
|
|
859
|
+
case 3 /* error */:
|
|
860
|
+
if (!this.waitinglinks.includes(this.touchIndex)) {
|
|
861
|
+
this.waitinglinks.push(this.touchIndex);
|
|
862
|
+
this.waitingLoadSet.delete(this.touchIndex);
|
|
863
|
+
}
|
|
864
|
+
nextTouchDelay = 0;
|
|
865
|
+
break;
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
this.requestAsyncCallBack(() => {
|
|
869
|
+
this.autoTouch();
|
|
870
|
+
}, nextTouchDelay);
|
|
807
871
|
}
|
|
808
|
-
|
|
809
|
-
const
|
|
810
|
-
|
|
811
|
-
this.head--;
|
|
812
|
-
if (!links[this.head]) {
|
|
872
|
+
createLink(index, resolve) {
|
|
873
|
+
const value = this.preloadMap.get(index);
|
|
874
|
+
if (value) {
|
|
813
875
|
const link = document.createElement("link");
|
|
814
|
-
links[this.head] = link;
|
|
815
876
|
link.rel = "preload";
|
|
816
877
|
link.as = "image";
|
|
817
|
-
link.href =
|
|
818
|
-
link.dataset.order =
|
|
878
|
+
link.href = value.src;
|
|
879
|
+
link.dataset.order = index + "";
|
|
819
880
|
document.head.appendChild(link);
|
|
820
|
-
|
|
881
|
+
link.onload = () => {
|
|
882
|
+
value.state = 2 /* loaded */;
|
|
883
|
+
this.preloadMap.set(index, value);
|
|
884
|
+
document.head.contains(link) && document.head.removeChild(link);
|
|
885
|
+
this.loadingLinks.delete(index);
|
|
886
|
+
resolve && resolve(2 /* loaded */);
|
|
887
|
+
this.autoTouch();
|
|
888
|
+
};
|
|
889
|
+
link.onerror = () => {
|
|
890
|
+
value.state = 3 /* error */;
|
|
891
|
+
this.preloadMap.set(index, value);
|
|
892
|
+
if (!this.waitinglinks.includes(index)) {
|
|
893
|
+
this.waitinglinks.push(index);
|
|
894
|
+
this.waitingLoadSet.delete(this.touchIndex);
|
|
895
|
+
}
|
|
896
|
+
document.head.contains(link) && document.head.removeChild(link);
|
|
897
|
+
this.loadingLinks.delete(index);
|
|
898
|
+
resolve && resolve(3 /* error */);
|
|
899
|
+
this.autoTouch();
|
|
900
|
+
};
|
|
901
|
+
this.loadingLinks.set(index, link);
|
|
902
|
+
value.state = 1 /* loading */;
|
|
903
|
+
this.preloadMap.set(index, value);
|
|
821
904
|
}
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
if (this.
|
|
825
|
-
|
|
826
|
-
links[this.tail] = link;
|
|
827
|
-
link.rel = "preload";
|
|
828
|
-
link.as = "image";
|
|
829
|
-
link.href = this.pages[this.tail].src;
|
|
830
|
-
link.dataset.order = this.count + "";
|
|
831
|
-
document.head.appendChild(link);
|
|
832
|
-
this.count++;
|
|
905
|
+
}
|
|
906
|
+
handler() {
|
|
907
|
+
if (!this.waitinglinks.length) {
|
|
908
|
+
return;
|
|
833
909
|
}
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
910
|
+
let i = this.loadingLinks.size;
|
|
911
|
+
while (i < _Preload.maxLinks) {
|
|
912
|
+
const index = this.waitinglinks.shift();
|
|
913
|
+
if (index !== void 0) {
|
|
914
|
+
this.createLink(index);
|
|
915
|
+
}
|
|
916
|
+
i++;
|
|
840
917
|
}
|
|
841
918
|
}
|
|
919
|
+
async requestAsyncCallBack(callBack, timeout) {
|
|
920
|
+
await new Promise(function(resolve) {
|
|
921
|
+
if (window.requestIdleCallback) {
|
|
922
|
+
requestIdleCallback(() => {
|
|
923
|
+
resolve(1);
|
|
924
|
+
}, { timeout });
|
|
925
|
+
} else {
|
|
926
|
+
setTimeout(() => {
|
|
927
|
+
resolve(2);
|
|
928
|
+
}, timeout);
|
|
929
|
+
}
|
|
930
|
+
});
|
|
931
|
+
callBack();
|
|
932
|
+
}
|
|
933
|
+
destroyLink(index, link) {
|
|
934
|
+
document.head.contains(link) && document.head.removeChild(link);
|
|
935
|
+
this.loadingLinks.delete(index);
|
|
936
|
+
}
|
|
842
937
|
dispose() {
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
this.
|
|
938
|
+
for (const [index, link] of this.loadingLinks) {
|
|
939
|
+
this.destroyLink(index, link);
|
|
940
|
+
}
|
|
941
|
+
this.preloadMap.clear();
|
|
942
|
+
this.waitingLoadSet.clear();
|
|
943
|
+
this.waitinglinks.length = 0;
|
|
847
944
|
}
|
|
848
945
|
};
|
|
946
|
+
_Preload.maxLinks = 5;
|
|
947
|
+
var Preload = _Preload;
|
|
849
948
|
|
|
850
949
|
// src/presentation.ts
|
|
851
950
|
var Presentation = class {
|
|
@@ -856,6 +955,7 @@ var NetlessAppPresentation = (function (exports) {
|
|
|
856
955
|
this.showPreview = false;
|
|
857
956
|
this.pageIndex = 0;
|
|
858
957
|
this.previewLazyload = null;
|
|
958
|
+
this.timer = null;
|
|
859
959
|
var _a;
|
|
860
960
|
this.pages = config.pages;
|
|
861
961
|
this.preload = new Preload(this.pages);
|
|
@@ -1058,15 +1158,22 @@ var NetlessAppPresentation = (function (exports) {
|
|
|
1058
1158
|
return this.pages[this.pageIndex];
|
|
1059
1159
|
}
|
|
1060
1160
|
updateImage() {
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
this.image.src = "";
|
|
1064
|
-
return;
|
|
1161
|
+
if (this.timer) {
|
|
1162
|
+
clearTimeout(this.timer);
|
|
1065
1163
|
}
|
|
1066
|
-
this.
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1164
|
+
this.timer = setTimeout(() => {
|
|
1165
|
+
this.timer = null;
|
|
1166
|
+
this.preload.touch(this.pageIndex).then(() => {
|
|
1167
|
+
const page = this.page();
|
|
1168
|
+
if (!page) {
|
|
1169
|
+
this.image.src = "";
|
|
1170
|
+
return;
|
|
1171
|
+
}
|
|
1172
|
+
this.image.width = page.width;
|
|
1173
|
+
this.image.height = page.height;
|
|
1174
|
+
this.image.src = page.src;
|
|
1175
|
+
});
|
|
1176
|
+
}, 200);
|
|
1070
1177
|
}
|
|
1071
1178
|
/** Returns a modified URL that points to the thumbnail image. */
|
|
1072
1179
|
thumbnail(src) {
|
|
@@ -1105,7 +1212,7 @@ var NetlessAppPresentation = (function (exports) {
|
|
|
1105
1212
|
var NetlessAppPresentation = {
|
|
1106
1213
|
kind: "Presentation",
|
|
1107
1214
|
setup(context) {
|
|
1108
|
-
var _a, _b;
|
|
1215
|
+
var _a, _b, _c;
|
|
1109
1216
|
const view = context.getView();
|
|
1110
1217
|
if (!view)
|
|
1111
1218
|
throw new Error("[Presentation]: no whiteboard view, make sure you have added options.scenePath in addApp()");
|
|
@@ -1137,9 +1244,10 @@ var NetlessAppPresentation = (function (exports) {
|
|
|
1137
1244
|
}
|
|
1138
1245
|
}
|
|
1139
1246
|
}
|
|
1140
|
-
const
|
|
1141
|
-
|
|
1247
|
+
const dispose2 = disposableStore();
|
|
1248
|
+
dispose2.add(() => log(`[Presentation] dispose ${context.appId}`));
|
|
1142
1249
|
const page$$ = context.createStorage("page", { index: 0 });
|
|
1250
|
+
const view$$ = context.createStorage("view", { uid: "", originX: 0, originY: 0, width: 0, height: 0 });
|
|
1143
1251
|
let lastIndex = -1;
|
|
1144
1252
|
const syncPage = async (index) => {
|
|
1145
1253
|
if (lastIndex !== index) {
|
|
@@ -1203,19 +1311,51 @@ var NetlessAppPresentation = (function (exports) {
|
|
|
1203
1311
|
width,
|
|
1204
1312
|
height
|
|
1205
1313
|
});
|
|
1314
|
+
syncViewFromRemote(true);
|
|
1206
1315
|
}
|
|
1207
1316
|
};
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1317
|
+
const me = ((_c = context.getRoom()) == null ? void 0 : _c.uid) || context.getDisplayer().observerId + "";
|
|
1318
|
+
let throttleSyncView = 0;
|
|
1319
|
+
const syncView = () => {
|
|
1320
|
+
if (throttleSyncView > 0)
|
|
1321
|
+
return;
|
|
1322
|
+
const { width, height } = app.page() || {};
|
|
1323
|
+
if (width && height && context.getIsWritable()) {
|
|
1324
|
+
const { camera, size } = view;
|
|
1325
|
+
const fixedW = Math.min(size.width, size.height * width / height);
|
|
1326
|
+
const fixedH = Math.min(size.height, size.width * height / width);
|
|
1327
|
+
const w = fixedW / camera.scale;
|
|
1328
|
+
const h = fixedH / camera.scale;
|
|
1329
|
+
const x = camera.centerX - w / 2;
|
|
1330
|
+
const y = camera.centerY - h / 2;
|
|
1331
|
+
throttleSyncView = setTimeout(() => {
|
|
1332
|
+
throttleSyncView = 0;
|
|
1333
|
+
view$$.setState({ uid: me, originX: x, originY: y, width: w, height: h });
|
|
1334
|
+
}, 50);
|
|
1214
1335
|
}
|
|
1215
|
-
}
|
|
1336
|
+
};
|
|
1337
|
+
dispose2.add(() => {
|
|
1338
|
+
clearTimeout(throttleSyncView);
|
|
1339
|
+
throttleSyncView = 0;
|
|
1340
|
+
});
|
|
1341
|
+
const syncViewFromRemote = (force = false, animate = false) => {
|
|
1342
|
+
const { uid, originX, originY, width, height } = view$$.state;
|
|
1343
|
+
if ((force || uid !== me) && width > 0 && height > 0) {
|
|
1344
|
+
view.moveCameraToContain({
|
|
1345
|
+
originX,
|
|
1346
|
+
originY,
|
|
1347
|
+
width,
|
|
1348
|
+
height,
|
|
1349
|
+
animationMode: animate ? "continuous" : "immediately"
|
|
1350
|
+
});
|
|
1351
|
+
}
|
|
1352
|
+
};
|
|
1353
|
+
syncPage(page$$.state.index);
|
|
1354
|
+
dispose2.add(page$$.addStateChangedListener(() => syncPage(page$$.state.index)));
|
|
1355
|
+
dispose2.add(view$$.addStateChangedListener(() => syncViewFromRemote(false, true)));
|
|
1216
1356
|
const box = context.getBox();
|
|
1217
|
-
const app =
|
|
1218
|
-
app.contentDOM.dataset.appPresentationVersion = "0.1.
|
|
1357
|
+
const app = dispose2.add(createPresentation(box, pages, jumpPage, page$$, options.thumbnail));
|
|
1358
|
+
app.contentDOM.dataset.appPresentationVersion = "0.1.2";
|
|
1219
1359
|
app.scaleDocsToFit = scaleDocsToFit;
|
|
1220
1360
|
app.log = log;
|
|
1221
1361
|
context.mountView(app.whiteboardDOM);
|
|
@@ -1223,14 +1363,31 @@ var NetlessAppPresentation = (function (exports) {
|
|
|
1223
1363
|
view.disableCameraTransform = true;
|
|
1224
1364
|
}
|
|
1225
1365
|
scaleDocsToFit();
|
|
1226
|
-
|
|
1366
|
+
dispose2.make(() => {
|
|
1227
1367
|
view.callbacks.on("onSizeUpdated", scaleDocsToFit);
|
|
1228
1368
|
return () => view.callbacks.off("onSizeUpdated", scaleDocsToFit);
|
|
1229
1369
|
});
|
|
1230
|
-
|
|
1370
|
+
if (options.viewport && context.isAddApp && app.page()) {
|
|
1371
|
+
const page = app.page();
|
|
1372
|
+
const viewport = typeof options.viewport === "function" ? options.viewport(page) : options.viewport;
|
|
1373
|
+
const fix = (i, x) => i == 0 ? i : i <= 1 ? i * x : i;
|
|
1374
|
+
view$$.setState({
|
|
1375
|
+
uid: me,
|
|
1376
|
+
originX: fix(viewport.x, page.width) - page.width / 2,
|
|
1377
|
+
originY: fix(viewport.y, page.height) - page.height / 2,
|
|
1378
|
+
width: fix(viewport.width, page.width),
|
|
1379
|
+
height: fix(viewport.height, page.height)
|
|
1380
|
+
});
|
|
1381
|
+
}
|
|
1382
|
+
dispose2.make(() => {
|
|
1383
|
+
view.callbacks.on("onCameraUpdatedByDevice", syncView);
|
|
1384
|
+
return () => view.callbacks.off("onCameraUpdatedByDevice", syncView);
|
|
1385
|
+
});
|
|
1386
|
+
syncViewFromRemote(true);
|
|
1387
|
+
dispose2.add(context.emitter.on("writableChange", (isWritable) => {
|
|
1231
1388
|
app.setReadonly(!isWritable);
|
|
1232
1389
|
}));
|
|
1233
|
-
context.emitter.on("destroy", () =>
|
|
1390
|
+
context.emitter.on("destroy", () => dispose2());
|
|
1234
1391
|
const reportProgress = (progress, result) => {
|
|
1235
1392
|
window.postMessage({ type: "@netless/_result_save_pdf_", appId: context.appId, progress, result }, "*");
|
|
1236
1393
|
return result;
|
|
@@ -1326,7 +1483,7 @@ var NetlessAppPresentation = (function (exports) {
|
|
|
1326
1483
|
const title = box.title;
|
|
1327
1484
|
return reportProgress(100, { pdf: data, title });
|
|
1328
1485
|
};
|
|
1329
|
-
|
|
1486
|
+
dispose2.add(listen(window, "message", (ev) => {
|
|
1330
1487
|
if (ev.data && ev.data.type == "@netless/_request_save_pdf_" && ev.data.appId == context.appId) {
|
|
1331
1488
|
toPdf().catch((err) => {
|
|
1332
1489
|
console.warn(err);
|
|
@@ -1335,10 +1492,10 @@ var NetlessAppPresentation = (function (exports) {
|
|
|
1335
1492
|
}
|
|
1336
1493
|
}));
|
|
1337
1494
|
const controller = { app, view, context, jumpPage, prevPage, nextPage, pageState, toPdf, log };
|
|
1338
|
-
|
|
1495
|
+
dispose2.add(listen(window, "message", (ev) => {
|
|
1339
1496
|
if (ev.data === "@netless/_presentation_") {
|
|
1340
1497
|
if (typeof window !== "undefined")
|
|
1341
|
-
|
|
1498
|
+
dispose2.make(() => {
|
|
1342
1499
|
const debug = window._presentation_ || (window._presentation_ = /* @__PURE__ */ new Set());
|
|
1343
1500
|
debug.add(controller);
|
|
1344
1501
|
return () => debug.delete(controller);
|
|
@@ -1390,7 +1547,7 @@ var NetlessAppPresentation = (function (exports) {
|
|
|
1390
1547
|
};
|
|
1391
1548
|
|
|
1392
1549
|
// src/index.ts
|
|
1393
|
-
var version = "0.1.
|
|
1550
|
+
var version = "0.1.2";
|
|
1394
1551
|
|
|
1395
1552
|
exports.NetlessAppPresentation = NetlessAppPresentation;
|
|
1396
1553
|
exports.Presentation = Presentation;
|