@netless/window-manager 1.0.0-canary.53 → 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 +381 -444
  2. package/dist/index.es.js +427 -490
  3. package/dist/index.umd.js +381 -445
  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 +3 -2
  9. package/dist/src/View/ScrollMode.d.ts +32 -0
  10. package/dist/src/View/ViewSync.d.ts +3 -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 +33 -22
  27. package/src/View/MainView.ts +1 -0
  28. package/src/View/ScrollMode.ts +229 -0
  29. package/src/View/ViewSync.ts +24 -16
  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.cjs.js CHANGED
@@ -36,8 +36,9 @@ var Emittery = require("emittery");
36
36
  var lodash = require("lodash");
37
37
  var whiteWebSdk = require("white-web-sdk");
38
38
  var uuid = require("uuid");
39
- var sideEffectManager = require("side-effect-manager");
39
+ var syncedStore = require("@netless/synced-store");
40
40
  var valueEnhancer = require("value-enhancer");
41
+ var sideEffectManager = require("side-effect-manager");
41
42
  var resizeObserver = require("@juggle/resize-observer");
42
43
  function _interopDefaultLegacy(e) {
43
44
  return e && typeof e === "object" && "default" in e ? e : { "default": e };
@@ -102,6 +103,8 @@ const ROOT_DIR = "/";
102
103
  const INIT_DIR = "/init";
103
104
  const SETUP_APP_DELAY = 50;
104
105
  const MAX_PAGE_SIZE = 500;
106
+ const SCROLL_MODE_BASE_WIDTH = 1600;
107
+ const SCROLL_MODE_BASE_HEIGHT = SCROLL_MODE_BASE_WIDTH * 3;
105
108
  const callbacks = new Emittery__default["default"]();
106
109
  class AppCreateQueue {
107
110
  constructor() {
@@ -522,67 +525,6 @@ const isRootDirPage = (scenePath) => {
522
525
  }, 0);
523
526
  return delimiterCount === 1;
524
527
  };
525
- class CameraSynchronizer {
526
- constructor(saveCamera) {
527
- this.saveCamera = saveCamera;
528
- this.setRect = (rect, updateCamera = true) => {
529
- this.rect = rect;
530
- if (this.remoteCamera && this.remoteSize && updateCamera) {
531
- this.onRemoteUpdate(this.remoteCamera, this.remoteSize);
532
- }
533
- };
534
- this.onRemoteUpdate = lodash.throttle((camera, size) => {
535
- this.remoteCamera = camera;
536
- this.remoteSize = size;
537
- if (this.remoteSize && this.rect) {
538
- const nextScale = camera.scale * computedMinScale(size, this.rect);
539
- const config = {
540
- scale: nextScale
541
- };
542
- if (camera.centerX !== null) {
543
- config.centerX = camera.centerX;
544
- }
545
- if (camera.centerY !== null) {
546
- config.centerY = camera.centerY;
547
- }
548
- console.trace("moveCamera");
549
- this.moveCamera(config);
550
- }
551
- }, 10);
552
- }
553
- setView(view) {
554
- this.view = view;
555
- }
556
- onRemoteSizeUpdate(size) {
557
- var _a;
558
- this.remoteSize = size;
559
- const needMoveCamera = !lodash.isEqual(lodash.pick(this.rect, ["width", "height"]), lodash.pick(size, ["width", "height"]));
560
- if (this.rect && this.remoteCamera && needMoveCamera) {
561
- if (!this.view)
562
- return;
563
- const currentCamera = this.view.camera;
564
- (_a = this.view) == null ? void 0 : _a.moveCameraToContain({
565
- width: size.width,
566
- height: size.height,
567
- originX: currentCamera.centerX - size.width / 2,
568
- originY: currentCamera.centerY - size.height / 2
569
- });
570
- }
571
- }
572
- onLocalCameraUpdate(camera) {
573
- this.saveCamera(camera);
574
- this.remoteCamera = camera;
575
- }
576
- moveCamera(camera) {
577
- var _a;
578
- (_a = this.view) == null ? void 0 : _a.moveCamera(__spreadProps(__spreadValues({}, camera), { animationMode: whiteWebSdk.AnimationMode.Immediately }));
579
- }
580
- }
581
- const computedMinScale = (remoteSize, currentSize) => {
582
- const wScale = currentSize.width / remoteSize.width;
583
- const hScale = currentSize.height / remoteSize.height;
584
- return Math.min(wScale, hScale);
585
- };
586
528
  class AppListeners {
587
529
  constructor(manager) {
588
530
  this.manager = manager;
@@ -683,16 +625,7 @@ class AppListeners {
683
625
  }
684
626
  };
685
627
  this.moveCameraHandler = (payload) => {
686
- var _a;
687
- const cameraPayload = payload;
688
- if (payload.scale) {
689
- const remoteSize = this.manager.mainViewProxy.size$.value;
690
- const currentSize = (_a = this.manager.boxManager) == null ? void 0 : _a.stageRect;
691
- if (remoteSize && currentSize) {
692
- cameraPayload.scale = payload.scale * computedMinScale(remoteSize, currentSize);
693
- }
694
- }
695
- this.manager.mainView.moveCamera(cameraPayload);
628
+ this.manager.mainView.moveCamera(payload);
696
629
  };
697
630
  this.moveCameraToContainHandler = (payload) => {
698
631
  this.manager.mainView.moveCameraToContain(payload);
@@ -760,292 +693,6 @@ class BindContainerRoomPhaseInvalidError extends Error {
760
693
  this.message = "[WindowManager]: room phase only Connected can be bindContainer";
761
694
  }
762
695
  }
763
- const onObjectByEvent = (event) => {
764
- return (object, func) => {
765
- if (object === void 0)
766
- return;
767
- if (whiteWebSdk.listenUpdated) {
768
- const listener = (events) => {
769
- const kinds = events.map((e) => e.kind);
770
- if (kinds.includes(event)) {
771
- func();
772
- }
773
- };
774
- whiteWebSdk.listenUpdated(object, listener);
775
- func();
776
- return () => whiteWebSdk.unlistenUpdated(object, listener);
777
- } else {
778
- return whiteWebSdk.reaction(() => object, () => {
779
- func();
780
- }, {
781
- fireImmediately: true
782
- });
783
- }
784
- };
785
- };
786
- const safeListenPropsUpdated = (getProps, callback, onDestroyed) => {
787
- let disposeListenUpdated = null;
788
- const disposeReaction = whiteWebSdk.reaction(getProps, () => {
789
- if (disposeListenUpdated) {
790
- disposeListenUpdated();
791
- disposeListenUpdated = null;
792
- }
793
- const props = getProps();
794
- if (lodash.isObject(props)) {
795
- disposeListenUpdated = () => whiteWebSdk.unlistenUpdated(props, callback);
796
- whiteWebSdk.listenUpdated(props, callback);
797
- } else {
798
- onDestroyed == null ? void 0 : onDestroyed(props);
799
- }
800
- }, { fireImmediately: true });
801
- return () => {
802
- disposeListenUpdated == null ? void 0 : disposeListenUpdated();
803
- disposeReaction();
804
- };
805
- };
806
- const onObjectRemoved = onObjectByEvent(whiteWebSdk.UpdateEventKind.Removed);
807
- onObjectByEvent(whiteWebSdk.UpdateEventKind.Inserted);
808
- const plainObjectKeys = Object.keys;
809
- function isRef(e) {
810
- return Boolean(lodash.has(e, "__isRef"));
811
- }
812
- function makeRef(v) {
813
- return { k: sideEffectManager.genUID(), v, __isRef: true };
814
- }
815
- class StorageEvent {
816
- constructor() {
817
- this.listeners = /* @__PURE__ */ new Set();
818
- }
819
- get length() {
820
- return this.listeners.size;
821
- }
822
- dispatch(message) {
823
- this.listeners.forEach((callback) => callback(message));
824
- }
825
- addListener(listener) {
826
- this.listeners.add(listener);
827
- }
828
- removeListener(listener) {
829
- this.listeners.delete(listener);
830
- }
831
- }
832
- const STORAGE_NS = "_WM-STORAGE_";
833
- class Storage {
834
- constructor(context, id, defaultState) {
835
- this._sideEffect = new sideEffectManager.SideEffectManager();
836
- this._destroyed = false;
837
- this._refMap = /* @__PURE__ */ new WeakMap();
838
- this._lastValue = /* @__PURE__ */ new Map();
839
- this.onStateChanged = new StorageEvent();
840
- if (defaultState && !lodash.isObject(defaultState)) {
841
- throw new Error(`Default state for Storage ${id} is not an object.`);
842
- }
843
- this._context = context;
844
- this.id = id || null;
845
- this._state = {};
846
- const rawState = this._getRawState(this._state);
847
- if (this._context.isWritable) {
848
- if (this.id === null) {
849
- if (context.isAddApp && defaultState) {
850
- this.setState(defaultState);
851
- }
852
- } else {
853
- if (rawState === this._state || !lodash.isObject(rawState)) {
854
- if (!lodash.get(this._context.getAttributes(), [STORAGE_NS])) {
855
- this._context.updateAttributes([STORAGE_NS], {});
856
- }
857
- this._context.updateAttributes([STORAGE_NS, this.id], this._state);
858
- if (defaultState) {
859
- this.setState(defaultState);
860
- }
861
- }
862
- }
863
- }
864
- plainObjectKeys(rawState).forEach((key) => {
865
- if (this.id === null && key === STORAGE_NS) {
866
- return;
867
- }
868
- try {
869
- const rawValue = lodash.isObject(rawState[key]) ? JSON.parse(JSON.stringify(rawState[key])) : rawState[key];
870
- if (isRef(rawValue)) {
871
- this._state[key] = rawValue.v;
872
- if (lodash.isObject(rawValue.v)) {
873
- this._refMap.set(rawValue.v, rawValue);
874
- }
875
- } else {
876
- this._state[key] = rawValue;
877
- }
878
- } catch (e) {
879
- console.error(e);
880
- }
881
- });
882
- 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)));
883
- }
884
- get state() {
885
- if (this._destroyed) {
886
- console.warn(`Accessing state on destroyed Storage "${this.id}"`);
887
- }
888
- return this._state;
889
- }
890
- addStateChangedListener(handler) {
891
- this.onStateChanged.addListener(handler);
892
- return () => this.onStateChanged.removeListener(handler);
893
- }
894
- ensureState(state) {
895
- return this.setState(plainObjectKeys(state).reduce((payload, key) => {
896
- if (!lodash.has(this._state, key)) {
897
- payload[key] = state[key];
898
- }
899
- return payload;
900
- }, {}));
901
- }
902
- setState(state) {
903
- if (this._destroyed) {
904
- console.error(new Error(`Cannot call setState on destroyed Storage "${this.id}".`));
905
- return;
906
- }
907
- if (!this._context.isWritable) {
908
- console.error(new Error(`Cannot setState on Storage "${this.id}" without writable access`), state);
909
- return;
910
- }
911
- const keys = plainObjectKeys(state);
912
- if (keys.length > 0) {
913
- keys.forEach((key) => {
914
- const value = state[key];
915
- if (value === this._state[key]) {
916
- return;
917
- }
918
- if (value === void 0) {
919
- this._lastValue.set(key, this._state[key]);
920
- delete this._state[key];
921
- this._setRawState(key, value);
922
- } else {
923
- this._lastValue.set(key, this._state[key]);
924
- this._state[key] = value;
925
- let payload = value;
926
- if (lodash.isObject(value)) {
927
- let refValue = this._refMap.get(value);
928
- if (!refValue) {
929
- refValue = makeRef(value);
930
- this._refMap.set(value, refValue);
931
- }
932
- payload = refValue;
933
- }
934
- this._setRawState(key, payload);
935
- }
936
- });
937
- }
938
- }
939
- emptyStorage() {
940
- if (lodash.size(this._state) <= 0) {
941
- return;
942
- }
943
- if (this._destroyed) {
944
- console.error(new Error(`Cannot empty destroyed Storage "${this.id}".`));
945
- return;
946
- }
947
- if (!this._context.isWritable) {
948
- console.error(new Error(`Cannot empty Storage "${this.id}" without writable access.`));
949
- return;
950
- }
951
- this.setState(lodash.mapValues(this._state, lodash.noop));
952
- }
953
- deleteStorage() {
954
- if (this.id === null) {
955
- throw new Error(`Cannot delete main Storage`);
956
- }
957
- if (!this._context.isWritable) {
958
- console.error(new Error(`Cannot delete Storage "${this.id}" without writable access.`));
959
- return;
960
- }
961
- this.destroy();
962
- this._context.updateAttributes([STORAGE_NS, this.id], void 0);
963
- }
964
- get destroyed() {
965
- return this._destroyed;
966
- }
967
- destroy() {
968
- this._destroyed = true;
969
- this._sideEffect.flushAll();
970
- }
971
- _getRawState(defaultValue) {
972
- var _a;
973
- if (this.id === null) {
974
- return (_a = this._context.getAttributes()) != null ? _a : defaultValue;
975
- } else {
976
- return lodash.get(this._context.getAttributes(), [STORAGE_NS, this.id], defaultValue);
977
- }
978
- }
979
- _setRawState(key, value) {
980
- if (this.id === null) {
981
- if (key === STORAGE_NS) {
982
- throw new Error(`Cannot set attribute internal filed "${STORAGE_NS}"`);
983
- }
984
- return this._context.updateAttributes([key], value);
985
- } else {
986
- return this._context.updateAttributes([STORAGE_NS, this.id, key], value);
987
- }
988
- }
989
- _updateProperties(actions) {
990
- var _a;
991
- if (this._destroyed) {
992
- console.error(new Error(`Cannot call _updateProperties on destroyed Storage "${this.id}".`));
993
- return;
994
- }
995
- if (actions.length > 0) {
996
- const diffs = {};
997
- for (let i = 0; i < actions.length; i++) {
998
- try {
999
- const action = actions[i];
1000
- const key = action.key;
1001
- if (this.id === null && key === STORAGE_NS) {
1002
- continue;
1003
- }
1004
- const value = lodash.isObject(action.value) ? JSON.parse(JSON.stringify(action.value)) : action.value;
1005
- let oldValue;
1006
- if (this._lastValue.has(key)) {
1007
- oldValue = this._lastValue.get(key);
1008
- this._lastValue.delete(key);
1009
- }
1010
- switch (action.kind) {
1011
- case 2: {
1012
- if (lodash.has(this._state, key)) {
1013
- oldValue = this._state[key];
1014
- delete this._state[key];
1015
- }
1016
- diffs[key] = { oldValue };
1017
- break;
1018
- }
1019
- default: {
1020
- let newValue = value;
1021
- if (isRef(value)) {
1022
- const { k: k2, v } = value;
1023
- const curValue = this._state[key];
1024
- if (lodash.isObject(curValue) && ((_a = this._refMap.get(curValue)) == null ? void 0 : _a.k) === k2) {
1025
- newValue = curValue;
1026
- } else {
1027
- newValue = v;
1028
- if (lodash.isObject(v)) {
1029
- this._refMap.set(v, value);
1030
- }
1031
- }
1032
- }
1033
- if (newValue !== this._state[key]) {
1034
- oldValue = this._state[key];
1035
- this._state[key] = newValue;
1036
- }
1037
- diffs[key] = { newValue, oldValue };
1038
- break;
1039
- }
1040
- }
1041
- } catch (e) {
1042
- console.error(e);
1043
- }
1044
- }
1045
- this.onStateChanged.dispatch(diffs);
1046
- }
1047
- }
1048
- }
1049
696
  class WhiteBoardView {
1050
697
  constructor(view, appContext, appProxy, ensureSize) {
1051
698
  this.view = view;
@@ -1074,11 +721,12 @@ class WhiteBoardView {
1074
721
  const scenePath = this.appProxy.scenePath;
1075
722
  if (!scenePath)
1076
723
  return;
724
+ const scenes = Array.isArray(scene) ? scene : [scene || {}];
1077
725
  if (after) {
1078
726
  const nextIndex = this.pageState.index + 1;
1079
- putScenes(this.appContext.room, scenePath, [scene || {}], nextIndex);
727
+ putScenes(this.appContext.room, scenePath, scenes, nextIndex);
1080
728
  } else {
1081
- putScenes(this.appContext.room, scenePath, [scene || {}]);
729
+ putScenes(this.appContext.room, scenePath, scenes);
1082
730
  }
1083
731
  };
1084
732
  this.removePage = async (index2) => {
@@ -1278,10 +926,20 @@ class AppContext {
1278
926
  this.getAppOptions = () => {
1279
927
  return typeof this.appOptions === "function" ? this.appOptions() : this.appOptions;
1280
928
  };
1281
- this.createStorage = (storeId, defaultState) => {
1282
- const storage = new Storage(this, storeId, defaultState);
929
+ this.createStorage = (namespace, defaultState) => {
930
+ const isWritable$ = new valueEnhancer.Val(this.isWritable);
931
+ const plugin$ = new valueEnhancer.Val(this.manager.windowManger);
932
+ const storage = new syncedStore.Storage({
933
+ plugin$,
934
+ isWritable$,
935
+ namespace,
936
+ defaultState
937
+ });
938
+ this.emitter.on("writableChange", (writable) => {
939
+ isWritable$.setValue(writable);
940
+ });
1283
941
  this.emitter.on("destroy", () => {
1284
- storage.destroy();
942
+ storage.disconnect();
1285
943
  });
1286
944
  return storage;
1287
945
  };
@@ -1344,7 +1002,7 @@ class AppContext {
1344
1002
  }
1345
1003
  get storage() {
1346
1004
  if (!this._storage) {
1347
- this._storage = new Storage(this);
1005
+ this._storage = this.createStorage(this.appId, this.getAttributes());
1348
1006
  }
1349
1007
  return this._storage;
1350
1008
  }
@@ -1402,6 +1060,77 @@ class AppPageStateImpl {
1402
1060
  (_a = this.sceneNode) == null ? void 0 : _a.dispose();
1403
1061
  }
1404
1062
  }
1063
+ class CameraSynchronizer {
1064
+ constructor(saveCamera) {
1065
+ this.saveCamera = saveCamera;
1066
+ this.scale = 1;
1067
+ this.setRect = (rect, updateCamera = true) => {
1068
+ this.rect = rect;
1069
+ if (this.remoteCamera && this.remoteSize && updateCamera) {
1070
+ this.onRemoteUpdate(this.remoteCamera, this.remoteSize);
1071
+ }
1072
+ };
1073
+ this.onRemoteUpdate = lodash.throttle((camera, size) => {
1074
+ this.remoteCamera = camera;
1075
+ this.remoteSize = size;
1076
+ if (this.remoteSize && this.rect) {
1077
+ requestAnimationFrame(() => {
1078
+ this.moveCameraToContian(size);
1079
+ this.moveCamera(camera);
1080
+ });
1081
+ }
1082
+ }, 32);
1083
+ }
1084
+ setView(view) {
1085
+ this.view = view;
1086
+ }
1087
+ onRemoteSizeUpdate(size) {
1088
+ var _a;
1089
+ this.remoteSize = size;
1090
+ const needMoveCamera = !lodash.isEqual(lodash.pick(this.rect, ["width", "height"]), lodash.pick(size, ["width", "height"]));
1091
+ if (this.rect && this.remoteCamera && needMoveCamera) {
1092
+ if (!this.view)
1093
+ return;
1094
+ const currentCamera = this.view.camera;
1095
+ (_a = this.view) == null ? void 0 : _a.moveCameraToContain({
1096
+ width: size.width,
1097
+ height: size.height,
1098
+ originX: currentCamera.centerX - size.width / 2,
1099
+ originY: currentCamera.centerY - size.height / 2
1100
+ });
1101
+ }
1102
+ }
1103
+ onLocalCameraUpdate(camera) {
1104
+ this.saveCamera(camera);
1105
+ this.remoteCamera = camera;
1106
+ }
1107
+ moveCameraToContian(size) {
1108
+ if (!lodash.isEmpty(size) && this.view) {
1109
+ this.view.moveCameraToContain({
1110
+ width: size.width,
1111
+ height: size.height,
1112
+ originX: -size.width / 2,
1113
+ originY: -size.height / 2,
1114
+ animationMode: whiteWebSdk.AnimationMode.Immediately
1115
+ });
1116
+ this.scale = this.view.camera.scale;
1117
+ }
1118
+ }
1119
+ moveCamera(camera) {
1120
+ if (!lodash.isEmpty(camera) && this.view && camera.centerX && camera.centerY) {
1121
+ if (lodash.isEqual(camera, this.view.camera))
1122
+ return;
1123
+ const { centerX, centerY, scale: scale2 } = camera;
1124
+ const needScale = scale2 * (this.scale || 1);
1125
+ this.view.moveCamera({
1126
+ centerX,
1127
+ centerY,
1128
+ scale: needScale,
1129
+ animationMode: whiteWebSdk.AnimationMode.Immediately
1130
+ });
1131
+ }
1132
+ }
1133
+ }
1405
1134
  class ViewSync {
1406
1135
  constructor(context) {
1407
1136
  this.context = context;
@@ -1419,8 +1148,9 @@ class ViewSync {
1419
1148
  };
1420
1149
  this.subscribeView = () => {
1421
1150
  return this.context.view$.subscribe((view) => {
1151
+ var _a;
1422
1152
  const currentCamera = this.context.camera$.value;
1423
- if (currentCamera && this.context.size$.value) {
1153
+ if (currentCamera && this.context.size$.value && ((_a = this.needRecoverCamera$) == null ? void 0 : _a.value)) {
1424
1154
  view == null ? void 0 : view.moveCamera({
1425
1155
  scale: 1,
1426
1156
  animationMode: whiteWebSdk.AnimationMode.Immediately
@@ -1469,10 +1199,13 @@ class ViewSync {
1469
1199
  return;
1470
1200
  if (!this.isBroadcastMode)
1471
1201
  return;
1472
- if (this.context.size$.value && this.context.stageRect$.value) {
1473
- const diffScale = computedMinScale(this.context.size$.value, this.context.stageRect$.value);
1474
- const remoteScale = camera.scale / diffScale;
1475
- this.synchronizer.onLocalCameraUpdate(__spreadProps(__spreadValues({}, camera), { scale: remoteScale, id: this.context.uid }));
1202
+ const { size$, stageRect$, view$ } = this.context;
1203
+ if (size$.value && stageRect$.value && view$.value) {
1204
+ this.synchronizer.onLocalCameraUpdate(__spreadProps(__spreadValues({}, camera), { id: this.context.uid }));
1205
+ const newSize = __spreadProps(__spreadValues({}, view$.value.size), { id: this.context.uid });
1206
+ if (!lodash.isEqual(size$.value, newSize)) {
1207
+ this.context.storeSize(newSize);
1208
+ }
1476
1209
  }
1477
1210
  };
1478
1211
  this.synchronizer = this.createSynchronizer();
@@ -1483,9 +1216,13 @@ class ViewSync {
1483
1216
  this.subscribeSize(),
1484
1217
  this.subscribeStageRect()
1485
1218
  ]);
1219
+ if (context.viewMode$) {
1220
+ this.needRecoverCamera$ = valueEnhancer.derive(context.viewMode$, (mode) => mode !== "scroll");
1221
+ }
1486
1222
  const camera$size$ = valueEnhancer.combine([this.context.camera$, this.context.size$]);
1487
1223
  camera$size$.reaction(([camera, size]) => {
1488
- if (camera && size) {
1224
+ var _a;
1225
+ if (camera && size && ((_a = this.needRecoverCamera$) == null ? void 0 : _a.value)) {
1489
1226
  this.synchronizer.onRemoteUpdate(camera, size);
1490
1227
  camera$size$.destroy();
1491
1228
  }
@@ -2566,6 +2303,51 @@ class MainViewProxy {
2566
2303
  this.sideEffectManager.flushAll();
2567
2304
  }
2568
2305
  }
2306
+ const onObjectByEvent = (event) => {
2307
+ return (object, func) => {
2308
+ if (object === void 0)
2309
+ return;
2310
+ if (whiteWebSdk.listenUpdated) {
2311
+ const listener = (events) => {
2312
+ const kinds = events.map((e) => e.kind);
2313
+ if (kinds.includes(event)) {
2314
+ func();
2315
+ }
2316
+ };
2317
+ whiteWebSdk.listenUpdated(object, listener);
2318
+ func();
2319
+ return () => whiteWebSdk.unlistenUpdated(object, listener);
2320
+ } else {
2321
+ return whiteWebSdk.reaction(() => object, () => {
2322
+ func();
2323
+ }, {
2324
+ fireImmediately: true
2325
+ });
2326
+ }
2327
+ };
2328
+ };
2329
+ const safeListenPropsUpdated = (getProps, callback, onDestroyed) => {
2330
+ let disposeListenUpdated = null;
2331
+ const disposeReaction = whiteWebSdk.reaction(getProps, () => {
2332
+ if (disposeListenUpdated) {
2333
+ disposeListenUpdated();
2334
+ disposeListenUpdated = null;
2335
+ }
2336
+ const props = getProps();
2337
+ if (lodash.isObject(props)) {
2338
+ disposeListenUpdated = () => whiteWebSdk.unlistenUpdated(props, callback);
2339
+ whiteWebSdk.listenUpdated(props, callback);
2340
+ } else {
2341
+ onDestroyed == null ? void 0 : onDestroyed(props);
2342
+ }
2343
+ }, { fireImmediately: true });
2344
+ return () => {
2345
+ disposeListenUpdated == null ? void 0 : disposeListenUpdated();
2346
+ disposeReaction();
2347
+ };
2348
+ };
2349
+ const onObjectRemoved = onObjectByEvent(whiteWebSdk.UpdateEventKind.Removed);
2350
+ onObjectByEvent(whiteWebSdk.UpdateEventKind.Inserted);
2569
2351
  class RedoUndo {
2570
2352
  constructor(context) {
2571
2353
  this.context = context;
@@ -2625,24 +2407,181 @@ class RedoUndo {
2625
2407
  this.disposePrevFocusViewRedoUndoListeners(this.context.focus());
2626
2408
  }
2627
2409
  }
2410
+ const createScrollStorage = (manager) => {
2411
+ return new syncedStore.Storage({
2412
+ plugin$: new valueEnhancer.Val(manager.windowManger),
2413
+ isWritable$: manager.isWritable$,
2414
+ namespace: "scrollStorage",
2415
+ defaultState: { scrollTop: 0 }
2416
+ });
2417
+ };
2418
+ function clamp$2(x2, min, max) {
2419
+ return x2 < min ? min : x2 > max ? max : x2;
2420
+ }
2421
+ class ScrollMode {
2422
+ constructor(manager) {
2423
+ var _a;
2424
+ this.manager = manager;
2425
+ this.sideEffect = new sideEffectManager.SideEffectManager();
2426
+ this.baseWidth = SCROLL_MODE_BASE_WIDTH;
2427
+ this.baseHeight = SCROLL_MODE_BASE_HEIGHT;
2428
+ this.initScroll = () => {
2429
+ const halfWbHeight = this._size$.value.height / 2 / this._scale$.value;
2430
+ const scrollTop = this._scrollTop$.value;
2431
+ this._scrollTop$.setValue(clamp$2(scrollTop, halfWbHeight, this.baseHeight - halfWbHeight) - 0.01);
2432
+ };
2433
+ this.getWhiteboardElement = (root) => {
2434
+ const className = ".netless-window-manager-main-view";
2435
+ return root && root.querySelector(className);
2436
+ };
2437
+ this.onWheel = (ev) => {
2438
+ var _a2;
2439
+ const target = ev.target;
2440
+ if (this.manager.canOperate && ((_a2 = this._whiteboard$.value) == null ? void 0 : _a2.contains(target))) {
2441
+ ev.preventDefault();
2442
+ ev.stopPropagation();
2443
+ const dy = ev.deltaY || 0;
2444
+ const { width } = this._size$.value;
2445
+ if (dy && width > 0) {
2446
+ const halfWbHeight = this._size$.value.height / 2 / this._scale$.value;
2447
+ const scrollTop = this._scrollTop$.value + dy / this._scale$.value;
2448
+ this.scrollStorage.setState({
2449
+ scrollTop: clamp$2(scrollTop, halfWbHeight, this.baseHeight - halfWbHeight)
2450
+ });
2451
+ callbacks.emit("userScroll");
2452
+ }
2453
+ }
2454
+ };
2455
+ this._root$ = new valueEnhancer.Val(null);
2456
+ this._mainView$ = new valueEnhancer.Val(this.manager.mainView);
2457
+ this._mainView$.value.disableCameraTransform = true;
2458
+ if ((_a = manager.scrollBaseSize$) == null ? void 0 : _a.value) {
2459
+ this.baseWidth = manager.scrollBaseSize$.value.width;
2460
+ this.baseHeight = manager.scrollBaseSize$.value.height;
2461
+ }
2462
+ this.scrollStorage = createScrollStorage(manager);
2463
+ const scrollTop$ = new valueEnhancer.Val(this.scrollStorage.state.scrollTop);
2464
+ this._scrollTop$ = scrollTop$;
2465
+ this.sideEffect.push(this.scrollStorage.on("stateChanged", () => {
2466
+ this._scrollTop$.setValue(this.scrollStorage.state.scrollTop);
2467
+ }));
2468
+ const size$ = new valueEnhancer.Val({ width: 0, height: 0 }, { compare: (a, b2) => a.width === b2.width && a.height === b2.height });
2469
+ this._size$ = size$;
2470
+ this.sideEffect.add(() => {
2471
+ const onSizeUpdated = size$.setValue.bind(size$);
2472
+ onSizeUpdated(this._mainView$.value.size);
2473
+ this._mainView$.value.callbacks.on("onSizeUpdated", onSizeUpdated);
2474
+ return () => this._mainView$.value.callbacks.off("onSizeUpdated", onSizeUpdated);
2475
+ });
2476
+ this.sideEffect.add(() => {
2477
+ const onCameraUpdated = (camera) => {
2478
+ const halfWbHeight = size$.value.height / 2 / scale$.value;
2479
+ const scrollTop = camera.centerY;
2480
+ this.scrollStorage.setState({
2481
+ scrollTop: clamp$2(scrollTop, halfWbHeight, this.baseHeight - halfWbHeight)
2482
+ });
2483
+ callbacks.emit("userScroll");
2484
+ };
2485
+ this._mainView$.value.callbacks.on("onCameraUpdatedByDevice", onCameraUpdated);
2486
+ return () => this._mainView$.value.callbacks.off("onCameraUpdatedByDevice", onCameraUpdated);
2487
+ });
2488
+ const scale$ = valueEnhancer.derive(size$, (size) => size.width / this.baseWidth);
2489
+ this._scale$ = scale$;
2490
+ const page$ = new valueEnhancer.Val(0);
2491
+ this.sideEffect.push(valueEnhancer.combine([scrollTop$, size$, scale$]).subscribe(([scrollTop, size, scale2]) => {
2492
+ if (scale2 > 0) {
2493
+ const wbHeight = size.height / scale2;
2494
+ page$.setValue(Math.max(scrollTop / wbHeight - 0.5, 0));
2495
+ }
2496
+ }));
2497
+ this._page$ = page$;
2498
+ this.sideEffect.push(valueEnhancer.combine([scrollTop$, scale$]).subscribe(([scrollTop, scale2]) => {
2499
+ this.updateBound(scrollTop, size$.value, scale2);
2500
+ }));
2501
+ this.sideEffect.push(size$.reaction(() => {
2502
+ this.updateScroll(scrollTop$.value);
2503
+ }));
2504
+ const whiteboard$ = valueEnhancer.derive(this._root$, this.getWhiteboardElement);
2505
+ this._whiteboard$ = whiteboard$;
2506
+ this.sideEffect.push(whiteboard$.reaction((el) => {
2507
+ if (el == null ? void 0 : el.parentElement) {
2508
+ this.sideEffect.addEventListener(el.parentElement, "wheel", this.onWheel, { capture: true, passive: false }, "wheel");
2509
+ }
2510
+ }));
2511
+ this.sideEffect.push(scale$.reaction((scale2) => {
2512
+ if (scale2 > 0) {
2513
+ this.sideEffect.flush("initScroll");
2514
+ this.sideEffect.setTimeout(this.initScroll, 0);
2515
+ }
2516
+ }), "initScroll");
2517
+ const maxScrollPage$ = valueEnhancer.combine([this._size$, this._scale$], ([size, scale2]) => {
2518
+ const halfWbHeight = size.height / 2 / scale2;
2519
+ return (this.baseHeight - halfWbHeight) / halfWbHeight / 2 - 0.51;
2520
+ });
2521
+ this.scrollState$ = valueEnhancer.combine([this._scrollTop$, this._page$, maxScrollPage$], ([scrollTop, page, maxScrollPage]) => {
2522
+ return {
2523
+ scrollTop,
2524
+ page,
2525
+ maxScrollPage
2526
+ };
2527
+ });
2528
+ this.updateScroll(scrollTop$.value);
2529
+ this.sideEffect.push(this.scrollState$.subscribe((state) => callbacks.emit("scrollStateChange", state)));
2530
+ }
2531
+ setRoot(root) {
2532
+ this._root$.setValue(root);
2533
+ }
2534
+ updateScroll(scrollTop) {
2535
+ this._mainView$.value.moveCamera({
2536
+ centerY: scrollTop,
2537
+ animationMode: whiteWebSdk.AnimationMode.Immediately
2538
+ });
2539
+ }
2540
+ updateBound(scrollTop, { height }, scale2) {
2541
+ if (scale2 > 0) {
2542
+ this._mainView$.value.moveCameraToContain({
2543
+ originX: 0,
2544
+ originY: scrollTop - height / scale2 / 2,
2545
+ width: this.baseWidth,
2546
+ height: height / scale2,
2547
+ animationMode: whiteWebSdk.AnimationMode.Immediately
2548
+ });
2549
+ this._mainView$.value.setCameraBound({
2550
+ damping: 1,
2551
+ maxContentMode: () => scale2,
2552
+ minContentMode: () => scale2,
2553
+ centerX: this.baseWidth / 2,
2554
+ centerY: this.baseHeight / 2,
2555
+ width: this.baseWidth,
2556
+ height: this.baseHeight
2557
+ });
2558
+ }
2559
+ }
2560
+ dispose() {
2561
+ this.sideEffect.flushAll();
2562
+ }
2563
+ }
2628
2564
  class AppManager {
2629
2565
  constructor(windowManger) {
2566
+ var _a;
2630
2567
  this.windowManger = windowManger;
2631
2568
  this.appProxies = /* @__PURE__ */ new Map();
2632
2569
  this.appStatus = /* @__PURE__ */ new Map();
2633
2570
  this.store = store;
2634
2571
  this.isReplay = this.windowManger.isReplay;
2635
2572
  this.mainViewScenesLength = 0;
2573
+ this.scrollBaseSize$ = new valueEnhancer.Val(null);
2636
2574
  this.callbacksNode = null;
2637
2575
  this.appCreateQueue = new AppCreateQueue();
2638
2576
  this.sceneIndex$ = new valueEnhancer.Val(void 0);
2639
2577
  this.focused$ = new valueEnhancer.Val(void 0);
2640
2578
  this.members$ = new valueEnhancer.Val([]);
2579
+ this.isWritable$ = new valueEnhancer.Val(Boolean((_a = this.room) == null ? void 0 : _a.isWritable));
2641
2580
  this.sideEffectManager = new sideEffectManager.SideEffectManager();
2642
2581
  this.sceneState = null;
2643
2582
  this.rootDirRemoving = false;
2644
2583
  this.onRemoveScenes = async (params) => {
2645
- var _a, _b;
2584
+ var _a2, _b;
2646
2585
  const { scenePath } = params;
2647
2586
  if (scenePath === ROOT_DIR) {
2648
2587
  await this.onRootDirRemoved();
@@ -2651,7 +2590,7 @@ class AppManager {
2651
2590
  }
2652
2591
  if (isRootDirPage(scenePath)) {
2653
2592
  let nextIndex = this.mainView.focusSceneIndex || 0;
2654
- let sceneName = (_a = this.callbacksNode) == null ? void 0 : _a.scenes[nextIndex];
2593
+ let sceneName = (_a2 = this.callbacksNode) == null ? void 0 : _a2.scenes[nextIndex];
2655
2594
  if (!sceneName) {
2656
2595
  nextIndex = 0;
2657
2596
  sceneName = (_b = this.callbacksNode) == null ? void 0 : _b.scenes[nextIndex];
@@ -2702,11 +2641,11 @@ class AppManager {
2702
2641
  }
2703
2642
  };
2704
2643
  this.removeSceneByIndex = async (index2) => {
2705
- var _a;
2644
+ var _a2;
2706
2645
  const nextIndex = calculateNextIndex(index2, this.windowManger.pageState);
2707
2646
  this.setSceneIndexWithoutSync(nextIndex);
2708
2647
  this.dispatchInternalEvent(Events.SetAppFocusIndex, { type: "main", index: nextIndex });
2709
- const scene = (_a = this.callbacksNode) == null ? void 0 : _a.scenes[index2];
2648
+ const scene = (_a2 = this.callbacksNode) == null ? void 0 : _a2.scenes[index2];
2710
2649
  setTimeout(() => {
2711
2650
  if (scene) {
2712
2651
  removeScenes(this.room, `${ROOT_DIR}${scene}`, index2);
@@ -2724,8 +2663,8 @@ class AppManager {
2724
2663
  });
2725
2664
  };
2726
2665
  this.setSceneIndexWithoutSync = (index2) => {
2727
- var _a;
2728
- const sceneName = (_a = this.callbacksNode) == null ? void 0 : _a.scenes[index2];
2666
+ var _a2;
2667
+ const sceneName = (_a2 = this.callbacksNode) == null ? void 0 : _a2.scenes[index2];
2729
2668
  if (sceneName) {
2730
2669
  this.mainViewProxy.setFocusScenePath(`${ROOT_DIR}${sceneName}`);
2731
2670
  }
@@ -2796,8 +2735,8 @@ class AppManager {
2796
2735
  });
2797
2736
  };
2798
2737
  this.addAppCloseListener = () => {
2799
- var _a;
2800
- (_a = this.refresher) == null ? void 0 : _a.add("appsClose", () => {
2738
+ var _a2;
2739
+ (_a2 = this.refresher) == null ? void 0 : _a2.add("appsClose", () => {
2801
2740
  return onObjectRemoved(this.attributes.apps, () => {
2802
2741
  this.onAppDelete(this.attributes.apps);
2803
2742
  });
@@ -2814,13 +2753,13 @@ class AppManager {
2814
2753
  }
2815
2754
  };
2816
2755
  this.onFocusChange = (focused) => {
2817
- var _a;
2756
+ var _a2;
2818
2757
  if (this.focused$.value !== focused) {
2819
2758
  callbacks.emit("focusedChange", focused);
2820
2759
  emitter.emit("focusedChange", { focused, prev: this.focused$.value });
2821
2760
  this.focused$.setValue(focused);
2822
2761
  if (focused !== void 0) {
2823
- (_a = this.boxManager) == null ? void 0 : _a.focusBox({ appId: focused });
2762
+ (_a2 = this.boxManager) == null ? void 0 : _a2.focusBox({ appId: focused });
2824
2763
  setTimeout(() => {
2825
2764
  const appProxy = this.appProxies.get(focused);
2826
2765
  if (appProxy) {
@@ -2846,14 +2785,14 @@ class AppManager {
2846
2785
  });
2847
2786
  };
2848
2787
  this.onMinimized = (minimized) => {
2849
- var _a, _b;
2850
- if (((_a = this.boxManager) == null ? void 0 : _a.minimized) !== minimized) {
2788
+ var _a2, _b;
2789
+ if (((_a2 = this.boxManager) == null ? void 0 : _a2.minimized) !== minimized) {
2851
2790
  if (minimized === true) {
2852
2791
  (_b = this.boxManager) == null ? void 0 : _b.blurAllBox();
2853
2792
  }
2854
2793
  setTimeout(() => {
2855
- var _a2;
2856
- (_a2 = this.boxManager) == null ? void 0 : _a2.setMinimized(Boolean(minimized));
2794
+ var _a3;
2795
+ (_a3 = this.boxManager) == null ? void 0 : _a3.setMinimized(Boolean(minimized));
2857
2796
  }, 0);
2858
2797
  }
2859
2798
  };
@@ -2893,11 +2832,11 @@ class AppManager {
2893
2832
  }
2894
2833
  };
2895
2834
  this.displayerWritableListener = (isReadonly) => {
2896
- var _a, _b;
2835
+ var _a2, _b;
2897
2836
  const isWritable = !isReadonly;
2898
2837
  const isManualWritable = this.windowManger.readonly === void 0 || !this.windowManger.readonly;
2899
2838
  if (this.windowManger.readonly === void 0) {
2900
- (_a = this.boxManager) == null ? void 0 : _a.setReadonly(isReadonly);
2839
+ (_a2 = this.boxManager) == null ? void 0 : _a2.setReadonly(isReadonly);
2901
2840
  } else {
2902
2841
  (_b = this.boxManager) == null ? void 0 : _b.setReadonly(!(isWritable && isManualWritable));
2903
2842
  }
@@ -2910,6 +2849,7 @@ class AppManager {
2910
2849
  }
2911
2850
  }
2912
2851
  emitter.emit("writableChange", isWritable);
2852
+ this.isWritable$.setValue(isWritable);
2913
2853
  };
2914
2854
  this.updateSceneIndex = () => {
2915
2855
  const scenePath = this.store.getMainViewScenePath();
@@ -2942,10 +2882,10 @@ class AppManager {
2942
2882
  this.refresher.setContext({ emitter });
2943
2883
  this.sideEffectManager.add(() => {
2944
2884
  return () => {
2945
- var _a, _b, _c;
2885
+ var _a2, _b, _c;
2946
2886
  this.appCreateQueue.destroy();
2947
2887
  this.mainViewProxy.destroy();
2948
- (_a = this.refresher) == null ? void 0 : _a.destroy();
2888
+ (_a2 = this.refresher) == null ? void 0 : _a2.destroy();
2949
2889
  this.viewManager.destroy();
2950
2890
  (_b = this.boxManager) == null ? void 0 : _b.destroy();
2951
2891
  (_c = this.callbacksNode) == null ? void 0 : _c.dispose();
@@ -2964,6 +2904,16 @@ class AppManager {
2964
2904
  this.safeUpdateAttributes([Fields.Registered, payload.kind], payload);
2965
2905
  });
2966
2906
  this.members$.setValue(serializeRoomMembers(this.displayer.state.roomMembers));
2907
+ emitter.on("mainViewMounted", () => {
2908
+ this.windowManger.viewMode$.subscribe((viewMode) => {
2909
+ const playground = this.windowManger.playground$.value;
2910
+ if (viewMode === "scroll" && playground) {
2911
+ const scrollMode = new ScrollMode(this);
2912
+ this.scrollMode = scrollMode;
2913
+ scrollMode.setRoot(playground);
2914
+ }
2915
+ });
2916
+ });
2967
2917
  }
2968
2918
  async onRootDirRemoved(needClose = true) {
2969
2919
  await this.setMainViewScenePath(INIT_DIR);
@@ -3135,6 +3085,7 @@ class AppManager {
3135
3085
  bindMainView(divElement, disableCameraTransform) {
3136
3086
  const mainView = this.mainViewProxy.view;
3137
3087
  mainView.disableCameraTransform = disableCameraTransform;
3088
+ console.log("bindMainView", mainView.disableCameraTransform);
3138
3089
  wait(30).then(() => {
3139
3090
  mainView.divElement = divElement;
3140
3091
  emitter.emit("mainViewMounted");
@@ -6901,7 +6852,7 @@ class CursorManager {
6901
6852
  this.initCursorInstance = (uid) => {
6902
6853
  let cursorInstance = this.cursorInstances.get(uid);
6903
6854
  if (!cursorInstance) {
6904
- cursorInstance = new Cursor(this.manager, uid, this, WindowManager.playground);
6855
+ cursorInstance = new Cursor(this.manager, uid, this, this.playground$.value);
6905
6856
  this.cursorInstances.set(uid, cursorInstance);
6906
6857
  }
6907
6858
  return cursorInstance;
@@ -6944,7 +6895,7 @@ class CursorManager {
6944
6895
  this.hideCursor(this.manager.uid);
6945
6896
  };
6946
6897
  this.roomMembers = (_a = this.manager.room) == null ? void 0 : _a.state.roomMembers;
6947
- const playground = WindowManager.playground;
6898
+ const playground = this.playground$.value;
6948
6899
  if (playground) {
6949
6900
  this.setupWrapper(playground);
6950
6901
  }
@@ -6958,6 +6909,9 @@ class CursorManager {
6958
6909
  this.applianceIcons = __spreadValues(__spreadValues({}, ApplianceMap), applianceIcons);
6959
6910
  }
6960
6911
  }
6912
+ get playground$() {
6913
+ return this.manager.windowManger.playground$;
6914
+ }
6961
6915
  canMoveCursor(member) {
6962
6916
  const isLaserPointer = (member == null ? void 0 : member.memberState.currentApplianceName) === whiteWebSdk.ApplianceNames.laserPointer;
6963
6917
  return this.enableCursor || isLaserPointer;
@@ -11695,70 +11649,35 @@ const reconnectRefresher = new ReconnectRefresher({ emitter });
11695
11649
  const _WindowManager = class extends whiteWebSdk.InvisiblePlugin {
11696
11650
  constructor(context) {
11697
11651
  super(context);
11698
- this.version = "1.0.0-canary.53";
11699
- 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" } };
11652
+ this.version = "1.0.0-canary.54";
11653
+ 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" } };
11700
11654
  this.emitter = callbacks;
11701
11655
  this.viewMode = whiteWebSdk.ViewMode.Broadcaster;
11702
11656
  this.viewMode$ = new valueEnhancer.Val(whiteWebSdk.ViewMode.Broadcaster);
11657
+ this.playground$ = new valueEnhancer.Val(void 0);
11703
11658
  this.isReplay = whiteWebSdk.isPlayer(this.displayer);
11704
- this.cameraUpdating = 0;
11705
- this.nextCamera = null;
11706
11659
  this.containerSizeRatio = _WindowManager.containerSizeRatio;
11707
11660
  this.moveCamera = (camera) => {
11708
11661
  var _a;
11662
+ const pureCamera = lodash.omit(camera, ["animationMode"]);
11709
11663
  const mainViewCamera = __spreadValues({}, this.mainView.camera);
11710
- const nextCamera = __spreadValues(__spreadValues({}, mainViewCamera), camera);
11711
- if (lodash.isEqual(nextCamera, mainViewCamera))
11664
+ if (lodash.isEqual(__spreadValues(__spreadValues({}, mainViewCamera), pureCamera), mainViewCamera))
11712
11665
  return;
11713
- if (!this.appManager)
11714
- return;
11715
- if (camera.animationMode === whiteWebSdk.AnimationMode.Immediately) {
11716
- this.appManager.mainViewProxy.storeCamera(__spreadValues({
11717
- id: this.appManager.uid
11718
- }, nextCamera));
11719
- } else {
11720
- const remoteCamera = this.appManager.mainViewProxy.size$.value;
11721
- const currentSize = (_a = this.boxManager) == null ? void 0 : _a.stageRect;
11722
- let nextScale;
11723
- if (camera.scale && remoteCamera && currentSize) {
11724
- nextScale = camera.scale * computedMinScale(remoteCamera, currentSize);
11725
- }
11726
- if (nextScale) {
11727
- this.mainView.moveCamera(__spreadProps(__spreadValues({}, camera), {
11728
- scale: nextScale
11729
- }));
11730
- } else {
11731
- this.mainView.moveCamera(camera);
11732
- }
11733
- this.appManager.dispatchInternalEvent(Events.MoveCamera, camera);
11734
- this.mainView.callbacks.off("onCameraUpdated", this.onCameraUpdated);
11735
- clearTimeout(this.cameraUpdating);
11736
- this.cameraUpdating = 0;
11737
- this.mainView.callbacks.on("onCameraUpdated", this.onCameraUpdated);
11738
- if (nextScale) {
11739
- this.nextCamera = nextCamera;
11740
- }
11741
- }
11742
- };
11743
- this.onCameraUpdated = () => {
11744
- if (this.cameraUpdating) {
11745
- clearTimeout(this.cameraUpdating);
11746
- this.cameraUpdating = 0;
11747
- }
11748
- this.cameraUpdating = setTimeout(() => {
11749
- this.mainView.callbacks.off("onCameraUpdated", this.onCameraUpdated);
11750
- clearTimeout(this.cameraUpdating);
11751
- this.cameraUpdating = 0;
11752
- if (!this.appManager || !this.nextCamera)
11753
- return;
11754
- this.appManager.mainViewProxy.storeCamera(__spreadValues({
11755
- id: this.appManager.uid
11756
- }, this.nextCamera));
11757
- this.nextCamera = null;
11758
- }, 50);
11666
+ this.debouncedStoreCamera();
11667
+ this.mainView.moveCamera(camera);
11668
+ (_a = this.appManager) == null ? void 0 : _a.dispatchInternalEvent(Events.MoveCamera, camera);
11669
+ };
11670
+ this.debouncedStoreCamera = () => {
11671
+ const storeCamera = lodash.debounce(() => {
11672
+ var _a, _b;
11673
+ (_a = this.appManager) == null ? void 0 : _a.mainViewProxy.storeCurrentCamera();
11674
+ (_b = this.appManager) == null ? void 0 : _b.mainViewProxy.storeCurrentSize();
11675
+ this.mainView.callbacks.off("onCameraUpdated", storeCamera);
11676
+ }, 200);
11677
+ this.mainView.callbacks.on("onCameraUpdated", storeCamera);
11759
11678
  };
11760
11679
  _WindowManager.displayer = context.displayer;
11761
- 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" } };
11680
+ 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" } };
11762
11681
  }
11763
11682
  static async mount(params) {
11764
11683
  var _a;
@@ -11805,6 +11724,9 @@ const _WindowManager = class extends whiteWebSdk.InvisiblePlugin {
11805
11724
  }
11806
11725
  manager.containerSizeRatio = _WindowManager.containerSizeRatio;
11807
11726
  await manager.ensureAttributes();
11727
+ if (params.viewMode) {
11728
+ manager.viewMode$.setValue(params.viewMode);
11729
+ }
11808
11730
  manager.appManager = new AppManager(manager);
11809
11731
  manager._pageState = new PageStateImpl(manager.appManager);
11810
11732
  manager.cursorManager = new CursorManager(manager.appManager, Boolean(cursor), params.applianceIcons);
@@ -11822,6 +11744,9 @@ const _WindowManager = class extends whiteWebSdk.InvisiblePlugin {
11822
11744
  if (params.container) {
11823
11745
  manager.bindContainer(params.container);
11824
11746
  }
11747
+ if (params.scrollModeWidth && params.scrollModeHeight) {
11748
+ manager.appManager.scrollBaseSize$.setValue({ width: params.scrollModeWidth, height: params.scrollModeHeight });
11749
+ }
11825
11750
  replaceRoomFunction(room, manager);
11826
11751
  emitter.emit("onCreated");
11827
11752
  _WindowManager.isCreated = true;
@@ -11890,6 +11815,7 @@ const _WindowManager = class extends whiteWebSdk.InvisiblePlugin {
11890
11815
  this.bindMainView(mainViewElement, params.disableCameraTransform);
11891
11816
  if (_WindowManager.playground) {
11892
11817
  (_b = this.cursorManager) == null ? void 0 : _b.setupWrapper(_WindowManager.playground);
11818
+ this.playground$.setValue(_WindowManager.playground);
11893
11819
  }
11894
11820
  }
11895
11821
  }
@@ -12105,10 +12031,11 @@ const _WindowManager = class extends whiteWebSdk.InvisiblePlugin {
12105
12031
  if (mode === whiteWebSdk.ViewMode.Broadcaster) {
12106
12032
  if (this.canOperate) {
12107
12033
  mainViewProxy == null ? void 0 : mainViewProxy.storeCurrentCamera();
12034
+ mainViewProxy == null ? void 0 : mainViewProxy.storeCurrentSize();
12108
12035
  }
12109
12036
  mainViewProxy == null ? void 0 : mainViewProxy.start();
12110
12037
  }
12111
- if (mode === whiteWebSdk.ViewMode.Freedom) {
12038
+ if (mode === whiteWebSdk.ViewMode.Freedom || mode === "scroll") {
12112
12039
  mainViewProxy == null ? void 0 : mainViewProxy.stop();
12113
12040
  }
12114
12041
  this.viewMode = mode;
@@ -12259,6 +12186,10 @@ const _WindowManager = class extends whiteWebSdk.InvisiblePlugin {
12259
12186
  throw new AppManagerNotInitError();
12260
12187
  }
12261
12188
  }
12189
+ get scrollState() {
12190
+ var _a, _b;
12191
+ return (_b = (_a = this.appManager) == null ? void 0 : _a.scrollMode) == null ? void 0 : _b.scrollState$.value;
12192
+ }
12262
12193
  get teleboxManager() {
12263
12194
  if (!this.boxManager) {
12264
12195
  throw new BoxManagerNotInitializeError();
@@ -12277,6 +12208,12 @@ const _WindowManager = class extends whiteWebSdk.InvisiblePlugin {
12277
12208
  var _a;
12278
12209
  return (_a = this.appManager) == null ? void 0 : _a.closeApp(appId);
12279
12210
  }
12211
+ moveCameraToContain(rectangle) {
12212
+ var _a;
12213
+ this.debouncedStoreCamera();
12214
+ this.mainView.moveCameraToContain(rectangle);
12215
+ (_a = this.appManager) == null ? void 0 : _a.dispatchInternalEvent(Events.MoveCameraToContain, rectangle);
12216
+ }
12280
12217
  convertToPointInWorld(point) {
12281
12218
  return this.mainView.convertToPointInWorld(point);
12282
12219
  }