@netless/window-manager 1.0.0-canary.52 → 1.0.0-canary.54

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 (44) hide show
  1. package/dist/index.cjs.js +389 -445
  2. package/dist/index.es.js +434 -490
  3. package/dist/index.umd.js +389 -446
  4. package/dist/src/App/AppContext.d.ts +8 -8
  5. package/dist/src/AppManager.d.ts +5 -1
  6. package/dist/src/Cursor/index.d.ts +1 -0
  7. package/dist/src/Utils/Reactive.d.ts +1 -1
  8. package/dist/src/View/CameraSynchronizer.d.ts +4 -3
  9. package/dist/src/View/ScrollMode.d.ts +32 -0
  10. package/dist/src/View/ViewSync.d.ts +4 -2
  11. package/dist/src/callback.d.ts +3 -0
  12. package/dist/src/constants.d.ts +2 -0
  13. package/dist/src/index.d.ts +21 -11
  14. package/dist/src/storage.d.ts +7 -0
  15. package/dist/src/typings.d.ts +5 -4
  16. package/dist/style.css +2 -1
  17. package/docs/api.md +10 -0
  18. package/package.json +4 -3
  19. package/pnpm-lock.yaml +28 -73
  20. package/src/App/AppContext.ts +19 -8
  21. package/src/App/WhiteboardView.ts +4 -2
  22. package/src/AppListener.ts +1 -10
  23. package/src/AppManager.ts +19 -1
  24. package/src/Cursor/index.ts +6 -2
  25. package/src/Utils/Reactive.ts +2 -1
  26. package/src/View/CameraSynchronizer.ts +35 -23
  27. package/src/View/MainView.ts +1 -0
  28. package/src/View/ScrollMode.ts +229 -0
  29. package/src/View/ViewSync.ts +31 -18
  30. package/src/callback.ts +3 -0
  31. package/src/constants.ts +3 -0
  32. package/src/index.ts +56 -63
  33. package/src/storage.ts +15 -0
  34. package/src/style.css +1 -1
  35. package/src/typings.ts +6 -3
  36. package/vite.config.js +1 -1
  37. package/dist/src/App/Storage/StorageEvent.d.ts +0 -8
  38. package/dist/src/App/Storage/index.d.ts +0 -39
  39. package/dist/src/App/Storage/typings.d.ts +0 -22
  40. package/dist/src/App/Storage/utils.d.ts +0 -5
  41. package/src/App/Storage/StorageEvent.ts +0 -21
  42. package/src/App/Storage/index.ts +0 -295
  43. package/src/App/Storage/typings.ts +0 -23
  44. package/src/App/Storage/utils.ts +0 -17
package/dist/index.umd.js CHANGED
@@ -30,8 +30,8 @@ var __objRest = (source, exclude) => {
30
30
  return target;
31
31
  };
32
32
  (function(global, factory) {
33
- typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("p-retry"), require("emittery"), require("lodash"), require("white-web-sdk"), require("uuid"), require("side-effect-manager"), require("value-enhancer"), require("@juggle/resize-observer")) : typeof define === "function" && define.amd ? define(["exports", "p-retry", "emittery", "lodash", "white-web-sdk", "uuid", "side-effect-manager", "value-enhancer", "@juggle/resize-observer"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.WindowManager = {}, global.pRetry, global.Emittery, global.lodash, global.whiteWebSdk, global.uuid, global.sideEffectManager, global.valueEnhancer, global.resizeObserver));
34
- })(this, function(exports2, pRetry, Emittery, lodash, whiteWebSdk, uuid, sideEffectManager, valueEnhancer, resizeObserver) {
33
+ typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("p-retry"), require("emittery"), require("lodash"), require("white-web-sdk"), require("uuid"), require("@netless/synced-store"), require("value-enhancer"), require("side-effect-manager"), require("@juggle/resize-observer")) : typeof define === "function" && define.amd ? define(["exports", "p-retry", "emittery", "lodash", "white-web-sdk", "uuid", "@netless/synced-store", "value-enhancer", "side-effect-manager", "@juggle/resize-observer"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.WindowManager = {}, global.pRetry, global.Emittery, global.lodash, global.whiteWebSdk, global.uuid, global.syncedStore, global.valueEnhancer, global.sideEffectManager, global.resizeObserver));
34
+ })(this, function(exports2, pRetry, Emittery, lodash, whiteWebSdk, uuid, syncedStore, valueEnhancer, sideEffectManager, resizeObserver) {
35
35
  "use strict";
36
36
  function _interopDefaultLegacy(e) {
37
37
  return e && typeof e === "object" && "default" in e ? e : { "default": e };
@@ -96,6 +96,8 @@ var __objRest = (source, exclude) => {
96
96
  const INIT_DIR = "/init";
97
97
  const SETUP_APP_DELAY = 50;
98
98
  const MAX_PAGE_SIZE = 500;
99
+ const SCROLL_MODE_BASE_WIDTH = 1600;
100
+ const SCROLL_MODE_BASE_HEIGHT = SCROLL_MODE_BASE_WIDTH * 3;
99
101
  const callbacks = new Emittery__default["default"]();
100
102
  class AppCreateQueue {
101
103
  constructor() {
@@ -516,66 +518,6 @@ var __objRest = (source, exclude) => {
516
518
  }, 0);
517
519
  return delimiterCount === 1;
518
520
  };
519
- class CameraSynchronizer {
520
- constructor(saveCamera) {
521
- this.saveCamera = saveCamera;
522
- this.setRect = (rect) => {
523
- this.rect = rect;
524
- if (this.remoteCamera && this.remoteSize) {
525
- this.onRemoteUpdate(this.remoteCamera, this.remoteSize);
526
- }
527
- };
528
- this.onRemoteUpdate = lodash.throttle((camera, size) => {
529
- this.remoteCamera = camera;
530
- this.remoteSize = size;
531
- if (this.remoteSize && this.rect) {
532
- const nextScale = camera.scale * computedMinScale(size, this.rect);
533
- const config = {
534
- scale: nextScale
535
- };
536
- if (camera.centerX !== null) {
537
- config.centerX = camera.centerX;
538
- }
539
- if (camera.centerY !== null) {
540
- config.centerY = camera.centerY;
541
- }
542
- this.moveCamera(config);
543
- }
544
- }, 10);
545
- }
546
- setView(view) {
547
- this.view = view;
548
- }
549
- onRemoteSizeUpdate(size) {
550
- var _a;
551
- this.remoteSize = size;
552
- const needMoveCamera = !lodash.isEqual(lodash.pick(this.rect, ["width", "height"]), lodash.pick(size, ["width", "height"]));
553
- if (this.rect && this.remoteCamera && needMoveCamera) {
554
- if (!this.view)
555
- return;
556
- const currentCamera = this.view.camera;
557
- (_a = this.view) == null ? void 0 : _a.moveCameraToContain({
558
- width: size.width,
559
- height: size.height,
560
- originX: currentCamera.centerX - size.width / 2,
561
- originY: currentCamera.centerY - size.height / 2
562
- });
563
- }
564
- }
565
- onLocalCameraUpdate(camera) {
566
- this.saveCamera(camera);
567
- this.remoteCamera = camera;
568
- }
569
- moveCamera(camera) {
570
- var _a;
571
- (_a = this.view) == null ? void 0 : _a.moveCamera(__spreadProps(__spreadValues({}, camera), { animationMode: whiteWebSdk.AnimationMode.Immediately }));
572
- }
573
- }
574
- const computedMinScale = (remoteSize, currentSize) => {
575
- const wScale = currentSize.width / remoteSize.width;
576
- const hScale = currentSize.height / remoteSize.height;
577
- return Math.min(wScale, hScale);
578
- };
579
521
  class AppListeners {
580
522
  constructor(manager) {
581
523
  this.manager = manager;
@@ -676,16 +618,7 @@ var __objRest = (source, exclude) => {
676
618
  }
677
619
  };
678
620
  this.moveCameraHandler = (payload) => {
679
- var _a;
680
- const cameraPayload = payload;
681
- if (payload.scale) {
682
- const remoteSize = this.manager.mainViewProxy.size$.value;
683
- const currentSize = (_a = this.manager.boxManager) == null ? void 0 : _a.stageRect;
684
- if (remoteSize && currentSize) {
685
- cameraPayload.scale = payload.scale * computedMinScale(remoteSize, currentSize);
686
- }
687
- }
688
- this.manager.mainView.moveCamera(cameraPayload);
621
+ this.manager.mainView.moveCamera(payload);
689
622
  };
690
623
  this.moveCameraToContainHandler = (payload) => {
691
624
  this.manager.mainView.moveCameraToContain(payload);
@@ -753,292 +686,6 @@ var __objRest = (source, exclude) => {
753
686
  this.message = "[WindowManager]: room phase only Connected can be bindContainer";
754
687
  }
755
688
  }
756
- const onObjectByEvent = (event) => {
757
- return (object, func) => {
758
- if (object === void 0)
759
- return;
760
- if (whiteWebSdk.listenUpdated) {
761
- const listener = (events) => {
762
- const kinds = events.map((e) => e.kind);
763
- if (kinds.includes(event)) {
764
- func();
765
- }
766
- };
767
- whiteWebSdk.listenUpdated(object, listener);
768
- func();
769
- return () => whiteWebSdk.unlistenUpdated(object, listener);
770
- } else {
771
- return whiteWebSdk.reaction(() => object, () => {
772
- func();
773
- }, {
774
- fireImmediately: true
775
- });
776
- }
777
- };
778
- };
779
- const safeListenPropsUpdated = (getProps, callback, onDestroyed) => {
780
- let disposeListenUpdated = null;
781
- const disposeReaction = whiteWebSdk.reaction(getProps, () => {
782
- if (disposeListenUpdated) {
783
- disposeListenUpdated();
784
- disposeListenUpdated = null;
785
- }
786
- const props = getProps();
787
- if (lodash.isObject(props)) {
788
- disposeListenUpdated = () => whiteWebSdk.unlistenUpdated(props, callback);
789
- whiteWebSdk.listenUpdated(props, callback);
790
- } else {
791
- onDestroyed == null ? void 0 : onDestroyed(props);
792
- }
793
- }, { fireImmediately: true });
794
- return () => {
795
- disposeListenUpdated == null ? void 0 : disposeListenUpdated();
796
- disposeReaction();
797
- };
798
- };
799
- const onObjectRemoved = onObjectByEvent(whiteWebSdk.UpdateEventKind.Removed);
800
- onObjectByEvent(whiteWebSdk.UpdateEventKind.Inserted);
801
- const plainObjectKeys = Object.keys;
802
- function isRef(e) {
803
- return Boolean(lodash.has(e, "__isRef"));
804
- }
805
- function makeRef(v) {
806
- return { k: sideEffectManager.genUID(), v, __isRef: true };
807
- }
808
- class StorageEvent {
809
- constructor() {
810
- this.listeners = /* @__PURE__ */ new Set();
811
- }
812
- get length() {
813
- return this.listeners.size;
814
- }
815
- dispatch(message) {
816
- this.listeners.forEach((callback) => callback(message));
817
- }
818
- addListener(listener) {
819
- this.listeners.add(listener);
820
- }
821
- removeListener(listener) {
822
- this.listeners.delete(listener);
823
- }
824
- }
825
- const STORAGE_NS = "_WM-STORAGE_";
826
- class Storage {
827
- constructor(context, id, defaultState) {
828
- this._sideEffect = new sideEffectManager.SideEffectManager();
829
- this._destroyed = false;
830
- this._refMap = /* @__PURE__ */ new WeakMap();
831
- this._lastValue = /* @__PURE__ */ new Map();
832
- this.onStateChanged = new StorageEvent();
833
- if (defaultState && !lodash.isObject(defaultState)) {
834
- throw new Error(`Default state for Storage ${id} is not an object.`);
835
- }
836
- this._context = context;
837
- this.id = id || null;
838
- this._state = {};
839
- const rawState = this._getRawState(this._state);
840
- if (this._context.isWritable) {
841
- if (this.id === null) {
842
- if (context.isAddApp && defaultState) {
843
- this.setState(defaultState);
844
- }
845
- } else {
846
- if (rawState === this._state || !lodash.isObject(rawState)) {
847
- if (!lodash.get(this._context.getAttributes(), [STORAGE_NS])) {
848
- this._context.updateAttributes([STORAGE_NS], {});
849
- }
850
- this._context.updateAttributes([STORAGE_NS, this.id], this._state);
851
- if (defaultState) {
852
- this.setState(defaultState);
853
- }
854
- }
855
- }
856
- }
857
- plainObjectKeys(rawState).forEach((key) => {
858
- if (this.id === null && key === STORAGE_NS) {
859
- return;
860
- }
861
- try {
862
- const rawValue = lodash.isObject(rawState[key]) ? JSON.parse(JSON.stringify(rawState[key])) : rawState[key];
863
- if (isRef(rawValue)) {
864
- this._state[key] = rawValue.v;
865
- if (lodash.isObject(rawValue.v)) {
866
- this._refMap.set(rawValue.v, rawValue);
867
- }
868
- } else {
869
- this._state[key] = rawValue;
870
- }
871
- } catch (e) {
872
- console.error(e);
873
- }
874
- });
875
- this._sideEffect.addDisposer(safeListenPropsUpdated(() => this.id === null ? context.getAttributes() : lodash.get(context.getAttributes(), [STORAGE_NS, this.id]), this._updateProperties.bind(this), this.destroy.bind(this)));
876
- }
877
- get state() {
878
- if (this._destroyed) {
879
- console.warn(`Accessing state on destroyed Storage "${this.id}"`);
880
- }
881
- return this._state;
882
- }
883
- addStateChangedListener(handler) {
884
- this.onStateChanged.addListener(handler);
885
- return () => this.onStateChanged.removeListener(handler);
886
- }
887
- ensureState(state) {
888
- return this.setState(plainObjectKeys(state).reduce((payload, key) => {
889
- if (!lodash.has(this._state, key)) {
890
- payload[key] = state[key];
891
- }
892
- return payload;
893
- }, {}));
894
- }
895
- setState(state) {
896
- if (this._destroyed) {
897
- console.error(new Error(`Cannot call setState on destroyed Storage "${this.id}".`));
898
- return;
899
- }
900
- if (!this._context.isWritable) {
901
- console.error(new Error(`Cannot setState on Storage "${this.id}" without writable access`), state);
902
- return;
903
- }
904
- const keys = plainObjectKeys(state);
905
- if (keys.length > 0) {
906
- keys.forEach((key) => {
907
- const value = state[key];
908
- if (value === this._state[key]) {
909
- return;
910
- }
911
- if (value === void 0) {
912
- this._lastValue.set(key, this._state[key]);
913
- delete this._state[key];
914
- this._setRawState(key, value);
915
- } else {
916
- this._lastValue.set(key, this._state[key]);
917
- this._state[key] = value;
918
- let payload = value;
919
- if (lodash.isObject(value)) {
920
- let refValue = this._refMap.get(value);
921
- if (!refValue) {
922
- refValue = makeRef(value);
923
- this._refMap.set(value, refValue);
924
- }
925
- payload = refValue;
926
- }
927
- this._setRawState(key, payload);
928
- }
929
- });
930
- }
931
- }
932
- emptyStorage() {
933
- if (lodash.size(this._state) <= 0) {
934
- return;
935
- }
936
- if (this._destroyed) {
937
- console.error(new Error(`Cannot empty destroyed Storage "${this.id}".`));
938
- return;
939
- }
940
- if (!this._context.isWritable) {
941
- console.error(new Error(`Cannot empty Storage "${this.id}" without writable access.`));
942
- return;
943
- }
944
- this.setState(lodash.mapValues(this._state, lodash.noop));
945
- }
946
- deleteStorage() {
947
- if (this.id === null) {
948
- throw new Error(`Cannot delete main Storage`);
949
- }
950
- if (!this._context.isWritable) {
951
- console.error(new Error(`Cannot delete Storage "${this.id}" without writable access.`));
952
- return;
953
- }
954
- this.destroy();
955
- this._context.updateAttributes([STORAGE_NS, this.id], void 0);
956
- }
957
- get destroyed() {
958
- return this._destroyed;
959
- }
960
- destroy() {
961
- this._destroyed = true;
962
- this._sideEffect.flushAll();
963
- }
964
- _getRawState(defaultValue) {
965
- var _a;
966
- if (this.id === null) {
967
- return (_a = this._context.getAttributes()) != null ? _a : defaultValue;
968
- } else {
969
- return lodash.get(this._context.getAttributes(), [STORAGE_NS, this.id], defaultValue);
970
- }
971
- }
972
- _setRawState(key, value) {
973
- if (this.id === null) {
974
- if (key === STORAGE_NS) {
975
- throw new Error(`Cannot set attribute internal filed "${STORAGE_NS}"`);
976
- }
977
- return this._context.updateAttributes([key], value);
978
- } else {
979
- return this._context.updateAttributes([STORAGE_NS, this.id, key], value);
980
- }
981
- }
982
- _updateProperties(actions) {
983
- var _a;
984
- if (this._destroyed) {
985
- console.error(new Error(`Cannot call _updateProperties on destroyed Storage "${this.id}".`));
986
- return;
987
- }
988
- if (actions.length > 0) {
989
- const diffs = {};
990
- for (let i = 0; i < actions.length; i++) {
991
- try {
992
- const action = actions[i];
993
- const key = action.key;
994
- if (this.id === null && key === STORAGE_NS) {
995
- continue;
996
- }
997
- const value = lodash.isObject(action.value) ? JSON.parse(JSON.stringify(action.value)) : action.value;
998
- let oldValue;
999
- if (this._lastValue.has(key)) {
1000
- oldValue = this._lastValue.get(key);
1001
- this._lastValue.delete(key);
1002
- }
1003
- switch (action.kind) {
1004
- case 2: {
1005
- if (lodash.has(this._state, key)) {
1006
- oldValue = this._state[key];
1007
- delete this._state[key];
1008
- }
1009
- diffs[key] = { oldValue };
1010
- break;
1011
- }
1012
- default: {
1013
- let newValue = value;
1014
- if (isRef(value)) {
1015
- const { k: k2, v } = value;
1016
- const curValue = this._state[key];
1017
- if (lodash.isObject(curValue) && ((_a = this._refMap.get(curValue)) == null ? void 0 : _a.k) === k2) {
1018
- newValue = curValue;
1019
- } else {
1020
- newValue = v;
1021
- if (lodash.isObject(v)) {
1022
- this._refMap.set(v, value);
1023
- }
1024
- }
1025
- }
1026
- if (newValue !== this._state[key]) {
1027
- oldValue = this._state[key];
1028
- this._state[key] = newValue;
1029
- }
1030
- diffs[key] = { newValue, oldValue };
1031
- break;
1032
- }
1033
- }
1034
- } catch (e) {
1035
- console.error(e);
1036
- }
1037
- }
1038
- this.onStateChanged.dispatch(diffs);
1039
- }
1040
- }
1041
- }
1042
689
  class WhiteBoardView {
1043
690
  constructor(view, appContext, appProxy, ensureSize) {
1044
691
  this.view = view;
@@ -1067,11 +714,12 @@ var __objRest = (source, exclude) => {
1067
714
  const scenePath = this.appProxy.scenePath;
1068
715
  if (!scenePath)
1069
716
  return;
717
+ const scenes = Array.isArray(scene) ? scene : [scene || {}];
1070
718
  if (after) {
1071
719
  const nextIndex = this.pageState.index + 1;
1072
- putScenes(this.appContext.room, scenePath, [scene || {}], nextIndex);
720
+ putScenes(this.appContext.room, scenePath, scenes, nextIndex);
1073
721
  } else {
1074
- putScenes(this.appContext.room, scenePath, [scene || {}]);
722
+ putScenes(this.appContext.room, scenePath, scenes);
1075
723
  }
1076
724
  };
1077
725
  this.removePage = async (index2) => {
@@ -1271,10 +919,20 @@ var __objRest = (source, exclude) => {
1271
919
  this.getAppOptions = () => {
1272
920
  return typeof this.appOptions === "function" ? this.appOptions() : this.appOptions;
1273
921
  };
1274
- this.createStorage = (storeId, defaultState) => {
1275
- const storage = new Storage(this, storeId, defaultState);
922
+ this.createStorage = (namespace, defaultState) => {
923
+ const isWritable$ = new valueEnhancer.Val(this.isWritable);
924
+ const plugin$ = new valueEnhancer.Val(this.manager.windowManger);
925
+ const storage = new syncedStore.Storage({
926
+ plugin$,
927
+ isWritable$,
928
+ namespace,
929
+ defaultState
930
+ });
931
+ this.emitter.on("writableChange", (writable) => {
932
+ isWritable$.setValue(writable);
933
+ });
1276
934
  this.emitter.on("destroy", () => {
1277
- storage.destroy();
935
+ storage.disconnect();
1278
936
  });
1279
937
  return storage;
1280
938
  };
@@ -1337,7 +995,7 @@ var __objRest = (source, exclude) => {
1337
995
  }
1338
996
  get storage() {
1339
997
  if (!this._storage) {
1340
- this._storage = new Storage(this);
998
+ this._storage = this.createStorage(this.appId, this.getAttributes());
1341
999
  }
1342
1000
  return this._storage;
1343
1001
  }
@@ -1395,6 +1053,77 @@ var __objRest = (source, exclude) => {
1395
1053
  (_a = this.sceneNode) == null ? void 0 : _a.dispose();
1396
1054
  }
1397
1055
  }
1056
+ class CameraSynchronizer {
1057
+ constructor(saveCamera) {
1058
+ this.saveCamera = saveCamera;
1059
+ this.scale = 1;
1060
+ this.setRect = (rect, updateCamera = true) => {
1061
+ this.rect = rect;
1062
+ if (this.remoteCamera && this.remoteSize && updateCamera) {
1063
+ this.onRemoteUpdate(this.remoteCamera, this.remoteSize);
1064
+ }
1065
+ };
1066
+ this.onRemoteUpdate = lodash.throttle((camera, size) => {
1067
+ this.remoteCamera = camera;
1068
+ this.remoteSize = size;
1069
+ if (this.remoteSize && this.rect) {
1070
+ requestAnimationFrame(() => {
1071
+ this.moveCameraToContian(size);
1072
+ this.moveCamera(camera);
1073
+ });
1074
+ }
1075
+ }, 32);
1076
+ }
1077
+ setView(view) {
1078
+ this.view = view;
1079
+ }
1080
+ onRemoteSizeUpdate(size) {
1081
+ var _a;
1082
+ this.remoteSize = size;
1083
+ const needMoveCamera = !lodash.isEqual(lodash.pick(this.rect, ["width", "height"]), lodash.pick(size, ["width", "height"]));
1084
+ if (this.rect && this.remoteCamera && needMoveCamera) {
1085
+ if (!this.view)
1086
+ return;
1087
+ const currentCamera = this.view.camera;
1088
+ (_a = this.view) == null ? void 0 : _a.moveCameraToContain({
1089
+ width: size.width,
1090
+ height: size.height,
1091
+ originX: currentCamera.centerX - size.width / 2,
1092
+ originY: currentCamera.centerY - size.height / 2
1093
+ });
1094
+ }
1095
+ }
1096
+ onLocalCameraUpdate(camera) {
1097
+ this.saveCamera(camera);
1098
+ this.remoteCamera = camera;
1099
+ }
1100
+ moveCameraToContian(size) {
1101
+ if (!lodash.isEmpty(size) && this.view) {
1102
+ this.view.moveCameraToContain({
1103
+ width: size.width,
1104
+ height: size.height,
1105
+ originX: -size.width / 2,
1106
+ originY: -size.height / 2,
1107
+ animationMode: whiteWebSdk.AnimationMode.Immediately
1108
+ });
1109
+ this.scale = this.view.camera.scale;
1110
+ }
1111
+ }
1112
+ moveCamera(camera) {
1113
+ if (!lodash.isEmpty(camera) && this.view && camera.centerX && camera.centerY) {
1114
+ if (lodash.isEqual(camera, this.view.camera))
1115
+ return;
1116
+ const { centerX, centerY, scale: scale2 } = camera;
1117
+ const needScale = scale2 * (this.scale || 1);
1118
+ this.view.moveCamera({
1119
+ centerX,
1120
+ centerY,
1121
+ scale: needScale,
1122
+ animationMode: whiteWebSdk.AnimationMode.Immediately
1123
+ });
1124
+ }
1125
+ }
1126
+ }
1398
1127
  class ViewSync {
1399
1128
  constructor(context) {
1400
1129
  this.context = context;
@@ -1412,8 +1141,9 @@ var __objRest = (source, exclude) => {
1412
1141
  };
1413
1142
  this.subscribeView = () => {
1414
1143
  return this.context.view$.subscribe((view) => {
1144
+ var _a;
1415
1145
  const currentCamera = this.context.camera$.value;
1416
- if (currentCamera && this.context.size$.value) {
1146
+ if (currentCamera && this.context.size$.value && ((_a = this.needRecoverCamera$) == null ? void 0 : _a.value)) {
1417
1147
  view == null ? void 0 : view.moveCamera({
1418
1148
  scale: 1,
1419
1149
  animationMode: whiteWebSdk.AnimationMode.Immediately
@@ -1435,7 +1165,7 @@ var __objRest = (source, exclude) => {
1435
1165
  };
1436
1166
  this.subscribeSize = () => {
1437
1167
  return this.context.size$.subscribe((size) => {
1438
- if (size) {
1168
+ if (size && this.isBroadcastMode) {
1439
1169
  this.synchronizer.onRemoteSizeUpdate(size);
1440
1170
  }
1441
1171
  });
@@ -1443,7 +1173,7 @@ var __objRest = (source, exclude) => {
1443
1173
  this.subscribeStageRect = () => {
1444
1174
  return this.context.stageRect$.subscribe((rect) => {
1445
1175
  if (rect) {
1446
- this.synchronizer.setRect(rect);
1176
+ this.synchronizer.setRect(rect, this.isBroadcastMode);
1447
1177
  }
1448
1178
  });
1449
1179
  };
@@ -1460,10 +1190,15 @@ var __objRest = (source, exclude) => {
1460
1190
  this.onCameraUpdatedByDevice = (camera) => {
1461
1191
  if (!camera)
1462
1192
  return;
1463
- if (this.context.size$.value && this.context.stageRect$.value) {
1464
- const diffScale = computedMinScale(this.context.size$.value, this.context.stageRect$.value);
1465
- const remoteScale = camera.scale / diffScale;
1466
- this.synchronizer.onLocalCameraUpdate(__spreadProps(__spreadValues({}, camera), { scale: remoteScale, id: this.context.uid }));
1193
+ if (!this.isBroadcastMode)
1194
+ return;
1195
+ const { size$, stageRect$, view$ } = this.context;
1196
+ if (size$.value && stageRect$.value && view$.value) {
1197
+ this.synchronizer.onLocalCameraUpdate(__spreadProps(__spreadValues({}, camera), { id: this.context.uid }));
1198
+ const newSize = __spreadProps(__spreadValues({}, view$.value.size), { id: this.context.uid });
1199
+ if (!lodash.isEqual(size$.value, newSize)) {
1200
+ this.context.storeSize(newSize);
1201
+ }
1467
1202
  }
1468
1203
  };
1469
1204
  this.synchronizer = this.createSynchronizer();
@@ -1474,14 +1209,22 @@ var __objRest = (source, exclude) => {
1474
1209
  this.subscribeSize(),
1475
1210
  this.subscribeStageRect()
1476
1211
  ]);
1212
+ if (context.viewMode$) {
1213
+ this.needRecoverCamera$ = valueEnhancer.derive(context.viewMode$, (mode) => mode !== "scroll");
1214
+ }
1477
1215
  const camera$size$ = valueEnhancer.combine([this.context.camera$, this.context.size$]);
1478
1216
  camera$size$.reaction(([camera, size]) => {
1479
- if (camera && size) {
1217
+ var _a;
1218
+ if (camera && size && ((_a = this.needRecoverCamera$) == null ? void 0 : _a.value)) {
1480
1219
  this.synchronizer.onRemoteUpdate(camera, size);
1481
1220
  camera$size$.destroy();
1482
1221
  }
1483
1222
  });
1484
1223
  }
1224
+ get isBroadcastMode() {
1225
+ var _a;
1226
+ return ((_a = this.context.viewMode$) == null ? void 0 : _a.value) === whiteWebSdk.ViewMode.Broadcaster;
1227
+ }
1485
1228
  destroy() {
1486
1229
  this.sem.flushAll();
1487
1230
  }
@@ -2553,6 +2296,51 @@ var __objRest = (source, exclude) => {
2553
2296
  this.sideEffectManager.flushAll();
2554
2297
  }
2555
2298
  }
2299
+ const onObjectByEvent = (event) => {
2300
+ return (object, func) => {
2301
+ if (object === void 0)
2302
+ return;
2303
+ if (whiteWebSdk.listenUpdated) {
2304
+ const listener = (events) => {
2305
+ const kinds = events.map((e) => e.kind);
2306
+ if (kinds.includes(event)) {
2307
+ func();
2308
+ }
2309
+ };
2310
+ whiteWebSdk.listenUpdated(object, listener);
2311
+ func();
2312
+ return () => whiteWebSdk.unlistenUpdated(object, listener);
2313
+ } else {
2314
+ return whiteWebSdk.reaction(() => object, () => {
2315
+ func();
2316
+ }, {
2317
+ fireImmediately: true
2318
+ });
2319
+ }
2320
+ };
2321
+ };
2322
+ const safeListenPropsUpdated = (getProps, callback, onDestroyed) => {
2323
+ let disposeListenUpdated = null;
2324
+ const disposeReaction = whiteWebSdk.reaction(getProps, () => {
2325
+ if (disposeListenUpdated) {
2326
+ disposeListenUpdated();
2327
+ disposeListenUpdated = null;
2328
+ }
2329
+ const props = getProps();
2330
+ if (lodash.isObject(props)) {
2331
+ disposeListenUpdated = () => whiteWebSdk.unlistenUpdated(props, callback);
2332
+ whiteWebSdk.listenUpdated(props, callback);
2333
+ } else {
2334
+ onDestroyed == null ? void 0 : onDestroyed(props);
2335
+ }
2336
+ }, { fireImmediately: true });
2337
+ return () => {
2338
+ disposeListenUpdated == null ? void 0 : disposeListenUpdated();
2339
+ disposeReaction();
2340
+ };
2341
+ };
2342
+ const onObjectRemoved = onObjectByEvent(whiteWebSdk.UpdateEventKind.Removed);
2343
+ onObjectByEvent(whiteWebSdk.UpdateEventKind.Inserted);
2556
2344
  class RedoUndo {
2557
2345
  constructor(context) {
2558
2346
  this.context = context;
@@ -2612,24 +2400,181 @@ var __objRest = (source, exclude) => {
2612
2400
  this.disposePrevFocusViewRedoUndoListeners(this.context.focus());
2613
2401
  }
2614
2402
  }
2403
+ const createScrollStorage = (manager) => {
2404
+ return new syncedStore.Storage({
2405
+ plugin$: new valueEnhancer.Val(manager.windowManger),
2406
+ isWritable$: manager.isWritable$,
2407
+ namespace: "scrollStorage",
2408
+ defaultState: { scrollTop: 0 }
2409
+ });
2410
+ };
2411
+ function clamp$2(x2, min, max) {
2412
+ return x2 < min ? min : x2 > max ? max : x2;
2413
+ }
2414
+ class ScrollMode {
2415
+ constructor(manager) {
2416
+ var _a;
2417
+ this.manager = manager;
2418
+ this.sideEffect = new sideEffectManager.SideEffectManager();
2419
+ this.baseWidth = SCROLL_MODE_BASE_WIDTH;
2420
+ this.baseHeight = SCROLL_MODE_BASE_HEIGHT;
2421
+ this.initScroll = () => {
2422
+ const halfWbHeight = this._size$.value.height / 2 / this._scale$.value;
2423
+ const scrollTop = this._scrollTop$.value;
2424
+ this._scrollTop$.setValue(clamp$2(scrollTop, halfWbHeight, this.baseHeight - halfWbHeight) - 0.01);
2425
+ };
2426
+ this.getWhiteboardElement = (root) => {
2427
+ const className = ".netless-window-manager-main-view";
2428
+ return root && root.querySelector(className);
2429
+ };
2430
+ this.onWheel = (ev) => {
2431
+ var _a2;
2432
+ const target = ev.target;
2433
+ if (this.manager.canOperate && ((_a2 = this._whiteboard$.value) == null ? void 0 : _a2.contains(target))) {
2434
+ ev.preventDefault();
2435
+ ev.stopPropagation();
2436
+ const dy = ev.deltaY || 0;
2437
+ const { width } = this._size$.value;
2438
+ if (dy && width > 0) {
2439
+ const halfWbHeight = this._size$.value.height / 2 / this._scale$.value;
2440
+ const scrollTop = this._scrollTop$.value + dy / this._scale$.value;
2441
+ this.scrollStorage.setState({
2442
+ scrollTop: clamp$2(scrollTop, halfWbHeight, this.baseHeight - halfWbHeight)
2443
+ });
2444
+ callbacks.emit("userScroll");
2445
+ }
2446
+ }
2447
+ };
2448
+ this._root$ = new valueEnhancer.Val(null);
2449
+ this._mainView$ = new valueEnhancer.Val(this.manager.mainView);
2450
+ this._mainView$.value.disableCameraTransform = true;
2451
+ if ((_a = manager.scrollBaseSize$) == null ? void 0 : _a.value) {
2452
+ this.baseWidth = manager.scrollBaseSize$.value.width;
2453
+ this.baseHeight = manager.scrollBaseSize$.value.height;
2454
+ }
2455
+ this.scrollStorage = createScrollStorage(manager);
2456
+ const scrollTop$ = new valueEnhancer.Val(this.scrollStorage.state.scrollTop);
2457
+ this._scrollTop$ = scrollTop$;
2458
+ this.sideEffect.push(this.scrollStorage.on("stateChanged", () => {
2459
+ this._scrollTop$.setValue(this.scrollStorage.state.scrollTop);
2460
+ }));
2461
+ const size$ = new valueEnhancer.Val({ width: 0, height: 0 }, { compare: (a, b2) => a.width === b2.width && a.height === b2.height });
2462
+ this._size$ = size$;
2463
+ this.sideEffect.add(() => {
2464
+ const onSizeUpdated = size$.setValue.bind(size$);
2465
+ onSizeUpdated(this._mainView$.value.size);
2466
+ this._mainView$.value.callbacks.on("onSizeUpdated", onSizeUpdated);
2467
+ return () => this._mainView$.value.callbacks.off("onSizeUpdated", onSizeUpdated);
2468
+ });
2469
+ this.sideEffect.add(() => {
2470
+ const onCameraUpdated = (camera) => {
2471
+ const halfWbHeight = size$.value.height / 2 / scale$.value;
2472
+ const scrollTop = camera.centerY;
2473
+ this.scrollStorage.setState({
2474
+ scrollTop: clamp$2(scrollTop, halfWbHeight, this.baseHeight - halfWbHeight)
2475
+ });
2476
+ callbacks.emit("userScroll");
2477
+ };
2478
+ this._mainView$.value.callbacks.on("onCameraUpdatedByDevice", onCameraUpdated);
2479
+ return () => this._mainView$.value.callbacks.off("onCameraUpdatedByDevice", onCameraUpdated);
2480
+ });
2481
+ const scale$ = valueEnhancer.derive(size$, (size) => size.width / this.baseWidth);
2482
+ this._scale$ = scale$;
2483
+ const page$ = new valueEnhancer.Val(0);
2484
+ this.sideEffect.push(valueEnhancer.combine([scrollTop$, size$, scale$]).subscribe(([scrollTop, size, scale2]) => {
2485
+ if (scale2 > 0) {
2486
+ const wbHeight = size.height / scale2;
2487
+ page$.setValue(Math.max(scrollTop / wbHeight - 0.5, 0));
2488
+ }
2489
+ }));
2490
+ this._page$ = page$;
2491
+ this.sideEffect.push(valueEnhancer.combine([scrollTop$, scale$]).subscribe(([scrollTop, scale2]) => {
2492
+ this.updateBound(scrollTop, size$.value, scale2);
2493
+ }));
2494
+ this.sideEffect.push(size$.reaction(() => {
2495
+ this.updateScroll(scrollTop$.value);
2496
+ }));
2497
+ const whiteboard$ = valueEnhancer.derive(this._root$, this.getWhiteboardElement);
2498
+ this._whiteboard$ = whiteboard$;
2499
+ this.sideEffect.push(whiteboard$.reaction((el) => {
2500
+ if (el == null ? void 0 : el.parentElement) {
2501
+ this.sideEffect.addEventListener(el.parentElement, "wheel", this.onWheel, { capture: true, passive: false }, "wheel");
2502
+ }
2503
+ }));
2504
+ this.sideEffect.push(scale$.reaction((scale2) => {
2505
+ if (scale2 > 0) {
2506
+ this.sideEffect.flush("initScroll");
2507
+ this.sideEffect.setTimeout(this.initScroll, 0);
2508
+ }
2509
+ }), "initScroll");
2510
+ const maxScrollPage$ = valueEnhancer.combine([this._size$, this._scale$], ([size, scale2]) => {
2511
+ const halfWbHeight = size.height / 2 / scale2;
2512
+ return (this.baseHeight - halfWbHeight) / halfWbHeight / 2 - 0.51;
2513
+ });
2514
+ this.scrollState$ = valueEnhancer.combine([this._scrollTop$, this._page$, maxScrollPage$], ([scrollTop, page, maxScrollPage]) => {
2515
+ return {
2516
+ scrollTop,
2517
+ page,
2518
+ maxScrollPage
2519
+ };
2520
+ });
2521
+ this.updateScroll(scrollTop$.value);
2522
+ this.sideEffect.push(this.scrollState$.subscribe((state) => callbacks.emit("scrollStateChange", state)));
2523
+ }
2524
+ setRoot(root) {
2525
+ this._root$.setValue(root);
2526
+ }
2527
+ updateScroll(scrollTop) {
2528
+ this._mainView$.value.moveCamera({
2529
+ centerY: scrollTop,
2530
+ animationMode: whiteWebSdk.AnimationMode.Immediately
2531
+ });
2532
+ }
2533
+ updateBound(scrollTop, { height }, scale2) {
2534
+ if (scale2 > 0) {
2535
+ this._mainView$.value.moveCameraToContain({
2536
+ originX: 0,
2537
+ originY: scrollTop - height / scale2 / 2,
2538
+ width: this.baseWidth,
2539
+ height: height / scale2,
2540
+ animationMode: whiteWebSdk.AnimationMode.Immediately
2541
+ });
2542
+ this._mainView$.value.setCameraBound({
2543
+ damping: 1,
2544
+ maxContentMode: () => scale2,
2545
+ minContentMode: () => scale2,
2546
+ centerX: this.baseWidth / 2,
2547
+ centerY: this.baseHeight / 2,
2548
+ width: this.baseWidth,
2549
+ height: this.baseHeight
2550
+ });
2551
+ }
2552
+ }
2553
+ dispose() {
2554
+ this.sideEffect.flushAll();
2555
+ }
2556
+ }
2615
2557
  class AppManager {
2616
2558
  constructor(windowManger) {
2559
+ var _a;
2617
2560
  this.windowManger = windowManger;
2618
2561
  this.appProxies = /* @__PURE__ */ new Map();
2619
2562
  this.appStatus = /* @__PURE__ */ new Map();
2620
2563
  this.store = store;
2621
2564
  this.isReplay = this.windowManger.isReplay;
2622
2565
  this.mainViewScenesLength = 0;
2566
+ this.scrollBaseSize$ = new valueEnhancer.Val(null);
2623
2567
  this.callbacksNode = null;
2624
2568
  this.appCreateQueue = new AppCreateQueue();
2625
2569
  this.sceneIndex$ = new valueEnhancer.Val(void 0);
2626
2570
  this.focused$ = new valueEnhancer.Val(void 0);
2627
2571
  this.members$ = new valueEnhancer.Val([]);
2572
+ this.isWritable$ = new valueEnhancer.Val(Boolean((_a = this.room) == null ? void 0 : _a.isWritable));
2628
2573
  this.sideEffectManager = new sideEffectManager.SideEffectManager();
2629
2574
  this.sceneState = null;
2630
2575
  this.rootDirRemoving = false;
2631
2576
  this.onRemoveScenes = async (params) => {
2632
- var _a, _b;
2577
+ var _a2, _b;
2633
2578
  const { scenePath } = params;
2634
2579
  if (scenePath === ROOT_DIR) {
2635
2580
  await this.onRootDirRemoved();
@@ -2638,7 +2583,7 @@ var __objRest = (source, exclude) => {
2638
2583
  }
2639
2584
  if (isRootDirPage(scenePath)) {
2640
2585
  let nextIndex = this.mainView.focusSceneIndex || 0;
2641
- let sceneName = (_a = this.callbacksNode) == null ? void 0 : _a.scenes[nextIndex];
2586
+ let sceneName = (_a2 = this.callbacksNode) == null ? void 0 : _a2.scenes[nextIndex];
2642
2587
  if (!sceneName) {
2643
2588
  nextIndex = 0;
2644
2589
  sceneName = (_b = this.callbacksNode) == null ? void 0 : _b.scenes[nextIndex];
@@ -2689,11 +2634,11 @@ var __objRest = (source, exclude) => {
2689
2634
  }
2690
2635
  };
2691
2636
  this.removeSceneByIndex = async (index2) => {
2692
- var _a;
2637
+ var _a2;
2693
2638
  const nextIndex = calculateNextIndex(index2, this.windowManger.pageState);
2694
2639
  this.setSceneIndexWithoutSync(nextIndex);
2695
2640
  this.dispatchInternalEvent(Events.SetAppFocusIndex, { type: "main", index: nextIndex });
2696
- const scene = (_a = this.callbacksNode) == null ? void 0 : _a.scenes[index2];
2641
+ const scene = (_a2 = this.callbacksNode) == null ? void 0 : _a2.scenes[index2];
2697
2642
  setTimeout(() => {
2698
2643
  if (scene) {
2699
2644
  removeScenes(this.room, `${ROOT_DIR}${scene}`, index2);
@@ -2711,8 +2656,8 @@ var __objRest = (source, exclude) => {
2711
2656
  });
2712
2657
  };
2713
2658
  this.setSceneIndexWithoutSync = (index2) => {
2714
- var _a;
2715
- const sceneName = (_a = this.callbacksNode) == null ? void 0 : _a.scenes[index2];
2659
+ var _a2;
2660
+ const sceneName = (_a2 = this.callbacksNode) == null ? void 0 : _a2.scenes[index2];
2716
2661
  if (sceneName) {
2717
2662
  this.mainViewProxy.setFocusScenePath(`${ROOT_DIR}${sceneName}`);
2718
2663
  }
@@ -2783,8 +2728,8 @@ var __objRest = (source, exclude) => {
2783
2728
  });
2784
2729
  };
2785
2730
  this.addAppCloseListener = () => {
2786
- var _a;
2787
- (_a = this.refresher) == null ? void 0 : _a.add("appsClose", () => {
2731
+ var _a2;
2732
+ (_a2 = this.refresher) == null ? void 0 : _a2.add("appsClose", () => {
2788
2733
  return onObjectRemoved(this.attributes.apps, () => {
2789
2734
  this.onAppDelete(this.attributes.apps);
2790
2735
  });
@@ -2801,13 +2746,13 @@ var __objRest = (source, exclude) => {
2801
2746
  }
2802
2747
  };
2803
2748
  this.onFocusChange = (focused) => {
2804
- var _a;
2749
+ var _a2;
2805
2750
  if (this.focused$.value !== focused) {
2806
2751
  callbacks.emit("focusedChange", focused);
2807
2752
  emitter.emit("focusedChange", { focused, prev: this.focused$.value });
2808
2753
  this.focused$.setValue(focused);
2809
2754
  if (focused !== void 0) {
2810
- (_a = this.boxManager) == null ? void 0 : _a.focusBox({ appId: focused });
2755
+ (_a2 = this.boxManager) == null ? void 0 : _a2.focusBox({ appId: focused });
2811
2756
  setTimeout(() => {
2812
2757
  const appProxy = this.appProxies.get(focused);
2813
2758
  if (appProxy) {
@@ -2833,14 +2778,14 @@ var __objRest = (source, exclude) => {
2833
2778
  });
2834
2779
  };
2835
2780
  this.onMinimized = (minimized) => {
2836
- var _a, _b;
2837
- if (((_a = this.boxManager) == null ? void 0 : _a.minimized) !== minimized) {
2781
+ var _a2, _b;
2782
+ if (((_a2 = this.boxManager) == null ? void 0 : _a2.minimized) !== minimized) {
2838
2783
  if (minimized === true) {
2839
2784
  (_b = this.boxManager) == null ? void 0 : _b.blurAllBox();
2840
2785
  }
2841
2786
  setTimeout(() => {
2842
- var _a2;
2843
- (_a2 = this.boxManager) == null ? void 0 : _a2.setMinimized(Boolean(minimized));
2787
+ var _a3;
2788
+ (_a3 = this.boxManager) == null ? void 0 : _a3.setMinimized(Boolean(minimized));
2844
2789
  }, 0);
2845
2790
  }
2846
2791
  };
@@ -2880,11 +2825,11 @@ var __objRest = (source, exclude) => {
2880
2825
  }
2881
2826
  };
2882
2827
  this.displayerWritableListener = (isReadonly) => {
2883
- var _a, _b;
2828
+ var _a2, _b;
2884
2829
  const isWritable = !isReadonly;
2885
2830
  const isManualWritable = this.windowManger.readonly === void 0 || !this.windowManger.readonly;
2886
2831
  if (this.windowManger.readonly === void 0) {
2887
- (_a = this.boxManager) == null ? void 0 : _a.setReadonly(isReadonly);
2832
+ (_a2 = this.boxManager) == null ? void 0 : _a2.setReadonly(isReadonly);
2888
2833
  } else {
2889
2834
  (_b = this.boxManager) == null ? void 0 : _b.setReadonly(!(isWritable && isManualWritable));
2890
2835
  }
@@ -2897,6 +2842,7 @@ var __objRest = (source, exclude) => {
2897
2842
  }
2898
2843
  }
2899
2844
  emitter.emit("writableChange", isWritable);
2845
+ this.isWritable$.setValue(isWritable);
2900
2846
  };
2901
2847
  this.updateSceneIndex = () => {
2902
2848
  const scenePath = this.store.getMainViewScenePath();
@@ -2929,10 +2875,10 @@ var __objRest = (source, exclude) => {
2929
2875
  this.refresher.setContext({ emitter });
2930
2876
  this.sideEffectManager.add(() => {
2931
2877
  return () => {
2932
- var _a, _b, _c;
2878
+ var _a2, _b, _c;
2933
2879
  this.appCreateQueue.destroy();
2934
2880
  this.mainViewProxy.destroy();
2935
- (_a = this.refresher) == null ? void 0 : _a.destroy();
2881
+ (_a2 = this.refresher) == null ? void 0 : _a2.destroy();
2936
2882
  this.viewManager.destroy();
2937
2883
  (_b = this.boxManager) == null ? void 0 : _b.destroy();
2938
2884
  (_c = this.callbacksNode) == null ? void 0 : _c.dispose();
@@ -2951,6 +2897,16 @@ var __objRest = (source, exclude) => {
2951
2897
  this.safeUpdateAttributes([Fields.Registered, payload.kind], payload);
2952
2898
  });
2953
2899
  this.members$.setValue(serializeRoomMembers(this.displayer.state.roomMembers));
2900
+ emitter.on("mainViewMounted", () => {
2901
+ this.windowManger.viewMode$.subscribe((viewMode) => {
2902
+ const playground = this.windowManger.playground$.value;
2903
+ if (viewMode === "scroll" && playground) {
2904
+ const scrollMode = new ScrollMode(this);
2905
+ this.scrollMode = scrollMode;
2906
+ scrollMode.setRoot(playground);
2907
+ }
2908
+ });
2909
+ });
2954
2910
  }
2955
2911
  async onRootDirRemoved(needClose = true) {
2956
2912
  await this.setMainViewScenePath(INIT_DIR);
@@ -3122,6 +3078,7 @@ var __objRest = (source, exclude) => {
3122
3078
  bindMainView(divElement, disableCameraTransform) {
3123
3079
  const mainView = this.mainViewProxy.view;
3124
3080
  mainView.disableCameraTransform = disableCameraTransform;
3081
+ console.log("bindMainView", mainView.disableCameraTransform);
3125
3082
  wait(30).then(() => {
3126
3083
  mainView.divElement = divElement;
3127
3084
  emitter.emit("mainViewMounted");
@@ -6888,7 +6845,7 @@ var __objRest = (source, exclude) => {
6888
6845
  this.initCursorInstance = (uid) => {
6889
6846
  let cursorInstance = this.cursorInstances.get(uid);
6890
6847
  if (!cursorInstance) {
6891
- cursorInstance = new Cursor(this.manager, uid, this, WindowManager.playground);
6848
+ cursorInstance = new Cursor(this.manager, uid, this, this.playground$.value);
6892
6849
  this.cursorInstances.set(uid, cursorInstance);
6893
6850
  }
6894
6851
  return cursorInstance;
@@ -6931,7 +6888,7 @@ var __objRest = (source, exclude) => {
6931
6888
  this.hideCursor(this.manager.uid);
6932
6889
  };
6933
6890
  this.roomMembers = (_a = this.manager.room) == null ? void 0 : _a.state.roomMembers;
6934
- const playground = WindowManager.playground;
6891
+ const playground = this.playground$.value;
6935
6892
  if (playground) {
6936
6893
  this.setupWrapper(playground);
6937
6894
  }
@@ -6945,6 +6902,9 @@ var __objRest = (source, exclude) => {
6945
6902
  this.applianceIcons = __spreadValues(__spreadValues({}, ApplianceMap), applianceIcons);
6946
6903
  }
6947
6904
  }
6905
+ get playground$() {
6906
+ return this.manager.windowManger.playground$;
6907
+ }
6948
6908
  canMoveCursor(member) {
6949
6909
  const isLaserPointer = (member == null ? void 0 : member.memberState.currentApplianceName) === whiteWebSdk.ApplianceNames.laserPointer;
6950
6910
  return this.enableCursor || isLaserPointer;
@@ -11682,70 +11642,35 @@ var __objRest = (source, exclude) => {
11682
11642
  const _WindowManager = class extends whiteWebSdk.InvisiblePlugin {
11683
11643
  constructor(context) {
11684
11644
  super(context);
11685
- this.version = "1.0.0-canary.52";
11686
- this.dependencies = { "dependencies": { "@juggle/resize-observer": "^3.3.1", "@netless/telebox-insider": "1.0.0-alpha.37", "emittery": "^0.11.0", "lodash": "^4.17.21", "p-retry": "^4.6.2", "side-effect-manager": "^1.1.1", "uuid": "^7.0.3", "value-enhancer": "^1.3.2" }, "peerDependencies": { "white-web-sdk": "^2.16.0" }, "devDependencies": { "@netless/app-docs-viewer": "^0.3.3", "@netless/app-plyr": "0.2.2", "@playwright/test": "^1.23.2", "@rollup/plugin-commonjs": "^20.0.0", "@rollup/plugin-node-resolve": "^13.0.4", "@rollup/plugin-url": "^6.1.0", "@sveltejs/vite-plugin-svelte": "^1.0.0-next.49", "@tsconfig/svelte": "^2.0.1", "@types/debug": "^4.1.7", "@types/lodash": "^4.14.182", "@types/lodash-es": "^4.17.6", "@types/node": "^18.0.3", "@types/uuid": "^8.3.4", "@typescript-eslint/eslint-plugin": "^4.30.0", "@typescript-eslint/parser": "^4.30.0", "@vitest/ui": "^0.14.2", "cypress": "^8.7.0", "dotenv": "^10.0.0", "eslint": "^7.32.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-svelte3": "^3.2.0", "jsdom": "^19.0.0", "less": "^4.1.3", "prettier": "^2.3.2", "prettier-plugin-svelte": "^2.4.0", "rollup-plugin-analyzer": "^4.0.0", "rollup-plugin-styles": "^3.14.1", "svelte": "^3.42.4", "typescript": "^4.5.5", "vite": "^2.5.3", "vite-plugin-dts": "^1.2.1", "vitest": "^0.18.0", "white-web-sdk": "2.16.26" } };
11645
+ this.version = "1.0.0-canary.54";
11646
+ this.dependencies = { "dependencies": { "@juggle/resize-observer": "^3.3.1", "@netless/synced-store": "^2.0.7", "@netless/telebox-insider": "1.0.0-alpha.37", "emittery": "^0.11.0", "lodash": "^4.17.21", "p-retry": "^4.6.2", "side-effect-manager": "^1.2.1", "uuid": "^7.0.3", "value-enhancer": "^1.3.2" }, "peerDependencies": { "white-web-sdk": "^2.16.0" }, "devDependencies": { "@netless/app-docs-viewer": "^0.3.3", "@netless/app-plyr": "0.2.2", "@playwright/test": "^1.23.2", "@rollup/plugin-commonjs": "^20.0.0", "@rollup/plugin-node-resolve": "^13.0.4", "@rollup/plugin-url": "^6.1.0", "@sveltejs/vite-plugin-svelte": "^1.0.0-next.49", "@tsconfig/svelte": "^2.0.1", "@types/debug": "^4.1.7", "@types/lodash": "^4.14.182", "@types/lodash-es": "^4.17.6", "@types/node": "^18.0.3", "@types/uuid": "^8.3.4", "@typescript-eslint/eslint-plugin": "^4.30.0", "@typescript-eslint/parser": "^4.30.0", "@vitest/ui": "^0.14.2", "cypress": "^8.7.0", "dotenv": "^10.0.0", "eslint": "^7.32.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-svelte3": "^3.2.0", "jsdom": "^19.0.0", "less": "^4.1.3", "prettier": "^2.3.2", "prettier-plugin-svelte": "^2.4.0", "rollup-plugin-analyzer": "^4.0.0", "rollup-plugin-styles": "^3.14.1", "svelte": "^3.42.4", "typescript": "^4.5.5", "vite": "^2.5.3", "vite-plugin-dts": "^1.2.1", "vitest": "^0.18.0", "white-web-sdk": "^2.16.35" } };
11687
11647
  this.emitter = callbacks;
11688
11648
  this.viewMode = whiteWebSdk.ViewMode.Broadcaster;
11689
11649
  this.viewMode$ = new valueEnhancer.Val(whiteWebSdk.ViewMode.Broadcaster);
11650
+ this.playground$ = new valueEnhancer.Val(void 0);
11690
11651
  this.isReplay = whiteWebSdk.isPlayer(this.displayer);
11691
- this.cameraUpdating = 0;
11692
- this.nextCamera = null;
11693
11652
  this.containerSizeRatio = _WindowManager.containerSizeRatio;
11694
11653
  this.moveCamera = (camera) => {
11695
11654
  var _a;
11655
+ const pureCamera = lodash.omit(camera, ["animationMode"]);
11696
11656
  const mainViewCamera = __spreadValues({}, this.mainView.camera);
11697
- const nextCamera = __spreadValues(__spreadValues({}, mainViewCamera), camera);
11698
- if (lodash.isEqual(nextCamera, mainViewCamera))
11657
+ if (lodash.isEqual(__spreadValues(__spreadValues({}, mainViewCamera), pureCamera), mainViewCamera))
11699
11658
  return;
11700
- if (!this.appManager)
11701
- return;
11702
- if (camera.animationMode === whiteWebSdk.AnimationMode.Immediately) {
11703
- this.appManager.mainViewProxy.storeCamera(__spreadValues({
11704
- id: this.appManager.uid
11705
- }, nextCamera));
11706
- } else {
11707
- const remoteCamera = this.appManager.mainViewProxy.size$.value;
11708
- const currentSize = (_a = this.boxManager) == null ? void 0 : _a.stageRect;
11709
- let nextScale;
11710
- if (camera.scale && remoteCamera && currentSize) {
11711
- nextScale = camera.scale * computedMinScale(remoteCamera, currentSize);
11712
- }
11713
- if (nextScale) {
11714
- this.mainView.moveCamera(__spreadProps(__spreadValues({}, camera), {
11715
- scale: nextScale
11716
- }));
11717
- } else {
11718
- this.mainView.moveCamera(camera);
11719
- }
11720
- this.appManager.dispatchInternalEvent(Events.MoveCamera, camera);
11721
- this.mainView.callbacks.off("onCameraUpdated", this.onCameraUpdated);
11722
- clearTimeout(this.cameraUpdating);
11723
- this.cameraUpdating = 0;
11724
- this.mainView.callbacks.on("onCameraUpdated", this.onCameraUpdated);
11725
- if (nextScale) {
11726
- this.nextCamera = nextCamera;
11727
- }
11728
- }
11729
- };
11730
- this.onCameraUpdated = () => {
11731
- if (this.cameraUpdating) {
11732
- clearTimeout(this.cameraUpdating);
11733
- this.cameraUpdating = 0;
11734
- }
11735
- this.cameraUpdating = setTimeout(() => {
11736
- this.mainView.callbacks.off("onCameraUpdated", this.onCameraUpdated);
11737
- clearTimeout(this.cameraUpdating);
11738
- this.cameraUpdating = 0;
11739
- if (!this.appManager || !this.nextCamera)
11740
- return;
11741
- this.appManager.mainViewProxy.storeCamera(__spreadValues({
11742
- id: this.appManager.uid
11743
- }, this.nextCamera));
11744
- this.nextCamera = null;
11745
- }, 50);
11659
+ this.debouncedStoreCamera();
11660
+ this.mainView.moveCamera(camera);
11661
+ (_a = this.appManager) == null ? void 0 : _a.dispatchInternalEvent(Events.MoveCamera, camera);
11662
+ };
11663
+ this.debouncedStoreCamera = () => {
11664
+ const storeCamera = lodash.debounce(() => {
11665
+ var _a, _b;
11666
+ (_a = this.appManager) == null ? void 0 : _a.mainViewProxy.storeCurrentCamera();
11667
+ (_b = this.appManager) == null ? void 0 : _b.mainViewProxy.storeCurrentSize();
11668
+ this.mainView.callbacks.off("onCameraUpdated", storeCamera);
11669
+ }, 200);
11670
+ this.mainView.callbacks.on("onCameraUpdated", storeCamera);
11746
11671
  };
11747
11672
  _WindowManager.displayer = context.displayer;
11748
- window.NETLESS_DEPS = { "dependencies": { "@juggle/resize-observer": "^3.3.1", "@netless/telebox-insider": "1.0.0-alpha.37", "emittery": "^0.11.0", "lodash": "^4.17.21", "p-retry": "^4.6.2", "side-effect-manager": "^1.1.1", "uuid": "^7.0.3", "value-enhancer": "^1.3.2" }, "peerDependencies": { "white-web-sdk": "^2.16.0" }, "devDependencies": { "@netless/app-docs-viewer": "^0.3.3", "@netless/app-plyr": "0.2.2", "@playwright/test": "^1.23.2", "@rollup/plugin-commonjs": "^20.0.0", "@rollup/plugin-node-resolve": "^13.0.4", "@rollup/plugin-url": "^6.1.0", "@sveltejs/vite-plugin-svelte": "^1.0.0-next.49", "@tsconfig/svelte": "^2.0.1", "@types/debug": "^4.1.7", "@types/lodash": "^4.14.182", "@types/lodash-es": "^4.17.6", "@types/node": "^18.0.3", "@types/uuid": "^8.3.4", "@typescript-eslint/eslint-plugin": "^4.30.0", "@typescript-eslint/parser": "^4.30.0", "@vitest/ui": "^0.14.2", "cypress": "^8.7.0", "dotenv": "^10.0.0", "eslint": "^7.32.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-svelte3": "^3.2.0", "jsdom": "^19.0.0", "less": "^4.1.3", "prettier": "^2.3.2", "prettier-plugin-svelte": "^2.4.0", "rollup-plugin-analyzer": "^4.0.0", "rollup-plugin-styles": "^3.14.1", "svelte": "^3.42.4", "typescript": "^4.5.5", "vite": "^2.5.3", "vite-plugin-dts": "^1.2.1", "vitest": "^0.18.0", "white-web-sdk": "2.16.26" } };
11673
+ window.NETLESS_DEPS = { "dependencies": { "@juggle/resize-observer": "^3.3.1", "@netless/synced-store": "^2.0.7", "@netless/telebox-insider": "1.0.0-alpha.37", "emittery": "^0.11.0", "lodash": "^4.17.21", "p-retry": "^4.6.2", "side-effect-manager": "^1.2.1", "uuid": "^7.0.3", "value-enhancer": "^1.3.2" }, "peerDependencies": { "white-web-sdk": "^2.16.0" }, "devDependencies": { "@netless/app-docs-viewer": "^0.3.3", "@netless/app-plyr": "0.2.2", "@playwright/test": "^1.23.2", "@rollup/plugin-commonjs": "^20.0.0", "@rollup/plugin-node-resolve": "^13.0.4", "@rollup/plugin-url": "^6.1.0", "@sveltejs/vite-plugin-svelte": "^1.0.0-next.49", "@tsconfig/svelte": "^2.0.1", "@types/debug": "^4.1.7", "@types/lodash": "^4.14.182", "@types/lodash-es": "^4.17.6", "@types/node": "^18.0.3", "@types/uuid": "^8.3.4", "@typescript-eslint/eslint-plugin": "^4.30.0", "@typescript-eslint/parser": "^4.30.0", "@vitest/ui": "^0.14.2", "cypress": "^8.7.0", "dotenv": "^10.0.0", "eslint": "^7.32.0", "eslint-config-prettier": "^8.3.0", "eslint-plugin-svelte3": "^3.2.0", "jsdom": "^19.0.0", "less": "^4.1.3", "prettier": "^2.3.2", "prettier-plugin-svelte": "^2.4.0", "rollup-plugin-analyzer": "^4.0.0", "rollup-plugin-styles": "^3.14.1", "svelte": "^3.42.4", "typescript": "^4.5.5", "vite": "^2.5.3", "vite-plugin-dts": "^1.2.1", "vitest": "^0.18.0", "white-web-sdk": "^2.16.35" } };
11749
11674
  }
11750
11675
  static async mount(params) {
11751
11676
  var _a;
@@ -11792,6 +11717,9 @@ var __objRest = (source, exclude) => {
11792
11717
  }
11793
11718
  manager.containerSizeRatio = _WindowManager.containerSizeRatio;
11794
11719
  await manager.ensureAttributes();
11720
+ if (params.viewMode) {
11721
+ manager.viewMode$.setValue(params.viewMode);
11722
+ }
11795
11723
  manager.appManager = new AppManager(manager);
11796
11724
  manager._pageState = new PageStateImpl(manager.appManager);
11797
11725
  manager.cursorManager = new CursorManager(manager.appManager, Boolean(cursor), params.applianceIcons);
@@ -11809,6 +11737,9 @@ var __objRest = (source, exclude) => {
11809
11737
  if (params.container) {
11810
11738
  manager.bindContainer(params.container);
11811
11739
  }
11740
+ if (params.scrollModeWidth && params.scrollModeHeight) {
11741
+ manager.appManager.scrollBaseSize$.setValue({ width: params.scrollModeWidth, height: params.scrollModeHeight });
11742
+ }
11812
11743
  replaceRoomFunction(room, manager);
11813
11744
  emitter.emit("onCreated");
11814
11745
  _WindowManager.isCreated = true;
@@ -11877,6 +11808,7 @@ var __objRest = (source, exclude) => {
11877
11808
  this.bindMainView(mainViewElement, params.disableCameraTransform);
11878
11809
  if (_WindowManager.playground) {
11879
11810
  (_b = this.cursorManager) == null ? void 0 : _b.setupWrapper(_WindowManager.playground);
11811
+ this.playground$.setValue(_WindowManager.playground);
11880
11812
  }
11881
11813
  }
11882
11814
  }
@@ -12092,10 +12024,11 @@ var __objRest = (source, exclude) => {
12092
12024
  if (mode === whiteWebSdk.ViewMode.Broadcaster) {
12093
12025
  if (this.canOperate) {
12094
12026
  mainViewProxy == null ? void 0 : mainViewProxy.storeCurrentCamera();
12027
+ mainViewProxy == null ? void 0 : mainViewProxy.storeCurrentSize();
12095
12028
  }
12096
12029
  mainViewProxy == null ? void 0 : mainViewProxy.start();
12097
12030
  }
12098
- if (mode === whiteWebSdk.ViewMode.Freedom) {
12031
+ if (mode === whiteWebSdk.ViewMode.Freedom || mode === "scroll") {
12099
12032
  mainViewProxy == null ? void 0 : mainViewProxy.stop();
12100
12033
  }
12101
12034
  this.viewMode = mode;
@@ -12246,6 +12179,10 @@ var __objRest = (source, exclude) => {
12246
12179
  throw new AppManagerNotInitError();
12247
12180
  }
12248
12181
  }
12182
+ get scrollState() {
12183
+ var _a, _b;
12184
+ return (_b = (_a = this.appManager) == null ? void 0 : _a.scrollMode) == null ? void 0 : _b.scrollState$.value;
12185
+ }
12249
12186
  get teleboxManager() {
12250
12187
  if (!this.boxManager) {
12251
12188
  throw new BoxManagerNotInitializeError();
@@ -12264,6 +12201,12 @@ var __objRest = (source, exclude) => {
12264
12201
  var _a;
12265
12202
  return (_a = this.appManager) == null ? void 0 : _a.closeApp(appId);
12266
12203
  }
12204
+ moveCameraToContain(rectangle) {
12205
+ var _a;
12206
+ this.debouncedStoreCamera();
12207
+ this.mainView.moveCameraToContain(rectangle);
12208
+ (_a = this.appManager) == null ? void 0 : _a.dispatchInternalEvent(Events.MoveCameraToContain, rectangle);
12209
+ }
12267
12210
  convertToPointInWorld(point) {
12268
12211
  return this.mainView.convertToPointInWorld(point);
12269
12212
  }