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