dsh-better-left-sidebar 0.1.0 → 0.1.2
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/README.en.md +37 -11
- package/README.md +38 -12
- package/lib/client.js +1475 -197
- package/lib/index.js +12 -2
- package/lib/slots.d.ts +18 -0
- package/locale/en.json +1 -1
- package/locale/zh.json +1 -1
- package/package.json +19 -5
package/lib/client.js
CHANGED
|
@@ -39,9 +39,9 @@ html.dsh-better-left-sidebar {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
html.dsh-better-left-sidebar [data-slot="sidebar"] > [data-dsh-better-left-sidebar-root] {
|
|
42
|
-
--dsh-better-left-sidebar-rail: 56px;
|
|
42
|
+
--dsh-better-left-sidebar-rail: min(56px, 100%);
|
|
43
43
|
--dsh-better-left-sidebar-open: 100%;
|
|
44
|
-
--dsh-better-left-sidebar-conversation: calc(100% - var(--dsh-better-left-sidebar-rail));
|
|
44
|
+
--dsh-better-left-sidebar-conversation: max(0px, calc(100% - var(--dsh-better-left-sidebar-rail)));
|
|
45
45
|
position: relative !important;
|
|
46
46
|
display: block !important;
|
|
47
47
|
min-height: 0;
|
|
@@ -88,7 +88,8 @@ html.dsh-better-left-sidebar [data-slot="sidebar"] > [data-dsh-better-left-sideb
|
|
|
88
88
|
html.dsh-better-left-sidebar [data-slot="sidebar"] > [data-dsh-better-left-sidebar-root] [data-dsh-better-left-sidebar-region="brand"],
|
|
89
89
|
html.dsh-better-left-sidebar [data-slot="sidebar"] > [data-dsh-better-left-sidebar-root] [data-dsh-better-left-sidebar-region="new-session"],
|
|
90
90
|
html.dsh-better-left-sidebar [data-slot="sidebar"] > [data-dsh-better-left-sidebar-root] [data-dsh-better-left-sidebar-region="global-navigation"],
|
|
91
|
-
html.dsh-better-left-sidebar [data-slot="sidebar"] > [data-dsh-better-left-sidebar-root] [data-dsh-better-left-sidebar-region="tools"]
|
|
91
|
+
html.dsh-better-left-sidebar [data-slot="sidebar"] > [data-dsh-better-left-sidebar-root] [data-dsh-better-left-sidebar-region="tools"],
|
|
92
|
+
html.dsh-better-left-sidebar [data-slot="sidebar"] > [data-dsh-better-left-sidebar-root] [data-dsh-better-left-sidebar-region="compact-widgets"] {
|
|
92
93
|
box-sizing: border-box;
|
|
93
94
|
min-width: 0;
|
|
94
95
|
margin: 0;
|
|
@@ -277,6 +278,94 @@ html.dsh-better-left-sidebar [data-slot="sidebar"] > [data-dsh-better-left-sideb
|
|
|
277
278
|
scrollbar-width: none;
|
|
278
279
|
}
|
|
279
280
|
|
|
281
|
+
html.dsh-better-left-sidebar [data-slot="sidebar"] > [data-dsh-better-left-sidebar-root] [data-dsh-better-left-sidebar-region="compact-widgets"] {
|
|
282
|
+
position: absolute;
|
|
283
|
+
z-index: 2;
|
|
284
|
+
bottom: var(--dsh-better-left-sidebar-compact-widgets-bottom, 16px);
|
|
285
|
+
left: 0;
|
|
286
|
+
display: flex;
|
|
287
|
+
width: 56px;
|
|
288
|
+
max-height: var(--dsh-better-left-sidebar-compact-widgets-height, 0px);
|
|
289
|
+
flex-direction: column;
|
|
290
|
+
align-items: stretch;
|
|
291
|
+
gap: 4px;
|
|
292
|
+
box-sizing: border-box;
|
|
293
|
+
padding: 0;
|
|
294
|
+
overflow: hidden;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
html.dsh-better-left-sidebar [data-slot="sidebar"] > [data-dsh-better-left-sidebar-root] [data-dsh-better-left-sidebar-compact-widget-clipped] {
|
|
298
|
+
visibility: hidden;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
html.dsh-better-left-sidebar [data-slot="sidebar"] > [data-dsh-better-left-sidebar-root] [data-dsh-better-left-sidebar-region="compact-widgets"][hidden] {
|
|
302
|
+
display: none !important;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
html.dsh-better-left-sidebar [data-slot="sidebar"] > [data-dsh-better-left-sidebar-root] .dsh-better-left-sidebar-compact-widget-box {
|
|
306
|
+
width: 100%;
|
|
307
|
+
flex: none;
|
|
308
|
+
overflow: hidden;
|
|
309
|
+
pointer-events: none;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/* A widget that renders nothing must not take a flex gap. */
|
|
313
|
+
html.dsh-better-left-sidebar [data-slot="sidebar"] > [data-dsh-better-left-sidebar-root] .dsh-better-left-sidebar-compact-widget-box:not(:has(> [data-slot] > *)) {
|
|
314
|
+
display: none;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
html.dsh-better-left-sidebar [data-slot="sidebar"] > [data-dsh-better-left-sidebar-root] .dsh-better-left-sidebar-clock,
|
|
318
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-clock-preview .dsh-better-left-sidebar-clock {
|
|
319
|
+
display: flex;
|
|
320
|
+
width: 100%;
|
|
321
|
+
min-width: 0;
|
|
322
|
+
box-sizing: border-box;
|
|
323
|
+
flex-direction: column;
|
|
324
|
+
align-items: center;
|
|
325
|
+
justify-content: center;
|
|
326
|
+
gap: 1px;
|
|
327
|
+
overflow: hidden;
|
|
328
|
+
color: var(--dsw-alias-label-secondary);
|
|
329
|
+
font-variant-numeric: tabular-nums;
|
|
330
|
+
font-feature-settings: 'tnum' 1;
|
|
331
|
+
line-height: 16px;
|
|
332
|
+
white-space: nowrap;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
html.dsh-better-left-sidebar [data-slot="sidebar"] > [data-dsh-better-left-sidebar-root] .dsh-better-left-sidebar-clock-time,
|
|
336
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-clock-preview .dsh-better-left-sidebar-clock-time {
|
|
337
|
+
display: inline-flex;
|
|
338
|
+
align-items: baseline;
|
|
339
|
+
gap: 3px;
|
|
340
|
+
color: var(--dsw-alias-label-primary);
|
|
341
|
+
font-size: 12px;
|
|
342
|
+
font-weight: 650;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
html.dsh-better-left-sidebar [data-slot="sidebar"] > [data-dsh-better-left-sidebar-root] .dsh-better-left-sidebar-clock-period,
|
|
346
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-clock-preview .dsh-better-left-sidebar-clock-period {
|
|
347
|
+
font-size: 12px;
|
|
348
|
+
font-weight: 650;
|
|
349
|
+
line-height: 16px;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
html.dsh-better-left-sidebar [data-slot="sidebar"] > [data-dsh-better-left-sidebar-root] .dsh-better-left-sidebar-clock-date,
|
|
353
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-clock-preview .dsh-better-left-sidebar-clock-date {
|
|
354
|
+
font-size: 11px;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-visually-hidden {
|
|
358
|
+
position: absolute !important;
|
|
359
|
+
width: 1px;
|
|
360
|
+
height: 1px;
|
|
361
|
+
padding: 0;
|
|
362
|
+
margin: -1px;
|
|
363
|
+
overflow: hidden;
|
|
364
|
+
clip: rect(0, 0, 0, 0);
|
|
365
|
+
white-space: nowrap;
|
|
366
|
+
border: 0;
|
|
367
|
+
}
|
|
368
|
+
|
|
280
369
|
html.dsh-better-left-sidebar [data-slot="sidebar"] > [data-dsh-better-left-sidebar-root][data-dsh-better-left-sidebar-tools-position="rail-bottom"] [data-dsh-better-left-sidebar-region="tools"] {
|
|
281
370
|
right: auto;
|
|
282
371
|
bottom: 8px;
|
|
@@ -540,12 +629,18 @@ html.dsh-better-left-sidebar[data-dsh-better-left-sidebar-animation="off"] {
|
|
|
540
629
|
}
|
|
541
630
|
}
|
|
542
631
|
|
|
543
|
-
/* DSH-native
|
|
632
|
+
/* DSH-native staged settings. Keep field controls and previews within one reading width. */
|
|
633
|
+
html.dsh-better-left-sidebar div:has(> .dsh-better-left-sidebar-preferences) {
|
|
634
|
+
width: 100%;
|
|
635
|
+
max-width: 780px;
|
|
636
|
+
box-sizing: border-box;
|
|
637
|
+
}
|
|
544
638
|
html.dsh-better-left-sidebar .dsh-better-left-sidebar-preferences {
|
|
545
639
|
display: flex;
|
|
546
640
|
min-width: 0;
|
|
547
641
|
flex-direction: column;
|
|
548
|
-
gap:
|
|
642
|
+
gap: 28px;
|
|
643
|
+
container-type: inline-size;
|
|
549
644
|
color: var(--dsw-alias-label-primary);
|
|
550
645
|
}
|
|
551
646
|
|
|
@@ -569,9 +664,228 @@ html.dsh-better-left-sidebar .dsh-better-left-sidebar-settings-group h3 {
|
|
|
569
664
|
line-height: 24px;
|
|
570
665
|
}
|
|
571
666
|
|
|
572
|
-
html.dsh-better-left-sidebar .dsh-better-left-sidebar-
|
|
667
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-compact-widgets-intro {
|
|
668
|
+
display: grid;
|
|
669
|
+
gap: 6px;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-compact-widgets-hint,
|
|
673
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-compact-widgets-empty {
|
|
674
|
+
margin: 0;
|
|
675
|
+
color: var(--dsw-alias-label-tertiary);
|
|
676
|
+
font-size: 12px;
|
|
677
|
+
line-height: 1.5;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-compact-widgets-link {
|
|
681
|
+
color: var(--dsw-alias-link);
|
|
682
|
+
text-decoration: none;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-compact-widgets-link:hover {
|
|
686
|
+
text-decoration: underline;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-compact-widgets-list {
|
|
690
|
+
display: flex;
|
|
691
|
+
min-width: 0;
|
|
692
|
+
flex-direction: column;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-compact-widget-setting {
|
|
696
|
+
display: grid;
|
|
697
|
+
min-width: 0;
|
|
698
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
699
|
+
align-items: center;
|
|
700
|
+
gap: 12px;
|
|
701
|
+
padding: 14px 0;
|
|
702
|
+
border-top: 1px solid var(--dsw-alias-border-l3);
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-widget-options {
|
|
706
|
+
grid-column: 1 / -1;
|
|
707
|
+
min-width: 0;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-widget-options > summary,
|
|
711
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-widget-reference > summary {
|
|
712
|
+
width: fit-content;
|
|
713
|
+
color: var(--dsw-alias-label-secondary);
|
|
714
|
+
font-size: 13px;
|
|
715
|
+
cursor: pointer;
|
|
716
|
+
line-height: 24px;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-widget-reference {
|
|
720
|
+
color: var(--dsw-alias-label-secondary);
|
|
721
|
+
font-size: 12px;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-widget-reference dl {
|
|
725
|
+
display: grid;
|
|
726
|
+
gap: 4px;
|
|
727
|
+
margin: 12px 0;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-widget-reference dt {
|
|
731
|
+
margin-top: 6px;
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-widget-reference dd {
|
|
735
|
+
margin: 0;
|
|
736
|
+
overflow-wrap: anywhere;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-widget-reference a {
|
|
740
|
+
color: var(--dsw-alias-link);
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-clock-options {
|
|
744
|
+
display: grid;
|
|
745
|
+
grid-template-columns: minmax(0, 420px) 104px;
|
|
746
|
+
max-width: 548px;
|
|
747
|
+
align-items: start;
|
|
748
|
+
gap: 24px;
|
|
749
|
+
margin-top: 12px;
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-clock-option-fields {
|
|
573
753
|
display: grid;
|
|
574
|
-
|
|
754
|
+
min-width: 0;
|
|
755
|
+
gap: 10px;
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-clock-modules {
|
|
759
|
+
display: flex;
|
|
760
|
+
min-height: 32px;
|
|
761
|
+
align-items: center;
|
|
762
|
+
flex-wrap: wrap;
|
|
763
|
+
gap: 12px 20px;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-clock-color-controls {
|
|
767
|
+
display: flex;
|
|
768
|
+
min-width: 0;
|
|
769
|
+
flex-wrap: wrap;
|
|
770
|
+
align-items: center;
|
|
771
|
+
gap: 8px;
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-clock-color-picker {
|
|
775
|
+
position: relative;
|
|
776
|
+
width: 28px;
|
|
777
|
+
height: 28px;
|
|
778
|
+
flex: none;
|
|
779
|
+
cursor: pointer;
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-clock-color-swatch {
|
|
783
|
+
display: block;
|
|
784
|
+
width: 28px;
|
|
785
|
+
height: 28px;
|
|
786
|
+
box-sizing: border-box;
|
|
787
|
+
border: 1px solid var(--dsw-alias-border-l3);
|
|
788
|
+
border-radius: 6px;
|
|
789
|
+
background: var(--dsw-alias-label-primary);
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-clock-color-input {
|
|
793
|
+
position: absolute;
|
|
794
|
+
inset: 0;
|
|
795
|
+
width: 100%;
|
|
796
|
+
height: 100%;
|
|
797
|
+
margin: 0;
|
|
798
|
+
padding: 0;
|
|
799
|
+
border: 0;
|
|
800
|
+
opacity: 0;
|
|
801
|
+
cursor: pointer;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-clock-color-picker:focus-within {
|
|
805
|
+
outline: 2px solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));
|
|
806
|
+
outline-offset: 2px;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-clock-color-value {
|
|
810
|
+
color: var(--dsw-alias-label-primary);
|
|
811
|
+
font-size: 13px;
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-clock-color-hint {
|
|
815
|
+
margin: 6px 0 0;
|
|
816
|
+
color: var(--dsw-alias-label-tertiary);
|
|
817
|
+
font-size: 12px;
|
|
818
|
+
line-height: 1.5;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-clock-preview {
|
|
822
|
+
width: 104px;
|
|
823
|
+
min-width: 56px;
|
|
824
|
+
margin: 0;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-clock-preview figcaption {
|
|
828
|
+
margin: 0 0 8px;
|
|
829
|
+
color: var(--dsw-alias-label-primary);
|
|
830
|
+
font-size: 12px;
|
|
831
|
+
font-weight: 600;
|
|
832
|
+
white-space: nowrap;
|
|
833
|
+
text-align: center;
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-clock-preview-rail {
|
|
837
|
+
display: flex;
|
|
838
|
+
box-sizing: border-box;
|
|
839
|
+
width: 56px;
|
|
840
|
+
min-height: 80px;
|
|
841
|
+
margin-inline: auto;
|
|
842
|
+
align-items: center;
|
|
843
|
+
justify-content: center;
|
|
844
|
+
padding: 0;
|
|
845
|
+
border: 0;
|
|
846
|
+
background: var(--dsw-specific-sidebar-fill, var(--dsw-alias-bg-base));
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-compact-widget-info {
|
|
850
|
+
display: grid;
|
|
851
|
+
min-width: 0;
|
|
852
|
+
gap: 4px;
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-compact-widget-name {
|
|
856
|
+
overflow-wrap: anywhere;
|
|
857
|
+
color: var(--dsw-alias-label-primary);
|
|
858
|
+
font-size: 14px;
|
|
859
|
+
font-weight: 600;
|
|
860
|
+
line-height: 19px;
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-compact-widget-source,
|
|
864
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-compact-widget-status {
|
|
865
|
+
overflow-wrap: anywhere;
|
|
866
|
+
color: var(--dsw-alias-label-secondary);
|
|
867
|
+
font-size: 12px;
|
|
868
|
+
line-height: 17px;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-compact-widget-status.is-failed {
|
|
872
|
+
color: var(--dsw-alias-state-danger, #b54736);
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-compact-widget-controls {
|
|
876
|
+
display: flex;
|
|
877
|
+
align-items: center;
|
|
878
|
+
gap: 12px;
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-widget-order {
|
|
882
|
+
display: flex;
|
|
883
|
+
gap: 4px;
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-settings-row {
|
|
887
|
+
display: grid;
|
|
888
|
+
grid-template-columns: 108px minmax(0, 1fr);
|
|
575
889
|
align-items: center;
|
|
576
890
|
gap: 12px;
|
|
577
891
|
min-width: 0;
|
|
@@ -580,7 +894,7 @@ html.dsh-better-left-sidebar .dsh-better-left-sidebar-choice-row {
|
|
|
580
894
|
border: 0;
|
|
581
895
|
}
|
|
582
896
|
|
|
583
|
-
html.dsh-better-left-sidebar .dsh-better-left-sidebar-
|
|
897
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-settings-row legend {
|
|
584
898
|
float: left;
|
|
585
899
|
width: 100%;
|
|
586
900
|
padding: 0;
|
|
@@ -596,10 +910,10 @@ html.dsh-better-left-sidebar .dsh-better-left-sidebar-choice-options {
|
|
|
596
910
|
|
|
597
911
|
html.dsh-better-left-sidebar .dsh-better-left-sidebar-choice-option {
|
|
598
912
|
display: inline-flex;
|
|
599
|
-
min-height:
|
|
913
|
+
min-height: 32px;
|
|
600
914
|
align-items: center;
|
|
601
915
|
gap: 7px;
|
|
602
|
-
padding: 0
|
|
916
|
+
padding: 0 9px;
|
|
603
917
|
border: 1px solid var(--dsw-alias-border-l3);
|
|
604
918
|
border-radius: var(--dsw-radius-md);
|
|
605
919
|
background: var(--dsw-alias-bg-base);
|
|
@@ -672,7 +986,7 @@ html.dsh-better-left-sidebar .dsh-better-left-sidebar-position-controls {
|
|
|
672
986
|
|
|
673
987
|
html.dsh-better-left-sidebar .dsh-better-left-sidebar-position {
|
|
674
988
|
display: grid;
|
|
675
|
-
grid-template-columns: minmax(
|
|
989
|
+
grid-template-columns: 108px minmax(0, 1fr);
|
|
676
990
|
align-items: center;
|
|
677
991
|
gap: 12px;
|
|
678
992
|
min-width: 0;
|
|
@@ -693,10 +1007,18 @@ html.dsh-better-left-sidebar .dsh-better-left-sidebar-position select {
|
|
|
693
1007
|
font-size: 13px;
|
|
694
1008
|
}
|
|
695
1009
|
|
|
696
|
-
html.dsh-better-left-sidebar .dsh-better-left-sidebar-layout-
|
|
1010
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-layout-settings {
|
|
697
1011
|
display: grid;
|
|
698
|
-
grid-template-columns:
|
|
699
|
-
gap:
|
|
1012
|
+
grid-template-columns: minmax(0, 1fr) 240px;
|
|
1013
|
+
gap: 16px 24px;
|
|
1014
|
+
align-items: start;
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-layout-settings > .dsh-better-left-sidebar-settings-heading {
|
|
1018
|
+
grid-column: 1 / -1;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-setting-control {
|
|
700
1022
|
min-width: 0;
|
|
701
1023
|
}
|
|
702
1024
|
|
|
@@ -809,18 +1131,77 @@ html.dsh-better-left-sidebar .dsh-better-left-sidebar-preview-hidden {
|
|
|
809
1131
|
font-style: italic;
|
|
810
1132
|
}
|
|
811
1133
|
|
|
812
|
-
|
|
813
|
-
|
|
1134
|
+
/* Sit beside the settings form's save control. The form is the parent of the preferences block. */
|
|
1135
|
+
html.dsh-better-left-sidebar div:has(> .dsh-better-left-sidebar-preferences):has(> .dsh-better-left-sidebar-layout-cancel) {
|
|
1136
|
+
display: grid;
|
|
1137
|
+
grid-template-columns: auto minmax(0, 1fr);
|
|
1138
|
+
align-items: center;
|
|
1139
|
+
column-gap: 8px;
|
|
1140
|
+
row-gap: 16px;
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
html.dsh-better-left-sidebar div:has(> .dsh-better-left-sidebar-layout-cancel) > .dsh-better-left-sidebar-preferences,
|
|
1144
|
+
html.dsh-better-left-sidebar div:has(> .dsh-better-left-sidebar-layout-cancel) > p {
|
|
1145
|
+
grid-column: 1 / -1;
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
html.dsh-better-left-sidebar div:has(> .dsh-better-left-sidebar-layout-cancel) > :last-child {
|
|
1149
|
+
padding-top: 0;
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
@container (max-width: 620px) {
|
|
1153
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-layout-settings {
|
|
1154
|
+
grid-template-columns: 1fr;
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-layout-preview {
|
|
1158
|
+
max-width: 320px;
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
@container (max-width: 480px) {
|
|
1163
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-clock-options {
|
|
1164
|
+
grid-template-columns: 1fr;
|
|
1165
|
+
gap: 16px;
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-clock-preview {
|
|
1169
|
+
display: flex;
|
|
1170
|
+
width: auto;
|
|
1171
|
+
align-items: center;
|
|
1172
|
+
gap: 16px;
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-clock-preview-rail {
|
|
1176
|
+
min-height: 64px;
|
|
1177
|
+
margin: 0;
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-clock-preview figcaption {
|
|
1181
|
+
margin: 0;
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-settings-row,
|
|
1185
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-position {
|
|
1186
|
+
grid-template-columns: 1fr;
|
|
1187
|
+
gap: 6px;
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-settings-row legend {
|
|
1191
|
+
float: none;
|
|
1192
|
+
width: auto;
|
|
1193
|
+
margin-bottom: 6px;
|
|
1194
|
+
}
|
|
814
1195
|
}
|
|
815
1196
|
|
|
816
1197
|
/* Keep sessions open behind a full-width editor, instead of squeezing a form into 287px. */
|
|
817
1198
|
@media (max-width: 760px) {
|
|
818
|
-
html.dsh-better-left-sidebar .dsh-better-left-sidebar-
|
|
1199
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-settings-row {
|
|
819
1200
|
grid-template-columns: 1fr;
|
|
820
1201
|
gap: 7px;
|
|
821
1202
|
}
|
|
822
1203
|
|
|
823
|
-
html.dsh-better-left-sidebar .dsh-better-left-sidebar-
|
|
1204
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-settings-row legend {
|
|
824
1205
|
float: none;
|
|
825
1206
|
width: auto;
|
|
826
1207
|
}
|
|
@@ -835,6 +1216,15 @@ html.dsh-better-left-sidebar .dsh-better-left-sidebar-layout-cancel {
|
|
|
835
1216
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
836
1217
|
}
|
|
837
1218
|
|
|
1219
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-clock-options,
|
|
1220
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-clock-color {
|
|
1221
|
+
grid-template-columns: 1fr;
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
html.dsh-better-left-sidebar .dsh-better-left-sidebar-clock-color-hint {
|
|
1225
|
+
grid-column: 1;
|
|
1226
|
+
}
|
|
1227
|
+
|
|
838
1228
|
html.dsh-better-left-sidebar [data-slot='main'] > section:has(> div > aside) {
|
|
839
1229
|
position: fixed;
|
|
840
1230
|
z-index: 100;
|
|
@@ -903,6 +1293,80 @@ html.dsh-better-left-sidebar .dsh-better-left-sidebar-layout-cancel {
|
|
|
903
1293
|
}
|
|
904
1294
|
`;
|
|
905
1295
|
|
|
1296
|
+
// src/clock-display.ts
|
|
1297
|
+
var CLOCK_WIDGET_ID = "dsh-better-left-sidebar.clock";
|
|
1298
|
+
var DEFAULT_CLOCK_DISPLAY = {
|
|
1299
|
+
hourCycle: "h23",
|
|
1300
|
+
monthDay: true,
|
|
1301
|
+
weekday: false,
|
|
1302
|
+
color: null
|
|
1303
|
+
};
|
|
1304
|
+
var HEX = /^#[0-9a-fA-F]{6}$/;
|
|
1305
|
+
function normalizeClockDisplay(value) {
|
|
1306
|
+
const input = value && typeof value === "object" ? value : {};
|
|
1307
|
+
const hourCycle = input.hourCycle === "h12" ? "h12" : "h23";
|
|
1308
|
+
const raw = typeof input.color === "string" ? input.color.trim() : "";
|
|
1309
|
+
return {
|
|
1310
|
+
hourCycle,
|
|
1311
|
+
...clockModules(input),
|
|
1312
|
+
color: HEX.test(raw) ? raw.toLowerCase() : null
|
|
1313
|
+
};
|
|
1314
|
+
}
|
|
1315
|
+
function toClockConfig(value) {
|
|
1316
|
+
const display = normalizeClockDisplay(value);
|
|
1317
|
+
return {
|
|
1318
|
+
hourCycle: display.hourCycle,
|
|
1319
|
+
monthDay: display.monthDay,
|
|
1320
|
+
weekday: display.weekday,
|
|
1321
|
+
color: display.color ?? ""
|
|
1322
|
+
};
|
|
1323
|
+
}
|
|
1324
|
+
function clockLines(now, locale, display) {
|
|
1325
|
+
const tag = Intl.DateTimeFormat.supportedLocalesOf(locale).length > 0 ? locale : void 0;
|
|
1326
|
+
const hourCycle = display.hourCycle;
|
|
1327
|
+
const timeParts = new Intl.DateTimeFormat(tag, {
|
|
1328
|
+
hour: "2-digit",
|
|
1329
|
+
minute: "2-digit",
|
|
1330
|
+
hourCycle
|
|
1331
|
+
}).formatToParts(now);
|
|
1332
|
+
const hour = timeParts.find((part) => part.type === "hour")?.value ?? "00";
|
|
1333
|
+
const minute = timeParts.find((part) => part.type === "minute")?.value ?? "00";
|
|
1334
|
+
const period = hourCycle === "h12" ? now.getHours() >= 12 ? "P" : "A" : null;
|
|
1335
|
+
return {
|
|
1336
|
+
time: `${hour}:${minute}`,
|
|
1337
|
+
period,
|
|
1338
|
+
monthDay: display.monthDay ? monthDayLine(now, tag) : null,
|
|
1339
|
+
weekday: display.weekday ? new Intl.DateTimeFormat(tag, { weekday: "short" }).format(now) : null,
|
|
1340
|
+
accessible: new Intl.DateTimeFormat(tag, {
|
|
1341
|
+
weekday: "long",
|
|
1342
|
+
year: "numeric",
|
|
1343
|
+
month: "long",
|
|
1344
|
+
day: "numeric",
|
|
1345
|
+
hour: "2-digit",
|
|
1346
|
+
minute: "2-digit",
|
|
1347
|
+
hourCycle,
|
|
1348
|
+
timeZoneName: "long"
|
|
1349
|
+
}).format(now)
|
|
1350
|
+
};
|
|
1351
|
+
}
|
|
1352
|
+
function clockModules(input) {
|
|
1353
|
+
const legacy = input.detail === "weekday" || input.detail === "none";
|
|
1354
|
+
const explicit = input.monthDay === false || input.weekday === true;
|
|
1355
|
+
if (legacy && !explicit) {
|
|
1356
|
+
return input.detail === "weekday" ? { monthDay: false, weekday: true } : { monthDay: false, weekday: false };
|
|
1357
|
+
}
|
|
1358
|
+
return {
|
|
1359
|
+
monthDay: input.monthDay !== false,
|
|
1360
|
+
weekday: input.weekday === true
|
|
1361
|
+
};
|
|
1362
|
+
}
|
|
1363
|
+
function monthDayLine(now, tag) {
|
|
1364
|
+
const dateParts = new Intl.DateTimeFormat(tag, { month: "numeric", day: "numeric" }).formatToParts(now);
|
|
1365
|
+
const month = dateParts.find((part) => part.type === "month")?.value ?? String(now.getMonth() + 1);
|
|
1366
|
+
const day = dateParts.find((part) => part.type === "day")?.value ?? String(now.getDate());
|
|
1367
|
+
return `${month}/${day}`;
|
|
1368
|
+
}
|
|
1369
|
+
|
|
906
1370
|
// src/preferences.ts
|
|
907
1371
|
var DEFAULT_PREFERENCES = {
|
|
908
1372
|
animation: "standard",
|
|
@@ -962,7 +1426,40 @@ function createNavigationToggle(onClick) {
|
|
|
962
1426
|
var NAMESPACE = "dsh-better-left-sidebar";
|
|
963
1427
|
var en = {
|
|
964
1428
|
summary: "Set how navigation opens and where each built-in area lives.",
|
|
965
|
-
|
|
1429
|
+
compactWidgets: "Compact widgets",
|
|
1430
|
+
compactWidgetsHint: "Order by priority; widgets at the top are shown first when space is limited. Changes apply when you save.",
|
|
1431
|
+
compactWidgetsDocs: "compact widget guide",
|
|
1432
|
+
compactWidgetsDocsUrl: "https://github.com/exoticknight/dsh-better-left-sidebar/blob/main/docs/compact-widgets.md",
|
|
1433
|
+
compactWidgetsEmpty: "No compact widgets are registered or saved.",
|
|
1434
|
+
widgetSettings: "Display settings",
|
|
1435
|
+
widgetInformation: "Widget information and developer guide",
|
|
1436
|
+
clockContents: "Show",
|
|
1437
|
+
clockColorCustom: "Custom color",
|
|
1438
|
+
effectPreview: "Effect preview",
|
|
1439
|
+
widgetClipped: "Hidden: not enough space",
|
|
1440
|
+
widgetInactive: "Hidden while navigation is expanded",
|
|
1441
|
+
widgetEmpty: "No content",
|
|
1442
|
+
widgetEnabled: "Enabled",
|
|
1443
|
+
widgetPendingEnable: "Enable on save",
|
|
1444
|
+
widgetPendingDisable: "Disable on save",
|
|
1445
|
+
clock: "Clock",
|
|
1446
|
+
clockHourCycle: "Hour cycle",
|
|
1447
|
+
clock24: "24-hour",
|
|
1448
|
+
clock12: "12-hour",
|
|
1449
|
+
clockMonthDay: "Date",
|
|
1450
|
+
clockWeekday: "Weekday",
|
|
1451
|
+
clockColor: "Time color",
|
|
1452
|
+
clockColorDefault: "Follow theme",
|
|
1453
|
+
clockColorReset: "Restore default",
|
|
1454
|
+
clockColorHint: "A custom color stays fixed when the theme changes.",
|
|
1455
|
+
widgetShown: "Shown",
|
|
1456
|
+
widgetDisabled: "Disabled",
|
|
1457
|
+
widgetNotLoaded: "Not loaded",
|
|
1458
|
+
widgetFailed: "Failed",
|
|
1459
|
+
widgetEnable: "Enable",
|
|
1460
|
+
moveUp: "Move up",
|
|
1461
|
+
moveDown: "Move down",
|
|
1462
|
+
navigationBehavior: "Expansion and animation",
|
|
966
1463
|
contentLayout: "Content layout",
|
|
967
1464
|
expansion: "Expansion",
|
|
968
1465
|
expandNavigation: "Expand navigation",
|
|
@@ -1000,7 +1497,40 @@ var en = {
|
|
|
1000
1497
|
};
|
|
1001
1498
|
var zh = {
|
|
1002
1499
|
summary: "\u8BBE\u7F6E\u5BFC\u822A\u5C55\u5F00\u65B9\u5F0F\uFF0C\u5E76\u4E3A\u5404\u4E2A\u533A\u57DF\u9009\u62E9\u4F4D\u7F6E\u3002",
|
|
1003
|
-
|
|
1500
|
+
compactWidgets: "\u6536\u8D77\u680F\u5C0F\u7EC4\u4EF6",
|
|
1501
|
+
compactWidgetsHint: "\u6309\u4F18\u5148\u7EA7\u6392\u5E8F\uFF0C\u7A7A\u95F4\u4E0D\u8DB3\u65F6\u4F18\u5148\u663E\u793A\u9760\u524D\u7684\u5C0F\u7EC4\u4EF6\u3002\u66F4\u6539\u5728\u4FDD\u5B58\u540E\u751F\u6548\u3002",
|
|
1502
|
+
compactWidgetsDocs: "\u6536\u8D77\u680F\u5C0F\u7EC4\u4EF6\u6307\u5357",
|
|
1503
|
+
compactWidgetsDocsUrl: "https://github.com/exoticknight/dsh-better-left-sidebar/blob/main/docs/compact-widgets.md",
|
|
1504
|
+
compactWidgetsEmpty: "\u76EE\u524D\u6CA1\u6709\u5DF2\u6CE8\u518C\u6216\u5DF2\u4FDD\u5B58\u7684\u5C0F\u7EC4\u4EF6\u3002",
|
|
1505
|
+
widgetSettings: "\u663E\u793A\u8BBE\u7F6E",
|
|
1506
|
+
widgetInformation: "\u7EC4\u4EF6\u4FE1\u606F\u4E0E\u63A5\u5165\u6307\u5357",
|
|
1507
|
+
clockContents: "\u663E\u793A\u5185\u5BB9",
|
|
1508
|
+
clockColorCustom: "\u81EA\u5B9A\u4E49\u989C\u8272",
|
|
1509
|
+
effectPreview: "\u6548\u679C\u9884\u89C8",
|
|
1510
|
+
widgetClipped: "\u7A7A\u95F4\u4E0D\u8DB3\uFF0C\u6682\u672A\u663E\u793A",
|
|
1511
|
+
widgetInactive: "\u5BFC\u822A\u5C55\u5F00\u65F6\u6682\u4E0D\u663E\u793A",
|
|
1512
|
+
widgetEmpty: "\u6682\u65E0\u663E\u793A\u5185\u5BB9",
|
|
1513
|
+
widgetEnabled: "\u5DF2\u542F\u7528",
|
|
1514
|
+
widgetPendingEnable: "\u4FDD\u5B58\u540E\u542F\u7528",
|
|
1515
|
+
widgetPendingDisable: "\u4FDD\u5B58\u540E\u505C\u7528",
|
|
1516
|
+
clock: "\u65F6\u949F",
|
|
1517
|
+
clockHourCycle: "\u5C0F\u65F6\u5236",
|
|
1518
|
+
clock24: "24 \u5C0F\u65F6",
|
|
1519
|
+
clock12: "12 \u5C0F\u65F6",
|
|
1520
|
+
clockMonthDay: "\u65E5\u671F",
|
|
1521
|
+
clockWeekday: "\u661F\u671F",
|
|
1522
|
+
clockColor: "\u65F6\u95F4\u989C\u8272",
|
|
1523
|
+
clockColorDefault: "\u8DDF\u968F\u4E3B\u9898",
|
|
1524
|
+
clockColorReset: "\u6062\u590D\u9ED8\u8BA4",
|
|
1525
|
+
clockColorHint: "\u81EA\u5B9A\u4E49\u989C\u8272\u5728\u5207\u6362\u4E3B\u9898\u65F6\u4FDD\u6301\u4E0D\u53D8\u3002",
|
|
1526
|
+
widgetShown: "\u663E\u793A\u4E2D",
|
|
1527
|
+
widgetDisabled: "\u5DF2\u7981\u7528",
|
|
1528
|
+
widgetNotLoaded: "\u672A\u52A0\u8F7D",
|
|
1529
|
+
widgetFailed: "\u5931\u8D25",
|
|
1530
|
+
widgetEnable: "\u542F\u7528",
|
|
1531
|
+
moveUp: "\u4E0A\u79FB",
|
|
1532
|
+
moveDown: "\u4E0B\u79FB",
|
|
1533
|
+
navigationBehavior: "\u5C55\u5F00\u4E0E\u52A8\u753B",
|
|
1004
1534
|
contentLayout: "\u5185\u5BB9\u5E03\u5C40",
|
|
1005
1535
|
expansion: "\u5C55\u5F00\u65B9\u5F0F",
|
|
1006
1536
|
expandNavigation: "\u5C55\u5F00\u5BFC\u822A",
|
|
@@ -1043,8 +1573,17 @@ function fallbackTranslate(key) {
|
|
|
1043
1573
|
return key;
|
|
1044
1574
|
}
|
|
1045
1575
|
|
|
1576
|
+
// src/client/rail-region.ts
|
|
1577
|
+
function isRailRegionEligible(region, preferences) {
|
|
1578
|
+
if (region === "brand") return preferences?.brandPosition === "navigation-top";
|
|
1579
|
+
if (region === "global-navigation") return preferences?.globalNavigationPosition === "rail";
|
|
1580
|
+
if (region === "compact-widgets") return true;
|
|
1581
|
+
if (region === "tools") return preferences?.toolsPosition === "rail-bottom";
|
|
1582
|
+
return false;
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1046
1585
|
// src/client/interaction.ts
|
|
1047
|
-
var NAV_REGION = '[data-dsh-better-left-sidebar-region="brand"], [data-dsh-better-left-sidebar-region="global-navigation"], [data-dsh-better-left-sidebar-region="tools"]';
|
|
1586
|
+
var NAV_REGION = '[data-dsh-better-left-sidebar-region="brand"], [data-dsh-better-left-sidebar-region="global-navigation"], [data-dsh-better-left-sidebar-region="tools"], [data-dsh-better-left-sidebar-region="compact-widgets"]';
|
|
1048
1587
|
var POPUP_SELECTOR = '[role="menu"], [role="listbox"], [role="dialog"], [data-menu-material]';
|
|
1049
1588
|
var ENTER_DELAY = 160;
|
|
1050
1589
|
var CLOSE_DELAY = 210;
|
|
@@ -1067,6 +1606,7 @@ function connectInteraction() {
|
|
|
1067
1606
|
let associatedPopups = /* @__PURE__ */ new Set();
|
|
1068
1607
|
let popupPending = false;
|
|
1069
1608
|
let toggle;
|
|
1609
|
+
let setCompactWidgetsActive;
|
|
1070
1610
|
let resizeObserver;
|
|
1071
1611
|
let rootIdOwned = false;
|
|
1072
1612
|
let documentCleanup;
|
|
@@ -1075,9 +1615,7 @@ function connectInteraction() {
|
|
|
1075
1615
|
if (!root || !(target instanceof Element) || !root.contains(target)) return false;
|
|
1076
1616
|
const region = target.closest(NAV_REGION);
|
|
1077
1617
|
if (!region) return false;
|
|
1078
|
-
|
|
1079
|
-
if (region.dataset.dshBetterLeftSidebarRegion === "global-navigation") return preferences?.globalNavigationPosition === "rail";
|
|
1080
|
-
return preferences?.toolsPosition === "rail-bottom";
|
|
1618
|
+
return isRailRegionEligible(region.dataset.dshBetterLeftSidebarRegion ?? "", preferences);
|
|
1081
1619
|
};
|
|
1082
1620
|
const isPopupTarget = (target) => {
|
|
1083
1621
|
if (!(target instanceof Node)) return false;
|
|
@@ -1092,6 +1630,7 @@ function connectInteraction() {
|
|
|
1092
1630
|
mode = next;
|
|
1093
1631
|
classRoot.classList.toggle("dsh-better-left-sidebar-expanded", next !== "compact");
|
|
1094
1632
|
classRoot.classList.toggle("dsh-better-left-sidebar-pinned", next === "pinned");
|
|
1633
|
+
setCompactWidgetsActive?.(next === "compact");
|
|
1095
1634
|
syncToggle();
|
|
1096
1635
|
};
|
|
1097
1636
|
const clearTimer = (timer) => {
|
|
@@ -1235,14 +1774,20 @@ function connectInteraction() {
|
|
|
1235
1774
|
if (full) full.textContent = label;
|
|
1236
1775
|
updateTogglePosition();
|
|
1237
1776
|
};
|
|
1238
|
-
const
|
|
1239
|
-
if (!root ||
|
|
1240
|
-
|
|
1241
|
-
document.body.append(toggle);
|
|
1777
|
+
const refreshToggleObservation = () => {
|
|
1778
|
+
if (!root || !toggle) return;
|
|
1779
|
+
resizeObserver?.disconnect();
|
|
1242
1780
|
resizeObserver = new ResizeObserver(updateTogglePosition);
|
|
1243
1781
|
resizeObserver.observe(root);
|
|
1244
1782
|
const tools = root.querySelector('[data-dsh-better-left-sidebar-region="tools"]');
|
|
1245
1783
|
if (tools) resizeObserver.observe(tools);
|
|
1784
|
+
updateTogglePosition();
|
|
1785
|
+
};
|
|
1786
|
+
const createToggle = () => {
|
|
1787
|
+
if (!root || preferences?.expansion !== "click" || toggle) return;
|
|
1788
|
+
toggle = createNavigationToggle(onToggleClick);
|
|
1789
|
+
document.body.append(toggle);
|
|
1790
|
+
refreshToggleObservation();
|
|
1246
1791
|
window.addEventListener("resize", updateTogglePosition);
|
|
1247
1792
|
window.addEventListener("scroll", updateTogglePosition, true);
|
|
1248
1793
|
syncToggle();
|
|
@@ -1357,8 +1902,11 @@ function connectInteraction() {
|
|
|
1357
1902
|
};
|
|
1358
1903
|
};
|
|
1359
1904
|
documentCleanup = attachDocumentListeners();
|
|
1360
|
-
const setRoot = (next) => {
|
|
1361
|
-
if (next === root)
|
|
1905
|
+
const setRoot = (next, refreshAnchors = false) => {
|
|
1906
|
+
if (next === root) {
|
|
1907
|
+
if (refreshAnchors) refreshToggleObservation();
|
|
1908
|
+
return;
|
|
1909
|
+
}
|
|
1362
1910
|
if (root && rootIdOwned && root.id === "dsh-better-left-sidebar-navigation") root.removeAttribute("id");
|
|
1363
1911
|
rootIdOwned = false;
|
|
1364
1912
|
removeToggle();
|
|
@@ -1395,6 +1943,10 @@ function connectInteraction() {
|
|
|
1395
1943
|
else removeToggle();
|
|
1396
1944
|
syncToggle();
|
|
1397
1945
|
},
|
|
1946
|
+
setCompactWidgetsActive(setActive) {
|
|
1947
|
+
setCompactWidgetsActive = setActive;
|
|
1948
|
+
setActive(mode === "compact");
|
|
1949
|
+
},
|
|
1398
1950
|
setTranslate(next) {
|
|
1399
1951
|
translate = next;
|
|
1400
1952
|
syncToggle();
|
|
@@ -1441,14 +1993,50 @@ var REGION_MARK = "data-dsh-better-left-sidebar-region";
|
|
|
1441
1993
|
var ROW_MARK = "data-dsh-better-left-sidebar-panel-row";
|
|
1442
1994
|
var GLYPH_MARK = "data-dsh-better-left-sidebar-panel-glyph";
|
|
1443
1995
|
var TITLE_MARK = "data-dsh-better-left-sidebar-panel-title";
|
|
1444
|
-
function
|
|
1996
|
+
function sizeConversationNavigation(rootHeight, navigationTop, footerHeight, panelContentHeight) {
|
|
1997
|
+
const height = Math.max(0, rootHeight);
|
|
1998
|
+
const top = Math.max(0, navigationTop);
|
|
1999
|
+
const footer = Math.max(0, footerHeight);
|
|
2000
|
+
const content = Math.max(0, panelContentHeight);
|
|
2001
|
+
const availableContentHeight = Math.max(0, height - top - footer - 8);
|
|
2002
|
+
const contentReserve = Math.min(112, availableContentHeight);
|
|
2003
|
+
const panelHeight = Math.min(content, Math.max(0, availableContentHeight - contentReserve));
|
|
2004
|
+
return {
|
|
2005
|
+
panelHeight,
|
|
2006
|
+
conversationTop: top + (panelHeight > 0 ? panelHeight + 8 : 0)
|
|
2007
|
+
};
|
|
2008
|
+
}
|
|
2009
|
+
var COMPACT_WIDGETS_MAX_HEIGHT = 112;
|
|
2010
|
+
var COMPACT_WIDGET_GAP = 4;
|
|
2011
|
+
var CLIPPED_MARK = "data-dsh-better-left-sidebar-compact-widget-clipped";
|
|
2012
|
+
function fitCompactWidgets(heights, gap, limit) {
|
|
2013
|
+
let height = 0;
|
|
2014
|
+
let visible = 0;
|
|
2015
|
+
let rendered = 0;
|
|
2016
|
+
for (const boxHeight of heights) {
|
|
2017
|
+
if (boxHeight <= 0) {
|
|
2018
|
+
visible += 1;
|
|
2019
|
+
continue;
|
|
2020
|
+
}
|
|
2021
|
+
const next = height + (rendered > 0 ? gap : 0) + boxHeight;
|
|
2022
|
+
if (next > limit) break;
|
|
2023
|
+
height = next;
|
|
2024
|
+
visible += 1;
|
|
2025
|
+
rendered += 1;
|
|
2026
|
+
}
|
|
2027
|
+
return { visible, height };
|
|
2028
|
+
}
|
|
2029
|
+
function connectLayoutAdapter(onRoot, compactWidgets) {
|
|
1445
2030
|
let preferences;
|
|
2031
|
+
let compactWidgetCount = 0;
|
|
2032
|
+
let compactWidgetsActive = true;
|
|
1446
2033
|
let current;
|
|
1447
|
-
let
|
|
2034
|
+
let candidateRoot;
|
|
2035
|
+
let observedSidebar;
|
|
1448
2036
|
let childrenObserver;
|
|
1449
2037
|
let measurementObserver;
|
|
1450
2038
|
let collapseObserver;
|
|
1451
|
-
let
|
|
2039
|
+
let hostObserver;
|
|
1452
2040
|
let resizeObserver;
|
|
1453
2041
|
let measureFrame = 0;
|
|
1454
2042
|
let warnedFor = /* @__PURE__ */ new WeakSet();
|
|
@@ -1465,7 +2053,7 @@ function connectLayoutAdapter(onRoot) {
|
|
|
1465
2053
|
!conversation && "conversation/workspace region",
|
|
1466
2054
|
!tools && "footer tools region"
|
|
1467
2055
|
].filter(Boolean);
|
|
1468
|
-
if (missing.length) {
|
|
2056
|
+
if (missing.length > 0) {
|
|
1469
2057
|
if (!warnedFor.has(root)) {
|
|
1470
2058
|
console.warn(`[dsh-better-left-sidebar] DSH sidebar adapter is inactive: missing ${missing.join(", ")}.`);
|
|
1471
2059
|
warnedFor.add(root);
|
|
@@ -1507,15 +2095,30 @@ function connectLayoutAdapter(onRoot) {
|
|
|
1507
2095
|
const conversationGlobalTop = sessionTop + sessionHeight + 8;
|
|
1508
2096
|
const panelRows = [...anchors.panelList.querySelectorAll(DSH.panelButton)];
|
|
1509
2097
|
const rowHeight = panelRows.reduce((height, row) => height + Math.ceil(row.getBoundingClientRect().height), 0);
|
|
1510
|
-
const rowGap = Number.parseFloat(getComputedStyle(anchors.panelList).rowGap) || 4;
|
|
1511
|
-
const panelContentHeight = Math.max(36, rowHeight + Math.max(0, panelRows.length - 1) * rowGap);
|
|
1512
|
-
const conversationHeight = anchors.root.getBoundingClientRect().height;
|
|
1513
|
-
const availablePanelHeight = Math.max(36, conversationHeight - conversationGlobalTop - (preferences?.toolsPosition === "conversation-bottom" ? toolsHeight + 8 : 8) - 16);
|
|
1514
|
-
const panelHeight = Math.min(panelContentHeight, availablePanelHeight);
|
|
1515
|
-
const conversationTop = conversationGlobalTop + (preferences?.globalNavigationPosition === "conversation-top" ? panelHeight + 8 : 0);
|
|
2098
|
+
const rowGap = Math.max(0, Number.parseFloat(getComputedStyle(anchors.panelList).rowGap) || 4);
|
|
1516
2099
|
const bottomPad = preferences?.toolsPosition === "conversation-bottom" ? toolsHeight + 8 : 0;
|
|
2100
|
+
const panelContentHeight = panelRows.length > 0 ? rowHeight + (panelRows.length - 1) * rowGap : 0;
|
|
2101
|
+
const conversationNavigation = preferences?.globalNavigationPosition === "conversation-top";
|
|
2102
|
+
const conversationSizing = sizeConversationNavigation(
|
|
2103
|
+
anchors.root.getBoundingClientRect().height,
|
|
2104
|
+
conversationGlobalTop,
|
|
2105
|
+
bottomPad,
|
|
2106
|
+
panelContentHeight
|
|
2107
|
+
);
|
|
2108
|
+
const panelHeight = conversationNavigation ? conversationSizing.panelHeight : panelContentHeight;
|
|
2109
|
+
const conversationTop = conversationNavigation ? conversationSizing.conversationTop : conversationGlobalTop;
|
|
1517
2110
|
const navBottomReserve = preferences?.toolsPosition === "rail-bottom" ? toolsHeight + 8 : 8;
|
|
1518
2111
|
const toggleReserve = preferences?.expansion === "click" ? 44 : 0;
|
|
2112
|
+
const footerReserve = preferences?.toolsPosition === "rail-bottom" ? toolsHeight + 8 : 8;
|
|
2113
|
+
const widgetBoxes = [...compactWidgets.children].filter((child) => child instanceof HTMLElement);
|
|
2114
|
+
for (const box of widgetBoxes) resizeObserver?.observe(box);
|
|
2115
|
+
const widgetBoxHeights = compactWidgetsActive && compactWidgetCount > 0 ? widgetBoxes.map((box) => Math.ceil(box.getBoundingClientRect().height)) : [];
|
|
2116
|
+
const widgetAvailable = Math.max(0, anchors.root.getBoundingClientRect().height - railGlobalTop - footerReserve - toggleReserve - 16);
|
|
2117
|
+
const widgetFit = fitCompactWidgets(widgetBoxHeights, COMPACT_WIDGET_GAP, Math.min(COMPACT_WIDGETS_MAX_HEIGHT, widgetAvailable));
|
|
2118
|
+
widgetBoxes.forEach((box, index) => box.toggleAttribute(CLIPPED_MARK, index >= widgetFit.visible));
|
|
2119
|
+
const widgetHeight = widgetFit.height;
|
|
2120
|
+
const widgetBottom = footerReserve + toggleReserve + 8;
|
|
2121
|
+
const railBottomReserve = widgetHeight > 0 ? footerReserve + toggleReserve + widgetHeight + 16 : navBottomReserve + toggleReserve;
|
|
1519
2122
|
anchors.root.style.setProperty("--dsh-better-left-sidebar-chrome", `${chrome}px`);
|
|
1520
2123
|
anchors.root.style.setProperty("--dsh-better-left-sidebar-brand-height", `${brandHeight}px`);
|
|
1521
2124
|
anchors.root.style.setProperty("--dsh-better-left-sidebar-session-top", `${sessionTop}px`);
|
|
@@ -1525,12 +2128,40 @@ function connectLayoutAdapter(onRoot) {
|
|
|
1525
2128
|
anchors.root.style.setProperty("--dsh-better-left-sidebar-tools-height", `${toolsHeight}px`);
|
|
1526
2129
|
anchors.root.style.setProperty("--dsh-better-left-sidebar-conversation-top", `${conversationTop}px`);
|
|
1527
2130
|
anchors.root.style.setProperty("--dsh-better-left-sidebar-conversation-bottom", `${bottomPad}px`);
|
|
1528
|
-
anchors.root.style.setProperty("--dsh-better-left-sidebar-nav-bottom-reserve", `${
|
|
2131
|
+
anchors.root.style.setProperty("--dsh-better-left-sidebar-nav-bottom-reserve", `${railBottomReserve}px`);
|
|
2132
|
+
anchors.root.style.setProperty("--dsh-better-left-sidebar-compact-widgets-height", `${widgetHeight}px`);
|
|
2133
|
+
anchors.root.style.setProperty("--dsh-better-left-sidebar-compact-widgets-bottom", `${widgetBottom}px`);
|
|
1529
2134
|
};
|
|
1530
2135
|
const scheduleMeasure = () => {
|
|
1531
2136
|
if (measureFrame) window.cancelAnimationFrame(measureFrame);
|
|
1532
2137
|
measureFrame = window.requestAnimationFrame(measure);
|
|
1533
2138
|
};
|
|
2139
|
+
const observeAnchors = (anchors) => {
|
|
2140
|
+
resizeObserver?.disconnect();
|
|
2141
|
+
measurementObserver?.disconnect();
|
|
2142
|
+
resizeObserver = new ResizeObserver(scheduleMeasure);
|
|
2143
|
+
for (const element of [anchors.root, anchors.brand, anchors.newSession, anchors.panelList, anchors.tools, compactWidgets]) resizeObserver.observe(element);
|
|
2144
|
+
measurementObserver = new MutationObserver(scheduleMeasure);
|
|
2145
|
+
measurementObserver.observe(anchors.panelList, { childList: true, subtree: true });
|
|
2146
|
+
measurementObserver.observe(anchors.tools, { childList: true, subtree: true });
|
|
2147
|
+
measurementObserver.observe(compactWidgets, { childList: true });
|
|
2148
|
+
};
|
|
2149
|
+
const sameAnchors = (a, b) => a.root === b.root && a.brand === b.brand && a.newSession === b.newSession && a.panelList === b.panelList && a.conversation === b.conversation && a.tools === b.tools;
|
|
2150
|
+
const releaseStaleAnchors = (previous, next) => {
|
|
2151
|
+
const retained = /* @__PURE__ */ new Set([next.brand, next.newSession, next.panelList, next.conversation, next.tools]);
|
|
2152
|
+
for (const element of [previous.brand, previous.newSession, previous.panelList, previous.conversation, previous.tools]) {
|
|
2153
|
+
if (retained.has(element)) continue;
|
|
2154
|
+
element.removeAttribute(REGION_MARK);
|
|
2155
|
+
element.querySelector(DSH.brandButton)?.removeAttribute("inert");
|
|
2156
|
+
element.querySelectorAll(`[${ROW_MARK}], [${GLYPH_MARK}], [${TITLE_MARK}], [data-dsh-better-left-sidebar-brand-mark], [data-dsh-better-left-sidebar-brand-name], [data-dsh-better-left-sidebar-session-label], [data-dsh-better-left-sidebar-settings-trigger-row]`).forEach((marked) => {
|
|
2157
|
+
for (const attribute of [ROW_MARK, GLYPH_MARK, TITLE_MARK, "data-dsh-better-left-sidebar-brand-mark", "data-dsh-better-left-sidebar-brand-name", "data-dsh-better-left-sidebar-session-label", "data-dsh-better-left-sidebar-settings-trigger-row"]) marked.removeAttribute(attribute);
|
|
2158
|
+
});
|
|
2159
|
+
element.querySelectorAll("[data-dsh-better-left-sidebar-owned-title]").forEach((ownedTitle) => {
|
|
2160
|
+
ownedTitle.removeAttribute("title");
|
|
2161
|
+
ownedTitle.removeAttribute("data-dsh-better-left-sidebar-owned-title");
|
|
2162
|
+
});
|
|
2163
|
+
}
|
|
2164
|
+
};
|
|
1534
2165
|
const apply2 = (anchors, next) => {
|
|
1535
2166
|
const { root, brand, newSession, panelList, conversation, tools } = anchors;
|
|
1536
2167
|
root.setAttribute(ROOT_MARK, "");
|
|
@@ -1560,12 +2191,10 @@ function connectLayoutAdapter(onRoot) {
|
|
|
1560
2191
|
scheduleMeasure();
|
|
1561
2192
|
};
|
|
1562
2193
|
const detach = () => {
|
|
1563
|
-
sidebarObserver?.disconnect();
|
|
1564
2194
|
childrenObserver?.disconnect();
|
|
1565
2195
|
measurementObserver?.disconnect();
|
|
1566
2196
|
collapseObserver?.disconnect();
|
|
1567
2197
|
resizeObserver?.disconnect();
|
|
1568
|
-
sidebarObserver = void 0;
|
|
1569
2198
|
childrenObserver = void 0;
|
|
1570
2199
|
measurementObserver = void 0;
|
|
1571
2200
|
collapseObserver = void 0;
|
|
@@ -1573,6 +2202,7 @@ function connectLayoutAdapter(onRoot) {
|
|
|
1573
2202
|
if (measureFrame) window.cancelAnimationFrame(measureFrame);
|
|
1574
2203
|
measureFrame = 0;
|
|
1575
2204
|
if (current) {
|
|
2205
|
+
if (compactWidgets.parentElement === current.root) compactWidgets.remove();
|
|
1576
2206
|
current.root.removeAttribute(ROOT_MARK);
|
|
1577
2207
|
current.root.removeAttribute("data-dsh-better-left-sidebar-brand-position");
|
|
1578
2208
|
current.root.removeAttribute("data-dsh-better-left-sidebar-global-position");
|
|
@@ -1592,7 +2222,9 @@ function connectLayoutAdapter(onRoot) {
|
|
|
1592
2222
|
"--dsh-better-left-sidebar-tools-height",
|
|
1593
2223
|
"--dsh-better-left-sidebar-conversation-top",
|
|
1594
2224
|
"--dsh-better-left-sidebar-conversation-bottom",
|
|
1595
|
-
"--dsh-better-left-sidebar-nav-bottom-reserve"
|
|
2225
|
+
"--dsh-better-left-sidebar-nav-bottom-reserve",
|
|
2226
|
+
"--dsh-better-left-sidebar-compact-widgets-height",
|
|
2227
|
+
"--dsh-better-left-sidebar-compact-widgets-bottom"
|
|
1596
2228
|
]) current.root.style.removeProperty(custom);
|
|
1597
2229
|
current.brand.querySelector(DSH.brandButton)?.removeAttribute("inert");
|
|
1598
2230
|
current.root.querySelectorAll(`[${ROW_MARK}], [${GLYPH_MARK}], [${TITLE_MARK}], [data-dsh-better-left-sidebar-brand-mark], [data-dsh-better-left-sidebar-brand-name], [data-dsh-better-left-sidebar-session-label], [data-dsh-better-left-sidebar-obsolete-collapse]`).forEach((element) => {
|
|
@@ -1606,15 +2238,32 @@ function connectLayoutAdapter(onRoot) {
|
|
|
1606
2238
|
}
|
|
1607
2239
|
current = void 0;
|
|
1608
2240
|
};
|
|
1609
|
-
const
|
|
1610
|
-
if (
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
2241
|
+
const subtreeHas = (node, selector) => {
|
|
2242
|
+
if (!(node instanceof Element)) return false;
|
|
2243
|
+
return node.matches(selector) || Boolean(node.querySelector(selector));
|
|
2244
|
+
};
|
|
2245
|
+
const watchHost = () => {
|
|
2246
|
+
if (hostObserver) return;
|
|
2247
|
+
hostObserver = new MutationObserver((records) => {
|
|
2248
|
+
const targetRoot = current?.root ?? candidateRoot;
|
|
2249
|
+
const relevant = records.some((record) => {
|
|
2250
|
+
const target = record.target;
|
|
2251
|
+
if (target === observedSidebar) return true;
|
|
2252
|
+
if (target === targetRoot) return !current || record.type !== "childList";
|
|
2253
|
+
if (target instanceof Element && (target.matches(DSH.sidebarSlot) || target.matches(DSH.root))) return true;
|
|
2254
|
+
if (target instanceof Element && target.parentElement === targetRoot) return !current || record.type !== "childList";
|
|
2255
|
+
return [...record.addedNodes, ...record.removedNodes].some(
|
|
2256
|
+
(node) => node === targetRoot || subtreeHas(node, DSH.sidebarSlot) || subtreeHas(node, DSH.root)
|
|
2257
|
+
);
|
|
2258
|
+
});
|
|
2259
|
+
if (relevant) attach();
|
|
2260
|
+
});
|
|
2261
|
+
hostObserver.observe(document.documentElement, {
|
|
2262
|
+
childList: true,
|
|
2263
|
+
subtree: true,
|
|
2264
|
+
attributes: true,
|
|
2265
|
+
attributeFilter: ["class", "data-slot"]
|
|
1616
2266
|
});
|
|
1617
|
-
pendingObserver.observe(document.body, { childList: true, subtree: true });
|
|
1618
2267
|
};
|
|
1619
2268
|
const attach = () => {
|
|
1620
2269
|
const sidebar = document.querySelector(DSH.sidebarSlot);
|
|
@@ -1624,60 +2273,73 @@ function connectLayoutAdapter(onRoot) {
|
|
|
1624
2273
|
detach();
|
|
1625
2274
|
onRoot(void 0);
|
|
1626
2275
|
}
|
|
1627
|
-
|
|
2276
|
+
observedSidebar = sidebar ?? void 0;
|
|
2277
|
+
candidateRoot = void 0;
|
|
1628
2278
|
return false;
|
|
1629
2279
|
}
|
|
1630
|
-
|
|
2280
|
+
observedSidebar = sidebar;
|
|
2281
|
+
candidateRoot = root;
|
|
2282
|
+
if (current?.root === root) {
|
|
2283
|
+
const refreshed = readAnchors(root);
|
|
2284
|
+
if (!refreshed) {
|
|
2285
|
+
detach();
|
|
2286
|
+
onRoot(void 0);
|
|
2287
|
+
return false;
|
|
2288
|
+
}
|
|
2289
|
+
if (sameAnchors(current, refreshed)) {
|
|
2290
|
+
if (compactWidgets.parentElement !== root) root.append(compactWidgets);
|
|
2291
|
+
if (preferences) apply2(refreshed, preferences);
|
|
2292
|
+
return true;
|
|
2293
|
+
}
|
|
2294
|
+
releaseStaleAnchors(current, refreshed);
|
|
2295
|
+
current = refreshed;
|
|
2296
|
+
root.append(compactWidgets);
|
|
2297
|
+
observeAnchors(refreshed);
|
|
2298
|
+
if (preferences) apply2(refreshed, preferences);
|
|
2299
|
+
onRoot(root, true);
|
|
2300
|
+
return true;
|
|
2301
|
+
}
|
|
1631
2302
|
detach();
|
|
1632
2303
|
const anchors = readAnchors(root);
|
|
1633
2304
|
if (!anchors) {
|
|
1634
2305
|
onRoot(void 0);
|
|
1635
|
-
watchPending();
|
|
1636
2306
|
return false;
|
|
1637
2307
|
}
|
|
1638
2308
|
current = anchors;
|
|
2309
|
+
root.append(compactWidgets);
|
|
1639
2310
|
if (preferences) apply2(anchors, preferences);
|
|
1640
2311
|
onRoot(root);
|
|
1641
2312
|
if (root.classList.contains("hHd-Xa_collapsed")) root.querySelector(DSH.collapse)?.click();
|
|
1642
2313
|
childrenObserver = new MutationObserver(() => {
|
|
1643
2314
|
if (!current || current.root !== root) return;
|
|
1644
|
-
|
|
1645
|
-
if (!reread) {
|
|
1646
|
-
detach();
|
|
1647
|
-
onRoot(void 0);
|
|
1648
|
-
watchPending();
|
|
1649
|
-
return;
|
|
1650
|
-
}
|
|
1651
|
-
current = reread;
|
|
1652
|
-
if (preferences) apply2(reread, preferences);
|
|
2315
|
+
attach();
|
|
1653
2316
|
});
|
|
1654
2317
|
childrenObserver.observe(root, { childList: true, subtree: true });
|
|
1655
2318
|
collapseObserver = new MutationObserver(() => {
|
|
1656
2319
|
if (root.classList.contains("hHd-Xa_collapsed")) root.querySelector(DSH.collapse)?.click();
|
|
1657
2320
|
});
|
|
1658
2321
|
collapseObserver.observe(root, { attributes: true, attributeFilter: ["class"] });
|
|
1659
|
-
|
|
1660
|
-
for (const element of [anchors.root, anchors.brand, anchors.newSession, anchors.panelList, anchors.tools]) resizeObserver.observe(element);
|
|
1661
|
-
measurementObserver = new MutationObserver(scheduleMeasure);
|
|
1662
|
-
measurementObserver.observe(anchors.panelList, { childList: true, subtree: true });
|
|
1663
|
-
measurementObserver.observe(anchors.tools, { childList: true, subtree: true });
|
|
1664
|
-
sidebarObserver = new MutationObserver(() => attach());
|
|
1665
|
-
sidebarObserver.observe(sidebar, { childList: true, subtree: true });
|
|
2322
|
+
observeAnchors(anchors);
|
|
1666
2323
|
return true;
|
|
1667
2324
|
};
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
};
|
|
1671
|
-
sync();
|
|
2325
|
+
watchHost();
|
|
2326
|
+
attach();
|
|
1672
2327
|
return {
|
|
1673
2328
|
update(next) {
|
|
1674
2329
|
preferences = next;
|
|
1675
2330
|
if (current) apply2(current, next);
|
|
1676
2331
|
},
|
|
2332
|
+
setCompactWidgets(count, active) {
|
|
2333
|
+
compactWidgetCount = Math.max(0, Math.floor(count));
|
|
2334
|
+
compactWidgetsActive = active;
|
|
2335
|
+
if (current && preferences) scheduleMeasure();
|
|
2336
|
+
},
|
|
1677
2337
|
dispose() {
|
|
1678
|
-
|
|
1679
|
-
|
|
2338
|
+
hostObserver?.disconnect();
|
|
2339
|
+
hostObserver = void 0;
|
|
1680
2340
|
detach();
|
|
2341
|
+
candidateRoot = void 0;
|
|
2342
|
+
observedSidebar = void 0;
|
|
1681
2343
|
onRoot(void 0);
|
|
1682
2344
|
}
|
|
1683
2345
|
};
|
|
@@ -1732,7 +2394,109 @@ function connectNavigation(ctx) {
|
|
|
1732
2394
|
|
|
1733
2395
|
// src/client/settings.ts
|
|
1734
2396
|
var import_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
2397
|
+
var import_react3 = require("react");
|
|
2398
|
+
|
|
2399
|
+
// src/client/clock.tsx
|
|
1735
2400
|
var import_react2 = require("react");
|
|
2401
|
+
function createClockWidget(locale, clock) {
|
|
2402
|
+
const subscribeLocale = (listener) => locale.subscribe(listener);
|
|
2403
|
+
const activeLocale = () => locale.getSnapshot().active;
|
|
2404
|
+
return function ClockWidget({ active }) {
|
|
2405
|
+
const now = useMinuteClock(active);
|
|
2406
|
+
const localeId = (0, import_react2.useSyncExternalStore)(subscribeLocale, activeLocale, activeLocale);
|
|
2407
|
+
const display = (0, import_react2.useSyncExternalStore)(clock.subscribe, clock.getSnapshot, clock.getSnapshot);
|
|
2408
|
+
return (0, import_react2.createElement)(ClockFace, { now, lines: clockLines(now, localeId, display), color: display.color });
|
|
2409
|
+
};
|
|
2410
|
+
}
|
|
2411
|
+
function useMinuteClock(active) {
|
|
2412
|
+
const [now, setNow] = (0, import_react2.useState)(() => /* @__PURE__ */ new Date());
|
|
2413
|
+
(0, import_react2.useEffect)(() => {
|
|
2414
|
+
if (!active) return;
|
|
2415
|
+
let timer = 0;
|
|
2416
|
+
const clearTimer = () => {
|
|
2417
|
+
if (timer) window.clearTimeout(timer);
|
|
2418
|
+
timer = 0;
|
|
2419
|
+
};
|
|
2420
|
+
const refresh = () => {
|
|
2421
|
+
clearTimer();
|
|
2422
|
+
const current = /* @__PURE__ */ new Date();
|
|
2423
|
+
setNow(current);
|
|
2424
|
+
if (!document.hidden) timer = window.setTimeout(refresh, 6e4 - current.getTime() % 6e4);
|
|
2425
|
+
};
|
|
2426
|
+
const onVisibilityChange = () => {
|
|
2427
|
+
if (document.hidden) clearTimer();
|
|
2428
|
+
else refresh();
|
|
2429
|
+
};
|
|
2430
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
2431
|
+
if (!document.hidden) refresh();
|
|
2432
|
+
return () => {
|
|
2433
|
+
clearTimer();
|
|
2434
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
2435
|
+
};
|
|
2436
|
+
}, [active]);
|
|
2437
|
+
return now;
|
|
2438
|
+
}
|
|
2439
|
+
function ClockFace(props) {
|
|
2440
|
+
const { now, lines, color } = props;
|
|
2441
|
+
return (0, import_react2.createElement)(
|
|
2442
|
+
"div",
|
|
2443
|
+
{ className: "dsh-better-left-sidebar-clock" },
|
|
2444
|
+
(0, import_react2.createElement)(
|
|
2445
|
+
"time",
|
|
2446
|
+
{
|
|
2447
|
+
className: "dsh-better-left-sidebar-clock-time",
|
|
2448
|
+
dateTime: now.toISOString(),
|
|
2449
|
+
"aria-hidden": "true",
|
|
2450
|
+
style: color ? { color } : void 0
|
|
2451
|
+
},
|
|
2452
|
+
lines.time,
|
|
2453
|
+
lines.period ? (0, import_react2.createElement)("span", { className: "dsh-better-left-sidebar-clock-period" }, lines.period) : null
|
|
2454
|
+
),
|
|
2455
|
+
lines.monthDay ? (0, import_react2.createElement)("span", { className: "dsh-better-left-sidebar-clock-date", "aria-hidden": "true" }, lines.monthDay) : null,
|
|
2456
|
+
lines.weekday ? (0, import_react2.createElement)("span", { className: "dsh-better-left-sidebar-clock-date", "aria-hidden": "true" }, lines.weekday) : null,
|
|
2457
|
+
(0, import_react2.createElement)("span", { className: "dsh-better-left-sidebar-visually-hidden" }, lines.accessible)
|
|
2458
|
+
);
|
|
2459
|
+
}
|
|
2460
|
+
|
|
2461
|
+
// src/client/compact-widget-preferences.ts
|
|
2462
|
+
function validateCompactWidgetPreferences(value) {
|
|
2463
|
+
if (!Array.isArray(value)) return [];
|
|
2464
|
+
const result = [];
|
|
2465
|
+
for (const item of value) {
|
|
2466
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) continue;
|
|
2467
|
+
const record = item;
|
|
2468
|
+
if (typeof record.id !== "string") continue;
|
|
2469
|
+
result.push({
|
|
2470
|
+
id: record.id,
|
|
2471
|
+
enabled: typeof record.enabled === "boolean" ? record.enabled : true
|
|
2472
|
+
});
|
|
2473
|
+
}
|
|
2474
|
+
return result;
|
|
2475
|
+
}
|
|
2476
|
+
function orderCompactWidgetEntries(entries, preferences) {
|
|
2477
|
+
const savedById = /* @__PURE__ */ new Map();
|
|
2478
|
+
preferences.forEach((preference, index) => {
|
|
2479
|
+
if (!savedById.has(preference.id)) savedById.set(preference.id, { index, enabled: preference.enabled });
|
|
2480
|
+
});
|
|
2481
|
+
return entries.map((entry, registrationIndex) => ({
|
|
2482
|
+
entry,
|
|
2483
|
+
registrationIndex,
|
|
2484
|
+
saved: savedById.get(entry.id)
|
|
2485
|
+
})).sort((a, b) => {
|
|
2486
|
+
if (a.saved && b.saved) return a.saved.index - b.saved.index || a.registrationIndex - b.registrationIndex;
|
|
2487
|
+
if (a.saved) return -1;
|
|
2488
|
+
if (b.saved) return 1;
|
|
2489
|
+
const orderA = typeof a.entry.order === "number" && Number.isFinite(a.entry.order) ? a.entry.order : 0;
|
|
2490
|
+
const orderB = typeof b.entry.order === "number" && Number.isFinite(b.entry.order) ? b.entry.order : 0;
|
|
2491
|
+
return orderA - orderB || a.registrationIndex - b.registrationIndex;
|
|
2492
|
+
}).map(({ entry, saved }) => ({
|
|
2493
|
+
entry,
|
|
2494
|
+
enabled: saved?.enabled ?? true,
|
|
2495
|
+
saved: saved !== void 0
|
|
2496
|
+
}));
|
|
2497
|
+
}
|
|
2498
|
+
|
|
2499
|
+
// src/client/settings.ts
|
|
1736
2500
|
var PACKAGE = "dsh-better-left-sidebar";
|
|
1737
2501
|
var animationValues = ["standard", "fast", "off"];
|
|
1738
2502
|
var expansionValues = ["hover", "click"];
|
|
@@ -1745,12 +2509,47 @@ var fields = [
|
|
|
1745
2509
|
choiceField("brandPosition", brandValues),
|
|
1746
2510
|
choiceField("globalNavigationPosition", globalValues),
|
|
1747
2511
|
choiceField("toolsPosition", toolsValues),
|
|
2512
|
+
compactWidgetField(),
|
|
2513
|
+
clockField(),
|
|
1748
2514
|
{
|
|
1749
2515
|
field: "layoutVersion",
|
|
1750
2516
|
format: (value) => value === 1 ? "1" : "",
|
|
1751
2517
|
parse: (text) => text === "1" ? { kind: "set", value: 1 } : text === "" ? { kind: "clear" } : void 0
|
|
1752
2518
|
}
|
|
1753
2519
|
];
|
|
2520
|
+
function compactWidgetField() {
|
|
2521
|
+
return {
|
|
2522
|
+
field: "compactWidgets",
|
|
2523
|
+
format: (value) => JSON.stringify(validateCompactWidgetPreferences(value), null, 2),
|
|
2524
|
+
parse: (text) => {
|
|
2525
|
+
let value;
|
|
2526
|
+
try {
|
|
2527
|
+
value = JSON.parse(text);
|
|
2528
|
+
} catch {
|
|
2529
|
+
return void 0;
|
|
2530
|
+
}
|
|
2531
|
+
if (!Array.isArray(value) || value.some((item) => {
|
|
2532
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) return true;
|
|
2533
|
+
const record = item;
|
|
2534
|
+
return typeof record.id !== "string" || typeof record.enabled !== "boolean";
|
|
2535
|
+
})) return void 0;
|
|
2536
|
+
return { kind: "set", value: validateCompactWidgetPreferences(value) };
|
|
2537
|
+
}
|
|
2538
|
+
};
|
|
2539
|
+
}
|
|
2540
|
+
function clockField() {
|
|
2541
|
+
return {
|
|
2542
|
+
field: "clock",
|
|
2543
|
+
format: (value) => JSON.stringify(toClockConfig(value)),
|
|
2544
|
+
parse: (text) => {
|
|
2545
|
+
try {
|
|
2546
|
+
return { kind: "set", value: toClockConfig(JSON.parse(text)) };
|
|
2547
|
+
} catch {
|
|
2548
|
+
return void 0;
|
|
2549
|
+
}
|
|
2550
|
+
}
|
|
2551
|
+
};
|
|
2552
|
+
}
|
|
1754
2553
|
function choiceField(field, values) {
|
|
1755
2554
|
return {
|
|
1756
2555
|
field,
|
|
@@ -1758,7 +2557,7 @@ function choiceField(field, values) {
|
|
|
1758
2557
|
parse: (text) => values.includes(text) ? { kind: "set", value: text } : void 0
|
|
1759
2558
|
};
|
|
1760
2559
|
}
|
|
1761
|
-
function connectSettings(ctx, onPreferences, onTranslate) {
|
|
2560
|
+
function connectSettings(ctx, compactWidgets, onPreferences, onTranslate) {
|
|
1762
2561
|
ctx.inject(["locale", "configForms"], (settingsCtx) => {
|
|
1763
2562
|
const form = settingsCtx.configForms.get(PACKAGE);
|
|
1764
2563
|
settingsCtx.effect(() => {
|
|
@@ -1778,7 +2577,7 @@ function connectSettings(ctx, onPreferences, onTranslate) {
|
|
|
1778
2577
|
settingsCtx.effect(
|
|
1779
2578
|
() => settingsCtx.slots.inject("plugins.bundle.config", () => settingsCtx.slots.register(
|
|
1780
2579
|
{ name: "plugins.bundle.config", key: PACKAGE, locale: NAMESPACE },
|
|
1781
|
-
(props) => (0,
|
|
2580
|
+
(props) => (0, import_react3.createElement)(SettingsPage, { ...props, ctx: settingsCtx, compactWidgets, locale: settingsCtx.locale })
|
|
1782
2581
|
)),
|
|
1783
2582
|
"better-left-sidebar: settings page"
|
|
1784
2583
|
);
|
|
@@ -1786,23 +2585,23 @@ function connectSettings(ctx, onPreferences, onTranslate) {
|
|
|
1786
2585
|
}
|
|
1787
2586
|
function SettingsPage(props) {
|
|
1788
2587
|
const { ctx, t } = props;
|
|
1789
|
-
const scope = (0,
|
|
2588
|
+
const scope = (0, import_react3.useMemo)(
|
|
1790
2589
|
() => ctx.configForms.get(PACKAGE),
|
|
1791
2590
|
[ctx]
|
|
1792
2591
|
);
|
|
1793
|
-
const model = (0,
|
|
1794
|
-
(0,
|
|
1795
|
-
const store = (0,
|
|
2592
|
+
const model = (0, import_react3.useMemo)(() => new import_dsh_client_ui_primitives.SettingsFormModel(scope, fields), [scope]);
|
|
2593
|
+
(0, import_react3.useEffect)(() => () => model.dispose(), [model]);
|
|
2594
|
+
const store = (0, import_react3.useMemo)(() => model.bind(() => ({
|
|
1796
2595
|
shell: model.shell(),
|
|
1797
2596
|
fields: Object.fromEntries(fields.map((spec) => [spec.field, model.field(spec.field)]))
|
|
1798
2597
|
})), [model]);
|
|
1799
|
-
const subscribe = (0,
|
|
1800
|
-
const getSnapshot = (0,
|
|
1801
|
-
const view = (0,
|
|
1802
|
-
|
|
2598
|
+
const subscribe = (0, import_react3.useCallback)((listener) => store.subscribe(listener), [store]);
|
|
2599
|
+
const getSnapshot = (0, import_react3.useCallback)(() => store.getSnapshot(), [store]);
|
|
2600
|
+
const view = (0, import_react3.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
2601
|
+
(0, import_react3.useSyncExternalStore)(props.compactWidgets.subscribeCatalog, props.compactWidgets.getCatalogVersion, props.compactWidgets.getCatalogVersion);
|
|
2602
|
+
const actions = (0, import_react3.useMemo)(() => model.actions(), [model]);
|
|
1803
2603
|
const disabled = !view.shell.writable || view.shell.saving;
|
|
1804
2604
|
const savedSnapshot = scope.getSnapshot();
|
|
1805
|
-
const savedPreferences = normalizePreferences(savedSnapshot.value);
|
|
1806
2605
|
const draft = normalizePreferences({
|
|
1807
2606
|
...savedSnapshot.value,
|
|
1808
2607
|
animation: view.fields.animation?.text,
|
|
@@ -1818,8 +2617,102 @@ function SettingsPage(props) {
|
|
|
1818
2617
|
actions.edit(field, value);
|
|
1819
2618
|
actions.edit("layoutVersion", "1");
|
|
1820
2619
|
};
|
|
1821
|
-
|
|
1822
|
-
|
|
2620
|
+
const savedWidgets = readWidgetDraft(view.fields.compactWidgets?.text);
|
|
2621
|
+
const widgetRows = buildWidgetRows(savedWidgets, props.compactWidgets.getCatalog(), validateCompactWidgetPreferences(savedSnapshot.value?.compactWidgets));
|
|
2622
|
+
const writeWidgetRows = (rows) => {
|
|
2623
|
+
const next = rows.map(({ id, enabled }) => ({ id, enabled }));
|
|
2624
|
+
actions.edit("compactWidgets", JSON.stringify(next, null, 2));
|
|
2625
|
+
};
|
|
2626
|
+
const clockDraft = readClockDraft(view.fields.clock?.text);
|
|
2627
|
+
const writeClock = (next) => {
|
|
2628
|
+
actions.edit("clock", JSON.stringify(toClockConfig(next)));
|
|
2629
|
+
};
|
|
2630
|
+
if (props.view === "summary") return (0, import_react3.createElement)("p", null, t("summary"));
|
|
2631
|
+
const widgetSection = (0, import_react3.createElement)(
|
|
2632
|
+
"section",
|
|
2633
|
+
{ className: "dsh-better-left-sidebar-settings-group dsh-better-left-sidebar-compact-widgets-settings" },
|
|
2634
|
+
(0, import_react3.createElement)(
|
|
2635
|
+
"div",
|
|
2636
|
+
{ className: "dsh-better-left-sidebar-compact-widgets-intro" },
|
|
2637
|
+
(0, import_react3.createElement)("h3", null, t("compactWidgets")),
|
|
2638
|
+
(0, import_react3.createElement)("p", { className: "dsh-better-left-sidebar-compact-widgets-hint" }, t("compactWidgetsHint"))
|
|
2639
|
+
),
|
|
2640
|
+
widgetRows.length === 0 ? (0, import_react3.createElement)("p", { className: "dsh-better-left-sidebar-compact-widgets-empty" }, t("compactWidgetsEmpty")) : (0, import_react3.createElement)(
|
|
2641
|
+
"div",
|
|
2642
|
+
{ className: "dsh-better-left-sidebar-compact-widgets-list" },
|
|
2643
|
+
...widgetRows.map((row, index) => (0, import_react3.createElement)(
|
|
2644
|
+
"div",
|
|
2645
|
+
{
|
|
2646
|
+
key: row.id,
|
|
2647
|
+
className: "dsh-better-left-sidebar-compact-widget-setting",
|
|
2648
|
+
"data-dsh-better-left-sidebar-widget-setting": row.id
|
|
2649
|
+
},
|
|
2650
|
+
(0, import_react3.createElement)(
|
|
2651
|
+
"div",
|
|
2652
|
+
{ className: "dsh-better-left-sidebar-compact-widget-info" },
|
|
2653
|
+
(0, import_react3.createElement)("div", { className: "dsh-better-left-sidebar-compact-widget-name" }, row.label),
|
|
2654
|
+
(0, import_react3.createElement)("div", {
|
|
2655
|
+
className: `dsh-better-left-sidebar-compact-widget-status is-${row.status}`,
|
|
2656
|
+
"aria-live": "polite"
|
|
2657
|
+
}, row.status === "failed" ? `${t("widgetFailed")}: ${row.error}` : t(widgetStatusKey(row.status)))
|
|
2658
|
+
),
|
|
2659
|
+
(0, import_react3.createElement)(
|
|
2660
|
+
"div",
|
|
2661
|
+
{ className: "dsh-better-left-sidebar-compact-widget-controls" },
|
|
2662
|
+
(0, import_react3.createElement)(import_dsh_client_ui_primitives.Switch, {
|
|
2663
|
+
checked: row.enabled,
|
|
2664
|
+
disabled,
|
|
2665
|
+
label: `${t("widgetEnable")} ${row.label}`,
|
|
2666
|
+
onChange: (checked) => writeWidgetRows(widgetRows.map((item) => item.id === row.id ? { ...item, enabled: checked } : item))
|
|
2667
|
+
}),
|
|
2668
|
+
widgetRows.length > 1 ? (0, import_react3.createElement)(
|
|
2669
|
+
"div",
|
|
2670
|
+
{ className: "dsh-better-left-sidebar-widget-order" },
|
|
2671
|
+
(0, import_react3.createElement)(import_dsh_client_ui_primitives.Button, {
|
|
2672
|
+
type: "button",
|
|
2673
|
+
variant: "outline",
|
|
2674
|
+
size: "sm",
|
|
2675
|
+
disabled: disabled || index === 0,
|
|
2676
|
+
"aria-label": `${t("moveUp")} ${row.label}`,
|
|
2677
|
+
onClick: () => writeWidgetRows(moveWidgetRow(widgetRows, index, -1))
|
|
2678
|
+
}, "\u2191"),
|
|
2679
|
+
(0, import_react3.createElement)(import_dsh_client_ui_primitives.Button, {
|
|
2680
|
+
type: "button",
|
|
2681
|
+
variant: "outline",
|
|
2682
|
+
size: "sm",
|
|
2683
|
+
disabled: disabled || index === widgetRows.length - 1,
|
|
2684
|
+
"aria-label": `${t("moveDown")} ${row.label}`,
|
|
2685
|
+
onClick: () => writeWidgetRows(moveWidgetRow(widgetRows, index, 1))
|
|
2686
|
+
}, "\u2193")
|
|
2687
|
+
) : null
|
|
2688
|
+
),
|
|
2689
|
+
row.id === CLOCK_WIDGET_ID ? (0, import_react3.createElement)(
|
|
2690
|
+
"details",
|
|
2691
|
+
{ className: "dsh-better-left-sidebar-widget-options", open: true },
|
|
2692
|
+
(0, import_react3.createElement)("summary", null, t("widgetSettings")),
|
|
2693
|
+
(0, import_react3.createElement)(ClockOptions, {
|
|
2694
|
+
t,
|
|
2695
|
+
disabled,
|
|
2696
|
+
display: clockDraft,
|
|
2697
|
+
caption: t("effectPreview"),
|
|
2698
|
+
locale: props.locale,
|
|
2699
|
+
onChange: writeClock
|
|
2700
|
+
})
|
|
2701
|
+
) : null
|
|
2702
|
+
))
|
|
2703
|
+
),
|
|
2704
|
+
(0, import_react3.createElement)(
|
|
2705
|
+
"details",
|
|
2706
|
+
{ className: "dsh-better-left-sidebar-widget-reference" },
|
|
2707
|
+
(0, import_react3.createElement)("summary", null, t("widgetInformation")),
|
|
2708
|
+
(0, import_react3.createElement)("dl", null, ...widgetRows.flatMap((row) => [
|
|
2709
|
+
(0, import_react3.createElement)("dt", { key: `${row.id}-label` }, row.label),
|
|
2710
|
+
(0, import_react3.createElement)("dd", { key: row.id }, (0, import_react3.createElement)("code", null, row.id))
|
|
2711
|
+
])),
|
|
2712
|
+
(0, import_react3.createElement)("a", { href: t("compactWidgetsDocsUrl"), target: "_blank", rel: "noopener noreferrer" }, t("compactWidgetsDocs"))
|
|
2713
|
+
)
|
|
2714
|
+
);
|
|
2715
|
+
return (0, import_react3.createElement)(import_dsh_client_ui_primitives.SettingsForm, {
|
|
1823
2716
|
labels: {
|
|
1824
2717
|
unavailable: t("unavailable"),
|
|
1825
2718
|
readOnly: t("readOnly"),
|
|
@@ -1830,128 +2723,305 @@ function SettingsPage(props) {
|
|
|
1830
2723
|
state: view.shell,
|
|
1831
2724
|
onSave: actions.save,
|
|
1832
2725
|
onDiscard: actions.discard,
|
|
1833
|
-
children:
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
2726
|
+
children: [
|
|
2727
|
+
(0, import_react3.createElement)(
|
|
2728
|
+
"div",
|
|
2729
|
+
{ className: "dsh-better-left-sidebar-preferences" },
|
|
2730
|
+
(0, import_react3.createElement)(
|
|
2731
|
+
"section",
|
|
2732
|
+
{ className: "dsh-better-left-sidebar-settings-group dsh-better-left-sidebar-layout-settings" },
|
|
2733
|
+
(0, import_react3.createElement)(
|
|
2734
|
+
"div",
|
|
2735
|
+
{ className: "dsh-better-left-sidebar-settings-heading" },
|
|
2736
|
+
(0, import_react3.createElement)("h3", null, t("contentLayout")),
|
|
2737
|
+
(0, import_react3.createElement)("button", {
|
|
2738
|
+
type: "button",
|
|
2739
|
+
className: "dsh-better-left-sidebar-layout-reset",
|
|
2740
|
+
disabled: disabled || !canRestore,
|
|
2741
|
+
onClick: () => {
|
|
2742
|
+
actions.edit("brandPosition", DEFAULT_PREFERENCES.brandPosition);
|
|
2743
|
+
actions.edit("globalNavigationPosition", DEFAULT_PREFERENCES.globalNavigationPosition);
|
|
2744
|
+
actions.edit("toolsPosition", DEFAULT_PREFERENCES.toolsPosition);
|
|
2745
|
+
actions.edit("layoutVersion", "1");
|
|
2746
|
+
}
|
|
2747
|
+
}, t("resetLayout"))
|
|
2748
|
+
),
|
|
2749
|
+
(0, import_react3.createElement)(
|
|
2750
|
+
"div",
|
|
2751
|
+
{ className: "dsh-better-left-sidebar-position-controls" },
|
|
2752
|
+
(0, import_react3.createElement)(PositionSelect, {
|
|
2753
|
+
field: "brandPosition",
|
|
2754
|
+
label: t("brand"),
|
|
2755
|
+
value: view.fields.brandPosition.text,
|
|
2756
|
+
disabled,
|
|
2757
|
+
options: brandValues.map((value) => ({ value, label: brandLabel(t, value) })),
|
|
2758
|
+
onChange: (value) => setChoice("brandPosition", value)
|
|
2759
|
+
}),
|
|
2760
|
+
(0, import_react3.createElement)(PositionSelect, {
|
|
2761
|
+
field: "globalNavigationPosition",
|
|
2762
|
+
label: t("globalNavigation"),
|
|
2763
|
+
value: view.fields.globalNavigationPosition.text,
|
|
2764
|
+
disabled,
|
|
2765
|
+
options: globalValues.map((value) => ({ value, label: globalLabel(t, value) })),
|
|
2766
|
+
onChange: (value) => setChoice("globalNavigationPosition", value)
|
|
2767
|
+
}),
|
|
2768
|
+
(0, import_react3.createElement)(PositionSelect, {
|
|
2769
|
+
field: "toolsPosition",
|
|
2770
|
+
label: t("tools"),
|
|
2771
|
+
value: view.fields.toolsPosition.text,
|
|
2772
|
+
disabled,
|
|
2773
|
+
options: toolsValues.map((value) => ({ value, label: toolsLabel(t, value) })),
|
|
2774
|
+
onChange: (value) => setChoice("toolsPosition", value)
|
|
2775
|
+
})
|
|
2776
|
+
),
|
|
2777
|
+
(0, import_react3.createElement)(LayoutPreview, { title: t("effectPreview"), preferences: draft, t })
|
|
1875
2778
|
),
|
|
1876
|
-
(0,
|
|
1877
|
-
"
|
|
1878
|
-
{ className: "dsh-better-left-sidebar-
|
|
1879
|
-
(0,
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
2779
|
+
(0, import_react3.createElement)(
|
|
2780
|
+
"section",
|
|
2781
|
+
{ className: "dsh-better-left-sidebar-settings-group" },
|
|
2782
|
+
(0, import_react3.createElement)("h3", null, t("navigationBehavior")),
|
|
2783
|
+
(0, import_react3.createElement)(ChoiceRow, {
|
|
2784
|
+
name: "dsh-better-left-sidebar-expansion",
|
|
2785
|
+
label: t("expansion"),
|
|
2786
|
+
value: view.fields.expansion.text,
|
|
1883
2787
|
disabled,
|
|
1884
|
-
options:
|
|
1885
|
-
onChange: (value) =>
|
|
2788
|
+
options: expansionValues.map((value) => ({ value, label: t(value) })),
|
|
2789
|
+
onChange: (value) => actions.edit("expansion", value)
|
|
1886
2790
|
}),
|
|
1887
|
-
(0,
|
|
1888
|
-
|
|
1889
|
-
label: t("
|
|
1890
|
-
value: view.fields.
|
|
2791
|
+
(0, import_react3.createElement)(ChoiceRow, {
|
|
2792
|
+
name: "dsh-better-left-sidebar-animation",
|
|
2793
|
+
label: t("animation"),
|
|
2794
|
+
value: view.fields.animation.text,
|
|
1891
2795
|
disabled,
|
|
1892
|
-
options:
|
|
1893
|
-
onChange: (value) =>
|
|
2796
|
+
options: animationValues.map((value) => ({ value, label: t(value) })),
|
|
2797
|
+
onChange: (value) => actions.edit("animation", value)
|
|
2798
|
+
})
|
|
2799
|
+
),
|
|
2800
|
+
widgetSection
|
|
2801
|
+
),
|
|
2802
|
+
view.shell.dirty ? (0, import_react3.createElement)("button", {
|
|
2803
|
+
type: "button",
|
|
2804
|
+
className: "dsh-better-left-sidebar-layout-cancel",
|
|
2805
|
+
disabled: view.shell.saving,
|
|
2806
|
+
onClick: actions.discard
|
|
2807
|
+
}, t("cancel")) : null
|
|
2808
|
+
]
|
|
2809
|
+
});
|
|
2810
|
+
}
|
|
2811
|
+
function sameLayout(a, b) {
|
|
2812
|
+
return a.brandPosition === b.brandPosition && a.globalNavigationPosition === b.globalNavigationPosition && a.toolsPosition === b.toolsPosition;
|
|
2813
|
+
}
|
|
2814
|
+
function readWidgetDraft(text) {
|
|
2815
|
+
if (text === void 0) return [];
|
|
2816
|
+
try {
|
|
2817
|
+
return validateCompactWidgetPreferences(JSON.parse(text));
|
|
2818
|
+
} catch {
|
|
2819
|
+
return [];
|
|
2820
|
+
}
|
|
2821
|
+
}
|
|
2822
|
+
function buildWidgetRows(preferences, catalog, applied) {
|
|
2823
|
+
const preferred = /* @__PURE__ */ new Map();
|
|
2824
|
+
for (const preference of preferences) if (!preferred.has(preference.id)) preferred.set(preference.id, preference);
|
|
2825
|
+
const byId = new Map(catalog.map((entry) => [entry.id, entry]));
|
|
2826
|
+
const ordered = orderCompactWidgetEntries(catalog, preferences);
|
|
2827
|
+
const ids = [];
|
|
2828
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2829
|
+
for (const preference of preferences) {
|
|
2830
|
+
if (seen.has(preference.id)) continue;
|
|
2831
|
+
seen.add(preference.id);
|
|
2832
|
+
ids.push(preference.id);
|
|
2833
|
+
}
|
|
2834
|
+
for (const item of ordered) {
|
|
2835
|
+
if (seen.has(item.entry.id)) continue;
|
|
2836
|
+
seen.add(item.entry.id);
|
|
2837
|
+
ids.push(item.entry.id);
|
|
2838
|
+
}
|
|
2839
|
+
return ids.map((id) => {
|
|
2840
|
+
const registration = byId.get(id);
|
|
2841
|
+
const enabled = preferred.get(id)?.enabled ?? true;
|
|
2842
|
+
const status = registration?.error !== void 0 ? "failed" : !registration ? "notLoaded" : enabled !== (applied.find((item) => item.id === id)?.enabled ?? true) ? enabled ? "pendingEnable" : "pendingDisable" : registration.presentation;
|
|
2843
|
+
const row = {
|
|
2844
|
+
id,
|
|
2845
|
+
label: registration?.label ?? id,
|
|
2846
|
+
enabled,
|
|
2847
|
+
status
|
|
2848
|
+
};
|
|
2849
|
+
if (registration?.error !== void 0) row.error = registration.error;
|
|
2850
|
+
return row;
|
|
2851
|
+
});
|
|
2852
|
+
}
|
|
2853
|
+
function widgetStatusKey(status) {
|
|
2854
|
+
switch (status) {
|
|
2855
|
+
case "shown":
|
|
2856
|
+
return "widgetShown";
|
|
2857
|
+
case "enabled":
|
|
2858
|
+
return "widgetEnabled";
|
|
2859
|
+
case "clipped":
|
|
2860
|
+
return "widgetClipped";
|
|
2861
|
+
case "inactive":
|
|
2862
|
+
return "widgetInactive";
|
|
2863
|
+
case "empty":
|
|
2864
|
+
return "widgetEmpty";
|
|
2865
|
+
case "pendingEnable":
|
|
2866
|
+
return "widgetPendingEnable";
|
|
2867
|
+
case "pendingDisable":
|
|
2868
|
+
return "widgetPendingDisable";
|
|
2869
|
+
case "disabled":
|
|
2870
|
+
return "widgetDisabled";
|
|
2871
|
+
case "notLoaded":
|
|
2872
|
+
return "widgetNotLoaded";
|
|
2873
|
+
case "failed":
|
|
2874
|
+
return "widgetFailed";
|
|
2875
|
+
}
|
|
2876
|
+
}
|
|
2877
|
+
function moveWidgetRow(rows, index, delta) {
|
|
2878
|
+
const next = [...rows];
|
|
2879
|
+
const target = index + delta;
|
|
2880
|
+
if (target < 0 || target >= next.length) return next;
|
|
2881
|
+
[next[index], next[target]] = [next[target], next[index]];
|
|
2882
|
+
return next;
|
|
2883
|
+
}
|
|
2884
|
+
var clockHourCycles = ["h23", "h12"];
|
|
2885
|
+
function ClockOptions(props) {
|
|
2886
|
+
const { t, disabled, display, onChange } = props;
|
|
2887
|
+
return (0, import_react3.createElement)(
|
|
2888
|
+
"div",
|
|
2889
|
+
{ className: "dsh-better-left-sidebar-clock-options" },
|
|
2890
|
+
(0, import_react3.createElement)(
|
|
2891
|
+
"div",
|
|
2892
|
+
{ className: "dsh-better-left-sidebar-clock-option-fields" },
|
|
2893
|
+
(0, import_react3.createElement)(ChoiceRow, {
|
|
2894
|
+
name: "dsh-better-left-sidebar-clock-hour",
|
|
2895
|
+
label: t("clockHourCycle"),
|
|
2896
|
+
value: display.hourCycle,
|
|
2897
|
+
disabled,
|
|
2898
|
+
options: clockHourCycles.map((value) => ({ value, label: t(value === "h23" ? "clock24" : "clock12") })),
|
|
2899
|
+
onChange: (value) => onChange({ ...display, hourCycle: value === "h12" ? "h12" : "h23" })
|
|
2900
|
+
}),
|
|
2901
|
+
(0, import_react3.createElement)(
|
|
2902
|
+
SettingsRow,
|
|
2903
|
+
{ label: t("clockContents"), disabled },
|
|
2904
|
+
(0, import_react3.createElement)(
|
|
2905
|
+
"div",
|
|
2906
|
+
{ className: "dsh-better-left-sidebar-clock-modules" },
|
|
2907
|
+
(0, import_react3.createElement)(import_dsh_client_ui_primitives.Checkbox, {
|
|
2908
|
+
checked: display.monthDay,
|
|
2909
|
+
disabled,
|
|
2910
|
+
label: t("clockMonthDay"),
|
|
2911
|
+
onChange: (checked) => onChange({ ...display, monthDay: checked })
|
|
1894
2912
|
}),
|
|
1895
|
-
(0,
|
|
1896
|
-
|
|
1897
|
-
label: t("tools"),
|
|
1898
|
-
value: view.fields.toolsPosition.text,
|
|
2913
|
+
(0, import_react3.createElement)(import_dsh_client_ui_primitives.Checkbox, {
|
|
2914
|
+
checked: display.weekday,
|
|
1899
2915
|
disabled,
|
|
1900
|
-
|
|
1901
|
-
onChange: (
|
|
2916
|
+
label: t("clockWeekday"),
|
|
2917
|
+
onChange: (checked) => onChange({ ...display, weekday: checked })
|
|
1902
2918
|
})
|
|
1903
|
-
)
|
|
1904
|
-
|
|
2919
|
+
)
|
|
2920
|
+
),
|
|
2921
|
+
(0, import_react3.createElement)(ChoiceRow, {
|
|
2922
|
+
name: "dsh-better-left-sidebar-clock-color-mode",
|
|
2923
|
+
label: t("clockColor"),
|
|
2924
|
+
value: display.color ? "custom" : "theme",
|
|
2925
|
+
disabled,
|
|
2926
|
+
options: [{ value: "theme", label: t("clockColorDefault") }, { value: "custom", label: t("clockColorCustom") }],
|
|
2927
|
+
onChange: (value) => onChange({ ...display, color: value === "theme" ? null : "#767676" })
|
|
2928
|
+
}),
|
|
2929
|
+
display.color ? (0, import_react3.createElement)(
|
|
2930
|
+
SettingsRow,
|
|
2931
|
+
{ label: t("clockColorCustom"), disabled },
|
|
2932
|
+
(0, import_react3.createElement)(
|
|
1905
2933
|
"div",
|
|
1906
|
-
{ className: "dsh-better-left-sidebar-
|
|
1907
|
-
|
|
1908
|
-
|
|
2934
|
+
{ className: "dsh-better-left-sidebar-clock-color-controls" },
|
|
2935
|
+
(0, import_react3.createElement)(
|
|
2936
|
+
"label",
|
|
2937
|
+
{ className: "dsh-better-left-sidebar-clock-color-picker" },
|
|
2938
|
+
(0, import_react3.createElement)("span", {
|
|
2939
|
+
className: "dsh-better-left-sidebar-clock-color-swatch",
|
|
2940
|
+
style: { backgroundColor: display.color },
|
|
2941
|
+
"aria-hidden": "true"
|
|
2942
|
+
}),
|
|
2943
|
+
(0, import_react3.createElement)("input", {
|
|
2944
|
+
type: "color",
|
|
2945
|
+
className: "dsh-better-left-sidebar-clock-color-input",
|
|
2946
|
+
value: display.color,
|
|
2947
|
+
disabled,
|
|
2948
|
+
"aria-label": t("clockColorCustom"),
|
|
2949
|
+
onChange: (event) => onChange({ ...display, color: event.currentTarget.value })
|
|
2950
|
+
})
|
|
2951
|
+
),
|
|
2952
|
+
(0, import_react3.createElement)("code", null, display.color)
|
|
1909
2953
|
),
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
2954
|
+
(0, import_react3.createElement)("p", { className: "dsh-better-left-sidebar-clock-color-hint" }, t("clockColorHint"))
|
|
2955
|
+
) : null
|
|
2956
|
+
),
|
|
2957
|
+
(0, import_react3.createElement)(ClockPreview, { display, caption: props.caption, locale: props.locale })
|
|
2958
|
+
);
|
|
2959
|
+
}
|
|
2960
|
+
function ClockPreview(props) {
|
|
2961
|
+
const now = useMinuteClock(true);
|
|
2962
|
+
const localeId = (0, import_react3.useSyncExternalStore)(
|
|
2963
|
+
(listener) => props.locale.subscribe(listener),
|
|
2964
|
+
() => props.locale.getSnapshot().active,
|
|
2965
|
+
() => props.locale.getSnapshot().active
|
|
2966
|
+
);
|
|
2967
|
+
return (0, import_react3.createElement)(
|
|
2968
|
+
"figure",
|
|
2969
|
+
{ className: "dsh-better-left-sidebar-clock-preview" },
|
|
2970
|
+
(0, import_react3.createElement)("figcaption", null, props.caption),
|
|
2971
|
+
(0, import_react3.createElement)(
|
|
2972
|
+
"div",
|
|
2973
|
+
{ className: "dsh-better-left-sidebar-clock-preview-rail" },
|
|
2974
|
+
(0, import_react3.createElement)(ClockFace, { now, lines: clockLines(now, localeId, props.display), color: props.display.color })
|
|
1917
2975
|
)
|
|
1918
|
-
|
|
2976
|
+
);
|
|
1919
2977
|
}
|
|
1920
|
-
function
|
|
1921
|
-
|
|
2978
|
+
function readClockDraft(text) {
|
|
2979
|
+
if (!text) return normalizeClockDisplay(void 0);
|
|
2980
|
+
try {
|
|
2981
|
+
return normalizeClockDisplay(JSON.parse(text));
|
|
2982
|
+
} catch {
|
|
2983
|
+
return normalizeClockDisplay(void 0);
|
|
2984
|
+
}
|
|
1922
2985
|
}
|
|
1923
|
-
function
|
|
1924
|
-
return (0,
|
|
2986
|
+
function SettingsRow(props) {
|
|
2987
|
+
return (0, import_react3.createElement)(
|
|
1925
2988
|
"fieldset",
|
|
1926
|
-
{ className: "dsh-better-left-sidebar-
|
|
1927
|
-
(0,
|
|
1928
|
-
(0,
|
|
2989
|
+
{ className: "dsh-better-left-sidebar-settings-row", disabled: props.disabled },
|
|
2990
|
+
(0, import_react3.createElement)("legend", null, props.label),
|
|
2991
|
+
(0, import_react3.createElement)("div", { className: "dsh-better-left-sidebar-setting-control" }, props.children)
|
|
2992
|
+
);
|
|
2993
|
+
}
|
|
2994
|
+
function ChoiceRow(props) {
|
|
2995
|
+
return (0, import_react3.createElement)(
|
|
2996
|
+
SettingsRow,
|
|
2997
|
+
{ label: props.label, disabled: props.disabled },
|
|
2998
|
+
(0, import_react3.createElement)(
|
|
1929
2999
|
"div",
|
|
1930
3000
|
{ className: "dsh-better-left-sidebar-choice-options" },
|
|
1931
|
-
...props.options.map((option) => (0,
|
|
3001
|
+
...props.options.map((option) => (0, import_react3.createElement)(
|
|
1932
3002
|
"label",
|
|
1933
3003
|
{
|
|
1934
3004
|
key: option.value,
|
|
1935
3005
|
className: "dsh-better-left-sidebar-choice-option"
|
|
1936
3006
|
},
|
|
1937
|
-
(0,
|
|
3007
|
+
(0, import_react3.createElement)("input", {
|
|
1938
3008
|
type: "radio",
|
|
1939
3009
|
name: props.name,
|
|
1940
3010
|
value: option.value,
|
|
1941
3011
|
checked: props.value === option.value,
|
|
1942
3012
|
onChange: () => props.onChange(option.value)
|
|
1943
3013
|
}),
|
|
1944
|
-
(0,
|
|
3014
|
+
(0, import_react3.createElement)("span", null, option.label)
|
|
1945
3015
|
))
|
|
1946
3016
|
)
|
|
1947
3017
|
);
|
|
1948
3018
|
}
|
|
1949
3019
|
function PositionSelect(props) {
|
|
1950
|
-
return (0,
|
|
3020
|
+
return (0, import_react3.createElement)(
|
|
1951
3021
|
"label",
|
|
1952
3022
|
{ className: "dsh-better-left-sidebar-position" },
|
|
1953
|
-
(0,
|
|
1954
|
-
(0,
|
|
3023
|
+
(0, import_react3.createElement)("span", null, props.label),
|
|
3024
|
+
(0, import_react3.createElement)(
|
|
1955
3025
|
"select",
|
|
1956
3026
|
{
|
|
1957
3027
|
name: props.field,
|
|
@@ -1960,40 +3030,40 @@ function PositionSelect(props) {
|
|
|
1960
3030
|
disabled: props.disabled,
|
|
1961
3031
|
onChange: (event) => props.onChange(event.currentTarget.value)
|
|
1962
3032
|
},
|
|
1963
|
-
...props.options.map((option) => (0,
|
|
3033
|
+
...props.options.map((option) => (0, import_react3.createElement)("option", { key: option.value, value: option.value }, option.label))
|
|
1964
3034
|
)
|
|
1965
3035
|
);
|
|
1966
3036
|
}
|
|
1967
3037
|
function LayoutPreview(props) {
|
|
1968
3038
|
const { preferences, t } = props;
|
|
1969
|
-
return (0,
|
|
3039
|
+
return (0, import_react3.createElement)(
|
|
1970
3040
|
"figure",
|
|
1971
3041
|
{ className: "dsh-better-left-sidebar-layout-preview" },
|
|
1972
|
-
(0,
|
|
1973
|
-
(0,
|
|
3042
|
+
(0, import_react3.createElement)("figcaption", null, props.title),
|
|
3043
|
+
(0, import_react3.createElement)(
|
|
1974
3044
|
"div",
|
|
1975
3045
|
{
|
|
1976
3046
|
className: "dsh-better-left-sidebar-preview-canvas",
|
|
1977
3047
|
role: "img",
|
|
1978
3048
|
"aria-label": `${t("brand")}: ${brandLabel(t, preferences.brandPosition)}; ${t("globalNavigation")}: ${globalLabel(t, preferences.globalNavigationPosition)}; ${t("tools")}: ${toolsLabel(t, preferences.toolsPosition)}`
|
|
1979
3049
|
},
|
|
1980
|
-
(0,
|
|
3050
|
+
(0, import_react3.createElement)(
|
|
1981
3051
|
"div",
|
|
1982
3052
|
{ className: "dsh-better-left-sidebar-preview-rail" },
|
|
1983
|
-
preferences.brandPosition === "navigation-top" ? (0,
|
|
1984
|
-
preferences.globalNavigationPosition === "rail" ? (0,
|
|
1985
|
-
preferences.toolsPosition === "rail-bottom" ? (0,
|
|
3053
|
+
preferences.brandPosition === "navigation-top" ? (0, import_react3.createElement)(PreviewBlock, { kind: "brand", label: t("previewBrand") }) : null,
|
|
3054
|
+
preferences.globalNavigationPosition === "rail" ? (0, import_react3.createElement)(PreviewBlock, { kind: "navigation", label: t("previewNavigation") }) : null,
|
|
3055
|
+
preferences.toolsPosition === "rail-bottom" ? (0, import_react3.createElement)(PreviewBlock, { kind: "tools", label: t("previewTools") }) : null
|
|
1986
3056
|
),
|
|
1987
|
-
(0,
|
|
3057
|
+
(0, import_react3.createElement)(
|
|
1988
3058
|
"div",
|
|
1989
3059
|
{ className: "dsh-better-left-sidebar-preview-conversation" },
|
|
1990
|
-
preferences.brandPosition === "sidebar-top" ? (0,
|
|
1991
|
-
(0,
|
|
1992
|
-
preferences.globalNavigationPosition === "conversation-top" ? (0,
|
|
1993
|
-
(0,
|
|
1994
|
-
preferences.toolsPosition === "conversation-bottom" ? (0,
|
|
3060
|
+
preferences.brandPosition === "sidebar-top" ? (0, import_react3.createElement)(PreviewBlock, { kind: "brand", label: t("previewBrand") }) : null,
|
|
3061
|
+
(0, import_react3.createElement)("div", { className: "dsh-better-left-sidebar-preview-session" }, t("previewNewSession")),
|
|
3062
|
+
preferences.globalNavigationPosition === "conversation-top" ? (0, import_react3.createElement)(PreviewBlock, { kind: "navigation", label: t("previewNavigation") }) : null,
|
|
3063
|
+
(0, import_react3.createElement)("div", { className: "dsh-better-left-sidebar-preview-list" }, t("previewConversations")),
|
|
3064
|
+
preferences.toolsPosition === "conversation-bottom" ? (0, import_react3.createElement)(PreviewBlock, { kind: "tools", label: t("previewTools") }) : null
|
|
1995
3065
|
),
|
|
1996
|
-
preferences.brandPosition === "hidden" ? (0,
|
|
3066
|
+
preferences.brandPosition === "hidden" ? (0, import_react3.createElement)("div", { className: "dsh-better-left-sidebar-preview-hidden" }, `${t("previewBrand")} \xB7 ${t("hidden")}`) : null
|
|
1997
3067
|
)
|
|
1998
3068
|
);
|
|
1999
3069
|
}
|
|
@@ -2007,7 +3077,207 @@ function toolsLabel(t, value) {
|
|
|
2007
3077
|
return t(value === "rail-bottom" ? "railBottom" : "conversationBottom");
|
|
2008
3078
|
}
|
|
2009
3079
|
function PreviewBlock(props) {
|
|
2010
|
-
return (0,
|
|
3080
|
+
return (0, import_react3.createElement)("div", { className: `dsh-better-left-sidebar-preview-block is-${props.kind}` }, props.label);
|
|
3081
|
+
}
|
|
3082
|
+
|
|
3083
|
+
// src/client/compact-widgets.tsx
|
|
3084
|
+
var import_react4 = require("react");
|
|
3085
|
+
var import_react_dom = require("react-dom");
|
|
3086
|
+
var SLOT = "dsh-better-left-sidebar.footer.compact";
|
|
3087
|
+
var HOST_ID = "dsh-better-left-sidebar.compact-host";
|
|
3088
|
+
function connectCompactWidgets(ctx, onChange) {
|
|
3089
|
+
const container = document.createElement("div");
|
|
3090
|
+
container.dataset.dshBetterLeftSidebarRegion = "compact-widgets";
|
|
3091
|
+
container.dataset.dshBetterLeftSidebarCompactWidgets = "";
|
|
3092
|
+
let active = true;
|
|
3093
|
+
let count = 0;
|
|
3094
|
+
let preferences = [];
|
|
3095
|
+
let clockDisplay = DEFAULT_CLOCK_DISPLAY;
|
|
3096
|
+
let surfaceVersion = 0;
|
|
3097
|
+
let disposed = false;
|
|
3098
|
+
const surfaceListeners = /* @__PURE__ */ new Set();
|
|
3099
|
+
const subscribeSurface = (listener) => {
|
|
3100
|
+
surfaceListeners.add(listener);
|
|
3101
|
+
return () => surfaceListeners.delete(listener);
|
|
3102
|
+
};
|
|
3103
|
+
const getSurfaceVersion = () => surfaceVersion;
|
|
3104
|
+
const publishSurface = () => {
|
|
3105
|
+
surfaceVersion += 1;
|
|
3106
|
+
for (const listener of surfaceListeners) listener();
|
|
3107
|
+
};
|
|
3108
|
+
const setActive = (next) => {
|
|
3109
|
+
if (disposed || active === next) return;
|
|
3110
|
+
active = next;
|
|
3111
|
+
container.hidden = !next;
|
|
3112
|
+
container.inert = !next;
|
|
3113
|
+
publishSurface();
|
|
3114
|
+
onChange(count, active);
|
|
3115
|
+
};
|
|
3116
|
+
container.hidden = false;
|
|
3117
|
+
container.inert = false;
|
|
3118
|
+
const entries = () => ctx.slots.entriesOfSlot(SLOT);
|
|
3119
|
+
const failures = /* @__PURE__ */ new Map();
|
|
3120
|
+
const metadata = (entry, registrationIndex, error) => {
|
|
3121
|
+
const id = entry.options.id;
|
|
3122
|
+
if (typeof id !== "string") return void 0;
|
|
3123
|
+
let label = id;
|
|
3124
|
+
try {
|
|
3125
|
+
const value = entry.options.label;
|
|
3126
|
+
const resolved = typeof value === "function" ? value() : value;
|
|
3127
|
+
if (typeof resolved === "string" && resolved.length > 0) label = resolved;
|
|
3128
|
+
} catch {
|
|
3129
|
+
}
|
|
3130
|
+
const box = [...container.children].find((child) => child.getAttribute("data-dsh-better-left-sidebar-compact-widget") === id);
|
|
3131
|
+
const enabled = preferences.find((item) => item.id === id)?.enabled ?? true;
|
|
3132
|
+
const presentation = !enabled ? "disabled" : !active ? "inactive" : !box ? "enabled" : box.getBoundingClientRect().height === 0 ? "empty" : box.hasAttribute("data-dsh-better-left-sidebar-compact-widget-clipped") ? "clipped" : "shown";
|
|
3133
|
+
const result = {
|
|
3134
|
+
presentation,
|
|
3135
|
+
id,
|
|
3136
|
+
label,
|
|
3137
|
+
order: typeof entry.options.order === "number" && Number.isFinite(entry.options.order) ? entry.options.order : 0,
|
|
3138
|
+
registrationIndex
|
|
3139
|
+
};
|
|
3140
|
+
if (error !== void 0) result.error = error;
|
|
3141
|
+
return result;
|
|
3142
|
+
};
|
|
3143
|
+
const refreshFailures = () => {
|
|
3144
|
+
const registered = new Set(ctx.slots.entries(SLOT));
|
|
3145
|
+
const live = new Map(entries().flatMap((entry) => typeof entry.options.id === "string" ? [[entry.options.id, entry]] : []));
|
|
3146
|
+
for (const [id, failure] of failures) {
|
|
3147
|
+
const replacement = live.get(id);
|
|
3148
|
+
if (!registered.has(failure.entry) || replacement && replacement !== failure.entry) failures.delete(id);
|
|
3149
|
+
}
|
|
3150
|
+
};
|
|
3151
|
+
const getCatalog = () => {
|
|
3152
|
+
const all = ctx.slots.entries(SLOT);
|
|
3153
|
+
const live = entries();
|
|
3154
|
+
const visible = live.flatMap((entry) => {
|
|
3155
|
+
const index = all.indexOf(entry);
|
|
3156
|
+
const item = metadata(entry, index < 0 ? all.length : index);
|
|
3157
|
+
return item ? [item] : [];
|
|
3158
|
+
});
|
|
3159
|
+
const liveIds = new Set(visible.map((entry) => entry.id));
|
|
3160
|
+
const failed = [...failures].flatMap(([id, failure]) => {
|
|
3161
|
+
if (liveIds.has(id)) return [];
|
|
3162
|
+
const index = all.indexOf(failure.entry);
|
|
3163
|
+
const item = metadata(failure.entry, index < 0 ? all.length : index, failure.message);
|
|
3164
|
+
return item ? [item] : [];
|
|
3165
|
+
});
|
|
3166
|
+
return [...visible, ...failed].sort((a, b) => a.registrationIndex - b.registrationIndex);
|
|
3167
|
+
};
|
|
3168
|
+
let presentationSnapshot = "";
|
|
3169
|
+
const publishPresentation = () => {
|
|
3170
|
+
const next = JSON.stringify(getCatalog().map(({ id, presentation }) => [id, presentation]));
|
|
3171
|
+
if (next === presentationSnapshot) return;
|
|
3172
|
+
presentationSnapshot = next;
|
|
3173
|
+
publishSurface();
|
|
3174
|
+
};
|
|
3175
|
+
const presentationObserver = new MutationObserver(publishPresentation);
|
|
3176
|
+
const presentationResize = new ResizeObserver(publishPresentation);
|
|
3177
|
+
presentationResize.observe(container);
|
|
3178
|
+
presentationObserver.observe(container, {
|
|
3179
|
+
childList: true,
|
|
3180
|
+
subtree: true,
|
|
3181
|
+
attributes: true,
|
|
3182
|
+
attributeFilter: ["data-dsh-better-left-sidebar-compact-widget-clipped"]
|
|
3183
|
+
});
|
|
3184
|
+
const getCatalogVersion = () => surfaceVersion;
|
|
3185
|
+
const orderedEntries = () => orderCompactWidgetEntries(
|
|
3186
|
+
entries().flatMap((entry) => typeof entry.options.id === "string" ? [{ id: entry.options.id, order: entry.options.order, entry }] : []),
|
|
3187
|
+
preferences
|
|
3188
|
+
);
|
|
3189
|
+
const readCount = () => orderedEntries().filter(({ enabled }) => enabled).length;
|
|
3190
|
+
const publishCount = () => {
|
|
3191
|
+
count = readCount();
|
|
3192
|
+
onChange(count, active);
|
|
3193
|
+
};
|
|
3194
|
+
const publishEntries = () => {
|
|
3195
|
+
refreshFailures();
|
|
3196
|
+
publishSurface();
|
|
3197
|
+
publishCount();
|
|
3198
|
+
};
|
|
3199
|
+
const unsubscribeEntries = ctx.slots.subscribe(SLOT, publishEntries);
|
|
3200
|
+
const unsubscribeErrors = ctx.slots.onEntryError((key, registration, error) => {
|
|
3201
|
+
if (key !== SLOT || !("options" in registration) || typeof registration.options.id !== "string") return;
|
|
3202
|
+
const entry = registration;
|
|
3203
|
+
failures.set(entry.options.id, {
|
|
3204
|
+
entry,
|
|
3205
|
+
message: error instanceof Error ? error.message : String(error)
|
|
3206
|
+
});
|
|
3207
|
+
publishSurface();
|
|
3208
|
+
});
|
|
3209
|
+
publishEntries();
|
|
3210
|
+
const subscribe = (listener) => ctx.slots.subscribe(SLOT, listener);
|
|
3211
|
+
const getVersion = () => ctx.slots.getVersion(SLOT);
|
|
3212
|
+
function CompactHost(props) {
|
|
3213
|
+
(0, import_react4.useSyncExternalStore)(subscribe, getVersion, getVersion);
|
|
3214
|
+
(0, import_react4.useSyncExternalStore)(subscribeSurface, getSurfaceVersion, getSurfaceVersion);
|
|
3215
|
+
const ordered = orderedEntries().filter(({ enabled }) => enabled);
|
|
3216
|
+
return (0, import_react_dom.createPortal)((0, import_react4.createElement)(import_react4.Fragment, null, ...ordered.map(({ entry, enabled: _enabled }) => {
|
|
3217
|
+
const id = entry.id;
|
|
3218
|
+
return (0, import_react4.createElement)("div", {
|
|
3219
|
+
key: id,
|
|
3220
|
+
className: "dsh-better-left-sidebar-compact-widget-box",
|
|
3221
|
+
"data-dsh-better-left-sidebar-compact-widget": id
|
|
3222
|
+
}, props.renderSlot(SLOT, { active }, { only: id }));
|
|
3223
|
+
})), container);
|
|
3224
|
+
}
|
|
3225
|
+
const stopHost = ctx.slots.inject("sidebar.footer.action", () => ctx.slots.register({
|
|
3226
|
+
name: "sidebar.footer.action",
|
|
3227
|
+
id: HOST_ID,
|
|
3228
|
+
label: "Compact footer widgets",
|
|
3229
|
+
order: 0,
|
|
3230
|
+
children: {
|
|
3231
|
+
[SLOT]: { kind: "list", scope: "root" }
|
|
3232
|
+
}
|
|
3233
|
+
}, CompactHost));
|
|
3234
|
+
const stopClock = ctx.slots.inject(SLOT, () => ctx.slots.register({
|
|
3235
|
+
name: SLOT,
|
|
3236
|
+
id: CLOCK_WIDGET_ID,
|
|
3237
|
+
label: () => ctx.locale.bind(NAMESPACE)("clock"),
|
|
3238
|
+
order: 100
|
|
3239
|
+
}, createClockWidget(ctx.locale, {
|
|
3240
|
+
subscribe: subscribeSurface,
|
|
3241
|
+
getSnapshot: () => clockDisplay
|
|
3242
|
+
})));
|
|
3243
|
+
return {
|
|
3244
|
+
container,
|
|
3245
|
+
get count() {
|
|
3246
|
+
return count;
|
|
3247
|
+
},
|
|
3248
|
+
get active() {
|
|
3249
|
+
return active;
|
|
3250
|
+
},
|
|
3251
|
+
setActive,
|
|
3252
|
+
setPreferences(next) {
|
|
3253
|
+
if (disposed) return;
|
|
3254
|
+
preferences = next;
|
|
3255
|
+
publishSurface();
|
|
3256
|
+
publishCount();
|
|
3257
|
+
},
|
|
3258
|
+
setClock(next) {
|
|
3259
|
+
if (disposed) return;
|
|
3260
|
+
const normalized = normalizeClockDisplay(next);
|
|
3261
|
+
if (normalized.hourCycle === clockDisplay.hourCycle && normalized.monthDay === clockDisplay.monthDay && normalized.weekday === clockDisplay.weekday && normalized.color === clockDisplay.color) return;
|
|
3262
|
+
clockDisplay = normalized;
|
|
3263
|
+
publishSurface();
|
|
3264
|
+
},
|
|
3265
|
+
subscribeCatalog: subscribeSurface,
|
|
3266
|
+
getCatalogVersion,
|
|
3267
|
+
getCatalog,
|
|
3268
|
+
dispose() {
|
|
3269
|
+
if (disposed) return;
|
|
3270
|
+
disposed = true;
|
|
3271
|
+
presentationObserver.disconnect();
|
|
3272
|
+
presentationResize.disconnect();
|
|
3273
|
+
stopClock();
|
|
3274
|
+
stopHost();
|
|
3275
|
+
unsubscribeEntries();
|
|
3276
|
+
unsubscribeErrors();
|
|
3277
|
+
surfaceListeners.clear();
|
|
3278
|
+
container.remove();
|
|
3279
|
+
}
|
|
3280
|
+
};
|
|
2011
3281
|
}
|
|
2012
3282
|
|
|
2013
3283
|
// src/client/index.ts
|
|
@@ -2023,9 +3293,16 @@ function apply(ctx) {
|
|
|
2023
3293
|
document.head.append(style);
|
|
2024
3294
|
html.classList.add("dsh-better-left-sidebar");
|
|
2025
3295
|
const interaction = connectInteraction();
|
|
2026
|
-
|
|
3296
|
+
let layout;
|
|
3297
|
+
const compactWidgets = connectCompactWidgets(ctx, (count, active) => layout?.setCompactWidgets(count, active));
|
|
3298
|
+
interaction.setCompactWidgetsActive(compactWidgets.setActive);
|
|
3299
|
+
layout = connectLayoutAdapter((root, anchorsChanged) => interaction.setRoot(root, anchorsChanged), compactWidgets.container);
|
|
3300
|
+
layout.setCompactWidgets(compactWidgets.count, compactWidgets.active);
|
|
2027
3301
|
const applyPreferences = (value) => {
|
|
2028
3302
|
preferences = normalizePreferences(value);
|
|
3303
|
+
const config = value && typeof value === "object" ? value : {};
|
|
3304
|
+
compactWidgets.setPreferences(validateCompactWidgetPreferences(config.compactWidgets));
|
|
3305
|
+
compactWidgets.setClock(normalizeClockDisplay(config.clock));
|
|
2029
3306
|
layout.update(preferences);
|
|
2030
3307
|
interaction.setPreferences(preferences);
|
|
2031
3308
|
};
|
|
@@ -2036,10 +3313,11 @@ function apply(ctx) {
|
|
|
2036
3313
|
applyPreferences(DEFAULT_PREFERENCES);
|
|
2037
3314
|
interaction.setTranslate(translate);
|
|
2038
3315
|
const disposeNavigation = connectNavigation(ctx);
|
|
2039
|
-
connectSettings(ctx, applyPreferences, applyTranslate);
|
|
3316
|
+
connectSettings(ctx, compactWidgets, applyPreferences, applyTranslate);
|
|
2040
3317
|
return () => {
|
|
2041
3318
|
disposeNavigation();
|
|
2042
3319
|
layout.dispose();
|
|
3320
|
+
compactWidgets.dispose();
|
|
2043
3321
|
interaction.dispose();
|
|
2044
3322
|
html.classList.remove("dsh-better-left-sidebar");
|
|
2045
3323
|
style.remove();
|