@netless/window-manager 1.0.0-canary.56 → 1.0.0-canary.58

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.
@@ -15,12 +15,16 @@
15
15
  export let color: string;
16
16
  export let cursorTagBackgroundColor: string;
17
17
  export let opacity: number;
18
+ export let pencilEraserSize: number;
18
19
 
19
20
  $: hasName = !isEmpty(cursorName);
20
21
  $: hasTagName = !isEmpty(tagName);
21
22
  $: hasAvatar = !isEmpty(avatar);
22
23
  $: display = visible ? "initial" : "none";
23
24
  $: isLaserPointer = appliance === ApplianceNames.laserPointer;
25
+ $: isLaserPointerPencilEraser = isLaserPointer || appliance === ApplianceNames.pencilEraser;
26
+ $: offset = isLaserPointerPencilEraser ? "netless-window-manager-laserPointer-pencilEraser-offset" : "";
27
+ $: pencilEraserSize3ImageOffset = pencilEraserSize === 3 ? "netless-window-manager-pencilEraser-3-offset" : "";
24
28
 
25
29
  const computedAvatarStyle = () => {
26
30
  return Object.entries({
@@ -40,7 +44,7 @@
40
44
  style="transform: translateX({x}px) translateY({y}px);display: {display}"
41
45
  >
42
46
  {#if !isLaserPointer}
43
- <div class="netless-window-manager-cursor-name">
47
+ <div class="netless-window-manager-cursor-name {offset} {pencilEraserSize3ImageOffset}">
44
48
  <div
45
49
  class={theme}
46
50
  style="background-color: {backgroundColor};color: {color};opacity: {opacity}"
@@ -63,6 +67,6 @@
63
67
  </div>
64
68
  {/if}
65
69
  <div class="cursor-image-wrapper">
66
- <img class="netless-window-manager-cursor-{appliance}-image" {src} alt={appliance} />
70
+ <img class="netless-window-manager-cursor-{appliance}-image {pencilEraserSize3ImageOffset}" {src} alt={appliance} />
67
71
  </div>
68
72
  </div>
@@ -157,14 +157,21 @@ export class Cursor {
157
157
  cursorTagBackgroundColor: this.memberCursorTagBackgroundColor,
158
158
  opacity: this.memberOpacity,
159
159
  tagName: this.memberTagName,
160
+ pencilEraserSize: this.member?.memberState.pencilEraserSize,
160
161
  };
161
162
  }
162
163
 
163
164
  private getIcon() {
164
165
  if (this.member) {
165
166
  const icons = this.cursorManager.applianceIcons;
166
- const applianceSrc = icons[this.memberApplianceName || ApplianceNames.shape];
167
- return applianceSrc || icons[ApplianceNames.shape];
167
+ let applianceSrc = icons[ApplianceNames.shape];
168
+ if (this.memberApplianceName === ApplianceNames.pencilEraser) {
169
+ const size = this.member?.memberState.pencilEraserSize || 1;
170
+ applianceSrc = icons[`${this.memberApplianceName}${size}`];
171
+ } else {
172
+ applianceSrc = icons[this.memberApplianceName || ApplianceNames.shape];
173
+ }
174
+ return applianceSrc;
168
175
  }
169
176
  }
170
177
 
@@ -5,6 +5,9 @@ import eraser from "../image/eraser-cursor.png";
5
5
  import shape from "../image/shape-cursor.svg";
6
6
  import text from "../image/text-cursor.svg";
7
7
  import laser from "../image/laser-pointer-cursor.svg";
8
+ import pencilEraser1 from "../image/pencil-eraser-1.svg";
9
+ import pencilEraser2 from "../image/pencil-eraser-2.svg";
10
+ import pencilEraser3 from "../image/pencil-eraser-3.svg";
8
11
 
9
12
  export const ApplianceMap: {
10
13
  [key: string]: string;
@@ -15,4 +18,7 @@ export const ApplianceMap: {
15
18
  [ApplianceNames.shape]: shape,
16
19
  [ApplianceNames.text]: text,
17
20
  [ApplianceNames.laserPointer]: laser,
21
+ ["pencilEraser1"]: pencilEraser1,
22
+ ["pencilEraser2"]: pencilEraser2,
23
+ ["pencilEraser3"]: pencilEraser3,
18
24
  };
@@ -4,6 +4,7 @@ import { combine, derive, Val } from "value-enhancer";
4
4
  import { createScrollStorage } from "../storage";
5
5
  import { SCROLL_MODE_BASE_HEIGHT, SCROLL_MODE_BASE_WIDTH } from "../constants";
6
6
  import { SideEffectManager } from "side-effect-manager";
7
+ import { round } from "lodash";
7
8
  import type { ReadonlyVal } from "value-enhancer";
8
9
  import type { AppManager } from "../AppManager";
9
10
  import type { ScrollStorage } from "../storage";
@@ -138,9 +139,9 @@ export class ScrollMode {
138
139
  [this._scrollTop$, this._page$, maxScrollPage$],
139
140
  ([scrollTop, page, maxScrollPage]) => {
140
141
  return {
141
- scrollTop,
142
- page,
143
- maxScrollPage,
142
+ scrollTop: round(scrollTop, 2),
143
+ page: round(page, 2),
144
+ maxScrollPage: round(maxScrollPage, 2),
144
145
  };
145
146
  }
146
147
  );
@@ -201,6 +202,15 @@ export class ScrollMode {
201
202
 
202
203
  public dispose(): void {
203
204
  this.sideEffect.flushAll();
205
+ this.scrollStorage.disconnect();
206
+ this._root$.destroy();
207
+ this._scale$.destroy();
208
+ this._scrollTop$.destroy();
209
+ this._whiteboard$.destroy();
210
+ this.scrollState$.destroy();
211
+ this._page$.destroy();
212
+ this._size$.destroy();
213
+ this._mainView$.destroy();
204
214
  }
205
215
 
206
216
  private getWhiteboardElement = (root: HTMLElement | null): HTMLElement | null => {
@@ -3,8 +3,9 @@ import { CameraSynchronizer } from "./CameraSynchronizer";
3
3
  import { combine, derive } from "value-enhancer";
4
4
  import { isEqual } from "lodash";
5
5
  import { SideEffectManager } from "side-effect-manager";
6
+ import { Val } from "value-enhancer";
6
7
  import type { Camera, View } from "white-web-sdk";
7
- import type { Val, ReadonlyVal } from "value-enhancer";
8
+ import type { ReadonlyVal } from "value-enhancer";
8
9
  import type { ICamera, ISize } from "../AttributesDelegate";
9
10
  import type { TeleBoxRect } from "@netless/telebox-insider";
10
11
  import type { ManagerViewMode } from "../typings";
@@ -43,6 +44,8 @@ export class ViewSync {
43
44
  ]);
44
45
  if (context.viewMode$) {
45
46
  this.needRecoverCamera$ = derive(context.viewMode$, mode => mode !== "scroll");
47
+ } else {
48
+ this.needRecoverCamera$ = new Val(true);
46
49
  }
47
50
  const camera$size$ = combine([this.context.camera$, this.context.size$]);
48
51
  camera$size$.reaction(([camera, size]) => {
@@ -0,0 +1,3 @@
1
+ <svg width="18" height="26" viewBox="0 0 18 26" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <rect x="0.5" y="0.5" width="17" height="25" rx="3.5" fill="black" fill-opacity="0.35" stroke="white"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg width="26" height="34" viewBox="0 0 26 34" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <rect x="0.5" y="0.5" width="25" height="33" rx="3.5" fill="black" fill-opacity="0.35" stroke="white"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg width="34" height="50" viewBox="0 0 34 50" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <rect x="0.5" y="0.5" width="33" height="49" rx="3.5" fill="black" fill-opacity="0.35" stroke="white"/>
3
+ </svg>
package/src/index.ts CHANGED
@@ -185,7 +185,6 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes, any>
185
185
  public emitter: Emittery<PublicEvent> = callbacks;
186
186
  public appManager?: AppManager;
187
187
  public cursorManager?: CursorManager;
188
- public viewMode: ManagerViewMode = ViewMode.Broadcaster;
189
188
  public viewMode$ = new Val<ManagerViewMode>(ViewMode.Broadcaster);
190
189
  public playground$ = new Val<HTMLElement | undefined>(undefined);
191
190
  public isReplay = isPlayer(this.displayer);
@@ -638,7 +637,6 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes, any>
638
637
  if (mode === ViewMode.Freedom || mode === "scroll") {
639
638
  mainViewProxy?.stop();
640
639
  }
641
- this.viewMode = mode;
642
640
  this.viewMode$.setValue(mode);
643
641
  }
644
642
 
@@ -727,6 +725,10 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes, any>
727
725
  return Boolean(this.appManager?.boxManager?.darkMode);
728
726
  }
729
727
 
728
+ public get viewMode() {
729
+ return this.viewMode$.value;
730
+ }
731
+
730
732
  public get prefersColorScheme(): TeleBoxColorScheme | undefined {
731
733
  if (this.appManager) {
732
734
  return this.appManager.boxManager?.prefersColorScheme;
@@ -1017,6 +1019,17 @@ export class WindowManager extends InvisiblePlugin<WindowMangerAttributes, any>
1017
1019
  });
1018
1020
  }, 500);
1019
1021
  }
1022
+ /**
1023
+ * 切换 focus 到指定的 app, 并且把这个 app 放到最前面
1024
+ */
1025
+ public focusApp(appId: string) {
1026
+ const box = this.boxManager?.getBox(appId);
1027
+ if (box) {
1028
+ this.boxManager?.focusBox({ appId }, false);
1029
+ // 1.0 版本这里会有正式的 api
1030
+ (this.boxManager?.teleBoxManager as any).makeBoxTop(box, false);
1031
+ }
1032
+ }
1020
1033
 
1021
1034
  public createPPTHandler() {
1022
1035
  return {
package/src/style.css CHANGED
@@ -119,6 +119,20 @@
119
119
  margin-top: 3px;
120
120
  }
121
121
 
122
+ .netless-window-manager-cursor-pencilEraser-image {
123
+ margin-left: -22px;
124
+ margin-top: 3px;
125
+ }
126
+
127
+ .netless-window-manager-laserPointer-pencilEraser-offset {
128
+ margin-left: -18px;
129
+ }
130
+
131
+ .netless-window-manager-pencilEraser-3-offset {
132
+ margin-top: -14px;
133
+ margin-left: -6px;
134
+ }
135
+
122
136
  .netless-window-manager-cursor-name {
123
137
  width: 100%;
124
138
  height: 48px;
package/src/typings.ts CHANGED
@@ -87,7 +87,7 @@ export type RegisterParams<AppOptions = any, SetupResult = any, Attributes exten
87
87
 
88
88
  export type AppListenerKeys = keyof AppEmitterEvent;
89
89
 
90
- export type ApplianceIcons = Partial<Record<ApplianceNames, string>>;
90
+ export type ApplianceIcons = Partial<Record<`${ApplianceNames}` | string, string>>;
91
91
 
92
92
  export type Writeable<T> = { -readonly [P in keyof T]: T[P] };
93
93