@netless/window-manager 0.4.0-canary.14 → 0.4.0-canary.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.
Files changed (49) hide show
  1. package/.vscode/settings.json +1 -0
  2. package/CHANGELOG.md +29 -1
  3. package/README.md +1 -0
  4. package/dist/AppListener.d.ts +1 -0
  5. package/dist/AppManager.d.ts +10 -7
  6. package/dist/AppProxy.d.ts +3 -2
  7. package/dist/AttributesDelegate.d.ts +2 -2
  8. package/dist/BoxManager.d.ts +5 -3
  9. package/dist/BuiltinApps.d.ts +0 -1
  10. package/dist/Cursor/Cursor.d.ts +8 -11
  11. package/dist/Cursor/index.d.ts +5 -15
  12. package/dist/Register/storage.d.ts +5 -1
  13. package/dist/Utils/Common.d.ts +4 -1
  14. package/dist/Utils/RoomHacker.d.ts +1 -1
  15. package/dist/View/MainView.d.ts +3 -2
  16. package/dist/constants.d.ts +3 -2
  17. package/dist/index.d.ts +16 -2
  18. package/dist/index.es.js +41 -1
  19. package/dist/index.es.js.map +1 -1
  20. package/dist/index.umd.js +41 -1
  21. package/dist/index.umd.js.map +1 -1
  22. package/dist/style.css +1 -1
  23. package/docs/api.md +36 -6
  24. package/docs/concept.md +9 -0
  25. package/package.json +5 -5
  26. package/src/AppContext.ts +1 -4
  27. package/src/AppListener.ts +14 -6
  28. package/src/AppManager.ts +96 -50
  29. package/src/AppProxy.ts +13 -8
  30. package/src/AttributesDelegate.ts +2 -2
  31. package/src/BoxManager.ts +33 -19
  32. package/src/BuiltinApps.ts +0 -1
  33. package/src/Cursor/Cursor.ts +22 -36
  34. package/src/Cursor/index.ts +33 -135
  35. package/src/Register/index.ts +25 -16
  36. package/src/Register/loader.ts +1 -1
  37. package/src/Register/storage.ts +6 -1
  38. package/src/Utils/Common.ts +32 -1
  39. package/src/Utils/RoomHacker.ts +28 -15
  40. package/src/View/MainView.ts +10 -11
  41. package/src/constants.ts +3 -2
  42. package/src/index.ts +61 -2
  43. package/src/shim.d.ts +2 -1
  44. package/src/style.css +1 -1
  45. package/vite.config.js +5 -2
  46. package/dist/Base/Context.d.ts +0 -12
  47. package/dist/Base/index.d.ts +0 -7
  48. package/src/Base/Context.ts +0 -45
  49. package/src/Base/index.ts +0 -10
@@ -1,6 +1,7 @@
1
1
  import { appRegister } from "../Register";
2
2
  import { debounce } from "lodash";
3
3
  import { emitter } from "../index";
4
+ import { ScenePathType } from "white-web-sdk";
4
5
  import { v4 } from "uuid";
5
6
  import type { PublicEvent } from "../index";
6
7
  import type { Displayer, ViewVisionMode, Room, View } from "white-web-sdk";
@@ -17,6 +18,14 @@ export const genAppId = async (kind: string) => {
17
18
  export const setViewFocusScenePath = (view: View, focusScenePath: string) => {
18
19
  if (view.focusScenePath !== focusScenePath) {
19
20
  view.focusScenePath = focusScenePath;
21
+ return view;
22
+ }
23
+ };
24
+
25
+ export const setViewSceneIndex = (view: View, index: number) => {
26
+ if (view.focusSceneIndex !== index) {
27
+ view.focusSceneIndex = index;
28
+ return view;
20
29
  }
21
30
  };
22
31
 
@@ -42,6 +51,15 @@ export const getScenePath = (
42
51
  }
43
52
  };
44
53
 
54
+ export const removeScenes = (room: Room | undefined, scenePath: string) => {
55
+ if (room) {
56
+ const type = room.scenePathType(scenePath);
57
+ if (type !== ScenePathType.None) {
58
+ room.removeScenes(scenePath);
59
+ }
60
+ }
61
+ };
62
+
45
63
  export const setViewMode = (view: View, mode: ViewVisionMode) => {
46
64
  if (!(view as any).didRelease && view.mode !== mode) {
47
65
  view.mode = mode;
@@ -70,7 +88,9 @@ export const notifyMainViewModeChange = debounce(
70
88
  export const makeValidScenePath = (displayer: Displayer, scenePath: string, index = 0) => {
71
89
  const scenes = entireScenes(displayer)[scenePath];
72
90
  if (!scenes) return;
73
- const firstSceneName = scenes[index].name;
91
+ const scene = scenes[index];
92
+ if (!scene) return;
93
+ const firstSceneName = scene.name;
74
94
  if (scenePath === "/") {
75
95
  return `/${firstSceneName}`;
76
96
  } else {
@@ -86,6 +106,17 @@ export const isValidScenePath = (scenePath: string) => {
86
106
  return scenePath.startsWith("/");
87
107
  };
88
108
 
109
+ export const parseSceneDir = (scenePath: string) => {
110
+ const sceneList = scenePath.split("/");
111
+ sceneList.pop();
112
+ let sceneDir = sceneList.join("/");
113
+ // "/page1" 的 dir 为 "/"
114
+ if (sceneDir === "") {
115
+ sceneDir = "/";
116
+ }
117
+ return sceneDir;
118
+ };
119
+
89
120
  export const ensureValidScenePath = (scenePath: string) => {
90
121
  if (scenePath.endsWith("/")) {
91
122
  return scenePath.slice(0, -1);
@@ -1,22 +1,13 @@
1
1
  import { emitter } from "../index";
2
2
  import { isPlayer } from "white-web-sdk";
3
- import type { WindowManager } from '../index';
4
- import type { Camera, Room , Player , PlayerSeekingResult } from "white-web-sdk";
3
+ import type { WindowManager } from "../index";
4
+ import type { Camera, Room, Player, PlayerSeekingResult } from "white-web-sdk";
5
5
 
6
6
  // 修改多窗口状态下一些失效的方法实现到 manager 的 mainview 上, 降低迁移成本
7
7
  export const replaceRoomFunction = (room: Room, manager: WindowManager) => {
8
8
  if (isPlayer(room)) {
9
9
  const player = room as unknown as Player;
10
- const originSeek = player.seekToProgressTime;
11
- // eslint-disable-next-line no-inner-declarations
12
- async function newSeek(time: number): Promise<PlayerSeekingResult> {
13
- const seekResult = await originSeek.call(player, time);
14
- if (seekResult === "success") {
15
- emitter.emit("seek", time);
16
- }
17
- return seekResult;
18
- }
19
- player.seekToProgressTime = newSeek;
10
+ delegateSeekToProgressTime(player);
20
11
  } else {
21
12
  const descriptor = Object.getOwnPropertyDescriptor(room, "disableCameraTransform");
22
13
  if (descriptor) return;
@@ -32,13 +23,13 @@ export const replaceRoomFunction = (room: Room, manager: WindowManager) => {
32
23
  Object.defineProperty(room, "canUndoSteps", {
33
24
  get() {
34
25
  return manager.mainView.canUndoSteps;
35
- }
26
+ },
36
27
  });
37
28
 
38
29
  Object.defineProperty(room, "canRedoSteps", {
39
30
  get() {
40
31
  return manager.mainView.canRedoSteps;
41
- }
32
+ },
42
33
  });
43
34
 
44
35
  room.moveCamera = (camera: Camera) => manager.mainView.moveCamera(camera);
@@ -52,6 +43,28 @@ export const replaceRoomFunction = (room: Room, manager: WindowManager) => {
52
43
  room.redo = () => manager.mainView.redo();
53
44
  room.undo = () => manager.mainView.undo();
54
45
  room.cleanCurrentScene = () => manager.mainView.cleanCurrentScene();
46
+ delegateRemoveScenes(room);
55
47
  }
48
+ };
56
49
 
57
- };
50
+ const delegateRemoveScenes = (room: Room) => {
51
+ const originRemoveScenes = room.removeScenes;
52
+ room.removeScenes = (scenePath: string) => {
53
+ const result = originRemoveScenes.call(room, scenePath);
54
+ emitter.emit("removeScenes", scenePath);
55
+ return result;
56
+ };
57
+ };
58
+
59
+ const delegateSeekToProgressTime = (player: Player) => {
60
+ const originSeek = player.seekToProgressTime;
61
+ // eslint-disable-next-line no-inner-declarations
62
+ async function newSeek(time: number): Promise<PlayerSeekingResult> {
63
+ const seekResult = await originSeek.call(player, time);
64
+ if (seekResult === "success") {
65
+ emitter.emit("seek", time);
66
+ }
67
+ return seekResult;
68
+ }
69
+ player.seekToProgressTime = newSeek;
70
+ };
@@ -1,5 +1,4 @@
1
1
  import { AnimationMode, reaction } from "white-web-sdk";
2
- import { Base } from "../Base";
3
2
  import { callbacks, emitter } from "../index";
4
3
  import { createView } from "./ViewManager";
5
4
  import { debounce, isEmpty, isEqual } from "lodash";
@@ -9,17 +8,17 @@ import { SideEffectManager } from "side-effect-manager";
9
8
  import type { Camera, Size, View } from "white-web-sdk";
10
9
  import type { AppManager } from "../AppManager";
11
10
 
12
- export class MainViewProxy extends Base {
11
+ export class MainViewProxy {
13
12
  private scale?: number;
14
13
  private started = false;
15
14
  private mainViewIsAddListener = false;
16
15
  private mainView: View;
17
16
  private viewId = "mainView";
17
+ private store = this.manager.store;
18
18
 
19
19
  private sideEffectManager = new SideEffectManager();
20
20
 
21
- constructor(manager: AppManager) {
22
- super(manager);
21
+ constructor(private manager: AppManager) {
23
22
  this.mainView = this.createMainView();
24
23
  this.moveCameraSizeByAttributes();
25
24
  emitter.once("mainViewMounted").then(() => {
@@ -62,15 +61,15 @@ export class MainViewProxy extends Base {
62
61
  }
63
62
 
64
63
  public setCameraAndSize(): void {
65
- this.store.setMainViewCamera({ ...this.mainView.camera, id: this.context.uid });
66
- this.store.setMainViewSize({ ...this.mainView.size, id: this.context.uid });
64
+ this.store.setMainViewCamera({ ...this.mainView.camera, id: this.manager.uid });
65
+ this.store.setMainViewSize({ ...this.mainView.size, id: this.manager.uid });
67
66
  }
68
67
 
69
68
  private cameraReaction = () => {
70
69
  return reaction(
71
70
  () => this.mainViewCamera,
72
71
  camera => {
73
- if (camera && camera.id !== this.context.uid) {
72
+ if (camera && camera.id !== this.manager.uid) {
74
73
  this.moveCameraToContian(this.mainViewSize);
75
74
  this.moveCamera(camera);
76
75
  }
@@ -106,8 +105,8 @@ export class MainViewProxy extends Base {
106
105
  }
107
106
 
108
107
  private onCameraUpdatedByDevice = (camera: Camera) => {
109
- this.store.setMainViewCamera({ ...camera, id: this.context.uid });
110
- if (!isEqual(this.mainViewSize, { ...this.mainView.size, id: this.context.uid })) {
108
+ this.store.setMainViewCamera({ ...camera, id: this.manager.uid });
109
+ if (!isEqual(this.mainViewSize, { ...this.mainView.size, id: this.manager.uid })) {
111
110
  this.setMainViewSize(this.view.size);
112
111
  }
113
112
  };
@@ -135,11 +134,11 @@ export class MainViewProxy extends Base {
135
134
  public async mainViewClickHandler(): Promise<void> {
136
135
  if (!this.manager.canOperate) return;
137
136
  this.store.cleanFocus();
138
- this.context.blurFocusBox();
137
+ this.manager.boxManager?.blurAllBox();
139
138
  }
140
139
 
141
140
  public setMainViewSize = debounce(size => {
142
- this.store.setMainViewSize({ ...size, id: this.context.uid });
141
+ this.store.setMainViewSize({ ...size, id: this.manager.uid });
143
142
  }, 50);
144
143
 
145
144
  private addCameraListener() {
package/src/constants.ts CHANGED
@@ -10,7 +10,8 @@ export enum Events {
10
10
  SetMainViewScenePath = "SetMainViewScenePath",
11
11
  SetMainViewSceneIndex = "SetMainViewSceneIndex",
12
12
  SwitchViewsToFreedom = "SwitchViewsToFreedom",
13
- MoveCameraToContain = "MoveCameraToContain"
13
+ MoveCameraToContain = "MoveCameraToContain",
14
+ CursorMove = "CursorMove",
14
15
  }
15
16
 
16
17
  export const MagixEventName = "__WindowManger";
@@ -37,7 +38,7 @@ export enum CursorState {
37
38
  Normal = "normal",
38
39
  }
39
40
 
40
- export const REQUIRE_VERSION = "2.16.0";
41
+ export const REQUIRE_VERSION = "2.16.1";
41
42
 
42
43
  export const MIN_WIDTH = 340 / 720;
43
44
  export const MIN_HEIGHT = 340 / 720;
package/src/index.ts CHANGED
@@ -21,6 +21,7 @@ import {
21
21
  ensureValidScenePath,
22
22
  getVersionNumber,
23
23
  isValidScenePath,
24
+ parseSceneDir,
24
25
  wait,
25
26
  } from "./Utils/Common";
26
27
  import type { TELE_BOX_STATE, BoxManager } from "./BoxManager";
@@ -31,7 +32,7 @@ import {
31
32
  ParamsInvalidError,
32
33
  WhiteWebSDKInvalidError,
33
34
  } from "./Utils/error";
34
- import type { Apps } from "./AttributesDelegate";
35
+ import type { Apps, Position } from "./AttributesDelegate";
35
36
  import {
36
37
  InvisiblePlugin,
37
38
  isPlayer,
@@ -124,6 +125,8 @@ export type AppInitState = {
124
125
  zIndex?: number;
125
126
  };
126
127
 
128
+ export type CursorMovePayload = { uid: string; state?: "leave"; position: Position };
129
+
127
130
  export type EmitterEvent = {
128
131
  onCreated: undefined;
129
132
  InitReplay: AppInitState;
@@ -138,6 +141,8 @@ export type EmitterEvent = {
138
141
  boxStateChange: string;
139
142
  playgroundSizeChange: DOMRect;
140
143
  onReconnected: void;
144
+ removeScenes: string;
145
+ cursorMove: CursorMovePayload;
141
146
  };
142
147
 
143
148
  export type EmitterType = Emittery<EmitterEvent>;
@@ -186,6 +191,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
186
191
  private static isCreated = false;
187
192
 
188
193
  public version = __APP_VERSION__;
194
+ public dependencies = __APP_DEPENDENCIES__;
189
195
 
190
196
  public appListeners?: AppListeners;
191
197
 
@@ -204,6 +210,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
204
210
  constructor(context: InvisiblePluginContext) {
205
211
  super(context);
206
212
  WindowManager.displayer = context.displayer;
213
+ (window as any).NETLESS_DEPS = __APP_DEPENDENCIES__;
207
214
  }
208
215
 
209
216
  public static async mount(params: MountParams): Promise<WindowManager> {
@@ -427,6 +434,12 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
427
434
  const appScenePath = appManager.store.getAppScenePath(appId);
428
435
  if (appScenePath && appScenePath === scenePath) {
429
436
  console.warn(`[WindowManager]: ScenePath ${scenePath} Already opened`);
437
+ if (this.boxManager) {
438
+ const topBox = this.boxManager.getTopBox();
439
+ if (topBox) {
440
+ this.boxManager.setZIndex(appId, topBox.zIndex + 1, false);
441
+ }
442
+ }
430
443
  return;
431
444
  }
432
445
  }
@@ -471,7 +484,7 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
471
484
  /**
472
485
  * 返回 mainView 的 ScenePath
473
486
  */
474
- public getMainViewScenePath(): string {
487
+ public getMainViewScenePath(): string | undefined {
475
488
  return this.appManager?.store.getMainViewScenePath();
476
489
  }
477
490
 
@@ -519,6 +532,35 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
519
532
  this.viewMode = mode;
520
533
  }
521
534
 
535
+ public setBoxState(boxState: TeleBoxState): void {
536
+ if (!this.canOperate) return;
537
+ switch (boxState) {
538
+ case "normal":
539
+ this.setMaximized(false);
540
+ this.setMinimized(false);
541
+ break;
542
+ case "maximized":
543
+ this.setMaximized(true);
544
+ this.setMinimized(false);
545
+ break;
546
+ case "minimized":
547
+ this.setMinimized(true);
548
+ break;
549
+ default:
550
+ break;
551
+ }
552
+ }
553
+
554
+ public setMaximized(maximized: boolean): void {
555
+ if (!this.canOperate) return;
556
+ this.boxManager?.setMaximized(maximized, false);
557
+ }
558
+
559
+ public setMinimized(minimized: boolean): void {
560
+ if (!this.canOperate) return;
561
+ this.boxManager?.setMinimized(minimized, false);
562
+ }
563
+
522
564
  public get mainView(): View {
523
565
  if (this.appManager) {
524
566
  return this.appManager.mainViewProxy.view;
@@ -575,6 +617,19 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
575
617
  return this.appManager?.store.getMainViewSceneIndex();
576
618
  }
577
619
 
620
+ public get mainViewSceneDir(): string {
621
+ const scenePath = this.appManager?.store.getMainViewScenePath();
622
+ if (scenePath) {
623
+ return parseSceneDir(scenePath);
624
+ } else {
625
+ throw new Error("[WindowManager]: mainViewSceneDir not found");
626
+ }
627
+ }
628
+
629
+ public get topApp(): string | undefined {
630
+ return this.boxManager?.getTopBox()?.id;
631
+ }
632
+
578
633
  /**
579
634
  * 查询所有的 App
580
635
  */
@@ -715,6 +770,10 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes> {
715
770
  }
716
771
  }
717
772
  }
773
+
774
+ private _removeScenes = (scenePath: string) => {
775
+ this.room.removeScenes(scenePath);
776
+ };
718
777
  }
719
778
 
720
779
  setupBuiltin();
package/src/shim.d.ts CHANGED
@@ -7,4 +7,5 @@ declare module "*.svelte" {
7
7
 
8
8
  declare global {
9
9
  const __APP_VERSION__: string;
10
- }
10
+ const __APP_DEPENDENCIES__: Record<string, string>;
11
+ }
package/src/style.css CHANGED
@@ -122,7 +122,7 @@
122
122
  left: 0;
123
123
  top: 0;
124
124
  will-change: transform;
125
- transition: transform 0.05s;
125
+ transition: transform 0.1s;
126
126
  transform-origin: 0 0;
127
127
  user-select: none;
128
128
  }
package/vite.config.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import path from "path";
2
2
  import { defineConfig } from "vite";
3
3
  import { svelte } from "@sveltejs/vite-plugin-svelte";
4
- import { dependencies ,peerDependencies, version } from "./package.json"
4
+ import { dependencies, peerDependencies, version, devDependencies } from "./package.json"
5
5
 
6
6
 
7
7
  export default defineConfig(({ mode }) => {
@@ -10,6 +10,9 @@ export default defineConfig(({ mode }) => {
10
10
  return {
11
11
  define: {
12
12
  __APP_VERSION__: JSON.stringify(version),
13
+ __APP_DEPENDENCIES__: JSON.stringify({
14
+ dependencies, peerDependencies, devDependencies
15
+ }),
13
16
  },
14
17
  plugins: [
15
18
  svelte({
@@ -23,7 +26,7 @@ export default defineConfig(({ mode }) => {
23
26
  lib: {
24
27
  // eslint-disable-next-line no-undef
25
28
  entry: path.resolve(__dirname, "src/index.ts"),
26
- formats: ["es","umd"], // TODO cjs 版本待修复
29
+ formats: ["es", "umd"], // TODO cjs 版本待修复
27
30
  name: "WindowManager",
28
31
  fileName: "index"
29
32
  },
@@ -1,12 +0,0 @@
1
- import type { AppManager } from "../AppManager";
2
- export declare class Context {
3
- private manager;
4
- observerId: number;
5
- constructor(manager: AppManager);
6
- get uid(): string;
7
- findMember: (memberId: number) => import("white-web-sdk").RoomMember | undefined;
8
- findMemberByUid: (uid: string) => import("white-web-sdk").RoomMember | undefined;
9
- updateManagerRect(): void;
10
- blurFocusBox(): void;
11
- }
12
- export declare const createContext: (manager: AppManager) => Context;
@@ -1,7 +0,0 @@
1
- import type { AppManager } from "../AppManager";
2
- export declare class Base {
3
- manager: AppManager;
4
- store: import("../AttributesDelegate").AttributesDelegate;
5
- context: import("./Context").Context;
6
- constructor(manager: AppManager);
7
- }
@@ -1,45 +0,0 @@
1
- import { emitter } from "../index";
2
- import type { AppManager } from "../AppManager";
3
-
4
- export class Context {
5
- public observerId: number;
6
-
7
- constructor(private manager: AppManager) {
8
- this.observerId = manager.displayer.observerId;
9
-
10
- emitter.on("observerIdChange", id => {
11
- this.observerId = id;
12
- });
13
- };
14
-
15
- public get uid() {
16
- return this.manager.room?.uid || "";
17
- }
18
-
19
- public findMember = (memberId: number) => {
20
- const roomMembers = this.manager.room?.state.roomMembers;
21
- return roomMembers?.find(member => member.memberId === memberId);
22
- }
23
-
24
- public findMemberByUid = (uid: string) => {
25
- const roomMembers = this.manager.room?.state.roomMembers;
26
- return roomMembers?.find(member => member.payload?.uid === uid);
27
- }
28
-
29
- public updateManagerRect() {
30
- this.manager.boxManager?.updateManagerRect();
31
- }
32
-
33
- public blurFocusBox() {
34
- this.manager.boxManager?.blurAllBox();
35
- }
36
- }
37
-
38
- let context: Context;
39
-
40
- export const createContext = (manager: AppManager) => {
41
- if (!context) {
42
- context = new Context(manager);
43
- }
44
- return context;
45
- };
package/src/Base/index.ts DELETED
@@ -1,10 +0,0 @@
1
- import type { AppManager } from "../AppManager";
2
- import { store } from "../AttributesDelegate";
3
- import { createContext } from "./Context";
4
-
5
- export class Base {
6
- public store = store;
7
- public context = createContext(this.manager);
8
-
9
- constructor(public manager: AppManager) {}
10
- }