@netless/app-presentation 0.1.12 → 0.1.13-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +18 -2
- package/dist/index.global.js +445 -99
- package/dist/index.js +445 -99
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +445 -99
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/app-presentation.ts +1041 -499
- package/src/preload.ts +14 -0
package/dist/index.mjs
CHANGED
|
@@ -1147,6 +1147,9 @@ var _Preload = class _Preload {
|
|
|
1147
1147
|
// 当前触摸的索引
|
|
1148
1148
|
this.touchIndex = 0;
|
|
1149
1149
|
this.preloadSize = 0;
|
|
1150
|
+
// 暂停后不再创建预加载链接(app 失焦降级时调用);已插入的 link 会被移除,
|
|
1151
|
+
// 挂起的 idle 回调重新进入 touch() 时也会被跳过
|
|
1152
|
+
this.paused = false;
|
|
1150
1153
|
this.preloadMap = new Map(pages.map((e, index) => [index, {
|
|
1151
1154
|
src: e.src,
|
|
1152
1155
|
state: 0 /* unloaded */
|
|
@@ -1154,7 +1157,21 @@ var _Preload = class _Preload {
|
|
|
1154
1157
|
this.preloadSize = this.preloadMap.size;
|
|
1155
1158
|
this.touch(0, true);
|
|
1156
1159
|
}
|
|
1160
|
+
pause() {
|
|
1161
|
+
if (this.paused)
|
|
1162
|
+
return;
|
|
1163
|
+
this.paused = true;
|
|
1164
|
+
this.destroySomeLink();
|
|
1165
|
+
}
|
|
1166
|
+
resume(index) {
|
|
1167
|
+
if (!this.paused)
|
|
1168
|
+
return;
|
|
1169
|
+
this.paused = false;
|
|
1170
|
+
this.touch(index != null ? index : this.touchIndex, true);
|
|
1171
|
+
}
|
|
1157
1172
|
touch(index, force = false) {
|
|
1173
|
+
if (this.paused)
|
|
1174
|
+
return;
|
|
1158
1175
|
if (index >= this.preloadSize) {
|
|
1159
1176
|
this.touchIndex = 0;
|
|
1160
1177
|
} else {
|
|
@@ -1953,6 +1970,138 @@ var ppt2page = (ppt, name, originSize) => {
|
|
|
1953
1970
|
const size = fitPageSizeToOrigin(ppt, originSize);
|
|
1954
1971
|
return __spreadProps(__spreadValues({}, size), { src: ppt.src, thumbnail: ppt.previewURL, name });
|
|
1955
1972
|
};
|
|
1973
|
+
var findBackgroundImage = (view) => {
|
|
1974
|
+
const container = view.divElement;
|
|
1975
|
+
if (!container || typeof container.querySelector !== "function")
|
|
1976
|
+
return null;
|
|
1977
|
+
return container.querySelector('img[alt="background"]');
|
|
1978
|
+
};
|
|
1979
|
+
var isBlurDegradationAllowed = (context) => {
|
|
1980
|
+
const boxStatus = context.getBoxStatus();
|
|
1981
|
+
if (boxStatus) {
|
|
1982
|
+
return boxStatus !== "normal";
|
|
1983
|
+
}
|
|
1984
|
+
const boxState = context.getWindowManager().boxState;
|
|
1985
|
+
return boxState !== void 0 && boxState !== "normal";
|
|
1986
|
+
};
|
|
1987
|
+
var DEFAULT_SETUP_READY_TIMEOUT = 5e3;
|
|
1988
|
+
var waitForCurrentPageImage = (view, timeoutMs, isDisposed) => {
|
|
1989
|
+
return new Promise((resolve) => {
|
|
1990
|
+
let settled = false;
|
|
1991
|
+
let pollTimer;
|
|
1992
|
+
const settle = (loaded) => {
|
|
1993
|
+
if (settled)
|
|
1994
|
+
return;
|
|
1995
|
+
settled = true;
|
|
1996
|
+
window.clearTimeout(timeoutTimer);
|
|
1997
|
+
if (pollTimer !== void 0)
|
|
1998
|
+
window.clearInterval(pollTimer);
|
|
1999
|
+
resolve(loaded);
|
|
2000
|
+
};
|
|
2001
|
+
const timeoutTimer = window.setTimeout(() => settle(false), timeoutMs);
|
|
2002
|
+
const check = () => {
|
|
2003
|
+
if (isDisposed()) {
|
|
2004
|
+
settle(false);
|
|
2005
|
+
return;
|
|
2006
|
+
}
|
|
2007
|
+
const img = findBackgroundImage(view);
|
|
2008
|
+
if (img && img.complete && img.naturalWidth > 0) {
|
|
2009
|
+
settle(true);
|
|
2010
|
+
}
|
|
2011
|
+
};
|
|
2012
|
+
check();
|
|
2013
|
+
if (!settled) {
|
|
2014
|
+
pollTimer = window.setInterval(check, 100);
|
|
2015
|
+
}
|
|
2016
|
+
});
|
|
2017
|
+
};
|
|
2018
|
+
var resolveImageUrl = (url) => {
|
|
2019
|
+
try {
|
|
2020
|
+
return new URL(url, window.location.href).href;
|
|
2021
|
+
} catch (e) {
|
|
2022
|
+
return url;
|
|
2023
|
+
}
|
|
2024
|
+
};
|
|
2025
|
+
var setupBlurThumbnailDegradation = (config) => {
|
|
2026
|
+
const { context, view, pages, pageIndex$, app, dispose: dispose2 } = config;
|
|
2027
|
+
let blurEpisode = false;
|
|
2028
|
+
let reDegradeEnabled = false;
|
|
2029
|
+
const degrade = () => {
|
|
2030
|
+
const page = pages[pageIndex$.value];
|
|
2031
|
+
if (!(page == null ? void 0 : page.thumbnail))
|
|
2032
|
+
return;
|
|
2033
|
+
const img = findBackgroundImage(view);
|
|
2034
|
+
if (img && resolveImageUrl(img.src) !== resolveImageUrl(page.thumbnail)) {
|
|
2035
|
+
img.src = page.thumbnail;
|
|
2036
|
+
}
|
|
2037
|
+
};
|
|
2038
|
+
const restore2 = () => {
|
|
2039
|
+
const page = pages[pageIndex$.value];
|
|
2040
|
+
const img = findBackgroundImage(view);
|
|
2041
|
+
if (page && img && resolveImageUrl(img.src) !== resolveImageUrl(page.src)) {
|
|
2042
|
+
img.src = page.src;
|
|
2043
|
+
}
|
|
2044
|
+
};
|
|
2045
|
+
const isBackgroundImg = (target) => {
|
|
2046
|
+
var _a;
|
|
2047
|
+
const el = target;
|
|
2048
|
+
return Boolean(
|
|
2049
|
+
el && el.tagName === "IMG" && ((_a = el.matches) == null ? void 0 : _a.call(el, 'img[alt="background"]'))
|
|
2050
|
+
);
|
|
2051
|
+
};
|
|
2052
|
+
const onImgLoad = (ev) => {
|
|
2053
|
+
if (!blurEpisode || !reDegradeEnabled)
|
|
2054
|
+
return;
|
|
2055
|
+
if (!isBackgroundImg(ev.target))
|
|
2056
|
+
return;
|
|
2057
|
+
degrade();
|
|
2058
|
+
};
|
|
2059
|
+
const onImgError = (ev) => {
|
|
2060
|
+
if (!blurEpisode || !reDegradeEnabled)
|
|
2061
|
+
return;
|
|
2062
|
+
if (!isBackgroundImg(ev.target))
|
|
2063
|
+
return;
|
|
2064
|
+
reDegradeEnabled = false;
|
|
2065
|
+
};
|
|
2066
|
+
const offFocus = context.emitter.on("focus", (isFocused) => {
|
|
2067
|
+
if (isFocused) {
|
|
2068
|
+
if (blurEpisode) {
|
|
2069
|
+
blurEpisode = false;
|
|
2070
|
+
reDegradeEnabled = false;
|
|
2071
|
+
restore2();
|
|
2072
|
+
app.preload.resume(pageIndex$.value);
|
|
2073
|
+
}
|
|
2074
|
+
} else {
|
|
2075
|
+
if (!isBlurDegradationAllowed(context))
|
|
2076
|
+
return;
|
|
2077
|
+
blurEpisode = true;
|
|
2078
|
+
reDegradeEnabled = true;
|
|
2079
|
+
degrade();
|
|
2080
|
+
app.preload.pause();
|
|
2081
|
+
}
|
|
2082
|
+
});
|
|
2083
|
+
dispose2.add(offFocus);
|
|
2084
|
+
const viewEl = view.divElement;
|
|
2085
|
+
if (viewEl && typeof viewEl.addEventListener === "function") {
|
|
2086
|
+
viewEl.addEventListener("load", onImgLoad, true);
|
|
2087
|
+
viewEl.addEventListener("error", onImgError, true);
|
|
2088
|
+
dispose2.add(() => {
|
|
2089
|
+
viewEl.removeEventListener("load", onImgLoad, true);
|
|
2090
|
+
viewEl.removeEventListener("error", onImgError, true);
|
|
2091
|
+
});
|
|
2092
|
+
} else {
|
|
2093
|
+
warnOnceMissingViewContainer(view);
|
|
2094
|
+
}
|
|
2095
|
+
};
|
|
2096
|
+
var degradedWarnedViews = /* @__PURE__ */ new WeakSet();
|
|
2097
|
+
var warnOnceMissingViewContainer = (view) => {
|
|
2098
|
+
if (degradedWarnedViews.has(view))
|
|
2099
|
+
return;
|
|
2100
|
+
degradedWarnedViews.add(view);
|
|
2101
|
+
console.warn(
|
|
2102
|
+
"[Presentation]: blur thumbnail degradation runs without re-degrade coverage (view container unavailable)"
|
|
2103
|
+
);
|
|
2104
|
+
};
|
|
1956
2105
|
var createLogger = (room) => {
|
|
1957
2106
|
if (room && room.logger) {
|
|
1958
2107
|
return (...args) => room.logger.info(...args);
|
|
@@ -1964,7 +2113,10 @@ var createDiagnosticLogger = (context) => {
|
|
|
1964
2113
|
var _a;
|
|
1965
2114
|
const createAppLogger = context.createLogger;
|
|
1966
2115
|
if (typeof createAppLogger === "function") {
|
|
1967
|
-
return createAppLogger.call(context, "camera", {
|
|
2116
|
+
return createAppLogger.call(context, "camera", {
|
|
2117
|
+
debounceTime: 300,
|
|
2118
|
+
maxWaitTime: 2e3
|
|
2119
|
+
});
|
|
1968
2120
|
}
|
|
1969
2121
|
const roomLogger = (_a = context.getRoom()) == null ? void 0 : _a.logger;
|
|
1970
2122
|
const prefix = `[Presentation][${context.appId}][camera]`;
|
|
@@ -2021,40 +2173,60 @@ var scenesEqual = (scenes1, scenes2) => {
|
|
|
2021
2173
|
return scene.name === scene2.name && ((_a = scene.ppt) == null ? void 0 : _a.width) === ((_b = scene2.ppt) == null ? void 0 : _b.width) && ((_c = scene.ppt) == null ? void 0 : _c.height) === ((_d = scene2.ppt) == null ? void 0 : _d.height) && ((_e = scene.ppt) == null ? void 0 : _e.src) === ((_f = scene2.ppt) == null ? void 0 : _f.src);
|
|
2022
2174
|
});
|
|
2023
2175
|
};
|
|
2176
|
+
var teardownByContext = /* @__PURE__ */ new WeakMap();
|
|
2024
2177
|
var NetlessAppPresentation = {
|
|
2025
2178
|
kind: "Presentation",
|
|
2026
2179
|
setup(context) {
|
|
2027
|
-
var _a, _b, _c;
|
|
2180
|
+
var _a, _b, _c, _d;
|
|
2028
2181
|
const diagnosticLogger = createDiagnosticLogger(context);
|
|
2029
2182
|
const view = context.getView();
|
|
2030
2183
|
if (!view)
|
|
2031
|
-
throw new Error(
|
|
2184
|
+
throw new Error(
|
|
2185
|
+
"[Presentation]: no whiteboard view, make sure you have added options.scenePath in addApp()"
|
|
2186
|
+
);
|
|
2032
2187
|
const options = context.getAppOptions() || {};
|
|
2033
2188
|
const room = context.getRoom();
|
|
2034
2189
|
const log = options.log || createLogger(room);
|
|
2035
2190
|
const roomLogger = room == null ? void 0 : room.logger;
|
|
2036
2191
|
const warn = (...data) => (roomLogger == null ? void 0 : roomLogger.warn) ? roomLogger.warn(...data) : log(...data);
|
|
2037
2192
|
const configuredOriginSize = context.storage.state.originSize;
|
|
2038
|
-
const originSize = isValidSize(configuredOriginSize) ? {
|
|
2193
|
+
const originSize = isValidSize(configuredOriginSize) ? {
|
|
2194
|
+
width: configuredOriginSize.width,
|
|
2195
|
+
height: configuredOriginSize.height
|
|
2196
|
+
} : void 0;
|
|
2039
2197
|
if (configuredOriginSize != null && !originSize) {
|
|
2040
|
-
warn(
|
|
2198
|
+
warn(
|
|
2199
|
+
`[Presentation] originSize should contain finite positive width and height, got ${JSON.stringify(configuredOriginSize)}`
|
|
2200
|
+
);
|
|
2041
2201
|
}
|
|
2042
2202
|
const pages = (_a = context.getScenes()) == null ? void 0 : _a.map(({ ppt, name }) => ppt2page(ppt, name, originSize)).filter(Boolean);
|
|
2043
2203
|
if (!pages || pages.length === 0)
|
|
2044
|
-
throw new Error(
|
|
2204
|
+
throw new Error(
|
|
2205
|
+
"[Presentation]: empty scenes, make sure you have added options.scenes in addApp()"
|
|
2206
|
+
);
|
|
2045
2207
|
if (pages[0].src.startsWith("ppt"))
|
|
2046
|
-
throw new Error(
|
|
2208
|
+
throw new Error(
|
|
2209
|
+
"[Presentation]: legacy dynamic PPT is unsupported, please use the projector converter and @netless/slide to render it"
|
|
2210
|
+
);
|
|
2047
2211
|
const scenePath = context.getInitScenePath();
|
|
2048
2212
|
let maxCameraScale = (_b = options.maxCameraScale) != null ? _b : 3;
|
|
2049
2213
|
if (!(Number.isFinite(maxCameraScale) && maxCameraScale > 0)) {
|
|
2050
|
-
warn(
|
|
2214
|
+
warn(
|
|
2215
|
+
`[Presentation] maxCameraScale should be a positive number, got ${options.maxCameraScale}`
|
|
2216
|
+
);
|
|
2051
2217
|
maxCameraScale = 3;
|
|
2052
2218
|
}
|
|
2053
2219
|
log(`[Presentation] new ${context.appId}`);
|
|
2054
2220
|
const dispose2 = disposableStore();
|
|
2055
2221
|
dispose2.add(() => log(`[Presentation] dispose ${context.appId}`));
|
|
2056
2222
|
dispose2.add(() => diagnosticLogger.flush());
|
|
2057
|
-
const view$$ = context.createStorage("view", {
|
|
2223
|
+
const view$$ = context.createStorage("view", {
|
|
2224
|
+
uid: "",
|
|
2225
|
+
originX: 0,
|
|
2226
|
+
originY: 0,
|
|
2227
|
+
width: 0,
|
|
2228
|
+
height: 0
|
|
2229
|
+
});
|
|
2058
2230
|
const _addScenePathListener = (name, listener) => {
|
|
2059
2231
|
const windowManger = context.manager.windowManger;
|
|
2060
2232
|
windowManger.emitter.on(name, listener);
|
|
@@ -2076,13 +2248,16 @@ var NetlessAppPresentation = {
|
|
|
2076
2248
|
let pageIndex = getPageIndex(view);
|
|
2077
2249
|
const pageIndex$ = readable(pageIndex, (set) => {
|
|
2078
2250
|
set(pageIndex);
|
|
2079
|
-
return _addScenePathListener(
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
const
|
|
2083
|
-
|
|
2251
|
+
return _addScenePathListener(
|
|
2252
|
+
"onAppScenePathChange",
|
|
2253
|
+
(payload) => {
|
|
2254
|
+
const { appId } = payload;
|
|
2255
|
+
if (appId === context.appId) {
|
|
2256
|
+
const _pageIndex = getPageIndex(payload.view);
|
|
2257
|
+
set(_pageIndex);
|
|
2258
|
+
}
|
|
2084
2259
|
}
|
|
2085
|
-
|
|
2260
|
+
);
|
|
2086
2261
|
});
|
|
2087
2262
|
dispose2.add(() => {
|
|
2088
2263
|
pageIndex$.dispose();
|
|
@@ -2099,7 +2274,12 @@ var NetlessAppPresentation = {
|
|
|
2099
2274
|
const p = pages[index];
|
|
2100
2275
|
const name = (_a2 = p.name) != null ? _a2 : String(index + 1);
|
|
2101
2276
|
if (!scenes.some((scene) => scene.name === name)) {
|
|
2102
|
-
await context.addPage({
|
|
2277
|
+
await context.addPage({
|
|
2278
|
+
scene: {
|
|
2279
|
+
name,
|
|
2280
|
+
ppt: { width: p.width, height: p.height, src: p.src }
|
|
2281
|
+
}
|
|
2282
|
+
});
|
|
2103
2283
|
}
|
|
2104
2284
|
if (logger) {
|
|
2105
2285
|
logger.info(`[Presentation] syncPage ${scenePath}/${name}`);
|
|
@@ -2111,15 +2291,21 @@ var NetlessAppPresentation = {
|
|
|
2111
2291
|
if (!context.isAddApp)
|
|
2112
2292
|
return;
|
|
2113
2293
|
if (pages.length > 100)
|
|
2114
|
-
warn(
|
|
2294
|
+
warn(
|
|
2295
|
+
`[Presentation]: too many pages (${pages.length}), may cause performance issues`
|
|
2296
|
+
);
|
|
2115
2297
|
if (!room || !room.isWritable)
|
|
2116
2298
|
return;
|
|
2117
2299
|
if (pageIndex$.value < 0 || pageIndex$.value >= pages.length) {
|
|
2118
|
-
throw new Error(
|
|
2300
|
+
throw new Error(
|
|
2301
|
+
`[Presentation] Invalid page index: ${pageIndex$.value}, scenes length: ${pages.length}`
|
|
2302
|
+
);
|
|
2119
2303
|
}
|
|
2120
2304
|
const scenes = room.entireScenes()[scenePath];
|
|
2121
2305
|
if (!scenes || !scenes[pageIndex$.value]) {
|
|
2122
|
-
throw new Error(
|
|
2306
|
+
throw new Error(
|
|
2307
|
+
`[Presentation]: no initial scene found at ${scenePath}, page index: ${pageIndex$.value}`
|
|
2308
|
+
);
|
|
2123
2309
|
}
|
|
2124
2310
|
const { name, ppt } = scenes[pageIndex$.value];
|
|
2125
2311
|
const nextScenes = pages.map((page, index) => {
|
|
@@ -2148,16 +2334,22 @@ var NetlessAppPresentation = {
|
|
|
2148
2334
|
const prepareScenesPromise = prepareScenes();
|
|
2149
2335
|
const canJumpPage = (index) => {
|
|
2150
2336
|
if (!context.getIsWritable()) {
|
|
2151
|
-
warn(
|
|
2337
|
+
warn(
|
|
2338
|
+
"[Presentation]: no permission, make sure you have test room.isWritable"
|
|
2339
|
+
);
|
|
2152
2340
|
return false;
|
|
2153
2341
|
}
|
|
2154
2342
|
if (!(0 <= index && index < pages.length)) {
|
|
2155
|
-
warn(
|
|
2343
|
+
warn(
|
|
2344
|
+
`[Presentation]: page ${index + 1} out of bounds [1, ${pages.length}]`
|
|
2345
|
+
);
|
|
2156
2346
|
return false;
|
|
2157
2347
|
}
|
|
2158
2348
|
const scenes = context.getDisplayer().entireScenes()[scenePath];
|
|
2159
2349
|
if (!scenes) {
|
|
2160
|
-
warn(
|
|
2350
|
+
warn(
|
|
2351
|
+
`[Presentation]: no scenes found at ${scenePath}, make sure you have added options.scenePath in addApp()`
|
|
2352
|
+
);
|
|
2161
2353
|
return false;
|
|
2162
2354
|
}
|
|
2163
2355
|
return true;
|
|
@@ -2263,13 +2455,20 @@ var NetlessAppPresentation = {
|
|
|
2263
2455
|
try {
|
|
2264
2456
|
const { camera, size } = view;
|
|
2265
2457
|
const referenceSize = getCameraReferenceSize(originSize, page);
|
|
2266
|
-
const viewport = cameraToSharedViewport(
|
|
2458
|
+
const viewport = cameraToSharedViewport(
|
|
2459
|
+
camera,
|
|
2460
|
+
size,
|
|
2461
|
+
referenceSize
|
|
2462
|
+
);
|
|
2267
2463
|
if (viewport)
|
|
2268
2464
|
view$$.setState(__spreadValues({ uid: me }, viewport));
|
|
2269
2465
|
if (pendingMoveCameraRequest) {
|
|
2270
2466
|
diagnosticLogger.debouncedInfo(
|
|
2271
2467
|
"moveCamera",
|
|
2272
|
-
getCameraDiagnosticState(
|
|
2468
|
+
getCameraDiagnosticState(
|
|
2469
|
+
"moveCamera",
|
|
2470
|
+
pendingMoveCameraRequest
|
|
2471
|
+
)
|
|
2273
2472
|
);
|
|
2274
2473
|
pendingMoveCameraRequest = void 0;
|
|
2275
2474
|
}
|
|
@@ -2277,7 +2476,10 @@ var NetlessAppPresentation = {
|
|
|
2277
2476
|
diagnosticLogger.error(
|
|
2278
2477
|
"syncView.failed",
|
|
2279
2478
|
error,
|
|
2280
|
-
getCameraDiagnosticState(
|
|
2479
|
+
getCameraDiagnosticState(
|
|
2480
|
+
"moveCamera",
|
|
2481
|
+
pendingMoveCameraRequest
|
|
2482
|
+
)
|
|
2281
2483
|
);
|
|
2282
2484
|
pendingMoveCameraRequest = void 0;
|
|
2283
2485
|
}
|
|
@@ -2302,17 +2504,32 @@ var NetlessAppPresentation = {
|
|
|
2302
2504
|
});
|
|
2303
2505
|
}
|
|
2304
2506
|
};
|
|
2305
|
-
dispose2.add(
|
|
2507
|
+
dispose2.add(
|
|
2508
|
+
view$$.addStateChangedListener(() => syncViewFromRemote(false, true))
|
|
2509
|
+
);
|
|
2306
2510
|
const getPageSize = () => {
|
|
2307
2511
|
const { width, height } = app.page() || {};
|
|
2308
2512
|
return { width: width || 0, height: height || 0 };
|
|
2309
2513
|
};
|
|
2310
2514
|
const box = context.getBox();
|
|
2311
|
-
const app = dispose2.add(
|
|
2312
|
-
|
|
2515
|
+
const app = dispose2.add(
|
|
2516
|
+
createPresentation(
|
|
2517
|
+
box,
|
|
2518
|
+
pages,
|
|
2519
|
+
jumpPage,
|
|
2520
|
+
pageIndex$,
|
|
2521
|
+
view,
|
|
2522
|
+
options.thumbnail,
|
|
2523
|
+
options.useClipView
|
|
2524
|
+
)
|
|
2525
|
+
);
|
|
2526
|
+
app.contentDOM.dataset.appPresentationVersion = "0.1.13-beta.1";
|
|
2313
2527
|
app.scaleDocsToFit = scaleDocsToFit;
|
|
2314
2528
|
app.log = log;
|
|
2315
2529
|
app.warn = warn;
|
|
2530
|
+
if (pageIndex$.value !== 0) {
|
|
2531
|
+
app.preload.touch(pageIndex$.value, true);
|
|
2532
|
+
}
|
|
2316
2533
|
const getCameraDiagnosticState = (reason, requestedCamera) => {
|
|
2317
2534
|
const page = app.page();
|
|
2318
2535
|
const pageSize = page && isValidSize(page) ? { width: page.width, height: page.height } : void 0;
|
|
@@ -2356,19 +2573,21 @@ var NetlessAppPresentation = {
|
|
|
2356
2573
|
};
|
|
2357
2574
|
if (originSize) {
|
|
2358
2575
|
let previousPageIndex = pageIndex$.value;
|
|
2359
|
-
dispose2.add(
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2576
|
+
dispose2.add(
|
|
2577
|
+
pageIndex$.subscribe((nextPageIndex) => {
|
|
2578
|
+
if (nextPageIndex === previousPageIndex)
|
|
2579
|
+
return;
|
|
2580
|
+
previousPageIndex = nextPageIndex;
|
|
2581
|
+
scaleDocsToFit();
|
|
2582
|
+
})
|
|
2583
|
+
);
|
|
2365
2584
|
}
|
|
2366
2585
|
if (options.justDocsViewReadonly) {
|
|
2367
2586
|
app.setDocsViewReadonly(true);
|
|
2368
2587
|
}
|
|
2369
2588
|
const goToPageByClick = () => {
|
|
2370
|
-
var _a2, _b2, _c2,
|
|
2371
|
-
const currentApplianceName = (
|
|
2589
|
+
var _a2, _b2, _c2, _d2;
|
|
2590
|
+
const currentApplianceName = (_d2 = (_c2 = (_b2 = (_a2 = context.getRoom()) == null ? void 0 : _a2.state) == null ? void 0 : _b2.memberState) == null ? void 0 : _c2.currentApplianceName) != null ? _d2 : "";
|
|
2372
2591
|
if (!app.readonly && currentApplianceName === "clicker") {
|
|
2373
2592
|
nextPage();
|
|
2374
2593
|
}
|
|
@@ -2410,9 +2629,14 @@ var NetlessAppPresentation = {
|
|
|
2410
2629
|
});
|
|
2411
2630
|
syncViewFromRemote(true);
|
|
2412
2631
|
reportInitializedCamera("setup");
|
|
2413
|
-
dispose2.add(
|
|
2414
|
-
|
|
2415
|
-
|
|
2632
|
+
dispose2.add(
|
|
2633
|
+
context.emitter.on("writableChange", (isWritable) => {
|
|
2634
|
+
app.setReadonly(!isWritable);
|
|
2635
|
+
})
|
|
2636
|
+
);
|
|
2637
|
+
if (!options.disableBlurThumbnailDegradation) {
|
|
2638
|
+
setupBlurThumbnailDegradation({ context, view, pages, pageIndex$, app, dispose: dispose2 });
|
|
2639
|
+
}
|
|
2416
2640
|
const getOriginScale = () => {
|
|
2417
2641
|
const page = app.page();
|
|
2418
2642
|
if (!page || !isValidSize(page))
|
|
@@ -2434,29 +2658,53 @@ var NetlessAppPresentation = {
|
|
|
2434
2658
|
img.crossOrigin = "Anonymous";
|
|
2435
2659
|
await new Promise((resolve, reject) => {
|
|
2436
2660
|
img.onload = () => resolve();
|
|
2437
|
-
img.onerror = () => reject(
|
|
2438
|
-
|
|
2439
|
-
|
|
2661
|
+
img.onerror = () => reject(
|
|
2662
|
+
new Error(
|
|
2663
|
+
`[Presentation]: failed to load screenshot page image: ${safeResourceLocation(src)}`
|
|
2664
|
+
)
|
|
2665
|
+
);
|
|
2440
2666
|
img.src = src;
|
|
2441
2667
|
});
|
|
2442
|
-
_context.drawImage(
|
|
2668
|
+
_context.drawImage(
|
|
2669
|
+
img,
|
|
2670
|
+
0,
|
|
2671
|
+
0,
|
|
2672
|
+
width,
|
|
2673
|
+
height,
|
|
2674
|
+
0,
|
|
2675
|
+
0,
|
|
2676
|
+
_width || width,
|
|
2677
|
+
_height || height
|
|
2678
|
+
);
|
|
2443
2679
|
const currentScenePath = view.focusScenePath;
|
|
2444
2680
|
if (!currentScenePath) {
|
|
2445
2681
|
throw new Error("[Presentation]: current scene path not found");
|
|
2446
2682
|
}
|
|
2447
2683
|
const windowManger = context.getWindowManager();
|
|
2448
2684
|
if (windowManger._appliancePlugin) {
|
|
2449
|
-
await windowManger._appliancePlugin.screenshotToCanvasAsync(
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2685
|
+
await windowManger._appliancePlugin.screenshotToCanvasAsync(
|
|
2686
|
+
_context,
|
|
2687
|
+
currentScenePath,
|
|
2688
|
+
_width || width,
|
|
2689
|
+
_height || height,
|
|
2690
|
+
{
|
|
2691
|
+
centerX: 0,
|
|
2692
|
+
centerY: 0,
|
|
2693
|
+
scale: _width && _height ? Math.min(_width / width, _height / height) : 1
|
|
2694
|
+
}
|
|
2695
|
+
);
|
|
2454
2696
|
} else {
|
|
2455
|
-
await view.screenshotToCanvasAsync(
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2697
|
+
await view.screenshotToCanvasAsync(
|
|
2698
|
+
_context,
|
|
2699
|
+
currentScenePath,
|
|
2700
|
+
_width || width,
|
|
2701
|
+
_height || height,
|
|
2702
|
+
{
|
|
2703
|
+
centerX: 0,
|
|
2704
|
+
centerY: 0,
|
|
2705
|
+
scale: _width && _height ? Math.min(_width / width, _height / height) : 1
|
|
2706
|
+
}
|
|
2707
|
+
);
|
|
2460
2708
|
}
|
|
2461
2709
|
};
|
|
2462
2710
|
const screenshotCurrentPageAsync = async (_context, _width, _height) => {
|
|
@@ -2474,21 +2722,27 @@ var NetlessAppPresentation = {
|
|
|
2474
2722
|
let scrollbar;
|
|
2475
2723
|
if (options.useScrollbar) {
|
|
2476
2724
|
dispose2.make(() => {
|
|
2477
|
-
scrollbar = new Scrollbar(
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2725
|
+
scrollbar = new Scrollbar(
|
|
2726
|
+
app.contentDOM,
|
|
2727
|
+
{
|
|
2728
|
+
appId: context.appId,
|
|
2729
|
+
getPageSize,
|
|
2730
|
+
getOriginScale,
|
|
2731
|
+
syncView,
|
|
2732
|
+
getWritable: () => context.getIsWritable(),
|
|
2733
|
+
scrollbarEventCallback: options.scrollbarEventCallback
|
|
2734
|
+
},
|
|
2735
|
+
view
|
|
2736
|
+
);
|
|
2485
2737
|
return () => scrollbar == null ? void 0 : scrollbar.destroy();
|
|
2486
2738
|
});
|
|
2487
2739
|
}
|
|
2488
2740
|
const moveCamera = (camera) => {
|
|
2489
2741
|
try {
|
|
2490
2742
|
if (!context.getIsWritable()) {
|
|
2491
|
-
throw new Error(
|
|
2743
|
+
throw new Error(
|
|
2744
|
+
"[Presentation]: moveCamera must be called in writable room"
|
|
2745
|
+
);
|
|
2492
2746
|
}
|
|
2493
2747
|
pendingMoveCameraRequest = __spreadValues({}, camera);
|
|
2494
2748
|
if (scrollbar) {
|
|
@@ -2509,9 +2763,29 @@ var NetlessAppPresentation = {
|
|
|
2509
2763
|
throw error;
|
|
2510
2764
|
}
|
|
2511
2765
|
};
|
|
2512
|
-
|
|
2766
|
+
let disposed = false;
|
|
2767
|
+
let offDestroy;
|
|
2768
|
+
const teardown = () => {
|
|
2769
|
+
if (disposed)
|
|
2770
|
+
return;
|
|
2771
|
+
disposed = true;
|
|
2772
|
+
const removeDestroy = offDestroy;
|
|
2773
|
+
offDestroy = void 0;
|
|
2774
|
+
removeDestroy == null ? void 0 : removeDestroy();
|
|
2775
|
+
dispose2();
|
|
2776
|
+
};
|
|
2777
|
+
offDestroy = context.emitter.on("destroy", teardown);
|
|
2778
|
+
teardownByContext.set(context, teardown);
|
|
2513
2779
|
const reportProgress = (progress, result) => {
|
|
2514
|
-
window.postMessage(
|
|
2780
|
+
window.postMessage(
|
|
2781
|
+
{
|
|
2782
|
+
type: "@netless/_result_save_pdf_",
|
|
2783
|
+
appId: context.appId,
|
|
2784
|
+
progress,
|
|
2785
|
+
result
|
|
2786
|
+
},
|
|
2787
|
+
"*"
|
|
2788
|
+
);
|
|
2515
2789
|
return result;
|
|
2516
2790
|
};
|
|
2517
2791
|
const base64url = async (url) => {
|
|
@@ -2551,7 +2825,9 @@ var NetlessAppPresentation = {
|
|
|
2551
2825
|
}
|
|
2552
2826
|
const scenes = context.getDisplayer().entireScenes()[scenePath];
|
|
2553
2827
|
if (!scenes) {
|
|
2554
|
-
throw new Error(
|
|
2828
|
+
throw new Error(
|
|
2829
|
+
`[Presentation]: no scenes found while exporting PDF: ${scenePath}`
|
|
2830
|
+
);
|
|
2555
2831
|
}
|
|
2556
2832
|
const stage_canvas = document.createElement("canvas");
|
|
2557
2833
|
stage_canvas.width = pdfWidth;
|
|
@@ -2576,20 +2852,32 @@ var NetlessAppPresentation = {
|
|
|
2576
2852
|
const img = document.createElement("img");
|
|
2577
2853
|
await new Promise((resolve, reject) => {
|
|
2578
2854
|
img.onload = () => resolve();
|
|
2579
|
-
img.onerror = () => reject(
|
|
2580
|
-
|
|
2581
|
-
|
|
2855
|
+
img.onerror = () => reject(
|
|
2856
|
+
new Error(
|
|
2857
|
+
`[Presentation]: failed to load PDF page image, page index: ${index}`
|
|
2858
|
+
)
|
|
2859
|
+
);
|
|
2582
2860
|
img.src = url;
|
|
2583
2861
|
});
|
|
2584
2862
|
stage.drawImage(img, 0, 0, width2, height2);
|
|
2585
2863
|
wb.clearRect(0, 0, pdfWidth, pdfHeight);
|
|
2586
2864
|
const name = (_a2 = p.name) != null ? _a2 : String(index + 1);
|
|
2587
2865
|
if (scenes.some((scene) => scene.name == name)) {
|
|
2588
|
-
const camera = {
|
|
2866
|
+
const camera = {
|
|
2867
|
+
centerX: 0,
|
|
2868
|
+
centerY: 0,
|
|
2869
|
+
scale: Math.min(wb_canvas.width / width2, wb_canvas.height / height2)
|
|
2870
|
+
};
|
|
2589
2871
|
const sPath = `${scenePath}/${name}`;
|
|
2590
2872
|
const windowManger = context.getWindowManager();
|
|
2591
2873
|
if (windowManger._appliancePlugin) {
|
|
2592
|
-
await windowManger._appliancePlugin.screenshotToCanvasAsync(
|
|
2874
|
+
await windowManger._appliancePlugin.screenshotToCanvasAsync(
|
|
2875
|
+
wb,
|
|
2876
|
+
sPath,
|
|
2877
|
+
wb_canvas.width,
|
|
2878
|
+
wb_canvas.height,
|
|
2879
|
+
camera
|
|
2880
|
+
);
|
|
2593
2881
|
} else {
|
|
2594
2882
|
await view.screenshotToCanvasAsync(
|
|
2595
2883
|
wb,
|
|
@@ -2636,14 +2924,20 @@ var NetlessAppPresentation = {
|
|
|
2636
2924
|
throw error;
|
|
2637
2925
|
}
|
|
2638
2926
|
};
|
|
2639
|
-
dispose2.add(
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2927
|
+
dispose2.add(
|
|
2928
|
+
listen(
|
|
2929
|
+
window,
|
|
2930
|
+
"message",
|
|
2931
|
+
(ev) => {
|
|
2932
|
+
if (ev.data && ev.data.type == "@netless/_request_save_pdf_" && ev.data.appId == context.appId) {
|
|
2933
|
+
toPdf().catch((err) => {
|
|
2934
|
+
warn(err);
|
|
2935
|
+
reportProgress(100, null);
|
|
2936
|
+
});
|
|
2937
|
+
}
|
|
2938
|
+
}
|
|
2939
|
+
)
|
|
2940
|
+
);
|
|
2647
2941
|
const setDocsViewReadonly = (bol) => {
|
|
2648
2942
|
app.setDocsViewReadonly(bol);
|
|
2649
2943
|
};
|
|
@@ -2654,19 +2948,57 @@ var NetlessAppPresentation = {
|
|
|
2654
2948
|
scrollbar.setReadonly(bol);
|
|
2655
2949
|
}
|
|
2656
2950
|
};
|
|
2657
|
-
const controller = {
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2951
|
+
const controller = {
|
|
2952
|
+
app,
|
|
2953
|
+
view,
|
|
2954
|
+
context,
|
|
2955
|
+
jumpPage,
|
|
2956
|
+
prevPage,
|
|
2957
|
+
nextPage,
|
|
2958
|
+
jumpPageAsync,
|
|
2959
|
+
prevPageAsync,
|
|
2960
|
+
nextPageAsync,
|
|
2961
|
+
pageState,
|
|
2962
|
+
toPdf,
|
|
2963
|
+
log,
|
|
2964
|
+
setDocsViewReadonly,
|
|
2965
|
+
setReadonly,
|
|
2966
|
+
moveCamera,
|
|
2967
|
+
getOriginScale,
|
|
2968
|
+
getScale,
|
|
2969
|
+
getPageSize,
|
|
2970
|
+
screenshotCurrentPageAsync
|
|
2971
|
+
};
|
|
2972
|
+
dispose2.add(
|
|
2973
|
+
listen(
|
|
2974
|
+
window,
|
|
2975
|
+
"message",
|
|
2976
|
+
(ev) => {
|
|
2977
|
+
if (ev.data === "@netless/_presentation_") {
|
|
2978
|
+
if (typeof window !== "undefined")
|
|
2979
|
+
dispose2.make(() => {
|
|
2980
|
+
const debug = window._presentation_ || (window._presentation_ = /* @__PURE__ */ new Set());
|
|
2981
|
+
debug.add(controller);
|
|
2982
|
+
return () => debug.delete(controller);
|
|
2983
|
+
});
|
|
2984
|
+
console.log(controller);
|
|
2985
|
+
}
|
|
2986
|
+
}
|
|
2987
|
+
)
|
|
2988
|
+
);
|
|
2989
|
+
const setupReadyTimeout = (_d = options.setupReadyTimeout) != null ? _d : DEFAULT_SETUP_READY_TIMEOUT;
|
|
2990
|
+
return prepareScenesPromise.then(async () => {
|
|
2991
|
+
const loaded = await waitForCurrentPageImage(view, setupReadyTimeout, () => disposed);
|
|
2992
|
+
if (!loaded) {
|
|
2993
|
+
warn(`[Presentation] setup ready wait timed out after ${setupReadyTimeout}ms`);
|
|
2994
|
+
}
|
|
2995
|
+
return controller;
|
|
2996
|
+
});
|
|
2997
|
+
},
|
|
2998
|
+
teardown(context) {
|
|
2999
|
+
var _a;
|
|
3000
|
+
(_a = teardownByContext.get(context)) == null ? void 0 : _a();
|
|
3001
|
+
teardownByContext.delete(context);
|
|
2670
3002
|
}
|
|
2671
3003
|
};
|
|
2672
3004
|
var AppPresentation = class extends Presentation {
|
|
@@ -2686,19 +3018,29 @@ var AppPresentation = class extends Presentation {
|
|
|
2686
3018
|
if (0 <= index && index < this.pages.length) {
|
|
2687
3019
|
this.jumpPage(index);
|
|
2688
3020
|
} else {
|
|
2689
|
-
(_a = this.warn) == null ? void 0 : _a.call(
|
|
3021
|
+
(_a = this.warn) == null ? void 0 : _a.call(
|
|
3022
|
+
this,
|
|
3023
|
+
`[Presentation]: page index ${index} out of bounds [0, ${this.pages.length - 1}]`
|
|
3024
|
+
);
|
|
2690
3025
|
}
|
|
2691
3026
|
}
|
|
2692
3027
|
};
|
|
2693
3028
|
function createPresentation(box, pages, jumpPage, pageIndex$, view, thumbnail, useClipView) {
|
|
2694
3029
|
box.mountStyles(style_default);
|
|
2695
|
-
const app = new AppPresentation({
|
|
3030
|
+
const app = new AppPresentation({
|
|
3031
|
+
pages,
|
|
3032
|
+
readonly: box.readonly,
|
|
3033
|
+
jumpPage,
|
|
3034
|
+
thumbnail
|
|
3035
|
+
});
|
|
2696
3036
|
app.box = box;
|
|
2697
3037
|
box.mountContent(app.contentDOM);
|
|
2698
3038
|
box.mountFooter(app.footerDOM);
|
|
2699
|
-
app.dispose.add(
|
|
2700
|
-
|
|
2701
|
-
|
|
3039
|
+
app.dispose.add(
|
|
3040
|
+
pageIndex$.subscribe((pageIndex) => {
|
|
3041
|
+
app.setPageIndex(pageIndex);
|
|
3042
|
+
})
|
|
3043
|
+
);
|
|
2702
3044
|
if (useClipView && view) {
|
|
2703
3045
|
const onCameraUpdatedEffectForMaskView = (0, import_debounce2.default)(() => {
|
|
2704
3046
|
const { width: pageWidth, height: pageHeight } = app.page() || {};
|
|
@@ -2707,8 +3049,12 @@ function createPresentation(box, pages, jumpPage, pageIndex$, view, thumbnail, u
|
|
|
2707
3049
|
}
|
|
2708
3050
|
const { scale } = view.camera;
|
|
2709
3051
|
const { width, height } = view.size;
|
|
2710
|
-
const pageRatioX = Math.round(
|
|
2711
|
-
|
|
3052
|
+
const pageRatioX = Math.round(
|
|
3053
|
+
(1 - pageWidth * scale / width) / 2 * 100
|
|
3054
|
+
);
|
|
3055
|
+
const pageRatioY = Math.round(
|
|
3056
|
+
(1 - pageHeight * scale / height) / 2 * 100
|
|
3057
|
+
);
|
|
2712
3058
|
app.whiteboardDOM.style.clipPath = `inset(${pageRatioY}% ${pageRatioX}%)`;
|
|
2713
3059
|
}, 50);
|
|
2714
3060
|
onCameraUpdatedEffectForMaskView();
|
|
@@ -2733,7 +3079,7 @@ var install = (register, options = {}) => {
|
|
|
2733
3079
|
};
|
|
2734
3080
|
|
|
2735
3081
|
// src/index.ts
|
|
2736
|
-
var version = "0.1.
|
|
3082
|
+
var version = "0.1.13-beta.1";
|
|
2737
3083
|
|
|
2738
3084
|
export { NetlessAppPresentation, Presentation, Scrollbar, NetlessAppPresentation as default, install, version };
|
|
2739
3085
|
//# sourceMappingURL=index.mjs.map
|