@netless/telebox-insider 0.2.32 → 0.3.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netless/telebox-insider",
3
- "version": "0.2.32",
3
+ "version": "0.3.0-beta.0",
4
4
  "private": false,
5
5
  "description": "Window widget for Whiteboard",
6
6
  "author": "CRIMX <straybugs@gmail.com> (https://github.com/crimx/)",
@@ -27,6 +27,8 @@ export enum TELE_BOX_EVENT {
27
27
  Maximized = "maximized",
28
28
  Readonly = "readonly",
29
29
  Destroyed = "destroyed",
30
+ BoxStatus = "box_status",
31
+ LastNotMinimizedBoxStatus = "last_not_minimized_box_status",
30
32
  }
31
33
 
32
34
  export enum TELE_BOX_DELEGATE_EVENT {
@@ -38,6 +38,7 @@ import type {
38
38
  TeleBoxCoord,
39
39
  TeleBoxSize,
40
40
  TeleBoxColorScheme,
41
+ NotMinimizedBoxState,
41
42
  } from "./typings";
42
43
 
43
44
  export * from "./constants";
@@ -108,6 +109,8 @@ export class TeleBox {
108
109
  height: window.innerHeight,
109
110
  },
110
111
  collectorRect,
112
+ boxStatus,
113
+ lastNotMinimizedBoxStatus
111
114
  }: TeleBoxConfig = {}) {
112
115
  this._sideEffect = new SideEffectManager();
113
116
  this._valSideEffectBinder = createSideEffectBinder(this._sideEffect);
@@ -117,6 +120,8 @@ export class TeleBox {
117
120
  this.namespace = namespace;
118
121
  this.events = new EventEmitter();
119
122
  this._delegateEvents = new EventEmitter();
123
+ const boxStatus$ = createVal<TeleBoxState | undefined, boolean>(boxStatus);
124
+ const lastNotMinimizedBoxStatus$ = createVal<NotMinimizedBoxState | undefined, boolean>(lastNotMinimizedBoxStatus);
120
125
 
121
126
  const prefersColorScheme$ = createVal<TeleBoxColorScheme, boolean>(
122
127
  prefersColorScheme
@@ -234,13 +239,14 @@ export class TeleBox {
234
239
  });
235
240
 
236
241
  const state$ = combine(
237
- [minimized$, maximized$],
238
- ([minimized, maximized]): TeleBoxState =>
242
+ [minimized$, maximized$, boxStatus$],
243
+ ([minimized, maximized, boxStatus]): TeleBoxState =>
239
244
  minimized
240
245
  ? TELE_BOX_STATE.Minimized
241
246
  : maximized
242
247
  ? TELE_BOX_STATE.Maximized
243
- : TELE_BOX_STATE.Normal
248
+ : !boxStatus ? TELE_BOX_STATE.Normal
249
+ : boxStatus
244
250
  );
245
251
  state$.reaction((state, _, skipUpdate) => {
246
252
  if (!skipUpdate) {
@@ -279,9 +285,9 @@ export class TeleBox {
279
285
  });
280
286
 
281
287
  const size$ = combine(
282
- [intrinsicSize$, maximized$],
283
- ([intrinsicSize, maximized]) => {
284
- if (maximized) {
288
+ [intrinsicSize$, maximized$, boxStatus$],
289
+ ([intrinsicSize, maximized, boxStatus]) => {
290
+ if (maximized || boxStatus === TELE_BOX_STATE.Maximized) {
285
291
  return { width: 1, height: 1 };
286
292
  }
287
293
  return intrinsicSize;
@@ -295,9 +301,9 @@ export class TeleBox {
295
301
  });
296
302
 
297
303
  const visualSize$ = combine(
298
- [size$, minimized$, containerRect$, collectorRect$],
299
- ([size, minimized, containerRect, collectorRect]) => {
300
- if (minimized && collectorRect) {
304
+ [size$, minimized$, containerRect$, collectorRect$, boxStatus$],
305
+ ([size, minimized, containerRect, collectorRect, boxStatus]) => {
306
+ if ((minimized || boxStatus === TELE_BOX_STATE.Minimized) && collectorRect) {
301
307
  return {
302
308
  width:
303
309
  collectorRect.width /
@@ -337,6 +343,8 @@ export class TeleBox {
337
343
  collectorRect$,
338
344
  minimized$,
339
345
  maximized$,
346
+ boxStatus$,
347
+ lastNotMinimizedBoxStatus$,
340
348
  ],
341
349
  ([
342
350
  intrinsicCoord,
@@ -345,9 +353,11 @@ export class TeleBox {
345
353
  collectorRect,
346
354
  minimized,
347
355
  maximized,
356
+ boxStatus,
357
+ lastNotMinimizedBoxStatus,
348
358
  ]) => {
349
- if (minimized && collectorRect) {
350
- if (maximized) {
359
+ if ((minimized || boxStatus === TELE_BOX_STATE.Minimized) && collectorRect) {
360
+ if (maximized || lastNotMinimizedBoxStatus === TELE_BOX_STATE.Maximized) {
351
361
  return {
352
362
  x:
353
363
  (collectorRect.x + collectorRect.width / 2) /
@@ -370,7 +380,7 @@ export class TeleBox {
370
380
  intrinsicSize.height / 2,
371
381
  };
372
382
  }
373
- if (maximized) {
383
+ if (maximized || boxStatus === TELE_BOX_STATE.Maximized) {
374
384
  return { x: 0, y: 0 };
375
385
  }
376
386
  return intrinsicCoord;
@@ -389,6 +399,7 @@ export class TeleBox {
389
399
  readonly: readonly$.value,
390
400
  title: title$.value,
391
401
  namespace: this.namespace,
402
+ boxStatus: boxStatus$.value,
392
403
  onDragStart: (event) => this._handleTrackStart?.(event),
393
404
  onEvent: (event): void => {
394
405
  if (this._delegateEvents.listeners.length > 0) {
@@ -396,11 +407,15 @@ export class TeleBox {
396
407
  } else {
397
408
  switch (event.type) {
398
409
  case TELE_BOX_DELEGATE_EVENT.Maximize: {
399
- maximized$.setValue(!maximized$.value);
410
+ if (!boxStatus$.value) {
411
+ maximized$.setValue(!maximized$.value);
412
+ }
400
413
  break;
401
414
  }
402
415
  case TELE_BOX_DELEGATE_EVENT.Minimize: {
403
- minimized$.setValue(true);
416
+ if (!boxStatus$.value) {
417
+ minimized$.setValue(true);
418
+ }
404
419
  break;
405
420
  }
406
421
  case TELE_BOX_DELEGATE_EVENT.Close: {
@@ -421,6 +436,9 @@ export class TeleBox {
421
436
  readonly$.reaction((readonly) => {
422
437
  this.titleBar.setReadonly(readonly);
423
438
  });
439
+ boxStatus$.reaction((boxStatus) => {
440
+ this.titleBar.setBoxStatus(boxStatus);
441
+ });
424
442
 
425
443
  const $userContent$ = createVal(content);
426
444
  const $userFooter$ = createVal(footer);
@@ -456,6 +474,8 @@ export class TeleBox {
456
474
  this._visualSize$ = visualSize$;
457
475
  this._coord$ = coord$;
458
476
  this._intrinsicCoord$ = intrinsicCoord$;
477
+ this._boxStatus$ = boxStatus$;
478
+ this._lastNotMinimizedBoxStatus$ = lastNotMinimizedBoxStatus$;
459
479
 
460
480
  if (this.fixRatio) {
461
481
  this.transform(
@@ -491,7 +511,20 @@ export class TeleBox {
491
511
  public _visualSize$: Val<TeleBoxSize, boolean>;
492
512
  public _coord$: Val<TeleBoxCoord, boolean>;
493
513
  public _intrinsicCoord$: Val<TeleBoxCoord, boolean>;
514
+ public _boxStatus$: Val<TeleBoxState | undefined, boolean>;
515
+ public _lastNotMinimizedBoxStatus$: Val<NotMinimizedBoxState | undefined, boolean>;
516
+
517
+ public get boxStatus(): TeleBoxState | undefined {
518
+ return this._boxStatus$.value;
519
+ }
520
+
521
+ public set boxStatus(boxStatus: TeleBoxState | undefined) {
522
+ this._boxStatus$.setValue(boxStatus);
523
+ }
494
524
 
525
+ public get lastNotMinimizedBoxStatus(): NotMinimizedBoxState | undefined {
526
+ return this._lastNotMinimizedBoxStatus$.value;
527
+ }
495
528
  public get darkMode(): boolean {
496
529
  return this._darkMode$.value;
497
530
  }
@@ -524,6 +557,29 @@ export class TeleBox {
524
557
  return this;
525
558
  }
526
559
 
560
+ public setBoxStatus(boxStatus: TeleBoxState, skipUpdate = false): this {
561
+ if (boxStatus === TELE_BOX_STATE.Minimized) {
562
+ if (this._boxStatus$.value && this._boxStatus$.value !== TELE_BOX_STATE.Minimized) {
563
+ this.setLastNotMinimizedBoxStatus(this._boxStatus$.value, skipUpdate);
564
+ }
565
+ } else {
566
+ this.setLastNotMinimizedBoxStatus(undefined, skipUpdate);
567
+ }
568
+ this._boxStatus$.setValue(boxStatus, skipUpdate);
569
+ if (!skipUpdate) {
570
+ this.events.emit(TELE_BOX_EVENT.BoxStatus, {id: this.id, boxStatus});
571
+ }
572
+ return this;
573
+ }
574
+
575
+ public setLastNotMinimizedBoxStatus(lastNotMinimizedBoxStatus?: NotMinimizedBoxState, skipUpdate = false): this {
576
+ this._lastNotMinimizedBoxStatus$.setValue(lastNotMinimizedBoxStatus, skipUpdate);
577
+ if (!skipUpdate) {
578
+ this.events.emit(TELE_BOX_EVENT.LastNotMinimizedBoxStatus, {id: this.id, lastNotMinimizedBoxStatus});
579
+ }
580
+ return this;
581
+ }
582
+
527
583
  /** Minimum box width relative to container element. 0~1. Default 0. */
528
584
  public get minWidth(): number {
529
585
  return this._minSize$.value.width;
@@ -892,25 +948,26 @@ export class TeleBox {
892
948
  this._minimized$,
893
949
  this._containerRect$,
894
950
  this._collectorRect$,
951
+ this._boxStatus$,
895
952
  ],
896
- ([coord, size, minimized, containerRect, collectorRect]) => {
953
+ ([coord, size, minimized, containerRect, collectorRect, boxStatus]) => {
897
954
  const absoluteWidth = size.width * containerRect.width;
898
955
  const absoluteHeight = size.height * containerRect.height;
899
956
  return {
900
957
  width:
901
958
  absoluteWidth +
902
- (minimized && collectorRect ? 1 : 0),
959
+ ((minimized || boxStatus === TELE_BOX_STATE.Minimized) && collectorRect ? 1 : 0),
903
960
  height:
904
961
  absoluteHeight +
905
- (minimized && collectorRect ? 1 : 0),
962
+ ((minimized || boxStatus === TELE_BOX_STATE.Minimized) && collectorRect ? 1 : 0),
906
963
  x: coord.x * containerRect.width,
907
964
  y: coord.y * containerRect.height,
908
965
  scaleX:
909
- minimized && collectorRect
966
+ (minimized || boxStatus === TELE_BOX_STATE.Minimized) && collectorRect
910
967
  ? collectorRect.width / absoluteWidth
911
968
  : 1,
912
969
  scaleY:
913
- minimized && collectorRect
970
+ (minimized || boxStatus === TELE_BOX_STATE.Minimized) && collectorRect
914
971
  ? collectorRect.height / absoluteHeight
915
972
  : 1,
916
973
  };
@@ -17,6 +17,8 @@ export type TeleBoxSize = { width: number; height: number };
17
17
 
18
18
  export type TeleBoxState = `${TELE_BOX_STATE}`;
19
19
 
20
+ export type NotMinimizedBoxState = `${Exclude<TELE_BOX_STATE, TELE_BOX_STATE.Minimized>}`;
21
+
20
22
  export interface TeleBoxRect {
21
23
  readonly x: number;
22
24
  readonly y: number;
@@ -81,6 +83,10 @@ export interface TeleBoxConfig {
81
83
  readonly containerRect?: TeleBoxRect;
82
84
  /** Position and dimension of collector */
83
85
  readonly collectorRect?: TeleBoxRect;
86
+ /** Status of boxes. */
87
+ readonly boxStatus?: TeleBoxState;
88
+ /** Last not minimized box status. */
89
+ readonly lastNotMinimizedBoxStatus?: NotMinimizedBoxState;
84
90
  }
85
91
 
86
92
  type CheckTeleBoxConfig<T extends Record<`${TELE_BOX_EVENT}`, any>> = T;
@@ -102,6 +108,8 @@ export type TeleBoxEventConfig = CheckTeleBoxConfig<{
102
108
  maximized: boolean;
103
109
  readonly: boolean;
104
110
  destroyed: void;
111
+ box_status: { id: string; boxStatus: TeleBoxState };
112
+ last_not_minimized_box_status: { id: string; lastNotMinimizedBoxStatus?: NotMinimizedBoxState };
105
113
  }>;
106
114
 
107
115
  export type TeleBoxEvent = keyof TeleBoxEventConfig;
@@ -5,16 +5,18 @@ import { DefaultTitleBar, DefaultTitleBarConfig } from "../../TeleTitleBar";
5
5
  import { TELE_BOX_STATE } from "../../TeleBox/constants";
6
6
  import { TeleBoxRect, TeleBoxState } from "../../TeleBox/typings";
7
7
 
8
- export type MaxTitleBarTeleBox = Pick<TeleBox, "id" | "title" | "readonly">;
8
+ export type MaxTitleBarTeleBox = Pick<TeleBox, "id" | "title" | "readonly" | "zIndex" | "$box">;
9
9
 
10
10
  export interface MaxTitleBarConfig extends DefaultTitleBarConfig {
11
11
  darkMode: boolean;
12
12
  boxes: MaxTitleBarTeleBox[];
13
13
  containerRect: TeleBoxRect;
14
14
  focusedBox?: MaxTitleBarTeleBox;
15
+ boxesStatus?: Map<string, TeleBoxState>;
15
16
  }
16
17
 
17
18
  export class MaxTitleBar extends DefaultTitleBar {
19
+ public boxesStatus?: Map<string, TeleBoxState>;
18
20
  public constructor(config: MaxTitleBarConfig) {
19
21
  super(config);
20
22
 
@@ -22,34 +24,74 @@ export class MaxTitleBar extends DefaultTitleBar {
22
24
  this.focusedBox = config.focusedBox;
23
25
  this.containerRect = config.containerRect;
24
26
  this.darkMode = config.darkMode;
27
+ this.boxesStatus = config.boxesStatus;
25
28
  }
26
29
 
30
+ public hasMaximizedBoxInStatus(): boolean {
31
+ if (!this.boxesStatus || this.boxesStatus.size === 0) {
32
+ return false
33
+ }
34
+ const hasMaximizedBox = [...this.boxesStatus.values()].find((state) => state === TELE_BOX_STATE.Maximized);
35
+ return !!hasMaximizedBox;
36
+ }
37
+
38
+ public get MaximizedBoxes(): MaxTitleBarTeleBox[] {
39
+ if (!this.boxesStatus || this.boxesStatus.size === 0) {
40
+ return [];
41
+ }
42
+ return this.boxes.filter((box) => this.boxesStatus && this.boxesStatus.get(box.id) === TELE_BOX_STATE.Maximized);
43
+ }
44
+
45
+ /**
46
+ * 设置MaxTitleBar的focusedBox
47
+ * @param box 如果box为空,则全部失去焦点
48
+ * @returns
49
+ */
27
50
  public focusBox(box?: MaxTitleBarTeleBox): void {
28
51
  if (this.focusedBox && this.focusedBox === box) {
29
52
  return;
30
53
  }
31
-
32
- if (this.$titles && this.state === TELE_BOX_STATE.Maximized) {
54
+ if (this.$titles) {
33
55
  const { children } = this.$titles.firstElementChild as HTMLElement;
34
- for (let i = children.length - 1; i >= 0; i -= 1) {
35
- const $tab = children[i] as HTMLElement;
36
- const id = $tab.dataset?.teleBoxID;
37
- if (id) {
38
- if (box && id === box.id) {
39
- $tab.classList.toggle(
40
- this.wrapClassName("titles-tab-focus"),
41
- true
42
- );
43
- } else if (this.focusedBox && id === this.focusedBox.id) {
44
- $tab.classList.toggle(
45
- this.wrapClassName("titles-tab-focus"),
46
- false
47
- );
56
+ if (this.state === TELE_BOX_STATE.Maximized && !this.hasMaximizedBoxInStatus()) {
57
+ for (let i = children.length - 1; i >= 0; i -= 1) {
58
+ const $tab = children[i] as HTMLElement;
59
+ const id = $tab.dataset?.teleBoxID;
60
+ if (id) {
61
+ if (box && id === box.id) {
62
+ $tab.classList.toggle(
63
+ this.wrapClassName("titles-tab-focus"),
64
+ true
65
+ );
66
+ } else if (this.focusedBox && id === this.focusedBox.id) {
67
+ $tab.classList.toggle(
68
+ this.wrapClassName("titles-tab-focus"),
69
+ false
70
+ );
71
+ }
72
+ }
73
+ }
74
+ } else if (this.hasMaximizedBoxInStatus()) {
75
+ for (let i = children.length - 1; i >= 0; i -= 1) {
76
+ const $tab = children[i] as HTMLElement;
77
+ const id = $tab.dataset?.teleBoxID;
78
+ if (id) {
79
+ if (box && id === box.id) {
80
+ $tab.classList.toggle(
81
+ this.wrapClassName("titles-tab-focus"),
82
+ true
83
+ );
84
+ } else if (this.focusedBox && id === this.focusedBox.id) {
85
+ $tab.classList.toggle(
86
+ this.wrapClassName("titles-tab-focus"),
87
+ false
88
+ );
89
+ }
48
90
  }
49
91
  }
50
92
  }
51
93
  }
52
- this.focusedBox = box;
94
+ this.focusedBox = box;
53
95
  }
54
96
 
55
97
  public setContainerRect(rect: TeleBoxRect): void {
@@ -61,12 +103,26 @@ export class MaxTitleBar extends DefaultTitleBar {
61
103
  }
62
104
  }
63
105
 
106
+ public setBoxesStatus(boxesStatus: Map<string, TeleBoxState>): void {
107
+ this.boxesStatus = boxesStatus;
108
+ if (this.hasMaximizedBoxInStatus()) {
109
+ this.setBoxStatus(TELE_BOX_STATE.Maximized);
110
+ }
111
+ if (this.$titleBar) {
112
+ this.$titleBar.classList.toggle(
113
+ this.wrapClassName("max-titlebar-maximized"),
114
+ this.state === TELE_BOX_STATE.Maximized && this.boxes.length > 0 || this.hasMaximizedBoxInStatus()
115
+ );
116
+ }
117
+ this.updateTitles();
118
+ }
119
+
64
120
  public setBoxes(boxes: MaxTitleBarTeleBox[]): void {
65
121
  this.boxes = boxes;
66
122
  if (this.$titleBar) {
67
123
  this.$titleBar.classList.toggle(
68
124
  this.wrapClassName("max-titlebar-maximized"),
69
- this.state === TELE_BOX_STATE.Maximized && boxes.length > 0
125
+ this.state === TELE_BOX_STATE.Maximized && boxes.length > 0 || this.hasMaximizedBoxInStatus()
70
126
  );
71
127
  }
72
128
  this.updateTitles();
@@ -77,7 +133,7 @@ export class MaxTitleBar extends DefaultTitleBar {
77
133
  if (this.$titleBar) {
78
134
  this.$titleBar.classList.toggle(
79
135
  this.wrapClassName("max-titlebar-maximized"),
80
- state === TELE_BOX_STATE.Maximized && this.boxes.length > 0
136
+ (state === TELE_BOX_STATE.Maximized && this.boxes.length > 0) || this.hasMaximizedBoxInStatus()
81
137
  );
82
138
  }
83
139
  this.updateTitles();
@@ -148,12 +204,12 @@ export class MaxTitleBar extends DefaultTitleBar {
148
204
  }
149
205
 
150
206
  public updateTitles(): void {
151
- if (this.$titleBar && this.state === TELE_BOX_STATE.Maximized) {
207
+ if (this.$titleBar && (this.state === TELE_BOX_STATE.Maximized || this.hasMaximizedBoxInStatus())) {
152
208
  this.$titleBar.classList.toggle(
153
209
  this.wrapClassName("max-titlebar-single-title"),
154
- this.boxes.length === 1
210
+ this.boxes.length === 1 || (this.hasMaximizedBoxInStatus() && this.MaximizedBoxes.length === 1)
155
211
  );
156
- if (this.boxes.length === 1) {
212
+ if (this.boxes.length === 1 || (this.hasMaximizedBoxInStatus() && this.MaximizedBoxes.length === 1)) {
157
213
  this.setTitle(this.boxes[0].title);
158
214
  } else {
159
215
  this.$titleBar.replaceChild(
@@ -182,7 +238,7 @@ export class MaxTitleBar extends DefaultTitleBar {
182
238
  $content.className = this.wrapClassName("titles-content");
183
239
  this.$titles.appendChild($content);
184
240
 
185
- this.boxes.forEach((box) => {
241
+ (this.hasMaximizedBoxInStatus() ? this.MaximizedBoxes : this.boxes).forEach((box) => {
186
242
  const $tab = document.createElement("button");
187
243
  $tab.className = this.wrapClassName("titles-tab");
188
244
  $tab.textContent = box.title;
@@ -14,4 +14,6 @@ export enum TELE_BOX_MANAGER_EVENT {
14
14
  ZIndex = "z_index",
15
15
  PrefersColorScheme = "prefers_color_scheme",
16
16
  DarkMode = "dark_mode",
17
+ BoxStatus = "box_status",
18
+ LastNotMinimizedBoxStatus = "last_not_minimized_box_status",
17
19
  }