@netless/app-presentation 0.1.13-beta.3 → 0.1.13

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.mjs CHANGED
@@ -1301,6 +1301,7 @@ var Presentation = class {
1301
1301
  var _a;
1302
1302
  this.pages = config.pages;
1303
1303
  this.preload = new Preload(this.pages);
1304
+ this.onThumbnailError = config.onThumbnailError;
1304
1305
  if (config.thumbnail)
1305
1306
  this.thumbnail = config.thumbnail;
1306
1307
  this.dispose.add(this.preload);
@@ -1516,12 +1517,16 @@ var Presentation = class {
1516
1517
  }
1517
1518
  /** Returns a modified URL that points to the thumbnail image. */
1518
1519
  thumbnail(src) {
1520
+ var _a;
1519
1521
  try {
1520
1522
  const url = new URL(src);
1521
1523
  url.searchParams.set("x-oss-process", "image/resize,l_50");
1522
1524
  return url.toString();
1523
1525
  } catch (err) {
1524
- console.error(err);
1526
+ try {
1527
+ (_a = this.onThumbnailError) == null ? void 0 : _a.call(this, err);
1528
+ } catch (e) {
1529
+ }
1525
1530
  return src;
1526
1531
  }
1527
1532
  }
@@ -2013,9 +2018,10 @@ var createPresentationRuntimeTeardown = (box, dispose2) => {
2013
2018
  };
2014
2019
 
2015
2020
  // src/setup-ready.ts
2016
- var waitForCurrentPageImage = (getImage, timeoutMs, isDisposed) => {
2021
+ var waitForCurrentPageImage = (getImage, timeoutMs, isDisposed, options) => {
2017
2022
  return new Promise((resolve) => {
2018
2023
  let settled = false;
2024
+ let timedOut = false;
2019
2025
  let pollTimer;
2020
2026
  const settle = (result) => {
2021
2027
  if (settled)
@@ -2026,13 +2032,22 @@ var waitForCurrentPageImage = (getImage, timeoutMs, isDisposed) => {
2026
2032
  window.clearInterval(pollTimer);
2027
2033
  resolve(result);
2028
2034
  };
2029
- const timeoutTimer = window.setTimeout(() => settle("timeout"), timeoutMs);
2035
+ const timeoutTimer = window.setTimeout(() => {
2036
+ timedOut = true;
2037
+ options == null ? void 0 : options.onTimeout();
2038
+ if (!(options == null ? void 0 : options.waitForReady()))
2039
+ settle("timeout");
2040
+ }, timeoutMs);
2030
2041
  const check = () => {
2031
2042
  var _a, _b;
2032
2043
  if (isDisposed()) {
2033
2044
  settle("disposed");
2034
2045
  return;
2035
2046
  }
2047
+ if (timedOut && !(options == null ? void 0 : options.waitForReady())) {
2048
+ settle("timeout");
2049
+ return;
2050
+ }
2036
2051
  const img = getImage();
2037
2052
  if (img == null ? void 0 : img.complete) {
2038
2053
  if (img.naturalWidth > 0) {
@@ -2106,7 +2121,21 @@ var setupBlurThumbnailDegradation = (config) => {
2106
2121
  const box = context.getBox();
2107
2122
  const boxBlurClass = box.wrapClassName("blur");
2108
2123
  let blurEpisode = false;
2109
- let reDegradeEnabled = false;
2124
+ let failedThumbnailPageIndex = null;
2125
+ const canReDegrade = () => blurEpisode && failedThumbnailPageIndex !== pageIndex$.value;
2126
+ let previewSuspended = false;
2127
+ let appliedFocusState = true;
2128
+ let logicalFocused = true;
2129
+ const activityBlocked = () => {
2130
+ var _a, _b;
2131
+ const wm = context.getWindowManager();
2132
+ if ((wm == null ? void 0 : wm.lazySetupInMaximizedMode) !== true)
2133
+ return false;
2134
+ const host = (_a = context.getRuntimeActivity) == null ? void 0 : _a.call(context);
2135
+ if (host)
2136
+ return document.visibilityState === "hidden" || !host.active;
2137
+ return document.visibilityState === "hidden" || wm.boxState === "minimized" || ((_b = wm.attributes) == null ? void 0 : _b.minimized) === true || context.getBoxStatus() === "minimized";
2138
+ };
2110
2139
  let boxBlurred = box.$box.classList.contains(boxBlurClass);
2111
2140
  const setBackgroundSuspended = (suspended) => {
2112
2141
  app.whiteboardDOM.classList.toggle(
@@ -2121,7 +2150,7 @@ var setupBlurThumbnailDegradation = (config) => {
2121
2150
  const thumbnailURL = page.thumbnail;
2122
2151
  const img = findBackgroundImage(view);
2123
2152
  if (!thumbnailURL || !hasUsableThumbnail(page)) {
2124
- if (boxBlurred) {
2153
+ if (boxBlurred || activityBlocked()) {
2125
2154
  setBackgroundSuspended(true);
2126
2155
  if (img && resolveImageUrl(img.src) !== resolveImageUrl(TRANSPARENT_BACKGROUND)) {
2127
2156
  img.src = TRANSPARENT_BACKGROUND;
@@ -2143,11 +2172,14 @@ var setupBlurThumbnailDegradation = (config) => {
2143
2172
  setBackgroundSuspended(false);
2144
2173
  };
2145
2174
  const suspendCachedResources = () => {
2146
- if (!blurEpisode || !boxBlurred)
2175
+ if (!blurEpisode || !boxBlurred && !activityBlocked())
2147
2176
  return;
2148
- app.suspendPreviewResources();
2177
+ if (!previewSuspended) {
2178
+ previewSuspended = true;
2179
+ app.suspendPreviewResources();
2180
+ }
2149
2181
  const page = pages[pageIndex$.value];
2150
- if (!page || !hasUsableThumbnail(page) || reDegradeEnabled) {
2182
+ if (!page || !hasUsableThumbnail(page) || canReDegrade()) {
2151
2183
  degrade();
2152
2184
  }
2153
2185
  };
@@ -2155,7 +2187,8 @@ var setupBlurThumbnailDegradation = (config) => {
2155
2187
  if (!blurEpisode)
2156
2188
  return;
2157
2189
  blurEpisode = false;
2158
- reDegradeEnabled = false;
2190
+ failedThumbnailPageIndex = null;
2191
+ previewSuspended = false;
2159
2192
  restore2();
2160
2193
  app.preload.resume(pageIndex$.value);
2161
2194
  };
@@ -2173,40 +2206,57 @@ var setupBlurThumbnailDegradation = (config) => {
2173
2206
  return !!(el && el.contains(target));
2174
2207
  };
2175
2208
  const onImgLoad = (ev) => {
2176
- if (!blurEpisode || !reDegradeEnabled)
2209
+ if (!canReDegrade())
2177
2210
  return;
2178
2211
  if (!ownsTarget(ev.target))
2179
2212
  return;
2180
2213
  degrade();
2181
2214
  };
2182
2215
  const onImgError = (ev) => {
2183
- if (!blurEpisode || !reDegradeEnabled)
2216
+ var _a;
2217
+ if (!canReDegrade())
2184
2218
  return;
2185
2219
  if (!ownsTarget(ev.target))
2186
2220
  return;
2187
- reDegradeEnabled = false;
2221
+ const thumbnailURL = (_a = pages[pageIndex$.value]) == null ? void 0 : _a.thumbnail;
2222
+ if (thumbnailURL && resolveImageUrl(ev.target.src) === resolveImageUrl(thumbnailURL)) {
2223
+ failedThumbnailPageIndex = pageIndex$.value;
2224
+ }
2188
2225
  };
2189
- const offFocus = context.emitter.on("focus", (isFocused) => {
2226
+ const applyActivity = () => {
2227
+ var _a;
2228
+ const lazy = ((_a = context.getWindowManager()) == null ? void 0 : _a.lazySetupInMaximizedMode) === true;
2229
+ const isFocused = (!lazy || logicalFocused) && !activityBlocked();
2230
+ if (appliedFocusState === isFocused)
2231
+ return;
2232
+ if (!isFocused && !isBlurDegradationAllowed(context) && !activityBlocked())
2233
+ return;
2190
2234
  if (isFocused) {
2191
2235
  restoreFocusedResources();
2192
2236
  } else {
2193
- if (!isBlurDegradationAllowed(context))
2194
- return;
2195
2237
  blurEpisode = true;
2196
- reDegradeEnabled = true;
2238
+ failedThumbnailPageIndex = null;
2197
2239
  degrade();
2198
2240
  app.preload.pause();
2199
2241
  suspendCachedResources();
2200
2242
  }
2243
+ appliedFocusState = isFocused;
2244
+ };
2245
+ const offFocus = context.emitter.on("focus", (isFocused) => {
2246
+ logicalFocused = isFocused;
2247
+ applyActivity();
2201
2248
  });
2202
2249
  dispose2.add(offFocus);
2250
+ dispose2.add(context.emitter.on("runtimeActivity", applyActivity));
2251
+ document.addEventListener("visibilitychange", applyActivity);
2252
+ dispose2.add(() => document.removeEventListener("visibilitychange", applyActivity));
2203
2253
  const updateBoxBlurred = (blurred) => {
2204
2254
  if (boxBlurred === blurred)
2205
2255
  return;
2206
2256
  boxBlurred = blurred;
2207
2257
  if (blurred)
2208
2258
  suspendCachedResources();
2209
- else
2259
+ else if (logicalFocused && !activityBlocked())
2210
2260
  restoreFocusedResources();
2211
2261
  };
2212
2262
  const onBoxBlur = () => updateBoxBlurred(true);
@@ -2232,26 +2282,21 @@ var setupBlurThumbnailDegradation = (config) => {
2232
2282
  document.removeEventListener("error", onImgError, true);
2233
2283
  });
2234
2284
  };
2235
- var createLogger = (room) => {
2236
- if (room && room.logger) {
2237
- return (...args) => room.logger.info(...args);
2238
- } else {
2239
- return (...args) => console.log(...args);
2240
- }
2285
+ var getLogger = (context) => {
2286
+ var _a, _b, _c;
2287
+ return (_c = (_a = context.getWindowManager()) == null ? void 0 : _a.Logger) != null ? _c : (_b = context.getRoom()) == null ? void 0 : _b.logger;
2288
+ };
2289
+ var createLogger = (context) => {
2290
+ return (...args) => {
2291
+ var _a, _b;
2292
+ return (_b = (_a = getLogger(context)) == null ? void 0 : _a.info) == null ? void 0 : _b.call(_a, ...args);
2293
+ };
2241
2294
  };
2242
2295
  var createDiagnosticLogger = (context) => {
2243
- var _a;
2244
- const createAppLogger = context.createLogger;
2245
- if (typeof createAppLogger === "function") {
2246
- return createAppLogger.call(context, "camera", {
2247
- debounceTime: 300,
2248
- maxWaitTime: 2e3
2249
- });
2250
- }
2251
- const roomLogger = (_a = context.getRoom()) == null ? void 0 : _a.logger;
2252
2296
  const prefix = `[Presentation][${context.appId}][camera]`;
2253
2297
  const emit = (level, event, ...data) => {
2254
2298
  try {
2299
+ const roomLogger = getLogger(context);
2255
2300
  const printer = roomLogger == null ? void 0 : roomLogger[level];
2256
2301
  if (typeof printer === "function")
2257
2302
  printer.call(roomLogger, `${prefix}[${event}]`, ...data);
@@ -2316,9 +2361,11 @@ var NetlessAppPresentation = {
2316
2361
  );
2317
2362
  const options = context.getAppOptions() || {};
2318
2363
  const room = context.getRoom();
2319
- const log = options.log || createLogger(room);
2320
- const roomLogger = room == null ? void 0 : room.logger;
2321
- const warn = (...data) => (roomLogger == null ? void 0 : roomLogger.warn) ? roomLogger.warn(...data) : log(...data);
2364
+ const log = options.log || createLogger(context);
2365
+ const warn = (...data) => {
2366
+ var _a2, _b2;
2367
+ return (_b2 = (_a2 = getLogger(context)) == null ? void 0 : _a2.warn) == null ? void 0 : _b2.call(_a2, ...data);
2368
+ };
2322
2369
  const configuredOriginSize = context.storage.state.originSize;
2323
2370
  const originSize = isValidSize(configuredOriginSize) ? {
2324
2371
  width: configuredOriginSize.width,
@@ -2650,10 +2697,14 @@ var NetlessAppPresentation = {
2650
2697
  pageIndex$,
2651
2698
  view,
2652
2699
  options.thumbnail,
2653
- options.useClipView
2700
+ options.useClipView,
2701
+ (error) => {
2702
+ var _a2, _b2;
2703
+ return (_b2 = (_a2 = getLogger(context)) == null ? void 0 : _a2.error) == null ? void 0 : _b2.call(_a2, "[Presentation] thumbnail URL parsing failed", context.appId, error);
2704
+ }
2654
2705
  )
2655
2706
  );
2656
- app.contentDOM.dataset.appPresentationVersion = "0.1.13-beta.3";
2707
+ app.contentDOM.dataset.appPresentationVersion = "0.1.13";
2657
2708
  app.scaleDocsToFit = scaleDocsToFit;
2658
2709
  app.log = log;
2659
2710
  app.warn = warn;
@@ -3125,11 +3176,15 @@ var NetlessAppPresentation = {
3125
3176
  const result = await waitForCurrentPageImage(
3126
3177
  () => findBackgroundImage(view),
3127
3178
  setupReadyTimeout,
3128
- () => disposed
3179
+ () => disposed,
3180
+ {
3181
+ waitForReady: () => Boolean(context.waitForActualSetupReady),
3182
+ onTimeout: () => warn(`[Presentation] setup page image still pending after ${setupReadyTimeout}ms`)
3183
+ }
3129
3184
  );
3130
- if (result === "timeout" && !disposed) {
3131
- warn(`[Presentation] setup ready wait timed out after ${setupReadyTimeout}ms`);
3132
- } else if (result === "error" && !disposed) {
3185
+ if (disposed)
3186
+ throw new Error("[Presentation] disposed before setup ready");
3187
+ if (result === "error") {
3133
3188
  warn("[Presentation] setup page image failed to load; continuing setup");
3134
3189
  }
3135
3190
  return controller;
@@ -3165,13 +3220,14 @@ var AppPresentation = class extends Presentation {
3165
3220
  }
3166
3221
  }
3167
3222
  };
3168
- function createPresentation(box, pages, jumpPage, pageIndex$, view, thumbnail, useClipView) {
3223
+ function createPresentation(box, pages, jumpPage, pageIndex$, view, thumbnail, useClipView, onThumbnailError) {
3169
3224
  box.mountStyles(style_default);
3170
3225
  const app = new AppPresentation({
3171
3226
  pages,
3172
3227
  readonly: box.readonly,
3173
3228
  jumpPage,
3174
- thumbnail
3229
+ thumbnail,
3230
+ onThumbnailError
3175
3231
  });
3176
3232
  app.box = box;
3177
3233
  box.mountContent(app.contentDOM);
@@ -3219,7 +3275,7 @@ var install = (register, options = {}) => {
3219
3275
  };
3220
3276
 
3221
3277
  // src/index.ts
3222
- var version = "0.1.13-beta.3";
3278
+ var version = "0.1.13";
3223
3279
 
3224
- export { NetlessAppPresentation, Presentation, Scrollbar, NetlessAppPresentation as default, install, setupBlurThumbnailDegradation, version };
3280
+ export { NetlessAppPresentation, Presentation, Scrollbar, createDiagnosticLogger, NetlessAppPresentation as default, install, setupBlurThumbnailDegradation, version };
3225
3281
  //# sourceMappingURL=index.mjs.map