@netless/telebox-insider 0.3.0-beta.1 → 0.3.0-beta.10

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.
@@ -30,6 +30,7 @@ import {
30
30
  ValEnhancedResult,
31
31
  withValueEnhancer,
32
32
  } from "value-enhancer";
33
+ import { AppMenu } from "../AppMenu";
33
34
 
34
35
  export * from "./typings";
35
36
  export * from "./constants";
@@ -49,6 +50,18 @@ export interface TeleBoxManager extends ValEnhancedResult<ValConfig> {}
49
50
  export class TeleBoxManager {
50
51
  private boxesStatus$: Map<string, TeleBoxState>;
51
52
  private lastNotMinimizedBoxesStatus$: Map<string, NotMinimizedBoxState>;
53
+ private appMenu: AppMenu | undefined;
54
+ private useBoxesStatus: boolean;
55
+ private effectBoxesStatusTimer?: {
56
+ skipUpdate: boolean;
57
+ timer: number | undefined;
58
+ resolve?: (skipUpdate: boolean) => void;
59
+ }
60
+ private effectLastNotMinimizedBoxStatusTimer?: {
61
+ skipUpdate: boolean;
62
+ timer: number | undefined;
63
+ resolve?: (skipUpdate: boolean) => void;
64
+ }
52
65
 
53
66
  public constructor({
54
67
  root = document.body,
@@ -65,8 +78,10 @@ export class TeleBoxManager {
65
78
  collector,
66
79
  namespace = "telebox",
67
80
  readonly = false,
81
+ useBoxesStatus = false,
68
82
  }: TeleBoxManagerConfig = {}) {
69
83
  this._sideEffect = new SideEffectManager();
84
+ this.useBoxesStatus = useBoxesStatus;
70
85
  const { combine, createVal } = createSideEffectBinder(this._sideEffect);
71
86
 
72
87
  this.root = root;
@@ -75,12 +90,17 @@ export class TeleBoxManager {
75
90
  this.boxes$ = createVal<TeleBox[]>([]);
76
91
  this.topBox$ = this.boxes$.derive((boxes) => {
77
92
  if (boxes.length > 0) {
78
- const topBox = boxes.reduce((topBox, box) => {
93
+ let currentTopBox: TeleBox | undefined = undefined;
94
+ const topBox = boxes.reduce((topBox, box) => {
79
95
  if (box.boxStatus && box.boxStatus === TELE_BOX_STATE.Minimized) {
80
96
  return topBox;
81
97
  }
98
+ if (!topBox) {
99
+ topBox = box;
100
+ return topBox;
101
+ }
82
102
  return topBox.zIndex > box.zIndex ? topBox : box;
83
- });
103
+ }, currentTopBox as (TeleBox | undefined));
84
104
  return topBox;
85
105
  }
86
106
  return;
@@ -181,7 +201,7 @@ export class TeleBoxManager {
181
201
  new TeleBoxCollector({
182
202
  visible: minimized,
183
203
  readonly: readonly,
184
- namespace,
204
+ namespace
185
205
  }).mount(root)
186
206
  );
187
207
  collector$.subscribe((collector) => {
@@ -189,20 +209,20 @@ export class TeleBoxManager {
189
209
  collector.setVisible(minimized$.value);
190
210
  collector.setReadonly(readonly$.value);
191
211
  collector.setDarkMode(this._darkMode$.value);
212
+ if (this.useBoxesStatus && this.appMenu) {
213
+ this.appMenu.setContainer(collector.$appMenuContainer);
214
+ }
192
215
  this._sideEffect.add(() => {
216
+ collector.getBoxesStatus = () => {
217
+ return this.boxesStatus$;
218
+ };
193
219
  collector.onClick = () => {
194
220
  if (!readonly$.value) {
195
- if (this.hasMinimizedBox()) {
196
- this.getAllMinimizedBoxes().forEach((box) => {
197
- const lastNotMinimizedBoxStatus = box.lastNotMinimizedBoxStatus;
198
- if (lastNotMinimizedBoxStatus) {
199
- this.setBoxStatus(box.id, lastNotMinimizedBoxStatus);
200
- } else {
201
- this.setBoxStatus(box.id, TELE_BOX_STATE.Normal);
202
- }
203
- });
221
+ if (!this.useBoxesStatus) {
222
+ minimized$.setValue(false);
223
+ } else if (this.useBoxesStatus && this.appMenu) {
224
+ this.appMenu.containerClickHandler();
204
225
  }
205
- minimized$.setValue(false);
206
226
  }
207
227
  };
208
228
  return () => collector.destroy();
@@ -232,6 +252,14 @@ export class TeleBoxManager {
232
252
  return;
233
253
  };
234
254
 
255
+ this._setCollectorRect = (collectorRect: TeleBoxRect | undefined) => {
256
+ if (collector$.value?.$collector) {
257
+ collectorRect$.setValue(collectorRect);
258
+ } else if (import.meta.env.DEV) {
259
+ console.warn("No collector for minimized boxes.");
260
+ }
261
+ };
262
+
235
263
  const collectorRect$ = createVal(
236
264
  minimized$.value ? this._calcCollectorRect() : void 0
237
265
  );
@@ -245,11 +273,7 @@ export class TeleBoxManager {
245
273
  collector$.value?.setVisible(minimized);
246
274
 
247
275
  if (minimized) {
248
- if (collector$.value?.$collector) {
249
- collectorRect$.setValue(this._calcCollectorRect());
250
- } else if (import.meta.env.DEV) {
251
- console.warn("No collector for minimized boxes.");
252
- }
276
+ this._setCollectorRect(this._calcCollectorRect());
253
277
  }
254
278
 
255
279
  this.boxes.forEach((box) =>
@@ -285,10 +309,27 @@ export class TeleBoxManager {
285
309
  if (id) {
286
310
  const box = this.getBox(id);
287
311
  if (box) {
288
- this.focusBox(box);
289
- if ((box.boxStatus && box.boxStatus !== TELE_BOX_STATE.Maximized) || !box.boxStatus) {
312
+ if (!this.useBoxesStatus) {
290
313
  this.makeBoxTop(box);
291
- }
314
+ } else {
315
+ if (box.boxStatus && box.boxStatus === TELE_BOX_STATE.Normal) {
316
+ const maxNormalBoxZIndex = this.getMaxNormalBoxZIndex();
317
+ if (maxNormalBoxZIndex > box.zIndex) {
318
+ this.setBox(box, {
319
+ zIndex: maxNormalBoxZIndex + 1
320
+ }, false);
321
+ }
322
+ } else if(box.boxStatus && box.boxStatus === TELE_BOX_STATE.Maximized){
323
+ const maxMaximizedBoxZIndex = this.getMaxMaximizedBoxZIndex();
324
+ if (maxMaximizedBoxZIndex > box.zIndex) {
325
+ this.setBox(box, {
326
+ zIndex: maxMaximizedBoxZIndex + 1
327
+ }, false);
328
+ }
329
+ this.makeMaximizedTopBoxFocus();
330
+ }
331
+ }
332
+ this.focusBox(box);
292
333
  return;
293
334
  }
294
335
  }
@@ -315,31 +356,85 @@ export class TeleBoxManager {
315
356
  state: state$.value,
316
357
  boxes: this.boxes$.value,
317
358
  containerRect: containerRect$.value,
318
- boxesStatus: this.boxesStatus$,
359
+ getBoxesStatus: () => {
360
+ return this.boxesStatus$;
361
+ },
319
362
  onEvent: (event): void => {
320
363
  switch (event.type) {
321
364
  case TELE_BOX_DELEGATE_EVENT.Maximize: {
322
- if (this.hasBoxesStatus() && this.maxTitleBar.focusedBox?.id) {
323
- this.setBoxStatus(this.maxTitleBar.focusedBox.id, TELE_BOX_STATE.Normal);
324
- this.makeMaximizedTopBoxFocus();
365
+ if (this.hasBoxesStatus()) {
366
+ let targetBox = this.maxTitleBar.focusedBox;
367
+ if (!targetBox) {
368
+ targetBox = this.getMaximizedTopBox();
369
+ }
370
+ if (targetBox?.id) {
371
+ const box = this.getBox(targetBox.id);
372
+ if (box) {
373
+ this.setBox(box, {
374
+ status: TELE_BOX_STATE.Normal,
375
+ zIndex: this.getMaxNormalBoxZIndex() + 1
376
+ }, false, ()=>{
377
+ this.makeMaximizedTopBoxFocus();
378
+ });
379
+ }
380
+ }
325
381
  } else {
326
382
  maximized$.setValue(!maximized$.value);
327
383
  }
328
384
  break;
329
385
  }
330
386
  case TELE_BOX_DELEGATE_EVENT.Minimize: {
331
- if (this.hasBoxesStatus() && this.maxTitleBar.focusedBox?.id) {
332
- this.setBoxStatus(this.maxTitleBar.focusedBox.id, TELE_BOX_STATE.Minimized);
333
- this.makeMaximizedTopBoxFocus();
387
+ if (this.hasBoxesStatus()) {
388
+ let targetBox = this.maxTitleBar.focusedBox;
389
+ if (!targetBox) {
390
+ targetBox = this.getMaximizedTopBox();
391
+ }
392
+ if(targetBox?.id){
393
+ const box = this.getBox(targetBox.id);
394
+ if (box) {
395
+ let isFocusChanged = false;
396
+ if (box.focus) {
397
+ this.blurBox(box);
398
+ isFocusChanged = true;
399
+ }
400
+ this.setBox(box, {
401
+ status: TELE_BOX_STATE.Minimized,
402
+ zIndex: -1
403
+ }, false);
404
+ if (isFocusChanged) {
405
+ this.focusTopBox();
406
+ } else {
407
+ this.makeMaximizedTopBoxFocus();
408
+ }
409
+ }
410
+ }
334
411
  } else {
335
412
  minimized$.setValue(true);
336
413
  }
337
414
  break;
338
415
  }
339
416
  case TELE_BOX_EVENT.Close: {
340
- if (this.hasBoxesStatus() && this.maxTitleBar.focusedBox?.id) {
341
- this.remove(this.maxTitleBar.focusedBox.id);
342
- this.makeMaximizedTopBoxFocus();
417
+ if (this.hasBoxesStatus()) {
418
+ let targetBox = this.maxTitleBar.focusedBox;
419
+ if (!targetBox) {
420
+ targetBox = this.getMaximizedTopBox();
421
+ }
422
+ if (targetBox?.id) {
423
+ const box = this.getBox(targetBox.id);
424
+ if (box) {
425
+ let isFocusChanged = false;
426
+ if (box.focus) {
427
+ this.blurBox(box);
428
+ isFocusChanged = true;
429
+ }
430
+ this.remove(box, false);
431
+ if (isFocusChanged) {
432
+ this.focusTopBox();
433
+ } else {
434
+ this.makeMaximizedTopBoxFocus();
435
+ }
436
+ }
437
+ }
343
438
  } else {
344
439
  this.removeTopBox();
345
440
  this.focusTopBox();
@@ -378,6 +473,10 @@ export class TeleBoxManager {
378
473
  this._state$ = state$;
379
474
 
380
475
  this.root.appendChild(this.maxTitleBar.render());
476
+
477
+ if (useBoxesStatus) {
478
+ this.appMenu = this.createMinimizedAppMenu();
479
+ }
381
480
  }
382
481
 
383
482
  public get boxes(): ReadonlyArray<TeleBox> {
@@ -400,6 +499,8 @@ export class TeleBoxManager {
400
499
 
401
500
  public _calcCollectorRect: () => TeleBoxRect | undefined;
402
501
 
502
+ public _setCollectorRect: (collectorRect: TeleBoxRect | undefined) => void;
503
+
403
504
  public get darkMode(): boolean {
404
505
  return this._darkMode$.value;
405
506
  }
@@ -433,93 +534,302 @@ export class TeleBoxManager {
433
534
  }
434
535
 
435
536
  public setBoxStatus(boxId: string, boxStatus?: TeleBoxState, skipUpdate = false): void {
436
- const boxesStatus = this.boxesStatus$;
437
537
  if (boxStatus) {
438
- const oldBoxStatus = boxesStatus.get(boxId);
439
- boxesStatus.set(boxId, boxStatus);
538
+ const oldBoxStatus = this.boxesStatus$.get(boxId);
539
+ this.boxesStatus$.set(boxId, boxStatus);
440
540
  if (boxStatus === TELE_BOX_STATE.Minimized && oldBoxStatus !== TELE_BOX_STATE.Minimized) {
441
541
  this.setLastNotMinimizedBoxStatus(boxId, oldBoxStatus, skipUpdate);
442
542
  } else if (oldBoxStatus === TELE_BOX_STATE.Minimized && boxStatus !== TELE_BOX_STATE.Minimized) {
443
543
  this.setLastNotMinimizedBoxStatus(boxId, undefined, skipUpdate);
444
544
  }
445
545
  } else {
446
- boxesStatus.delete(boxId);
546
+ this.boxesStatus$.delete(boxId);
447
547
  this.setLastNotMinimizedBoxStatus(boxId, undefined, skipUpdate);
448
548
  }
449
- this.setBoxesStatus(boxesStatus, skipUpdate);
450
549
  if (!skipUpdate) {
451
550
  this.events.emit(TELE_BOX_MANAGER_EVENT.BoxStatus, { id: boxId, boxStatus});
452
551
  }
453
552
  }
454
553
 
455
- private setBoxesStatus(boxesStatus: Map<string, TeleBoxState>, skipUpdate = false): void {
456
- let topBox:TeleBox | undefined;
457
- const topBoxId = this.topBox?.id;
458
- let hasMinimizedBox = false;
554
+ public getBoxStatus(boxId: string): TeleBoxState | undefined {
555
+ return this.boxesStatus$.get(boxId);
556
+ }
557
+
558
+ public get boxesStatus(): ReadonlyMap<string, TeleBoxState> {
559
+ return this.boxesStatus$;
560
+ }
561
+
562
+ public get lastNotMinimizedBoxesStatus(): ReadonlyMap<string, NotMinimizedBoxState> {
563
+ return this.lastNotMinimizedBoxesStatus$;
564
+ }
565
+
566
+ public setBoxesStatus(boxesStatus: Map<string, TeleBoxState>, skipUpdate = false) {
567
+ this.boxesStatus$ = boxesStatus;
568
+ this.effectBoxesStatusChange(skipUpdate);
569
+ }
570
+
571
+ public getBoxesStatus(): Map<string, TeleBoxState> {
572
+ return this.boxesStatus$;
573
+ }
574
+
575
+ private effectBoxStatusChange(){
576
+ if (!this.useBoxesStatus) {
577
+ return;
578
+ }
579
+ if(this.collector){
580
+ this.collector.updateBoxesStatus();
581
+ if(this.hasMinimizedBox()){
582
+ this._setCollectorRect(this._calcCollectorRect());
583
+ }
584
+ }
585
+ if (this.appMenu) {
586
+ this.appMenu.appMenuChange();
587
+ }
588
+ if (this.maxTitleBar) {
589
+ this.maxTitleBar.updateBoxesStatus();
590
+ }
591
+ }
592
+
593
+ private effectBoxesStatusTimerFunc(skipUpdate: boolean){
594
+ if (!this.useBoxesStatus) {
595
+ return;
596
+ }
597
+ let newTopBox:TeleBox | undefined;
598
+ const curTopBox = this.topBox;
459
599
  this.boxes.forEach((box) => {
460
- const boxStatus = boxesStatus.get(box.id);
600
+ const boxStatus = this.boxesStatus$.get(box.id);
461
601
  if (boxStatus) {
462
- if (boxStatus !== TELE_BOX_STATE.Minimized && box.zIndex > (topBox?.zIndex ?? 0)) {
463
- topBox = box;
602
+ if (boxStatus !== TELE_BOX_STATE.Minimized && box.zIndex > (newTopBox?.zIndex ?? 0)) {
603
+ newTopBox = box;
464
604
  }
465
605
  box.setBoxStatus(boxStatus, skipUpdate);
466
- if (boxStatus === TELE_BOX_STATE.Minimized) {
467
- hasMinimizedBox = true;
468
- }
469
606
  }
470
607
  });
471
- if (hasMinimizedBox) {
472
- this.collector?.setVisible(true);
473
- if (this.collector?.$collector) {
474
- this.setCollectorRect(this._calcCollectorRect());
475
- } else if (import.meta.env.DEV) {
476
- console.warn("No collector for minimized boxes.");
608
+ this.effectBoxStatusChange();
609
+ if (newTopBox && curTopBox !== newTopBox) {
610
+ this.topBox$.setValue(newTopBox);
611
+ }
612
+ if (!newTopBox && curTopBox) {
613
+ this.topBox$.setValue(undefined);
614
+ }
615
+ }
616
+
617
+ public async effectBoxesStatusChange(skipUpdate = false): Promise<void> {
618
+ if (!this.useBoxesStatus) {
619
+ if (this.effectBoxesStatusTimer && this.effectBoxesStatusTimer.timer) {
620
+ clearTimeout(this.effectBoxesStatusTimer.timer);
621
+ if (this.effectBoxesStatusTimer.resolve) {
622
+ this.effectBoxesStatusTimer.resolve(!!this.effectBoxesStatusTimer?.skipUpdate);
623
+ }
477
624
  }
478
- } else {
479
- this.collector?.setVisible(false);
625
+ this.effectBoxesStatusTimer=undefined;
626
+ return;
480
627
  }
481
- if (topBox && topBoxId !== topBox.id) {
482
- this.makeBoxTop(topBox, skipUpdate);
483
- this.focusTopBox();
484
- this.topBox$.setValue(topBox);
628
+ if (this.effectBoxesStatusTimer && this.effectBoxesStatusTimer.timer) {
629
+ if (this.effectBoxesStatusTimer.skipUpdate !== skipUpdate) {
630
+ clearTimeout(this.effectBoxesStatusTimer.timer);
631
+ if (this.effectBoxesStatusTimer.resolve) {
632
+ this.effectBoxesStatusTimer.resolve(!!this.effectBoxesStatusTimer?.skipUpdate);
633
+ }
634
+ this.effectBoxesStatusTimer.skipUpdate = skipUpdate;
635
+ } else {
636
+ return;
637
+ }
485
638
  }
486
- if (this.maxTitleBar) {
487
- this.maxTitleBar.setBoxesStatus(boxesStatus);
639
+ if (!this.effectBoxesStatusTimer) {
640
+ this.effectBoxesStatusTimer = {
641
+ skipUpdate,
642
+ timer: undefined,
643
+ resolve: undefined,
644
+ } as {
645
+ skipUpdate: boolean;
646
+ timer: number | undefined;
647
+ }
648
+ }
649
+ if (this.effectBoxesStatusTimer) {
650
+ const _skipUpdate = await new Promise<boolean>((resolve)=>{
651
+ this.effectBoxesStatusTimer!.resolve = resolve;
652
+ this.effectBoxesStatusTimer!.timer = setTimeout(()=>{
653
+ if (this.effectBoxesStatusTimer && this.effectBoxesStatusTimer.resolve) {
654
+ this.effectBoxesStatusTimer.resolve(this.effectBoxesStatusTimer!.skipUpdate);
655
+ }
656
+ }, 100) as unknown as number;
657
+ })
658
+ this.effectBoxesStatusTimerFunc(_skipUpdate)
659
+ this.effectBoxesStatusTimer = undefined;
488
660
  }
489
661
  }
490
662
 
491
663
  public hasBoxesStatus(): boolean {
664
+ if (!this.useBoxesStatus) {
665
+ return false;
666
+ }
492
667
  return this.boxesStatus$.size > 0;
493
668
  }
494
669
 
495
670
  public hasMinimizedBox(): boolean {
671
+ if (!this.useBoxesStatus) {
672
+ return false;
673
+ }
496
674
  return this.boxes.some((box) => box.boxStatus && box.boxStatus === TELE_BOX_STATE.Minimized);
497
675
  }
498
676
 
677
+ public getMinimizedBoxesStatus(): Map<string, TELE_BOX_STATE.Minimized> {
678
+ const minimizedBoxes = new Map<string, TELE_BOX_STATE.Minimized>();
679
+ this.boxesStatus$.forEach((boxStatus, boxId) => {
680
+ if (boxStatus === TELE_BOX_STATE.Minimized) {
681
+ minimizedBoxes.set(boxId, boxStatus as TELE_BOX_STATE.Minimized);
682
+ }
683
+ });
684
+ return minimizedBoxes;
685
+ }
686
+
687
+ public getNotMinimizedBoxesStatus(): Map<string, NotMinimizedBoxState> {
688
+ const notMinimizedBoxes = new Map<string, NotMinimizedBoxState>();
689
+ this.boxesStatus$.forEach((boxStatus, boxId) => {
690
+ if (boxStatus !== TELE_BOX_STATE.Minimized) {
691
+ notMinimizedBoxes.set(boxId, boxStatus as NotMinimizedBoxState);
692
+ }
693
+ });
694
+ return notMinimizedBoxes;
695
+ }
696
+
697
+ public getAllMaximizedBoxesStatus(): Map<string, TELE_BOX_STATE.Maximized> {
698
+ const maximizedBoxes = new Map<string, TELE_BOX_STATE.Maximized>();
699
+ this.boxesStatus$.forEach((boxStatus, boxId) => {
700
+ if (boxStatus === TELE_BOX_STATE.Maximized) {
701
+ maximizedBoxes.set(boxId, boxStatus as TELE_BOX_STATE.Maximized);
702
+ }
703
+ });
704
+ return maximizedBoxes;
705
+ }
706
+
707
+ public getAllNormalBoxesStatus(): Map<string, TELE_BOX_STATE.Normal> {
708
+ const normalBoxes = new Map<string, TELE_BOX_STATE.Normal>();
709
+ this.boxesStatus$.forEach((boxStatus, boxId) => {
710
+ if (boxStatus === TELE_BOX_STATE.Normal) {
711
+ normalBoxes.set(boxId, boxStatus as TELE_BOX_STATE.Normal);
712
+ }
713
+ });
714
+ return normalBoxes;
715
+ }
716
+
717
+ public getLastNotMinimizedBoxStatus(boxId: string): NotMinimizedBoxState | undefined {
718
+ return this.lastNotMinimizedBoxesStatus$.get(boxId);
719
+ }
720
+
499
721
  public setLastNotMinimizedBoxStatus(boxId: string, lastNotMinimizedBoxStatus?: NotMinimizedBoxState, skipUpdate = false): void {
500
- const boxesStatus = this.lastNotMinimizedBoxesStatus$;
501
722
  if (lastNotMinimizedBoxStatus) {
502
- boxesStatus.set(boxId, lastNotMinimizedBoxStatus);
723
+ this.lastNotMinimizedBoxesStatus$.set(boxId, lastNotMinimizedBoxStatus);
503
724
  } else {
504
- boxesStatus.delete(boxId);
725
+ this.lastNotMinimizedBoxesStatus$.delete(boxId);
505
726
  }
506
- this.setLastNotMinimizedBoxesStatus(boxesStatus, skipUpdate);
507
727
  if (!skipUpdate) {
508
728
  this.events.emit(TELE_BOX_MANAGER_EVENT.LastNotMinimizedBoxStatus, { id: boxId, boxStatus:lastNotMinimizedBoxStatus});
509
729
  }
510
730
  }
511
731
 
512
- private setLastNotMinimizedBoxesStatus(lastNotMinimizedBoxesStatus: Map<string, NotMinimizedBoxState>, skipUpdate = false): void {
732
+ public setLastNotMinimizedBoxesStatus(lastNotMinimizedBoxesStatus: Map<string, NotMinimizedBoxState>, skipUpdate = false): void {
733
+ this.lastNotMinimizedBoxesStatus$ = lastNotMinimizedBoxesStatus;
734
+ this.effectLastNotMinimizedBoxStatusChange(skipUpdate);
735
+ }
736
+
737
+ private async effectLastNotMinimizedBoxStatusChange(skipUpdate = false): Promise<void> {
738
+ if (!this.useBoxesStatus) {
739
+ if (this.effectLastNotMinimizedBoxStatusTimer && this.effectLastNotMinimizedBoxStatusTimer.timer) {
740
+ clearTimeout(this.effectLastNotMinimizedBoxStatusTimer.timer);
741
+ if (this.effectLastNotMinimizedBoxStatusTimer.resolve) {
742
+ this.effectLastNotMinimizedBoxStatusTimer.resolve(!!this.effectLastNotMinimizedBoxStatusTimer?.skipUpdate);
743
+ }
744
+ }
745
+ this.effectLastNotMinimizedBoxStatusTimer=undefined;
746
+ return;
747
+ }
748
+ if (this.effectLastNotMinimizedBoxStatusTimer && this.effectLastNotMinimizedBoxStatusTimer.timer) {
749
+ clearTimeout(this.effectLastNotMinimizedBoxStatusTimer.timer);
750
+ if (this.effectLastNotMinimizedBoxStatusTimer.skipUpdate !== skipUpdate) {
751
+ // this.effectLastNotMinimizedBoxStatusFunc(this.effectLastNotMinimizedBoxStatusTimer.skipUpdate)
752
+ if (this.effectLastNotMinimizedBoxStatusTimer.resolve) {
753
+ this.effectLastNotMinimizedBoxStatusTimer.resolve(!!this.effectLastNotMinimizedBoxStatusTimer?.skipUpdate);
754
+ }
755
+ this.effectLastNotMinimizedBoxStatusTimer.skipUpdate = skipUpdate;
756
+ } else {
757
+ return;
758
+ }
759
+ }
760
+ if (!this.effectLastNotMinimizedBoxStatusTimer) {
761
+ this.effectLastNotMinimizedBoxStatusTimer = {
762
+ skipUpdate,
763
+ timer: undefined,
764
+ resolve: undefined,
765
+ } as {
766
+ skipUpdate: boolean;
767
+ timer: number | undefined;
768
+ }
769
+ }
770
+ if (this.effectLastNotMinimizedBoxStatusTimer) {
771
+ const _skipUpdate = await new Promise<boolean>((resolve)=>{
772
+ this.effectLastNotMinimizedBoxStatusTimer!.resolve = resolve;
773
+ this.effectLastNotMinimizedBoxStatusTimer!.timer = setTimeout(()=>{
774
+ if (this.effectLastNotMinimizedBoxStatusTimer && this.effectLastNotMinimizedBoxStatusTimer.resolve) {
775
+ this.effectLastNotMinimizedBoxStatusTimer.resolve(this.effectLastNotMinimizedBoxStatusTimer!.skipUpdate);
776
+ }
777
+ }, 100) as unknown as number;
778
+ })
779
+ this.effectLastNotMinimizedBoxStatusFunc(_skipUpdate)
780
+ this.effectLastNotMinimizedBoxStatusTimer = undefined;
781
+ }
782
+ }
783
+
784
+ private effectLastNotMinimizedBoxStatusFunc(skipUpdate = false){
785
+ if (!this.useBoxesStatus) {
786
+ return;
787
+ }
513
788
  this.boxes.forEach((box) => {
514
- const boxStatus = lastNotMinimizedBoxesStatus.get(box.id);
515
- if (boxStatus) {
789
+ const boxStatus = this.lastNotMinimizedBoxesStatus$.get(box.id);
790
+ if(boxStatus){
516
791
  box.setLastNotMinimizedBoxStatus(boxStatus, skipUpdate);
517
792
  }
518
793
  });
519
794
  }
520
795
 
521
- private getAllMinimizedBoxes(): ReadonlyArray<TeleBox> {
522
- return this.boxes.filter((box) => box.boxStatus && box.boxStatus === TELE_BOX_STATE.Minimized);
796
+ private getUnabledBoxesStatusZIndex(): number {
797
+ return this.topBox ? this.topBox.zIndex : 99;
798
+ }
799
+
800
+ // private getTopBoxZIndex(): number {
801
+ // if (!this.useBoxesStatus) {
802
+ // return this.getUnabledBoxesStatusZIndex();
803
+ // }
804
+ // return [...this.boxes].filter((box) => box.boxStatus !== TELE_BOX_STATE.Minimized).reduce((maxZIndex, box) => {
805
+ // return Math.max(maxZIndex, box.zIndex);
806
+ // }, 100);
807
+ // }
808
+
809
+ /** Maximized box zIndex range: 100-299 */
810
+ public getMaxMaximizedBoxZIndex(): number {
811
+ if (!this.useBoxesStatus) {
812
+ return this.getUnabledBoxesStatusZIndex();
813
+ }
814
+ return this.boxes.reduce((maxZIndex, box) => {
815
+ if (box.boxStatus && box.boxStatus === TELE_BOX_STATE.Maximized) {
816
+ return Math.max(maxZIndex, box.zIndex);
817
+ }
818
+ return maxZIndex;
819
+ }, 99);
820
+ }
821
+
822
+ /** normal box zIndex range: 300-499 */
823
+ public getMaxNormalBoxZIndex(): number {
824
+ if (!this.useBoxesStatus) {
825
+ return this.getUnabledBoxesStatusZIndex();
826
+ }
827
+ return this.boxes.reduce((maxZIndex, box) => {
828
+ if (box.boxStatus && box.boxStatus === TELE_BOX_STATE.Normal) {
829
+ return Math.max(maxZIndex, box.zIndex);
830
+ }
831
+ return maxZIndex;
832
+ }, 299);
523
833
  }
524
834
 
525
835
  public create(
@@ -527,7 +837,7 @@ export class TeleBoxManager {
527
837
  smartPosition = true
528
838
  ): ReadonlyTeleBox {
529
839
  const box = new TeleBox({
530
- zIndex: this.topBox ? this.topBox.zIndex + 1 : 100,
840
+ zIndex: this.getMaxNormalBoxZIndex() + 1,
531
841
  ...(smartPosition ? this.smartPosition(config) : config),
532
842
  darkMode: this.darkMode,
533
843
  prefersColorScheme: this.prefersColorScheme,
@@ -542,6 +852,15 @@ export class TeleBoxManager {
542
852
 
543
853
  box.mount(this.root);
544
854
 
855
+ this.boxes$.setValue([...this.boxes, box]);
856
+
857
+ if (box.boxStatus && this.useBoxesStatus) {
858
+ this.setBox(box, {
859
+ status: box.boxStatus,
860
+ lastNotMinimizedBoxStatus: box._lastNotMinimizedBoxStatus$.value
861
+ }, true);
862
+ }
863
+
545
864
  if (box.focus) {
546
865
  this.focusBox(box);
547
866
  if (smartPosition) {
@@ -549,45 +868,50 @@ export class TeleBoxManager {
549
868
  }
550
869
  }
551
870
 
552
- this.boxes$.setValue([...this.boxes, box]);
553
-
554
- if (box.boxStatus) {
555
- this.setBoxStatus(box.id, box.boxStatus, true);
556
- }
557
-
558
- if (box._lastNotMinimizedBoxStatus$.value) {
559
- this.setLastNotMinimizedBoxStatus(box.id, box._lastNotMinimizedBoxStatus$.value, true);
560
- }
561
-
562
871
  box._delegateEvents.on(TELE_BOX_DELEGATE_EVENT.Maximize, () => {
563
- if (box.boxStatus) {
872
+ if (this.useBoxesStatus && box.boxStatus) {
564
873
  if (box.boxStatus === TELE_BOX_STATE.Maximized) {
565
- this.setBoxStatus(box.id, TELE_BOX_STATE.Normal);
874
+ this.setBox(box.id, {
875
+ status: TELE_BOX_STATE.Normal,
876
+ zIndex: this.getMaxNormalBoxZIndex() + 1
877
+ }, false);
566
878
  } else {
567
- this.boxes.forEach((box) => {
879
+ // 所有normal box都最大化
880
+ [...this.boxes].filter((box) => box.boxStatus === TELE_BOX_STATE.Normal).sort((a, b) => a.zIndex - b.zIndex).forEach((box) => {
568
881
  if (box.boxStatus === TELE_BOX_STATE.Normal) {
569
- this.setBoxStatus(box.id, TELE_BOX_STATE.Maximized);
882
+ this.setBox(box.id, {
883
+ status: TELE_BOX_STATE.Maximized,
884
+ zIndex: this.getMaxMaximizedBoxZIndex() + 1
885
+ }, false);
570
886
  }
571
887
  });
888
+ this.makeMaximizedTopBoxFocus();
572
889
  }
573
- this.makeMaximizedTopBoxFocus();
574
890
  } else {
575
891
  this.setMaximized(!this.maximized);
576
892
  }
577
893
 
578
894
  });
579
895
  box._delegateEvents.on(TELE_BOX_DELEGATE_EVENT.Minimize, () => {
580
- if (box.boxStatus) {
581
- const oldBoxStatus = box.boxStatus;
582
- this.setBoxStatus(box.id, TELE_BOX_STATE.Minimized);
583
- if (oldBoxStatus === TELE_BOX_STATE.Maximized) {
584
- this.makeMaximizedTopBoxFocus();
896
+ if (box.boxStatus && this.useBoxesStatus) {
897
+ if(box.focus) {
898
+ this.blurBox(box);
585
899
  }
900
+ this.setBox(box, {
901
+ status: TELE_BOX_STATE.Minimized,
902
+ zIndex: -1
903
+ }, false, ()=>{
904
+ this.focusTopBox();
905
+ });
906
+
586
907
  } else{
587
908
  this.setMinimized(true);
588
909
  }
589
910
  });
590
911
  box._delegateEvents.on(TELE_BOX_DELEGATE_EVENT.Close, () => {
912
+ if (this.useBoxesStatus && box.focus) {
913
+ this.blurBox(box);
914
+ }
591
915
  this.remove(box);
592
916
  this.focusTopBox();
593
917
  });
@@ -618,12 +942,17 @@ export class TeleBoxManager {
618
942
  });
619
943
  box._zIndex$.reaction((_, __, skipUpdate) => {
620
944
  if (this.boxes.length > 0) {
945
+ let currentTopBox: TeleBox | undefined = undefined;
621
946
  const topBox = this.boxes.reduce((topBox, box) => {
622
947
  if (box.boxStatus && box.boxStatus === TELE_BOX_STATE.Minimized) {
623
948
  return topBox;
624
949
  }
950
+ if (!topBox) {
951
+ topBox = box;
952
+ return topBox;
953
+ }
625
954
  return topBox.zIndex > box.zIndex ? topBox : box;
626
- });
955
+ }, currentTopBox as (TeleBox | undefined));
627
956
  this.topBox$.setValue(topBox);
628
957
  }
629
958
  if (!skipUpdate) {
@@ -669,21 +998,48 @@ export class TeleBoxManager {
669
998
  });
670
999
  }
671
1000
 
1001
+ public setBox(boxOrID: string | TeleBox, options: {
1002
+ status?: TeleBoxState;
1003
+ lastNotMinimizedBoxStatus?: NotMinimizedBoxState;
1004
+ zIndex?: number;
1005
+ }, skipUpdate = false, effectFunc?: () => void){
1006
+ const box = this.getBox(boxOrID)
1007
+ if (box) {
1008
+ const {status, zIndex, lastNotMinimizedBoxStatus} = options;
1009
+ if (status) {
1010
+ this.setBoxStatus(box.id, status, skipUpdate);
1011
+ box.setBoxStatus(status, skipUpdate);
1012
+ this.effectBoxStatusChange();
1013
+ }
1014
+ if (zIndex) {
1015
+ box.setZIndex(zIndex, skipUpdate);
1016
+ }
1017
+ if (lastNotMinimizedBoxStatus) {
1018
+ this.setLastNotMinimizedBoxStatus(box.id, lastNotMinimizedBoxStatus, skipUpdate);
1019
+ box.setLastNotMinimizedBoxStatus(lastNotMinimizedBoxStatus, skipUpdate);
1020
+ }
1021
+ effectFunc && effectFunc();
1022
+ }
1023
+ }
1024
+
672
1025
  public remove(
673
1026
  boxOrID: string | TeleBox,
674
- skipUpdate = false
1027
+ skipUpdate = false,
1028
+ effectFunc?: () => void
675
1029
  ): ReadonlyTeleBox | undefined {
676
1030
  const box = this.getBox(boxOrID);
677
- if (box) {
678
- this.setBoxStatus(box.id, undefined, skipUpdate);
679
- this.setLastNotMinimizedBoxStatus(box.id, undefined, skipUpdate);
680
- }
681
1031
  const index = this.getBoxIndex(boxOrID);
682
1032
  if (index >= 0) {
683
1033
  const boxes = this.boxes.slice();
684
1034
  const deletedBoxes = boxes.splice(index, 1);
685
1035
  this.boxes$.setValue(boxes);
686
1036
  deletedBoxes.forEach((box) => box.destroy());
1037
+ if (box && this.useBoxesStatus) {
1038
+ this.setBoxStatus(box.id, undefined, skipUpdate);
1039
+ this.setLastNotMinimizedBoxStatus(box.id, undefined, skipUpdate);
1040
+ this.effectBoxStatusChange();
1041
+ effectFunc && effectFunc();
1042
+ }
687
1043
  if (!skipUpdate) {
688
1044
  if (this.boxes.length <= 0) {
689
1045
  this.setMaximized(false);
@@ -756,10 +1112,10 @@ export class TeleBoxManager {
756
1112
  this.blurBox(box, skipUpdate);
757
1113
  }
758
1114
  });
759
- if (this.maxTitleBar.hasMaximizedBoxInStatus()) {
760
- this.makeMaximizedBoxFocus(targetBox);
761
- } else {
1115
+ if (!this.useBoxesStatus) {
762
1116
  this.maxTitleBar.focusBox(targetBox);
1117
+ } else if (this.useBoxesStatus && this.maxTitleBar.hasMaximizedBoxInStatus()) {
1118
+ this.makeMaximizedTopBoxFocus();
763
1119
  }
764
1120
  }
765
1121
  }
@@ -780,11 +1136,7 @@ export class TeleBoxManager {
780
1136
  }
781
1137
  }
782
1138
  if (this.maxTitleBar.focusedBox === targetBox) {
783
- if (this.maxTitleBar.hasMaximizedBoxInStatus()) {
784
- this.makeMaximizedTopBoxFocus();
785
- } else {
786
- this.maxTitleBar.focusBox();
787
- }
1139
+ this.maxTitleBar.focusBox();
788
1140
  }
789
1141
  }
790
1142
  }
@@ -799,11 +1151,7 @@ export class TeleBoxManager {
799
1151
  }
800
1152
  });
801
1153
  if (this.maxTitleBar.focusedBox) {
802
- if (this.maxTitleBar.hasMaximizedBoxInStatus()) {
803
- this.makeMaximizedBoxBlur();
804
- } else {
805
- this.maxTitleBar.focusBox();
806
- }
1154
+ this.maxTitleBar.focusBox();
807
1155
  }
808
1156
  }
809
1157
 
@@ -811,6 +1159,7 @@ export class TeleBoxManager {
811
1159
 
812
1160
  protected boxes$: Val<TeleBox[]>;
813
1161
  protected topBox$: Val<TeleBox | undefined>;
1162
+ // protected maximizedTopBox$: Val<MaxTitleBarTeleBox | undefined>;
814
1163
 
815
1164
  protected teleBoxMatcher(
816
1165
  config: TeleBoxManagerQueryConfig
@@ -872,11 +1221,11 @@ export class TeleBoxManager {
872
1221
  if (config.footer != null) {
873
1222
  box.mountFooter(config.footer);
874
1223
  }
875
- if (config.boxStatus) {
876
- this.setBoxStatus(box.id, config.boxStatus, skipUpdate);
877
- }
878
- if (config.lastNotMinimizedBoxStatus) {
879
- this.setLastNotMinimizedBoxStatus(box.id, config.lastNotMinimizedBoxStatus, skipUpdate);
1224
+ if (this.useBoxesStatus && (config.boxStatus || config.lastNotMinimizedBoxStatus)) {
1225
+ this.setBox(box, {
1226
+ status: config.boxStatus,
1227
+ lastNotMinimizedBoxStatus: config.lastNotMinimizedBoxStatus
1228
+ }, skipUpdate);
880
1229
  }
881
1230
  }
882
1231
 
@@ -888,13 +1237,17 @@ export class TeleBoxManager {
888
1237
  let vx = 20;
889
1238
  if (this.topBox) {
890
1239
  vx = this.topBox.intrinsicX * this.containerRect.width + 20;
891
-
892
1240
  if (
893
1241
  vx >
894
1242
  this.containerRect.width - width * this.containerRect.width
895
1243
  ) {
896
1244
  vx = 20;
897
1245
  }
1246
+ } else if (this.hasMinimizedBox()) {
1247
+ // 如果都最小化,则获取lastNotMinimizedBoxesStatus中normal box的最大x
1248
+ vx = [...this.boxes].filter((box) => box.boxStatus && box.boxStatus === TELE_BOX_STATE.Minimized && box.lastNotMinimizedBoxStatus && box.lastNotMinimizedBoxStatus === TELE_BOX_STATE.Normal).reduce((maxX, box) => {
1249
+ return Math.max(maxX, box.intrinsicX * this.containerRect.width + 20);
1250
+ }, vx);
898
1251
  }
899
1252
  x = vx / this.containerRect.width;
900
1253
  }
@@ -912,6 +1265,11 @@ export class TeleBoxManager {
912
1265
  ) {
913
1266
  vy = 20;
914
1267
  }
1268
+ } else if (this.hasMinimizedBox()) {
1269
+ // 如果都最小化,则获取lastNotMinimizedBoxesStatus中normal box的最大y
1270
+ vy = [...this.boxes].filter((box) => box.boxStatus && box.boxStatus === TELE_BOX_STATE.Minimized && box.lastNotMinimizedBoxStatus && box.lastNotMinimizedBoxStatus === TELE_BOX_STATE.Normal).reduce((maxY, box) => {
1271
+ return Math.max(maxY, box.intrinsicY * this.containerRect.height + 20);
1272
+ }, vy);
915
1273
  }
916
1274
 
917
1275
  y = vy / this.containerRect.height;
@@ -921,17 +1279,19 @@ export class TeleBoxManager {
921
1279
  }
922
1280
 
923
1281
  protected makeBoxTop(box: TeleBox, skipUpdate = false): void {
924
- if (this.topBox) {
1282
+ if (!this.useBoxesStatus && this.topBox) {
925
1283
  if (box !== this.topBox) {
926
- const currentBoxZIndex = box.zIndex;
927
- const addZIndex = this.topBox.zIndex + 1 - box.zIndex;
928
1284
  box.setZIndex(this.topBox.zIndex + 1, skipUpdate);
929
- this.makeTopBoxEffect(box.id, addZIndex, currentBoxZIndex, skipUpdate);
930
1285
  }
1286
+ } else if (this.useBoxesStatus) {
1287
+ // todo
931
1288
  }
932
1289
  }
933
1290
 
934
- protected makeMaximizedTopBoxFocus(): void {
1291
+ private getMaximizedTopBox(): MaxTitleBarTeleBox | undefined {
1292
+ if (!this.useBoxesStatus) {
1293
+ return undefined;
1294
+ }
935
1295
  let maximizedBox: MaxTitleBarTeleBox | undefined;
936
1296
  if (this.maxTitleBar.hasMaximizedBoxInStatus()) {
937
1297
  maximizedBox = this.maxTitleBar.MaximizedBoxes.reduce((topBox, currentBox) => {
@@ -939,49 +1299,17 @@ export class TeleBoxManager {
939
1299
  return currentBox;
940
1300
  }
941
1301
  return topBox.zIndex > currentBox.zIndex ? topBox : currentBox;
942
- });
943
- if (maximizedBox) {
944
- this.maxTitleBar.focusBox(maximizedBox);
945
- }
946
- }
947
- }
948
-
949
- private makeTopBoxEffect(boxId: string, addZIndex: number, currentZIndex: number, skipUpdate = false): void {
950
- if (this.hasBoxesStatus() && this.hasMinimizedBox()) {
951
- this.boxes.forEach((b) => {
952
- if (b.boxStatus && b.id !== boxId && b.zIndex >= currentZIndex) {
953
- b.setZIndex(b.zIndex + addZIndex, skipUpdate);
954
- }
955
- });
1302
+ }, );
956
1303
  }
1304
+ return maximizedBox;
957
1305
  }
958
1306
 
959
- protected makeMaximizedBoxFocus(maximizedBox: MaxTitleBarTeleBox, skipUpdate = false): void {
960
- if (this.maxTitleBar.hasMaximizedBoxInStatus() && this.maxTitleBar.MaximizedBoxes.find((box) => box.id === maximizedBox.id)) {
961
- const currentZIndex = maximizedBox.zIndex;
962
- const currentMaximizedTopBox = this.maxTitleBar.MaximizedBoxes.reduce((topBox, box) => {
963
- if (!topBox) {
964
- return box;
965
- }
966
- return topBox.zIndex > box.zIndex ? topBox : box;
967
- });
968
- if (currentMaximizedTopBox !== maximizedBox) {
969
- const addZIndex = currentMaximizedTopBox.zIndex - currentZIndex + 1;
970
- this.boxes.forEach((box) => {
971
- if (this.maxTitleBar.MaximizedBoxes.find((b) => b.id === box.id && b.id !== maximizedBox.id)) {
972
- return;
973
- }
974
- if (box.zIndex >= currentZIndex) {
975
- box.setZIndex(box.zIndex + addZIndex, skipUpdate);
976
- }
977
- });
978
- }
979
- this.maxTitleBar.focusBox(maximizedBox);
1307
+ protected makeMaximizedTopBoxFocus(): void {
1308
+ if (!this.useBoxesStatus) {
1309
+ return;
980
1310
  }
981
- }
982
-
983
- protected makeMaximizedBoxBlur(): void {
984
- this.maxTitleBar.focusBox();
1311
+ const maximizedBox: MaxTitleBarTeleBox | undefined = this.getMaximizedTopBox();
1312
+ this.maxTitleBar.focusBox(maximizedBox);
985
1313
  }
986
1314
 
987
1315
  protected getBoxIndex(boxOrID: TeleBox | string): number {
@@ -990,9 +1318,23 @@ export class TeleBoxManager {
990
1318
  : this.boxes.findIndex((box) => box === boxOrID);
991
1319
  }
992
1320
 
993
- protected getBox(boxOrID: TeleBox | string): TeleBox | undefined {
1321
+ public getBox(boxOrID: TeleBox | string): TeleBox | undefined {
994
1322
  return typeof boxOrID === "string"
995
1323
  ? this.boxes.find((box) => box.id === boxOrID)
996
1324
  : boxOrID;
997
1325
  }
1326
+
1327
+ public createMinimizedAppMenu():AppMenu | undefined {
1328
+ if (this.collector?.$appMenuContainer) {
1329
+ return new AppMenu({
1330
+ manager: this,
1331
+ container: this.collector?.$appMenuContainer,
1332
+ theme: this.prefersColorScheme ? 'dark' : 'light',
1333
+ getBoxesStatus: () => {
1334
+ return this.boxesStatus$;
1335
+ }
1336
+ });
1337
+ }
1338
+ return;
1339
+ }
998
1340
  }