@netless/app-slide 0.0.56 → 0.0.57

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/typings.d.ts CHANGED
@@ -12,3 +12,8 @@ export declare type MagixPayload = {
12
12
  type: typeof SLIDE_EVENTS.syncDispatch;
13
13
  payload: SyncEvent;
14
14
  };
15
+ export declare type MagixEvents = {
16
+ [SLIDE_EVENTS.syncDispatch]: MagixPayload;
17
+ };
18
+ export interface A {
19
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netless/app-slide",
3
- "version": "0.0.56",
3
+ "version": "0.0.57",
4
4
  "main": "dist/main.cjs.js",
5
5
  "module": "dist/main.es.js",
6
6
  "types": "dist/index.d.ts",
@@ -11,7 +11,7 @@
11
11
  ],
12
12
  "devDependencies": {
13
13
  "@netless/app-shared": "^0.1.1",
14
- "@netless/slide": "^0.2.3",
14
+ "@netless/slide": "^0.2.7",
15
15
  "@types/color-string": "^1.5.2",
16
16
  "color-string": "^1.9.0",
17
17
  "side-effect-manager": "^0.1.5",
@@ -8,10 +8,9 @@
8
8
  // 4. automatically re-create scenes to sync strokes, a view must be existing
9
9
  // 5. pages information are loaded dynamically by the slide package
10
10
 
11
- import type { Event as MagixEvent } from "white-web-sdk";
12
11
  import type { AppContext, Player, Room } from "@netless/window-manager";
13
12
  import type { SyncEvent } from "@netless/slide";
14
- import type { Attributes, MagixPayload, SlideState } from "../typings";
13
+ import type { Attributes, MagixEvents, MagixPayload, SlideState } from "../typings";
15
14
 
16
15
  import { SideEffectManager } from "side-effect-manager";
17
16
  import { Slide, SLIDE_EVENTS } from "@netless/slide";
@@ -29,7 +28,7 @@ export const EmptyAttributes: Attributes = {
29
28
  };
30
29
 
31
30
  export interface SlideControllerOptions {
32
- context: AppContext<Attributes>;
31
+ context: AppContext<Attributes, MagixEvents>;
33
32
  anchor: HTMLDivElement;
34
33
  onPageChanged: (page: number) => void;
35
34
  onTransitionStart: () => void;
@@ -37,11 +36,14 @@ export interface SlideControllerOptions {
37
36
  onError: (args: { error: Error }) => void;
38
37
  }
39
38
 
39
+ type MagixEventListener = Parameters<
40
+ AppContext<Attributes, MagixEvents>["addMagixEventListener"]
41
+ >[1];
42
+
40
43
  export class SlideController {
41
44
  public readonly context: SlideControllerOptions["context"];
42
45
  public readonly slide: Slide;
43
46
 
44
- private readonly channel: string;
45
47
  private readonly room?: Room;
46
48
  private readonly player?: Player;
47
49
  private readonly sideEffect = new SideEffectManager();
@@ -66,7 +68,6 @@ export class SlideController {
66
68
  this.onTransitionEnd = onTransitionEnd;
67
69
  this.onError = onError;
68
70
  this.context = context;
69
- this.channel = `channel-${context.appId}`;
70
71
  this.room = context.getRoom();
71
72
  this.player = this.room ? undefined : (context.getDisplayer() as Player);
72
73
  this.slide = this.createSlide(anchor);
@@ -137,20 +138,11 @@ export class SlideController {
137
138
  return disposer;
138
139
  });
139
140
 
140
- this.sideEffect.add(() => {
141
- context.emitter.on("seek", this.onSeeked);
142
- return () => context.emitter.off("seek", this.onSeeked);
143
- });
144
-
145
- this.sideEffect.add(() => {
146
- const displayer = context.getDisplayer();
147
- displayer.addMagixEventListener(this.channel, this.magixEventListener, {
141
+ this.sideEffect.add(() =>
142
+ context.addMagixEventListener(SLIDE_EVENTS.syncDispatch, this.magixEventListener, {
148
143
  fireSelfEventAfterCommit: true,
149
- });
150
- // here we do not pass second param -- the listener
151
- // because channel name is already unique, just make it simpler
152
- return () => displayer.removeMagixEventListener(this.channel);
153
- });
144
+ })
145
+ );
154
146
 
155
147
  slide.on(SLIDE_EVENTS.slideChange, this.onPageChanged);
156
148
  slide.on(SLIDE_EVENTS.renderStart, this.onTransitionStart);
@@ -171,12 +163,12 @@ export class SlideController {
171
163
  payload: event,
172
164
  };
173
165
  log("[Slide] dispatch", event);
174
- this.room.dispatchMagixEvent(this.channel, payload);
166
+ this.context.dispatchMagixEvent(SLIDE_EVENTS.syncDispatch, payload);
175
167
  }
176
168
  };
177
169
 
178
- private magixEventListener = (ev: MagixEvent) => {
179
- if (ev.event === this.channel && isObj(ev.payload)) {
170
+ private magixEventListener: MagixEventListener = ev => {
171
+ if (ev.event === SLIDE_EVENTS.syncDispatch && isObj(ev.payload)) {
180
172
  const { type, payload } = ev.payload as MagixPayload;
181
173
  if (type === SLIDE_EVENTS.syncDispatch) {
182
174
  this.syncStateOnce();
@@ -189,7 +181,7 @@ export class SlideController {
189
181
  private syncStateOnce() {
190
182
  // sync state before the first event, so that they can be in the correct order
191
183
  if (this.syncStateOnceFlag) {
192
- const { state } = { ...EmptyAttributes, ...this.context.getAttributes() };
184
+ const { state } = { ...EmptyAttributes, ...this.context.storage.state };
193
185
  if (state) {
194
186
  log("[Slide] sync with state (once)", deepClone(state));
195
187
  this.slide.setSlideState(deepClone(state));
@@ -201,15 +193,7 @@ export class SlideController {
201
193
  private onStateChange = (state: SlideState) => {
202
194
  if (this.context.getIsWritable()) {
203
195
  verbose("[Slide] state change", JSON.stringify(state, null, 2));
204
- this.context.updateAttributes(["state"], state);
205
- }
206
- };
207
-
208
- private onSeeked = () => {
209
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
210
- const state = this.context.getAttributes()!.state;
211
- if (state) {
212
- this.slide.setSlideState(deepClone(state));
196
+ this.context.storage.setState({ state });
213
197
  }
214
198
  };
215
199
 
package/src/index.ts CHANGED
@@ -1,12 +1,11 @@
1
1
  import type { NetlessApp } from "@netless/window-manager";
2
2
  import type { RoomState } from "white-web-sdk";
3
+ import type { Slide } from "@netless/slide";
3
4
  import type { MountSlideOptions } from "./SlideDocsViewer";
4
- import type { Attributes } from "./typings";
5
+ import type { Attributes, MagixEvents } from "./typings";
5
6
  import type { AddHooks, FreezableSlide } from "./utils/freezer";
6
- import { useFreezer } from "./utils/freezer";
7
7
 
8
8
  import { SideEffectManager } from "side-effect-manager";
9
- import { ensureAttributes } from "@netless/app-shared";
10
9
  import {
11
10
  DefaultUrl,
12
11
  EmptyAttributes,
@@ -14,7 +13,7 @@ import {
14
13
  SlideController,
15
14
  } from "./SlideController";
16
15
  import { SlideDocsViewer } from "./SlideDocsViewer";
17
- import { apps, FreezerLength, addHooks } from "./utils/freezer";
16
+ import { apps, FreezerLength, addHooks, useFreezer } from "./utils/freezer";
18
17
  import { log, logger } from "./utils/logger";
19
18
  import styles from "./style.scss?inline";
20
19
 
@@ -27,17 +26,31 @@ export const version = __APP_VERSION__;
27
26
 
28
27
  export { DefaultUrl, apps, FreezerLength, addHooks };
29
28
 
30
- const SlideApp: NetlessApp<Attributes> = {
29
+ export interface AppOptions {
30
+ debug?: boolean;
31
+ resolution?: number;
32
+ bgColor?: string;
33
+ }
34
+
35
+ export interface Controller {
36
+ slide: () => Slide | undefined;
37
+ position: () => [page: number, pageCount: number] | undefined;
38
+ nextStep: () => boolean;
39
+ prevStep: () => boolean;
40
+ nextPage: () => boolean;
41
+ prevPage: () => boolean;
42
+ }
43
+
44
+ const SlideApp: NetlessApp<Attributes, MagixEvents, AppOptions, Controller> = {
31
45
  kind: "Slide",
32
46
  setup(context) {
33
47
  console.log("[Slide] setup @ " + version);
34
48
 
35
49
  if (context.getIsWritable()) {
36
- ensureAttributes(context, EmptyAttributes);
50
+ context.storage.ensureState(EmptyAttributes);
37
51
  }
38
52
 
39
- const attributes = context.getAttributes();
40
- if (!attributes?.taskId) {
53
+ if (!context.storage.state.taskId) {
41
54
  throw new Error("[Slide] no taskId");
42
55
  }
43
56
 
@@ -143,6 +156,54 @@ const SlideApp: NetlessApp<Attributes> = {
143
156
  });
144
157
 
145
158
  docsViewer.mount();
159
+
160
+ return {
161
+ slide: () => {
162
+ return docsViewer?.slideController?.slide;
163
+ },
164
+ nextStep: () => {
165
+ if (docsViewer && docsViewer.slideController) {
166
+ docsViewer?.slideController?.slide.nextStep();
167
+ return true;
168
+ }
169
+ return false;
170
+ },
171
+ prevStep: () => {
172
+ if (docsViewer && docsViewer.slideController) {
173
+ docsViewer?.slideController?.slide.prevStep();
174
+ return true;
175
+ }
176
+ return false;
177
+ },
178
+ position: () => {
179
+ const controller = docsViewer?.slideController;
180
+ if (controller) {
181
+ return [controller.page, controller.pageCount] as [page: number, pageCount: number];
182
+ }
183
+ },
184
+ nextPage: () => {
185
+ const controller = docsViewer?.slideController;
186
+ if (controller) {
187
+ const { page, pageCount } = controller;
188
+ if (pageCount > 0 && page < pageCount) {
189
+ controller.jumpToPage(page + 1);
190
+ return true;
191
+ }
192
+ }
193
+ return false;
194
+ },
195
+ prevPage: () => {
196
+ const controller = docsViewer?.slideController;
197
+ if (controller) {
198
+ const { page, pageCount } = controller;
199
+ if (pageCount > 0 && page > 1) {
200
+ controller.jumpToPage(page - 1);
201
+ return true;
202
+ }
203
+ }
204
+ return false;
205
+ },
206
+ };
146
207
  },
147
208
  };
148
209
 
package/src/typings.ts CHANGED
@@ -15,3 +15,9 @@ export type MagixPayload = {
15
15
  type: typeof SLIDE_EVENTS.syncDispatch;
16
16
  payload: SyncEvent;
17
17
  };
18
+
19
+ export type MagixEvents = {
20
+ [SLIDE_EVENTS.syncDispatch]: MagixPayload;
21
+ };
22
+
23
+ export interface A {}