@netless/app-slide 0.2.17 → 0.2.18

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.
@@ -4,7 +4,10 @@ export interface FreezableSlide {
4
4
  unfreeze: () => void;
5
5
  }
6
6
  export declare let useFreezer: boolean;
7
- export declare const FreezerLength = 2;
7
+ export declare let FreezerLength: number;
8
+ export declare function getFreezerLength(): number;
9
+ /** @param length - must be >= 1, default is 2 */
10
+ export declare function setFreezerLength(length: number): void;
8
11
  export declare const apps: {
9
12
  map: Map<string, FreezableSlide>;
10
13
  boxes: Map<string, ReadonlyTeleBox>;
@@ -14,10 +17,12 @@ export declare const apps: {
14
17
  delete(appId: string): void;
15
18
  focus(appId: string): void;
16
19
  };
20
+ export declare function onCreated(callback: (appId: string) => void): () => boolean;
21
+ export declare function onDestroyed(callback: (appId: string) => void): () => boolean;
17
22
  export declare type AddHooks = NonNullable<RegisterParams["addHooks"]>;
18
23
  /**
19
24
  * Put this function in your register code:
20
- * `WindowManager.register({ addHooks })`
25
+ * `WindowManager.register({ kind: 'Slide', src: SlideApp, addHooks })`
21
26
  * So that it will automatically freeze the app when it is not in focus.
22
27
  */
23
28
  export declare const addHooks: AddHooks;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netless/app-slide",
3
- "version": "0.2.17",
3
+ "version": "0.2.18",
4
4
  "main": "dist/main.cjs.js",
5
5
  "module": "dist/main.es.js",
6
6
  "types": "dist/index.d.ts",
@@ -10,7 +10,7 @@
10
10
  "README-zh.md"
11
11
  ],
12
12
  "devDependencies": {
13
- "@netless/slide": "^0.7.7",
13
+ "@netless/slide": "^0.7.8",
14
14
  "@types/color-string": "^1.5.2",
15
15
  "color-string": "^1.9.1",
16
16
  "side-effect-manager": "^1.2.1",
@@ -35,7 +35,9 @@ export interface SlideControllerOptions {
35
35
  onPageChanged: (page: number) => void;
36
36
  onTransitionStart: () => void;
37
37
  onTransitionEnd: () => void;
38
- onError: (args: { error: Error }) => void;
38
+ onError: (args: { error: Error; index: number }) => void;
39
+ onRenderError?: (error: Error, pageIndex: number) => void;
40
+ showRenderError?: boolean;
39
41
  }
40
42
 
41
43
  type MagixEventListener = Parameters<
@@ -45,6 +47,8 @@ type MagixEventListener = Parameters<
45
47
  export class SlideController {
46
48
  public readonly context: SlideControllerOptions["context"];
47
49
  public readonly slide: Slide;
50
+ public readonly showRenderError: boolean;
51
+ public readonly onRenderError?: (error: Error, pageIndex: number) => void;
48
52
 
49
53
  private readonly room?: Room;
50
54
  private readonly player?: Player;
@@ -67,11 +71,15 @@ export class SlideController {
67
71
  onTransitionStart,
68
72
  onTransitionEnd,
69
73
  onError,
74
+ onRenderError,
75
+ showRenderError,
70
76
  }: SlideControllerOptions) {
71
77
  this.onPageChanged = onPageChanged;
72
78
  this.onTransitionStart = onTransitionStart;
73
79
  this.onTransitionEnd = onTransitionEnd;
74
80
  this.onError = onError;
81
+ this.onRenderError = onRenderError;
82
+ this.showRenderError = showRenderError ?? true;
75
83
 
76
84
  this.context = context;
77
85
  this.room = context.getRoom();
@@ -130,10 +130,15 @@ export class SlideDocsViewer {
130
130
  return this;
131
131
  }
132
132
 
133
- protected onError = ({ error }: { error: Error }) => {
133
+ protected onError = ({ error, index }: { error: Error; index: number }) => {
134
134
  this.viewer.setPaused();
135
- this.$overlay.textContent = `Error on slide[page=${this.slideController?.page}]: ${error.message}`;
136
- this.$overlay.style.opacity = "1";
135
+ if (this.slideController?.showRenderError) {
136
+ this.$overlay.textContent = `Error on slide[page=${this.slideController.page}]: ${error.message}`;
137
+ this.$overlay.style.opacity = "1";
138
+ }
139
+ if (this.slideController?.onRenderError) {
140
+ this.slideController.onRenderError(error, index);
141
+ }
137
142
  logger.warn("[Slide] render error", error);
138
143
  };
139
144
 
@@ -20,6 +20,7 @@ $namespace: "netless-app-slide";
20
20
  left: 0;
21
21
  width: 100%;
22
22
  height: 100%;
23
+ padding: 8px;
23
24
  background: rgba(255, 0, 0, 0.25);
24
25
  transition: opacity 0.3s;
25
26
  opacity: 0;
package/src/index.ts CHANGED
@@ -30,6 +30,8 @@ export const version = __APP_VERSION__;
30
30
 
31
31
  export { DefaultUrl, apps, FreezerLength, addHooks };
32
32
 
33
+ export { setFreezerLength, getFreezerLength, onCreated, onDestroyed } from "./utils/freezer";
34
+
33
35
  export interface AppOptions
34
36
  extends Pick<
35
37
  ISlideConfig,
@@ -57,6 +59,10 @@ export interface AppOptions
57
59
  autoResolution?: boolean;
58
60
  /** 1~4, default: 3 */
59
61
  maxResolutionLevel?: number;
62
+ /** custom error handler */
63
+ onRenderError?: (error: Error, pageIndex: number) => void;
64
+ /** whether to show an overlay of error message @default: true */
65
+ showRenderError?: boolean;
60
66
  }
61
67
 
62
68
  export interface ILogger {
@@ -65,7 +71,9 @@ export interface ILogger {
65
71
  warn?(msg: string): void;
66
72
  }
67
73
 
68
- export interface Controller {
74
+ export interface AppResult {
75
+ viewer: () => SlideDocsViewer | null;
76
+ controller: () => SlideController | null | undefined;
69
77
  slide: () => Slide | undefined;
70
78
  position: () => [page: number, pageCount: number] | undefined;
71
79
  nextStep: () => boolean;
@@ -75,7 +83,7 @@ export interface Controller {
75
83
  jumpToPage: (page: number) => boolean;
76
84
  }
77
85
 
78
- const SlideApp: NetlessApp<Attributes, MagixEvents, AppOptions, Controller> = {
86
+ const SlideApp: NetlessApp<Attributes, MagixEvents, AppOptions, AppResult> = {
79
87
  kind: "Slide",
80
88
  setup(context) {
81
89
  console.log("[Slide] setup @ " + version);
@@ -121,10 +129,14 @@ const SlideApp: NetlessApp<Attributes, MagixEvents, AppOptions, Controller> = {
121
129
  };
122
130
 
123
131
  const mountSlideController = (options: MountSlideOptions): SlideController => {
132
+ const appOptions = context.getAppOptions() || {};
133
+
124
134
  const slideController = new SlideController({
125
135
  context,
126
136
  ...options,
127
137
  onPageChanged,
138
+ onRenderError: appOptions.onRenderError,
139
+ showRenderError: appOptions.showRenderError,
128
140
  });
129
141
  if (useFreezer) apps.set(context.appId, slideController, box);
130
142
  logger.setAppController(context.appId, slideController);
@@ -194,6 +206,12 @@ const SlideApp: NetlessApp<Attributes, MagixEvents, AppOptions, Controller> = {
194
206
  docsViewer.mount();
195
207
 
196
208
  return {
209
+ viewer: () => {
210
+ return docsViewer;
211
+ },
212
+ controller: () => {
213
+ return docsViewer?.slideController;
214
+ },
197
215
  slide: () => {
198
216
  return docsViewer?.slideController?.slide;
199
217
  },
@@ -7,7 +7,16 @@ export interface FreezableSlide {
7
7
  }
8
8
 
9
9
  export let useFreezer = false;
10
- export const FreezerLength = 2;
10
+ export let FreezerLength = 2;
11
+
12
+ export function getFreezerLength() {
13
+ return FreezerLength;
14
+ }
15
+
16
+ /** @param length - must be >= 1, default is 2 */
17
+ export function setFreezerLength(length: number) {
18
+ FreezerLength = length < 1 ? Infinity : length;
19
+ }
11
20
 
12
21
  const inspect = (arr: string[]) => {
13
22
  return "[" + arr + "]";
@@ -69,16 +78,39 @@ if (import.meta.env.DEV) {
69
78
  (window as any).freezer = apps;
70
79
  }
71
80
 
81
+ const on_created_callbacks = new Set<(appId: string) => void>();
82
+
83
+ export function onCreated(callback: (appId: string) => void) {
84
+ on_created_callbacks.add(callback);
85
+ return () => on_created_callbacks.delete(callback);
86
+ }
87
+
88
+ const on_destroyed_callbacks = new Set<(appId: string) => void>();
89
+
90
+ export function onDestroyed(callback: (appId: string) => void) {
91
+ on_destroyed_callbacks.add(callback);
92
+ return () => on_destroyed_callbacks.delete(callback);
93
+ }
94
+
72
95
  export type AddHooks = NonNullable<RegisterParams["addHooks"]>;
73
96
 
74
97
  /**
75
98
  * Put this function in your register code:
76
- * `WindowManager.register({ addHooks })`
99
+ * `WindowManager.register({ kind: 'Slide', src: SlideApp, addHooks })`
77
100
  * So that it will automatically freeze the app when it is not in focus.
78
101
  */
79
102
  export const addHooks: AddHooks = emitter => {
80
103
  useFreezer = true;
104
+
81
105
  emitter.on("focus", ({ appId }) => {
82
106
  apps.focus(appId);
83
107
  });
108
+
109
+ emitter.on("created", ({ appId }) => {
110
+ on_created_callbacks.forEach(callback => callback(appId));
111
+ });
112
+
113
+ emitter.on("destroy", ({ appId }) => {
114
+ on_destroyed_callbacks.forEach(callback => callback(appId));
115
+ });
84
116
  };