@gallop.software/studio 0.1.22 → 0.1.23
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/dist/{StudioUI-TPVIV5T7.js → StudioUI-2BWLIO4W.js} +423 -478
- package/dist/StudioUI-2BWLIO4W.js.map +1 -0
- package/dist/{StudioUI-3VFEM3VE.mjs → StudioUI-QPAHJJ64.mjs} +538 -593
- package/dist/StudioUI-QPAHJJ64.mjs.map +1 -0
- package/dist/handlers.d.mts +4 -0
- package/dist/handlers.d.ts +4 -0
- package/dist/handlers.js +13 -4
- package/dist/handlers.js.map +1 -1
- package/dist/handlers.mjs +13 -4
- package/dist/handlers.mjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/dist/StudioUI-3VFEM3VE.mjs.map +0 -1
- package/dist/StudioUI-TPVIV5T7.js.map +0 -1
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
|
|
9
9
|
// src/components/StudioUI.tsx
|
|
10
10
|
import { useEffect as useEffect3, useCallback as useCallback2, useState as useState6 } from "react";
|
|
11
|
-
import { css as
|
|
11
|
+
import { css as css7 } from "@emotion/react";
|
|
12
12
|
|
|
13
13
|
// src/components/StudioContext.tsx
|
|
14
14
|
import { createContext, useContext } from "react";
|
|
@@ -38,6 +38,9 @@ var defaultState = {
|
|
|
38
38
|
viewMode: "grid",
|
|
39
39
|
setViewMode: () => {
|
|
40
40
|
},
|
|
41
|
+
focusedItem: null,
|
|
42
|
+
setFocusedItem: () => {
|
|
43
|
+
},
|
|
41
44
|
meta: null,
|
|
42
45
|
setMeta: () => {
|
|
43
46
|
},
|
|
@@ -204,6 +207,7 @@ function AlertModal({
|
|
|
204
207
|
|
|
205
208
|
// src/components/StudioToolbar.tsx
|
|
206
209
|
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "@emotion/react/jsx-runtime";
|
|
210
|
+
var btnHeight = "36px";
|
|
207
211
|
var spin = keyframes2`
|
|
208
212
|
to { transform: rotate(360deg); }
|
|
209
213
|
`;
|
|
@@ -224,13 +228,15 @@ var styles2 = {
|
|
|
224
228
|
right: css2`
|
|
225
229
|
display: flex;
|
|
226
230
|
align-items: center;
|
|
227
|
-
gap:
|
|
231
|
+
gap: 8px;
|
|
228
232
|
`,
|
|
229
233
|
btn: css2`
|
|
230
234
|
display: inline-flex;
|
|
231
235
|
align-items: center;
|
|
236
|
+
justify-content: center;
|
|
232
237
|
gap: 6px;
|
|
233
|
-
|
|
238
|
+
height: ${btnHeight};
|
|
239
|
+
padding: 0 14px;
|
|
234
240
|
border-radius: 6px;
|
|
235
241
|
font-size: ${fontSize.base};
|
|
236
242
|
font-weight: 500;
|
|
@@ -251,6 +257,9 @@ var styles2 = {
|
|
|
251
257
|
opacity: 0.5;
|
|
252
258
|
}
|
|
253
259
|
`,
|
|
260
|
+
btnIconOnly: css2`
|
|
261
|
+
padding: 0 10px;
|
|
262
|
+
`,
|
|
254
263
|
btnPrimary: css2`
|
|
255
264
|
background: ${colors.primary};
|
|
256
265
|
border-color: ${colors.primary};
|
|
@@ -270,8 +279,8 @@ var styles2 = {
|
|
|
270
279
|
}
|
|
271
280
|
`,
|
|
272
281
|
icon: css2`
|
|
273
|
-
width:
|
|
274
|
-
height:
|
|
282
|
+
width: 16px;
|
|
283
|
+
height: 16px;
|
|
275
284
|
`,
|
|
276
285
|
iconSpin: css2`
|
|
277
286
|
animation: ${spin} 1s linear infinite;
|
|
@@ -282,6 +291,7 @@ var styles2 = {
|
|
|
282
291
|
display: flex;
|
|
283
292
|
align-items: center;
|
|
284
293
|
gap: 8px;
|
|
294
|
+
margin-right: 8px;
|
|
285
295
|
`,
|
|
286
296
|
clearBtn: css2`
|
|
287
297
|
color: ${colors.primary};
|
|
@@ -305,16 +315,17 @@ var styles2 = {
|
|
|
305
315
|
viewToggle: css2`
|
|
306
316
|
display: flex;
|
|
307
317
|
align-items: center;
|
|
308
|
-
|
|
318
|
+
height: ${btnHeight};
|
|
319
|
+
background-color: ${colors.surface};
|
|
309
320
|
border: 1px solid ${colors.border};
|
|
310
321
|
border-radius: 6px;
|
|
311
|
-
|
|
322
|
+
overflow: hidden;
|
|
312
323
|
`,
|
|
313
324
|
viewBtn: css2`
|
|
314
|
-
|
|
325
|
+
height: 100%;
|
|
326
|
+
padding: 0 10px;
|
|
315
327
|
background: transparent;
|
|
316
328
|
border: none;
|
|
317
|
-
border-radius: 4px;
|
|
318
329
|
cursor: pointer;
|
|
319
330
|
color: ${colors.textSecondary};
|
|
320
331
|
transition: all 0.15s ease;
|
|
@@ -324,16 +335,16 @@ var styles2 = {
|
|
|
324
335
|
|
|
325
336
|
&:hover {
|
|
326
337
|
color: ${colors.text};
|
|
338
|
+
background-color: ${colors.surfaceHover};
|
|
327
339
|
}
|
|
328
340
|
`,
|
|
329
341
|
viewBtnActive: css2`
|
|
330
|
-
background-color: ${colors.
|
|
342
|
+
background-color: ${colors.background};
|
|
331
343
|
color: ${colors.text};
|
|
332
|
-
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
|
|
333
344
|
`
|
|
334
345
|
};
|
|
335
346
|
function StudioToolbar() {
|
|
336
|
-
const { selectedItems, viewMode, setViewMode, clearSelection, currentPath, triggerRefresh } = useStudio();
|
|
347
|
+
const { selectedItems, viewMode, setViewMode, clearSelection, currentPath, triggerRefresh, focusedItem } = useStudio();
|
|
337
348
|
const fileInputRef = useRef(null);
|
|
338
349
|
const [uploading, setUploading] = useState(false);
|
|
339
350
|
const [refreshing, setRefreshing] = useState(false);
|
|
@@ -431,6 +442,9 @@ function StudioToolbar() {
|
|
|
431
442
|
console.log("Scan clicked");
|
|
432
443
|
}, []);
|
|
433
444
|
const hasSelection = selectedItems.size > 0;
|
|
445
|
+
if (focusedItem) {
|
|
446
|
+
return null;
|
|
447
|
+
}
|
|
434
448
|
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
435
449
|
showDeleteConfirm && /* @__PURE__ */ jsx2(
|
|
436
450
|
ConfirmModal,
|
|
@@ -527,7 +541,7 @@ function StudioToolbar() {
|
|
|
527
541
|
/* @__PURE__ */ jsx2(
|
|
528
542
|
"button",
|
|
529
543
|
{
|
|
530
|
-
css: styles2.btn,
|
|
544
|
+
css: [styles2.btn, styles2.btnIconOnly],
|
|
531
545
|
onClick: handleRefresh,
|
|
532
546
|
children: /* @__PURE__ */ jsx2(RefreshIcon, { spinning: refreshing })
|
|
533
547
|
}
|
|
@@ -578,118 +592,21 @@ function ListIcon() {
|
|
|
578
592
|
return /* @__PURE__ */ jsx2("svg", { css: styles2.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx2("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 10h16M4 14h16M4 18h16" }) });
|
|
579
593
|
}
|
|
580
594
|
|
|
581
|
-
// src/components/StudioBreadcrumb.tsx
|
|
582
|
-
import { css as css3 } from "@emotion/react";
|
|
583
|
-
import { jsx as jsx3, jsxs as jsxs3 } from "@emotion/react/jsx-runtime";
|
|
584
|
-
var styles3 = {
|
|
585
|
-
container: css3`
|
|
586
|
-
display: flex;
|
|
587
|
-
align-items: center;
|
|
588
|
-
gap: 8px;
|
|
589
|
-
padding: 10px 24px;
|
|
590
|
-
background-color: ${colors.surface};
|
|
591
|
-
border-bottom: 1px solid ${colors.borderLight};
|
|
592
|
-
`,
|
|
593
|
-
backBtn: css3`
|
|
594
|
-
padding: 6px;
|
|
595
|
-
background: ${colors.surface};
|
|
596
|
-
border: 1px solid ${colors.border};
|
|
597
|
-
border-radius: 6px;
|
|
598
|
-
cursor: pointer;
|
|
599
|
-
transition: all 0.15s ease;
|
|
600
|
-
display: flex;
|
|
601
|
-
align-items: center;
|
|
602
|
-
justify-content: center;
|
|
603
|
-
|
|
604
|
-
&:hover {
|
|
605
|
-
background-color: ${colors.surfaceHover};
|
|
606
|
-
border-color: ${colors.borderHover};
|
|
607
|
-
}
|
|
608
|
-
`,
|
|
609
|
-
backIcon: css3`
|
|
610
|
-
width: 16px;
|
|
611
|
-
height: 16px;
|
|
612
|
-
color: ${colors.textSecondary};
|
|
613
|
-
`,
|
|
614
|
-
nav: css3`
|
|
615
|
-
display: flex;
|
|
616
|
-
align-items: center;
|
|
617
|
-
gap: 2px;
|
|
618
|
-
font-size: ${fontSize.base};
|
|
619
|
-
`,
|
|
620
|
-
item: css3`
|
|
621
|
-
display: flex;
|
|
622
|
-
align-items: center;
|
|
623
|
-
gap: 2px;
|
|
624
|
-
`,
|
|
625
|
-
separator: css3`
|
|
626
|
-
color: ${colors.textMuted};
|
|
627
|
-
margin: 0 2px;
|
|
628
|
-
`,
|
|
629
|
-
btn: css3`
|
|
630
|
-
padding: 4px 8px;
|
|
631
|
-
background: none;
|
|
632
|
-
border: none;
|
|
633
|
-
border-radius: 4px;
|
|
634
|
-
cursor: pointer;
|
|
635
|
-
transition: all 0.15s ease;
|
|
636
|
-
font-size: ${fontSize.base};
|
|
637
|
-
letter-spacing: -0.01em;
|
|
638
|
-
|
|
639
|
-
&:hover {
|
|
640
|
-
background-color: ${colors.surfaceHover};
|
|
641
|
-
}
|
|
642
|
-
`,
|
|
643
|
-
btnActive: css3`
|
|
644
|
-
color: ${colors.text};
|
|
645
|
-
font-weight: 600;
|
|
646
|
-
`,
|
|
647
|
-
btnInactive: css3`
|
|
648
|
-
color: ${colors.textSecondary};
|
|
649
|
-
|
|
650
|
-
&:hover {
|
|
651
|
-
color: ${colors.text};
|
|
652
|
-
}
|
|
653
|
-
`
|
|
654
|
-
};
|
|
655
|
-
function StudioBreadcrumb() {
|
|
656
|
-
const { currentPath, setCurrentPath, navigateUp } = useStudio();
|
|
657
|
-
const parts = currentPath.split("/").filter(Boolean);
|
|
658
|
-
const handleClick = (index) => {
|
|
659
|
-
const newPath = parts.slice(0, index + 1).join("/");
|
|
660
|
-
setCurrentPath(newPath);
|
|
661
|
-
};
|
|
662
|
-
return /* @__PURE__ */ jsxs3("div", { css: styles3.container, children: [
|
|
663
|
-
currentPath !== "public" && /* @__PURE__ */ jsx3("button", { css: styles3.backBtn, onClick: navigateUp, "aria-label": "Go back", children: /* @__PURE__ */ jsx3("svg", { css: styles3.backIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) }) }),
|
|
664
|
-
/* @__PURE__ */ jsx3("nav", { css: styles3.nav, children: parts.map((part, index) => /* @__PURE__ */ jsxs3("span", { css: styles3.item, children: [
|
|
665
|
-
index > 0 && /* @__PURE__ */ jsx3("span", { css: styles3.separator, children: "/" }),
|
|
666
|
-
/* @__PURE__ */ jsx3(
|
|
667
|
-
"button",
|
|
668
|
-
{
|
|
669
|
-
css: [styles3.btn, index === parts.length - 1 ? styles3.btnActive : styles3.btnInactive],
|
|
670
|
-
onClick: () => handleClick(index),
|
|
671
|
-
children: part
|
|
672
|
-
}
|
|
673
|
-
)
|
|
674
|
-
] }, index)) })
|
|
675
|
-
] });
|
|
676
|
-
}
|
|
677
|
-
|
|
678
595
|
// src/components/StudioFileGrid.tsx
|
|
679
596
|
import { useEffect, useState as useState2 } from "react";
|
|
680
|
-
import { css as
|
|
681
|
-
import { jsx as
|
|
597
|
+
import { css as css3, keyframes as keyframes3 } from "@emotion/react";
|
|
598
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "@emotion/react/jsx-runtime";
|
|
682
599
|
var spin2 = keyframes3`
|
|
683
600
|
to { transform: rotate(360deg); }
|
|
684
601
|
`;
|
|
685
|
-
var
|
|
686
|
-
loading:
|
|
602
|
+
var styles3 = {
|
|
603
|
+
loading: css3`
|
|
687
604
|
display: flex;
|
|
688
605
|
align-items: center;
|
|
689
606
|
justify-content: center;
|
|
690
607
|
height: 256px;
|
|
691
608
|
`,
|
|
692
|
-
spinner:
|
|
609
|
+
spinner: css3`
|
|
693
610
|
width: 32px;
|
|
694
611
|
height: 32px;
|
|
695
612
|
border-radius: 50%;
|
|
@@ -697,7 +614,7 @@ var styles4 = {
|
|
|
697
614
|
border-top-color: ${colors.primary};
|
|
698
615
|
animation: ${spin2} 0.8s linear infinite;
|
|
699
616
|
`,
|
|
700
|
-
empty:
|
|
617
|
+
empty: css3`
|
|
701
618
|
display: flex;
|
|
702
619
|
flex-direction: column;
|
|
703
620
|
align-items: center;
|
|
@@ -705,13 +622,13 @@ var styles4 = {
|
|
|
705
622
|
height: 256px;
|
|
706
623
|
color: ${colors.textSecondary};
|
|
707
624
|
`,
|
|
708
|
-
emptyIcon:
|
|
625
|
+
emptyIcon: css3`
|
|
709
626
|
width: 48px;
|
|
710
627
|
height: 48px;
|
|
711
628
|
margin-bottom: 16px;
|
|
712
629
|
opacity: 0.5;
|
|
713
630
|
`,
|
|
714
|
-
emptyText:
|
|
631
|
+
emptyText: css3`
|
|
715
632
|
font-size: ${fontSize.base};
|
|
716
633
|
margin: 0 0 4px 0;
|
|
717
634
|
|
|
@@ -720,7 +637,7 @@ var styles4 = {
|
|
|
720
637
|
font-size: ${fontSize.sm};
|
|
721
638
|
}
|
|
722
639
|
`,
|
|
723
|
-
grid:
|
|
640
|
+
grid: css3`
|
|
724
641
|
display: grid;
|
|
725
642
|
grid-template-columns: repeat(2, 1fr);
|
|
726
643
|
gap: 12px;
|
|
@@ -730,7 +647,7 @@ var styles4 = {
|
|
|
730
647
|
@media (min-width: 1024px) { grid-template-columns: repeat(5, 1fr); }
|
|
731
648
|
@media (min-width: 1280px) { grid-template-columns: repeat(6, 1fr); }
|
|
732
649
|
`,
|
|
733
|
-
item:
|
|
650
|
+
item: css3`
|
|
734
651
|
position: relative;
|
|
735
652
|
border-radius: 8px;
|
|
736
653
|
border: 1px solid ${colors.border};
|
|
@@ -746,7 +663,7 @@ var styles4 = {
|
|
|
746
663
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.06);
|
|
747
664
|
}
|
|
748
665
|
`,
|
|
749
|
-
itemSelected:
|
|
666
|
+
itemSelected: css3`
|
|
750
667
|
border-color: ${colors.primary};
|
|
751
668
|
box-shadow: 0 0 0 1px ${colors.primary};
|
|
752
669
|
|
|
@@ -754,7 +671,14 @@ var styles4 = {
|
|
|
754
671
|
border-color: ${colors.primary};
|
|
755
672
|
}
|
|
756
673
|
`,
|
|
757
|
-
|
|
674
|
+
parentItem: css3`
|
|
675
|
+
cursor: pointer;
|
|
676
|
+
|
|
677
|
+
&:hover {
|
|
678
|
+
border-color: ${colors.primary};
|
|
679
|
+
}
|
|
680
|
+
`,
|
|
681
|
+
checkboxWrapper: css3`
|
|
758
682
|
position: absolute;
|
|
759
683
|
top: 0;
|
|
760
684
|
left: 0;
|
|
@@ -762,13 +686,13 @@ var styles4 = {
|
|
|
762
686
|
padding: 8px;
|
|
763
687
|
cursor: pointer;
|
|
764
688
|
`,
|
|
765
|
-
checkbox:
|
|
689
|
+
checkbox: css3`
|
|
766
690
|
width: 16px;
|
|
767
691
|
height: 16px;
|
|
768
692
|
accent-color: ${colors.primary};
|
|
769
693
|
cursor: pointer;
|
|
770
694
|
`,
|
|
771
|
-
cdnBadge:
|
|
695
|
+
cdnBadge: css3`
|
|
772
696
|
position: absolute;
|
|
773
697
|
top: 8px;
|
|
774
698
|
right: 8px;
|
|
@@ -780,7 +704,7 @@ var styles4 = {
|
|
|
780
704
|
padding: 2px 8px;
|
|
781
705
|
border-radius: 4px;
|
|
782
706
|
`,
|
|
783
|
-
content:
|
|
707
|
+
content: css3`
|
|
784
708
|
aspect-ratio: 1;
|
|
785
709
|
display: flex;
|
|
786
710
|
align-items: center;
|
|
@@ -788,38 +712,43 @@ var styles4 = {
|
|
|
788
712
|
padding: 16px;
|
|
789
713
|
background: ${colors.background};
|
|
790
714
|
`,
|
|
791
|
-
folderIcon:
|
|
715
|
+
folderIcon: css3`
|
|
792
716
|
width: 56px;
|
|
793
717
|
height: 56px;
|
|
794
718
|
color: #f5a623;
|
|
795
719
|
`,
|
|
796
|
-
|
|
720
|
+
parentIcon: css3`
|
|
721
|
+
width: 56px;
|
|
722
|
+
height: 56px;
|
|
723
|
+
color: ${colors.textMuted};
|
|
724
|
+
`,
|
|
725
|
+
fileIcon: css3`
|
|
797
726
|
width: 40px;
|
|
798
727
|
height: 40px;
|
|
799
728
|
color: ${colors.textMuted};
|
|
800
729
|
`,
|
|
801
|
-
image:
|
|
730
|
+
image: css3`
|
|
802
731
|
max-width: 100%;
|
|
803
732
|
max-height: 100%;
|
|
804
733
|
object-fit: contain;
|
|
805
734
|
border-radius: 4px;
|
|
806
735
|
`,
|
|
807
|
-
label:
|
|
736
|
+
label: css3`
|
|
808
737
|
padding: 10px 12px;
|
|
809
738
|
background-color: ${colors.surface};
|
|
810
739
|
border-top: 1px solid ${colors.borderLight};
|
|
811
740
|
`,
|
|
812
|
-
labelRow:
|
|
741
|
+
labelRow: css3`
|
|
813
742
|
display: flex;
|
|
814
743
|
align-items: center;
|
|
815
744
|
justify-content: space-between;
|
|
816
745
|
gap: 8px;
|
|
817
746
|
`,
|
|
818
|
-
labelText:
|
|
747
|
+
labelText: css3`
|
|
819
748
|
flex: 1;
|
|
820
749
|
min-width: 0;
|
|
821
750
|
`,
|
|
822
|
-
name:
|
|
751
|
+
name: css3`
|
|
823
752
|
font-size: ${fontSize.sm};
|
|
824
753
|
font-weight: 500;
|
|
825
754
|
color: ${colors.text};
|
|
@@ -829,29 +758,32 @@ var styles4 = {
|
|
|
829
758
|
margin: 0;
|
|
830
759
|
letter-spacing: -0.01em;
|
|
831
760
|
`,
|
|
832
|
-
size:
|
|
761
|
+
size: css3`
|
|
833
762
|
font-size: ${fontSize.xs};
|
|
834
763
|
color: ${colors.textMuted};
|
|
835
764
|
margin: 2px 0 0 0;
|
|
836
765
|
`,
|
|
837
|
-
openBtn:
|
|
766
|
+
openBtn: css3`
|
|
838
767
|
flex-shrink: 0;
|
|
768
|
+
height: 28px;
|
|
839
769
|
font-size: ${fontSize.xs};
|
|
840
770
|
font-weight: 500;
|
|
841
771
|
color: ${colors.primary};
|
|
842
772
|
background: ${colors.surface};
|
|
843
773
|
border: 1px solid ${colors.border};
|
|
844
|
-
padding:
|
|
774
|
+
padding: 0 10px;
|
|
845
775
|
cursor: pointer;
|
|
846
776
|
border-radius: 4px;
|
|
847
777
|
transition: all 0.15s ease;
|
|
778
|
+
display: inline-flex;
|
|
779
|
+
align-items: center;
|
|
848
780
|
|
|
849
781
|
&:hover {
|
|
850
782
|
background-color: ${colors.primaryLight};
|
|
851
783
|
border-color: ${colors.primary};
|
|
852
784
|
}
|
|
853
785
|
`,
|
|
854
|
-
selectAllRow:
|
|
786
|
+
selectAllRow: css3`
|
|
855
787
|
display: flex;
|
|
856
788
|
align-items: center;
|
|
857
789
|
margin-bottom: 16px;
|
|
@@ -860,7 +792,7 @@ var styles4 = {
|
|
|
860
792
|
border-radius: 8px;
|
|
861
793
|
border: 1px solid ${colors.border};
|
|
862
794
|
`,
|
|
863
|
-
selectAllLabel:
|
|
795
|
+
selectAllLabel: css3`
|
|
864
796
|
display: flex;
|
|
865
797
|
align-items: center;
|
|
866
798
|
gap: 10px;
|
|
@@ -873,14 +805,14 @@ var styles4 = {
|
|
|
873
805
|
color: ${colors.text};
|
|
874
806
|
}
|
|
875
807
|
`,
|
|
876
|
-
selectAllCheckbox:
|
|
808
|
+
selectAllCheckbox: css3`
|
|
877
809
|
width: 16px;
|
|
878
810
|
height: 16px;
|
|
879
811
|
accent-color: ${colors.primary};
|
|
880
812
|
`
|
|
881
813
|
};
|
|
882
814
|
function StudioFileGrid() {
|
|
883
|
-
const { currentPath, setCurrentPath, selectedItems, toggleSelection, selectRange, lastSelectedPath, selectAll, clearSelection, refreshKey } = useStudio();
|
|
815
|
+
const { currentPath, setCurrentPath, navigateUp, selectedItems, toggleSelection, selectRange, lastSelectedPath, selectAll, clearSelection, refreshKey, setFocusedItem } = useStudio();
|
|
884
816
|
const [items, setItems] = useState2([]);
|
|
885
817
|
const [loading, setLoading] = useState2(true);
|
|
886
818
|
useEffect(() => {
|
|
@@ -900,13 +832,14 @@ function StudioFileGrid() {
|
|
|
900
832
|
loadItems();
|
|
901
833
|
}, [currentPath, refreshKey]);
|
|
902
834
|
if (loading) {
|
|
903
|
-
return /* @__PURE__ */
|
|
835
|
+
return /* @__PURE__ */ jsx3("div", { css: styles3.loading, children: /* @__PURE__ */ jsx3("div", { css: styles3.spinner }) });
|
|
904
836
|
}
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
/* @__PURE__ */
|
|
909
|
-
/* @__PURE__ */
|
|
837
|
+
const isAtRoot = currentPath === "public";
|
|
838
|
+
if (items.length === 0 && isAtRoot) {
|
|
839
|
+
return /* @__PURE__ */ jsxs3("div", { css: styles3.empty, children: [
|
|
840
|
+
/* @__PURE__ */ jsx3("svg", { css: styles3.emptyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
|
|
841
|
+
/* @__PURE__ */ jsx3("p", { css: styles3.emptyText, children: "No files in this folder" }),
|
|
842
|
+
/* @__PURE__ */ jsx3("p", { css: styles3.emptyText, children: "Upload images to get started" })
|
|
910
843
|
] });
|
|
911
844
|
}
|
|
912
845
|
const sortedItems = [...items].sort((a, b) => {
|
|
@@ -921,9 +854,11 @@ function StudioFileGrid() {
|
|
|
921
854
|
toggleSelection(item.path);
|
|
922
855
|
}
|
|
923
856
|
};
|
|
924
|
-
const
|
|
857
|
+
const handleOpen = (item) => {
|
|
925
858
|
if (item.type === "folder") {
|
|
926
859
|
setCurrentPath(item.path);
|
|
860
|
+
} else {
|
|
861
|
+
setFocusedItem(item);
|
|
927
862
|
}
|
|
928
863
|
};
|
|
929
864
|
const allItemsSelected = sortedItems.length > 0 && sortedItems.every((item) => selectedItems.has(item.path));
|
|
@@ -935,13 +870,13 @@ function StudioFileGrid() {
|
|
|
935
870
|
selectAll(sortedItems);
|
|
936
871
|
}
|
|
937
872
|
};
|
|
938
|
-
return /* @__PURE__ */
|
|
939
|
-
sortedItems.length > 0 && /* @__PURE__ */
|
|
940
|
-
/* @__PURE__ */
|
|
873
|
+
return /* @__PURE__ */ jsxs3("div", { children: [
|
|
874
|
+
sortedItems.length > 0 && /* @__PURE__ */ jsx3("div", { css: styles3.selectAllRow, children: /* @__PURE__ */ jsxs3("label", { css: styles3.selectAllLabel, children: [
|
|
875
|
+
/* @__PURE__ */ jsx3(
|
|
941
876
|
"input",
|
|
942
877
|
{
|
|
943
878
|
type: "checkbox",
|
|
944
|
-
css:
|
|
879
|
+
css: styles3.selectAllCheckbox,
|
|
945
880
|
checked: allItemsSelected,
|
|
946
881
|
ref: (el) => {
|
|
947
882
|
if (el) el.indeterminate = someItemsSelected && !allItemsSelected;
|
|
@@ -953,65 +888,81 @@ function StudioFileGrid() {
|
|
|
953
888
|
sortedItems.length,
|
|
954
889
|
")"
|
|
955
890
|
] }) }),
|
|
956
|
-
/* @__PURE__ */
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
891
|
+
/* @__PURE__ */ jsxs3("div", { css: styles3.grid, children: [
|
|
892
|
+
!isAtRoot && /* @__PURE__ */ jsxs3(
|
|
893
|
+
"div",
|
|
894
|
+
{
|
|
895
|
+
css: [styles3.item, styles3.parentItem],
|
|
896
|
+
onClick: navigateUp,
|
|
897
|
+
children: [
|
|
898
|
+
/* @__PURE__ */ jsx3("div", { css: styles3.content, children: /* @__PURE__ */ jsx3("svg", { css: styles3.parentIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" }) }) }),
|
|
899
|
+
/* @__PURE__ */ jsxs3("div", { css: styles3.label, children: [
|
|
900
|
+
/* @__PURE__ */ jsx3("p", { css: styles3.name, children: ".." }),
|
|
901
|
+
/* @__PURE__ */ jsx3("p", { css: styles3.size, children: "Parent folder" })
|
|
902
|
+
] })
|
|
903
|
+
]
|
|
904
|
+
}
|
|
905
|
+
),
|
|
906
|
+
sortedItems.map((item) => /* @__PURE__ */ jsx3(
|
|
907
|
+
GridItem,
|
|
908
|
+
{
|
|
909
|
+
item,
|
|
910
|
+
isSelected: selectedItems.has(item.path),
|
|
911
|
+
onClick: (e) => handleItemClick(item, e),
|
|
912
|
+
onOpen: () => handleOpen(item)
|
|
913
|
+
},
|
|
914
|
+
item.path
|
|
915
|
+
))
|
|
916
|
+
] })
|
|
966
917
|
] });
|
|
967
918
|
}
|
|
968
919
|
function GridItem({ item, isSelected, onClick, onOpen }) {
|
|
969
920
|
const isFolder = item.type === "folder";
|
|
970
|
-
return /* @__PURE__ */
|
|
921
|
+
return /* @__PURE__ */ jsxs3(
|
|
971
922
|
"div",
|
|
972
923
|
{
|
|
973
|
-
css: [
|
|
924
|
+
css: [styles3.item, isSelected && styles3.itemSelected],
|
|
974
925
|
onClick,
|
|
975
926
|
children: [
|
|
976
|
-
/* @__PURE__ */
|
|
927
|
+
/* @__PURE__ */ jsx3(
|
|
977
928
|
"div",
|
|
978
929
|
{
|
|
979
|
-
css:
|
|
930
|
+
css: styles3.checkboxWrapper,
|
|
980
931
|
onClick: (e) => e.stopPropagation(),
|
|
981
|
-
children: /* @__PURE__ */
|
|
932
|
+
children: /* @__PURE__ */ jsx3(
|
|
982
933
|
"input",
|
|
983
934
|
{
|
|
984
935
|
type: "checkbox",
|
|
985
|
-
css:
|
|
936
|
+
css: styles3.checkbox,
|
|
986
937
|
checked: isSelected,
|
|
987
938
|
onChange: () => onClick({})
|
|
988
939
|
}
|
|
989
940
|
)
|
|
990
941
|
}
|
|
991
942
|
),
|
|
992
|
-
item.cdnSynced && /* @__PURE__ */
|
|
993
|
-
/* @__PURE__ */
|
|
943
|
+
item.cdnSynced && /* @__PURE__ */ jsx3("span", { css: styles3.cdnBadge, children: "CDN" }),
|
|
944
|
+
/* @__PURE__ */ jsx3("div", { css: styles3.content, children: isFolder ? /* @__PURE__ */ jsx3("svg", { css: styles3.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3("path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }) : item.thumbnail ? /* @__PURE__ */ jsx3(
|
|
994
945
|
"img",
|
|
995
946
|
{
|
|
996
|
-
css:
|
|
947
|
+
css: styles3.image,
|
|
997
948
|
src: item.thumbnail,
|
|
998
949
|
alt: item.name,
|
|
999
950
|
loading: "lazy"
|
|
1000
951
|
}
|
|
1001
|
-
) : /* @__PURE__ */
|
|
1002
|
-
/* @__PURE__ */
|
|
1003
|
-
/* @__PURE__ */
|
|
1004
|
-
/* @__PURE__ */
|
|
1005
|
-
isFolder ? /* @__PURE__ */
|
|
952
|
+
) : /* @__PURE__ */ jsx3("svg", { css: styles3.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) }) }),
|
|
953
|
+
/* @__PURE__ */ jsx3("div", { css: styles3.label, children: /* @__PURE__ */ jsxs3("div", { css: styles3.labelRow, children: [
|
|
954
|
+
/* @__PURE__ */ jsxs3("div", { css: styles3.labelText, children: [
|
|
955
|
+
/* @__PURE__ */ jsx3("p", { css: styles3.name, title: item.name, children: item.name }),
|
|
956
|
+
isFolder ? /* @__PURE__ */ jsxs3("p", { css: styles3.size, children: [
|
|
1006
957
|
item.fileCount !== void 0 ? `${item.fileCount} files` : "",
|
|
1007
958
|
item.fileCount !== void 0 && item.totalSize !== void 0 ? " \xB7 " : "",
|
|
1008
959
|
item.totalSize !== void 0 ? formatFileSize(item.totalSize) : ""
|
|
1009
|
-
] }) : item.size !== void 0 && /* @__PURE__ */
|
|
960
|
+
] }) : item.size !== void 0 && /* @__PURE__ */ jsx3("p", { css: styles3.size, children: formatFileSize(item.size) })
|
|
1010
961
|
] }),
|
|
1011
|
-
|
|
962
|
+
/* @__PURE__ */ jsx3(
|
|
1012
963
|
"button",
|
|
1013
964
|
{
|
|
1014
|
-
css:
|
|
965
|
+
css: styles3.openBtn,
|
|
1015
966
|
onClick: (e) => {
|
|
1016
967
|
e.stopPropagation();
|
|
1017
968
|
onOpen();
|
|
@@ -1032,19 +983,19 @@ function formatFileSize(bytes) {
|
|
|
1032
983
|
|
|
1033
984
|
// src/components/StudioFileList.tsx
|
|
1034
985
|
import { useEffect as useEffect2, useState as useState3 } from "react";
|
|
1035
|
-
import { css as
|
|
1036
|
-
import { jsx as
|
|
986
|
+
import { css as css4, keyframes as keyframes4 } from "@emotion/react";
|
|
987
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "@emotion/react/jsx-runtime";
|
|
1037
988
|
var spin3 = keyframes4`
|
|
1038
989
|
to { transform: rotate(360deg); }
|
|
1039
990
|
`;
|
|
1040
|
-
var
|
|
1041
|
-
loading:
|
|
991
|
+
var styles4 = {
|
|
992
|
+
loading: css4`
|
|
1042
993
|
display: flex;
|
|
1043
994
|
align-items: center;
|
|
1044
995
|
justify-content: center;
|
|
1045
996
|
height: 256px;
|
|
1046
997
|
`,
|
|
1047
|
-
spinner:
|
|
998
|
+
spinner: css4`
|
|
1048
999
|
width: 32px;
|
|
1049
1000
|
height: 32px;
|
|
1050
1001
|
border-radius: 50%;
|
|
@@ -1052,7 +1003,7 @@ var styles5 = {
|
|
|
1052
1003
|
border-top-color: ${colors.primary};
|
|
1053
1004
|
animation: ${spin3} 0.8s linear infinite;
|
|
1054
1005
|
`,
|
|
1055
|
-
empty:
|
|
1006
|
+
empty: css4`
|
|
1056
1007
|
display: flex;
|
|
1057
1008
|
flex-direction: column;
|
|
1058
1009
|
align-items: center;
|
|
@@ -1060,17 +1011,17 @@ var styles5 = {
|
|
|
1060
1011
|
height: 256px;
|
|
1061
1012
|
color: ${colors.textSecondary};
|
|
1062
1013
|
`,
|
|
1063
|
-
tableWrapper:
|
|
1014
|
+
tableWrapper: css4`
|
|
1064
1015
|
background: ${colors.surface};
|
|
1065
1016
|
border-radius: 8px;
|
|
1066
1017
|
border: 1px solid ${colors.border};
|
|
1067
1018
|
overflow: hidden;
|
|
1068
1019
|
`,
|
|
1069
|
-
table:
|
|
1020
|
+
table: css4`
|
|
1070
1021
|
width: 100%;
|
|
1071
1022
|
border-collapse: collapse;
|
|
1072
1023
|
`,
|
|
1073
|
-
th:
|
|
1024
|
+
th: css4`
|
|
1074
1025
|
text-align: left;
|
|
1075
1026
|
font-size: 11px;
|
|
1076
1027
|
color: ${colors.textMuted};
|
|
@@ -1081,20 +1032,20 @@ var styles5 = {
|
|
|
1081
1032
|
background: ${colors.background};
|
|
1082
1033
|
border-bottom: 1px solid ${colors.border};
|
|
1083
1034
|
`,
|
|
1084
|
-
thCheckbox:
|
|
1035
|
+
thCheckbox: css4`
|
|
1085
1036
|
width: 48px;
|
|
1086
1037
|
`,
|
|
1087
|
-
thSize:
|
|
1038
|
+
thSize: css4`
|
|
1088
1039
|
width: 96px;
|
|
1089
1040
|
`,
|
|
1090
|
-
thDimensions:
|
|
1041
|
+
thDimensions: css4`
|
|
1091
1042
|
width: 128px;
|
|
1092
1043
|
`,
|
|
1093
|
-
thCdn:
|
|
1044
|
+
thCdn: css4`
|
|
1094
1045
|
width: 96px;
|
|
1095
1046
|
`,
|
|
1096
|
-
tbody:
|
|
1097
|
-
row:
|
|
1047
|
+
tbody: css4``,
|
|
1048
|
+
row: css4`
|
|
1098
1049
|
cursor: pointer;
|
|
1099
1050
|
transition: background-color 0.15s ease;
|
|
1100
1051
|
user-select: none;
|
|
@@ -1107,44 +1058,57 @@ var styles5 = {
|
|
|
1107
1058
|
border-bottom: 1px solid ${colors.borderLight};
|
|
1108
1059
|
}
|
|
1109
1060
|
`,
|
|
1110
|
-
rowSelected:
|
|
1061
|
+
rowSelected: css4`
|
|
1111
1062
|
background-color: ${colors.primaryLight};
|
|
1112
1063
|
|
|
1113
1064
|
&:hover {
|
|
1114
1065
|
background-color: ${colors.primaryLight};
|
|
1115
1066
|
}
|
|
1116
1067
|
`,
|
|
1117
|
-
|
|
1068
|
+
parentRow: css4`
|
|
1069
|
+
cursor: pointer;
|
|
1070
|
+
|
|
1071
|
+
&:hover {
|
|
1072
|
+
background-color: ${colors.surfaceHover};
|
|
1073
|
+
}
|
|
1074
|
+
`,
|
|
1075
|
+
td: css4`
|
|
1118
1076
|
padding: 12px 16px;
|
|
1119
1077
|
`,
|
|
1120
|
-
checkboxCell:
|
|
1078
|
+
checkboxCell: css4`
|
|
1121
1079
|
padding: 12px 16px;
|
|
1122
1080
|
cursor: pointer;
|
|
1123
1081
|
`,
|
|
1124
|
-
checkbox:
|
|
1082
|
+
checkbox: css4`
|
|
1125
1083
|
width: 16px;
|
|
1126
1084
|
height: 16px;
|
|
1127
1085
|
accent-color: ${colors.primary};
|
|
1128
1086
|
cursor: pointer;
|
|
1129
1087
|
`,
|
|
1130
|
-
nameCell:
|
|
1088
|
+
nameCell: css4`
|
|
1131
1089
|
display: flex;
|
|
1132
1090
|
align-items: center;
|
|
1133
1091
|
gap: 12px;
|
|
1134
1092
|
`,
|
|
1135
|
-
folderIcon:
|
|
1093
|
+
folderIcon: css4`
|
|
1136
1094
|
width: 20px;
|
|
1137
1095
|
height: 20px;
|
|
1138
1096
|
color: #f5a623;
|
|
1139
1097
|
flex-shrink: 0;
|
|
1140
1098
|
`,
|
|
1141
|
-
|
|
1099
|
+
parentIcon: css4`
|
|
1142
1100
|
width: 20px;
|
|
1143
1101
|
height: 20px;
|
|
1144
1102
|
color: ${colors.textMuted};
|
|
1145
1103
|
flex-shrink: 0;
|
|
1146
1104
|
`,
|
|
1147
|
-
|
|
1105
|
+
fileIcon: css4`
|
|
1106
|
+
width: 20px;
|
|
1107
|
+
height: 20px;
|
|
1108
|
+
color: ${colors.textMuted};
|
|
1109
|
+
flex-shrink: 0;
|
|
1110
|
+
`,
|
|
1111
|
+
thumbnail: css4`
|
|
1148
1112
|
width: 36px;
|
|
1149
1113
|
height: 36px;
|
|
1150
1114
|
object-fit: cover;
|
|
@@ -1152,17 +1116,17 @@ var styles5 = {
|
|
|
1152
1116
|
flex-shrink: 0;
|
|
1153
1117
|
border: 1px solid ${colors.borderLight};
|
|
1154
1118
|
`,
|
|
1155
|
-
name:
|
|
1119
|
+
name: css4`
|
|
1156
1120
|
font-size: ${fontSize.base};
|
|
1157
1121
|
font-weight: 500;
|
|
1158
1122
|
color: ${colors.text};
|
|
1159
1123
|
letter-spacing: -0.01em;
|
|
1160
1124
|
`,
|
|
1161
|
-
meta:
|
|
1125
|
+
meta: css4`
|
|
1162
1126
|
font-size: ${fontSize.sm};
|
|
1163
1127
|
color: ${colors.textSecondary};
|
|
1164
1128
|
`,
|
|
1165
|
-
cdnBadge:
|
|
1129
|
+
cdnBadge: css4`
|
|
1166
1130
|
display: inline-flex;
|
|
1167
1131
|
align-items: center;
|
|
1168
1132
|
gap: 4px;
|
|
@@ -1170,24 +1134,28 @@ var styles5 = {
|
|
|
1170
1134
|
font-weight: 500;
|
|
1171
1135
|
color: ${colors.success};
|
|
1172
1136
|
`,
|
|
1173
|
-
cdnIcon:
|
|
1137
|
+
cdnIcon: css4`
|
|
1174
1138
|
width: 12px;
|
|
1175
1139
|
height: 12px;
|
|
1176
1140
|
`,
|
|
1177
|
-
cdnEmpty:
|
|
1141
|
+
cdnEmpty: css4`
|
|
1178
1142
|
font-size: ${fontSize.sm};
|
|
1179
1143
|
color: ${colors.textMuted};
|
|
1180
1144
|
`,
|
|
1181
|
-
openBtn:
|
|
1145
|
+
openBtn: css4`
|
|
1146
|
+
height: 28px;
|
|
1182
1147
|
font-size: ${fontSize.xs};
|
|
1183
1148
|
font-weight: 500;
|
|
1184
1149
|
color: ${colors.primary};
|
|
1185
1150
|
background: ${colors.surface};
|
|
1186
1151
|
border: 1px solid ${colors.border};
|
|
1187
|
-
padding:
|
|
1152
|
+
padding: 0 12px;
|
|
1188
1153
|
cursor: pointer;
|
|
1189
1154
|
border-radius: 4px;
|
|
1190
1155
|
transition: all 0.15s ease;
|
|
1156
|
+
display: inline-flex;
|
|
1157
|
+
align-items: center;
|
|
1158
|
+
margin-left: auto;
|
|
1191
1159
|
|
|
1192
1160
|
&:hover {
|
|
1193
1161
|
background-color: ${colors.primaryLight};
|
|
@@ -1196,7 +1164,7 @@ var styles5 = {
|
|
|
1196
1164
|
`
|
|
1197
1165
|
};
|
|
1198
1166
|
function StudioFileList() {
|
|
1199
|
-
const { currentPath, setCurrentPath, selectedItems, toggleSelection, selectRange, lastSelectedPath, selectAll, clearSelection, refreshKey } = useStudio();
|
|
1167
|
+
const { currentPath, setCurrentPath, navigateUp, selectedItems, toggleSelection, selectRange, lastSelectedPath, selectAll, clearSelection, refreshKey, setFocusedItem } = useStudio();
|
|
1200
1168
|
const [items, setItems] = useState3([]);
|
|
1201
1169
|
const [loading, setLoading] = useState3(true);
|
|
1202
1170
|
useEffect2(() => {
|
|
@@ -1216,10 +1184,11 @@ function StudioFileList() {
|
|
|
1216
1184
|
loadItems();
|
|
1217
1185
|
}, [currentPath, refreshKey]);
|
|
1218
1186
|
if (loading) {
|
|
1219
|
-
return /* @__PURE__ */
|
|
1187
|
+
return /* @__PURE__ */ jsx4("div", { css: styles4.loading, children: /* @__PURE__ */ jsx4("div", { css: styles4.spinner }) });
|
|
1220
1188
|
}
|
|
1221
|
-
|
|
1222
|
-
|
|
1189
|
+
const isAtRoot = currentPath === "public";
|
|
1190
|
+
if (items.length === 0 && isAtRoot) {
|
|
1191
|
+
return /* @__PURE__ */ jsx4("div", { css: styles4.empty, children: /* @__PURE__ */ jsx4("p", { children: "No files in this folder" }) });
|
|
1223
1192
|
}
|
|
1224
1193
|
const sortedItems = [...items].sort((a, b) => {
|
|
1225
1194
|
if (a.type === "folder" && b.type !== "folder") return -1;
|
|
@@ -1233,9 +1202,11 @@ function StudioFileList() {
|
|
|
1233
1202
|
toggleSelection(item.path);
|
|
1234
1203
|
}
|
|
1235
1204
|
};
|
|
1236
|
-
const
|
|
1205
|
+
const handleOpen = (item) => {
|
|
1237
1206
|
if (item.type === "folder") {
|
|
1238
1207
|
setCurrentPath(item.path);
|
|
1208
|
+
} else {
|
|
1209
|
+
setFocusedItem(item);
|
|
1239
1210
|
}
|
|
1240
1211
|
};
|
|
1241
1212
|
const allItemsSelected = sortedItems.length > 0 && sortedItems.every((item) => selectedItems.has(item.path));
|
|
@@ -1247,13 +1218,13 @@ function StudioFileList() {
|
|
|
1247
1218
|
selectAll(sortedItems);
|
|
1248
1219
|
}
|
|
1249
1220
|
};
|
|
1250
|
-
return /* @__PURE__ */
|
|
1251
|
-
/* @__PURE__ */
|
|
1252
|
-
/* @__PURE__ */
|
|
1221
|
+
return /* @__PURE__ */ jsx4("div", { css: styles4.tableWrapper, children: /* @__PURE__ */ jsxs4("table", { css: styles4.table, children: [
|
|
1222
|
+
/* @__PURE__ */ jsx4("thead", { children: /* @__PURE__ */ jsxs4("tr", { children: [
|
|
1223
|
+
/* @__PURE__ */ jsx4("th", { css: [styles4.th, styles4.thCheckbox], children: sortedItems.length > 0 && /* @__PURE__ */ jsx4(
|
|
1253
1224
|
"input",
|
|
1254
1225
|
{
|
|
1255
1226
|
type: "checkbox",
|
|
1256
|
-
css:
|
|
1227
|
+
css: styles4.checkbox,
|
|
1257
1228
|
checked: allItemsSelected,
|
|
1258
1229
|
ref: (el) => {
|
|
1259
1230
|
if (el) el.indeterminate = someItemsSelected && !allItemsSelected;
|
|
@@ -1261,54 +1232,66 @@ function StudioFileList() {
|
|
|
1261
1232
|
onChange: handleSelectAll
|
|
1262
1233
|
}
|
|
1263
1234
|
) }),
|
|
1264
|
-
/* @__PURE__ */
|
|
1265
|
-
/* @__PURE__ */
|
|
1266
|
-
/* @__PURE__ */
|
|
1267
|
-
/* @__PURE__ */
|
|
1235
|
+
/* @__PURE__ */ jsx4("th", { css: styles4.th, children: "Name" }),
|
|
1236
|
+
/* @__PURE__ */ jsx4("th", { css: [styles4.th, styles4.thSize], children: "Size" }),
|
|
1237
|
+
/* @__PURE__ */ jsx4("th", { css: [styles4.th, styles4.thDimensions], children: "Dimensions" }),
|
|
1238
|
+
/* @__PURE__ */ jsx4("th", { css: [styles4.th, styles4.thCdn], children: "CDN" })
|
|
1268
1239
|
] }) }),
|
|
1269
|
-
/* @__PURE__ */
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1240
|
+
/* @__PURE__ */ jsxs4("tbody", { css: styles4.tbody, children: [
|
|
1241
|
+
!isAtRoot && /* @__PURE__ */ jsxs4("tr", { css: styles4.parentRow, onClick: navigateUp, children: [
|
|
1242
|
+
/* @__PURE__ */ jsx4("td", { css: styles4.td }),
|
|
1243
|
+
/* @__PURE__ */ jsx4("td", { css: styles4.td, children: /* @__PURE__ */ jsxs4("div", { css: styles4.nameCell, children: [
|
|
1244
|
+
/* @__PURE__ */ jsx4("svg", { css: styles4.parentIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" }) }),
|
|
1245
|
+
/* @__PURE__ */ jsx4("span", { css: styles4.name, children: ".." })
|
|
1246
|
+
] }) }),
|
|
1247
|
+
/* @__PURE__ */ jsx4("td", { css: [styles4.td, styles4.meta], children: "--" }),
|
|
1248
|
+
/* @__PURE__ */ jsx4("td", { css: [styles4.td, styles4.meta], children: "Parent folder" }),
|
|
1249
|
+
/* @__PURE__ */ jsx4("td", { css: styles4.td, children: "--" })
|
|
1250
|
+
] }),
|
|
1251
|
+
sortedItems.map((item) => /* @__PURE__ */ jsx4(
|
|
1252
|
+
ListRow,
|
|
1253
|
+
{
|
|
1254
|
+
item,
|
|
1255
|
+
isSelected: selectedItems.has(item.path),
|
|
1256
|
+
onClick: (e) => handleItemClick(item, e),
|
|
1257
|
+
onOpen: () => handleOpen(item)
|
|
1258
|
+
},
|
|
1259
|
+
item.path
|
|
1260
|
+
))
|
|
1261
|
+
] })
|
|
1262
|
+
] }) });
|
|
1280
1263
|
}
|
|
1281
1264
|
function ListRow({ item, isSelected, onClick, onOpen }) {
|
|
1282
1265
|
const isFolder = item.type === "folder";
|
|
1283
|
-
return /* @__PURE__ */
|
|
1266
|
+
return /* @__PURE__ */ jsxs4(
|
|
1284
1267
|
"tr",
|
|
1285
1268
|
{
|
|
1286
|
-
css: [
|
|
1269
|
+
css: [styles4.row, isSelected && styles4.rowSelected],
|
|
1287
1270
|
onClick,
|
|
1288
1271
|
children: [
|
|
1289
|
-
/* @__PURE__ */
|
|
1272
|
+
/* @__PURE__ */ jsx4(
|
|
1290
1273
|
"td",
|
|
1291
1274
|
{
|
|
1292
|
-
css: [
|
|
1275
|
+
css: [styles4.td, styles4.checkboxCell],
|
|
1293
1276
|
onClick: (e) => e.stopPropagation(),
|
|
1294
|
-
children: /* @__PURE__ */
|
|
1277
|
+
children: /* @__PURE__ */ jsx4(
|
|
1295
1278
|
"input",
|
|
1296
1279
|
{
|
|
1297
1280
|
type: "checkbox",
|
|
1298
|
-
css:
|
|
1281
|
+
css: styles4.checkbox,
|
|
1299
1282
|
checked: isSelected,
|
|
1300
1283
|
onChange: () => onClick({})
|
|
1301
1284
|
}
|
|
1302
1285
|
)
|
|
1303
1286
|
}
|
|
1304
1287
|
),
|
|
1305
|
-
/* @__PURE__ */
|
|
1306
|
-
isFolder ? /* @__PURE__ */
|
|
1307
|
-
/* @__PURE__ */
|
|
1308
|
-
|
|
1288
|
+
/* @__PURE__ */ jsx4("td", { css: styles4.td, children: /* @__PURE__ */ jsxs4("div", { css: styles4.nameCell, children: [
|
|
1289
|
+
isFolder ? /* @__PURE__ */ jsx4("svg", { css: styles4.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }) : item.thumbnail ? /* @__PURE__ */ jsx4("img", { css: styles4.thumbnail, src: item.thumbnail, alt: item.name, loading: "lazy" }) : /* @__PURE__ */ jsx4("svg", { css: styles4.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) }),
|
|
1290
|
+
/* @__PURE__ */ jsx4("span", { css: styles4.name, children: item.name }),
|
|
1291
|
+
/* @__PURE__ */ jsx4(
|
|
1309
1292
|
"button",
|
|
1310
1293
|
{
|
|
1311
|
-
css:
|
|
1294
|
+
css: styles4.openBtn,
|
|
1312
1295
|
onClick: (e) => {
|
|
1313
1296
|
e.stopPropagation();
|
|
1314
1297
|
onOpen();
|
|
@@ -1317,12 +1300,12 @@ function ListRow({ item, isSelected, onClick, onOpen }) {
|
|
|
1317
1300
|
}
|
|
1318
1301
|
)
|
|
1319
1302
|
] }) }),
|
|
1320
|
-
/* @__PURE__ */
|
|
1321
|
-
/* @__PURE__ */
|
|
1322
|
-
/* @__PURE__ */
|
|
1323
|
-
/* @__PURE__ */
|
|
1303
|
+
/* @__PURE__ */ jsx4("td", { css: [styles4.td, styles4.meta], children: isFolder ? item.fileCount !== void 0 ? `${item.fileCount} files` : "--" : item.size !== void 0 ? formatFileSize2(item.size) : "--" }),
|
|
1304
|
+
/* @__PURE__ */ jsx4("td", { css: [styles4.td, styles4.meta], children: isFolder ? item.totalSize !== void 0 ? formatFileSize2(item.totalSize) : "--" : item.dimensions ? `${item.dimensions.width}x${item.dimensions.height}` : "--" }),
|
|
1305
|
+
/* @__PURE__ */ jsx4("td", { css: styles4.td, children: item.cdnSynced ? /* @__PURE__ */ jsxs4("span", { css: styles4.cdnBadge, children: [
|
|
1306
|
+
/* @__PURE__ */ jsx4("svg", { css: styles4.cdnIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx4("path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }),
|
|
1324
1307
|
"Synced"
|
|
1325
|
-
] }) : /* @__PURE__ */
|
|
1308
|
+
] }) : /* @__PURE__ */ jsx4("span", { css: styles4.cdnEmpty, children: "--" }) })
|
|
1326
1309
|
]
|
|
1327
1310
|
}
|
|
1328
1311
|
);
|
|
@@ -1333,10 +1316,10 @@ function formatFileSize2(bytes) {
|
|
|
1333
1316
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
1334
1317
|
}
|
|
1335
1318
|
|
|
1336
|
-
// src/components/
|
|
1319
|
+
// src/components/StudioDetailView.tsx
|
|
1337
1320
|
import { useState as useState4 } from "react";
|
|
1338
|
-
import { css as
|
|
1339
|
-
import { Fragment as Fragment2, jsx as
|
|
1321
|
+
import { css as css5 } from "@emotion/react";
|
|
1322
|
+
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs5 } from "@emotion/react/jsx-runtime";
|
|
1340
1323
|
var IMAGE_EXTENSIONS = [".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg", ".ico", ".bmp", ".tiff", ".tif"];
|
|
1341
1324
|
var VIDEO_EXTENSIONS = [".mp4", ".webm", ".mov", ".avi", ".mkv", ".m4v"];
|
|
1342
1325
|
function isImageFile(filename) {
|
|
@@ -1347,191 +1330,203 @@ function isVideoFile(filename) {
|
|
|
1347
1330
|
const ext = filename.toLowerCase().substring(filename.lastIndexOf("."));
|
|
1348
1331
|
return VIDEO_EXTENSIONS.includes(ext);
|
|
1349
1332
|
}
|
|
1350
|
-
var
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1333
|
+
var styles5 = {
|
|
1334
|
+
container: css5`
|
|
1335
|
+
display: flex;
|
|
1336
|
+
flex: 1;
|
|
1337
|
+
overflow: hidden;
|
|
1338
|
+
`,
|
|
1339
|
+
main: css5`
|
|
1340
|
+
flex: 1;
|
|
1341
|
+
display: flex;
|
|
1342
|
+
flex-direction: column;
|
|
1343
|
+
align-items: center;
|
|
1344
|
+
justify-content: center;
|
|
1345
|
+
padding: 24px;
|
|
1346
|
+
background: ${colors.background};
|
|
1356
1347
|
overflow: auto;
|
|
1357
1348
|
`,
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
margin: 0 0 16px 0;
|
|
1349
|
+
mediaWrapper: css5`
|
|
1350
|
+
max-width: 100%;
|
|
1351
|
+
max-height: 100%;
|
|
1352
|
+
display: flex;
|
|
1353
|
+
align-items: center;
|
|
1354
|
+
justify-content: center;
|
|
1365
1355
|
`,
|
|
1366
|
-
|
|
1367
|
-
|
|
1356
|
+
image: css5`
|
|
1357
|
+
max-width: 100%;
|
|
1358
|
+
max-height: calc(100vh - 200px);
|
|
1359
|
+
object-fit: contain;
|
|
1368
1360
|
border-radius: 8px;
|
|
1369
|
-
|
|
1370
|
-
padding: 12px;
|
|
1371
|
-
margin-bottom: 20px;
|
|
1361
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
1372
1362
|
`,
|
|
1373
|
-
|
|
1374
|
-
width: 100%;
|
|
1375
|
-
height:
|
|
1376
|
-
border-radius:
|
|
1363
|
+
video: css5`
|
|
1364
|
+
max-width: 100%;
|
|
1365
|
+
max-height: calc(100vh - 200px);
|
|
1366
|
+
border-radius: 8px;
|
|
1367
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
1377
1368
|
`,
|
|
1378
|
-
|
|
1369
|
+
filePlaceholder: css5`
|
|
1379
1370
|
display: flex;
|
|
1380
1371
|
flex-direction: column;
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1372
|
+
align-items: center;
|
|
1373
|
+
justify-content: center;
|
|
1374
|
+
padding: 48px;
|
|
1375
|
+
background: ${colors.surface};
|
|
1376
|
+
border-radius: 12px;
|
|
1377
|
+
border: 1px solid ${colors.border};
|
|
1387
1378
|
`,
|
|
1388
|
-
|
|
1389
|
-
|
|
1379
|
+
fileIcon: css5`
|
|
1380
|
+
width: 80px;
|
|
1381
|
+
height: 80px;
|
|
1382
|
+
color: ${colors.textMuted};
|
|
1383
|
+
margin-bottom: 16px;
|
|
1390
1384
|
`,
|
|
1391
|
-
|
|
1385
|
+
fileName: css5`
|
|
1386
|
+
font-size: ${fontSize.lg};
|
|
1387
|
+
font-weight: 600;
|
|
1392
1388
|
color: ${colors.text};
|
|
1393
|
-
|
|
1389
|
+
margin: 0;
|
|
1394
1390
|
`,
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1391
|
+
sidebar: css5`
|
|
1392
|
+
width: 280px;
|
|
1393
|
+
background: ${colors.surface};
|
|
1394
|
+
border-left: 1px solid ${colors.border};
|
|
1395
|
+
display: flex;
|
|
1396
|
+
flex-direction: column;
|
|
1398
1397
|
overflow: hidden;
|
|
1399
|
-
text-overflow: ellipsis;
|
|
1400
|
-
`,
|
|
1401
|
-
section: css6`
|
|
1402
|
-
padding-top: 12px;
|
|
1403
|
-
margin-top: 4px;
|
|
1404
|
-
border-top: 1px solid ${colors.borderLight};
|
|
1405
1398
|
`,
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
color: ${colors.textMuted};
|
|
1410
|
-
text-transform: uppercase;
|
|
1411
|
-
letter-spacing: 0.05em;
|
|
1412
|
-
margin: 0 0 10px 0;
|
|
1413
|
-
`,
|
|
1414
|
-
cdnStatus: css6`
|
|
1399
|
+
sidebarHeader: css5`
|
|
1400
|
+
padding: 16px 20px;
|
|
1401
|
+
border-bottom: 1px solid ${colors.border};
|
|
1415
1402
|
display: flex;
|
|
1416
1403
|
align-items: center;
|
|
1417
|
-
|
|
1418
|
-
font-size: ${fontSize.sm};
|
|
1419
|
-
color: ${colors.success};
|
|
1420
|
-
font-weight: 500;
|
|
1404
|
+
justify-content: space-between;
|
|
1421
1405
|
`,
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1406
|
+
sidebarTitle: css5`
|
|
1407
|
+
font-size: ${fontSize.base};
|
|
1408
|
+
font-weight: 600;
|
|
1409
|
+
color: ${colors.text};
|
|
1410
|
+
margin: 0;
|
|
1425
1411
|
`,
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
background: none;
|
|
1432
|
-
border: none;
|
|
1412
|
+
closeBtn: css5`
|
|
1413
|
+
padding: 6px;
|
|
1414
|
+
background: ${colors.surface};
|
|
1415
|
+
border: 1px solid ${colors.border};
|
|
1416
|
+
border-radius: 6px;
|
|
1433
1417
|
cursor: pointer;
|
|
1434
|
-
|
|
1418
|
+
transition: all 0.15s ease;
|
|
1419
|
+
display: flex;
|
|
1420
|
+
align-items: center;
|
|
1421
|
+
justify-content: center;
|
|
1435
1422
|
|
|
1436
1423
|
&:hover {
|
|
1437
|
-
|
|
1424
|
+
background-color: ${colors.surfaceHover};
|
|
1425
|
+
border-color: ${colors.borderHover};
|
|
1438
1426
|
}
|
|
1439
1427
|
`,
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
height:
|
|
1443
|
-
|
|
1444
|
-
|
|
1428
|
+
closeIcon: css5`
|
|
1429
|
+
width: 16px;
|
|
1430
|
+
height: 16px;
|
|
1431
|
+
color: ${colors.textSecondary};
|
|
1432
|
+
`,
|
|
1433
|
+
sidebarContent: css5`
|
|
1434
|
+
flex: 1;
|
|
1435
|
+
padding: 20px;
|
|
1436
|
+
overflow: auto;
|
|
1445
1437
|
`,
|
|
1446
|
-
|
|
1438
|
+
info: css5`
|
|
1447
1439
|
display: flex;
|
|
1448
1440
|
flex-direction: column;
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
height: 200px;
|
|
1452
|
-
text-align: center;
|
|
1453
|
-
`,
|
|
1454
|
-
emptyText: css6`
|
|
1455
|
-
font-size: ${fontSize.sm};
|
|
1456
|
-
color: ${colors.textMuted};
|
|
1457
|
-
margin: 0;
|
|
1441
|
+
gap: 12px;
|
|
1442
|
+
margin-bottom: 24px;
|
|
1458
1443
|
`,
|
|
1459
|
-
|
|
1444
|
+
infoRow: css5`
|
|
1460
1445
|
display: flex;
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
height: 120px;
|
|
1464
|
-
background: ${colors.background};
|
|
1465
|
-
border-radius: 6px;
|
|
1466
|
-
`,
|
|
1467
|
-
fileIcon: css6`
|
|
1468
|
-
width: 56px;
|
|
1469
|
-
height: 56px;
|
|
1470
|
-
color: ${colors.textMuted};
|
|
1446
|
+
justify-content: space-between;
|
|
1447
|
+
font-size: ${fontSize.sm};
|
|
1471
1448
|
`,
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
height: 56px;
|
|
1475
|
-
color: #f5a623;
|
|
1449
|
+
infoLabel: css5`
|
|
1450
|
+
color: ${colors.textSecondary};
|
|
1476
1451
|
`,
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1452
|
+
infoValue: css5`
|
|
1453
|
+
color: ${colors.text};
|
|
1454
|
+
font-weight: 500;
|
|
1455
|
+
text-align: right;
|
|
1456
|
+
max-width: 160px;
|
|
1457
|
+
overflow: hidden;
|
|
1458
|
+
text-overflow: ellipsis;
|
|
1459
|
+
white-space: nowrap;
|
|
1481
1460
|
`,
|
|
1482
|
-
actions:
|
|
1483
|
-
margin-top: 20px;
|
|
1484
|
-
padding-top: 20px;
|
|
1485
|
-
border-top: 1px solid ${colors.border};
|
|
1461
|
+
actions: css5`
|
|
1486
1462
|
display: flex;
|
|
1487
1463
|
flex-direction: column;
|
|
1488
1464
|
gap: 8px;
|
|
1489
1465
|
`,
|
|
1490
|
-
actionBtn:
|
|
1466
|
+
actionBtn: css5`
|
|
1467
|
+
display: flex;
|
|
1468
|
+
align-items: center;
|
|
1469
|
+
gap: 10px;
|
|
1491
1470
|
width: 100%;
|
|
1492
|
-
padding:
|
|
1471
|
+
padding: 12px 14px;
|
|
1493
1472
|
font-size: ${fontSize.base};
|
|
1494
1473
|
font-weight: 500;
|
|
1495
|
-
background
|
|
1474
|
+
background: ${colors.surface};
|
|
1496
1475
|
border: 1px solid ${colors.border};
|
|
1497
1476
|
border-radius: 6px;
|
|
1498
1477
|
cursor: pointer;
|
|
1499
1478
|
transition: all 0.15s ease;
|
|
1500
1479
|
color: ${colors.text};
|
|
1480
|
+
text-align: left;
|
|
1501
1481
|
|
|
1502
1482
|
&:hover {
|
|
1503
1483
|
background-color: ${colors.surfaceHover};
|
|
1504
|
-
border-color:
|
|
1484
|
+
border-color: ${colors.borderHover};
|
|
1505
1485
|
}
|
|
1506
1486
|
`,
|
|
1507
|
-
actionBtnDanger:
|
|
1487
|
+
actionBtnDanger: css5`
|
|
1508
1488
|
color: ${colors.danger};
|
|
1509
1489
|
|
|
1510
1490
|
&:hover {
|
|
1511
1491
|
background-color: ${colors.dangerLight};
|
|
1512
1492
|
border-color: ${colors.danger};
|
|
1513
1493
|
}
|
|
1494
|
+
`,
|
|
1495
|
+
actionIcon: css5`
|
|
1496
|
+
width: 16px;
|
|
1497
|
+
height: 16px;
|
|
1498
|
+
flex-shrink: 0;
|
|
1514
1499
|
`
|
|
1515
1500
|
};
|
|
1516
|
-
function
|
|
1517
|
-
const {
|
|
1501
|
+
function StudioDetailView() {
|
|
1502
|
+
const { focusedItem, setFocusedItem, triggerRefresh, clearSelection } = useStudio();
|
|
1518
1503
|
const [showDeleteConfirm, setShowDeleteConfirm] = useState4(false);
|
|
1519
1504
|
const [alertMessage, setAlertMessage] = useState4(null);
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1505
|
+
if (!focusedItem) return null;
|
|
1506
|
+
const isImage = isImageFile(focusedItem.name);
|
|
1507
|
+
const isVideo = isVideoFile(focusedItem.name);
|
|
1508
|
+
const imageSrc = focusedItem.path.replace("public", "");
|
|
1509
|
+
const handleClose = () => {
|
|
1510
|
+
setFocusedItem(null);
|
|
1523
1511
|
};
|
|
1524
|
-
const
|
|
1512
|
+
const handleRename = () => {
|
|
1513
|
+
const newName = prompt("Enter new name:", focusedItem.name);
|
|
1514
|
+
if (newName && newName !== focusedItem.name) {
|
|
1515
|
+
console.log("Rename to:", newName);
|
|
1516
|
+
}
|
|
1517
|
+
};
|
|
1518
|
+
const handleDelete = async () => {
|
|
1525
1519
|
setShowDeleteConfirm(false);
|
|
1526
1520
|
try {
|
|
1527
1521
|
const response = await fetch("/api/studio/delete", {
|
|
1528
1522
|
method: "POST",
|
|
1529
1523
|
headers: { "Content-Type": "application/json" },
|
|
1530
|
-
body: JSON.stringify({ paths:
|
|
1524
|
+
body: JSON.stringify({ paths: [focusedItem.path] })
|
|
1531
1525
|
});
|
|
1532
1526
|
if (response.ok) {
|
|
1533
1527
|
clearSelection();
|
|
1534
1528
|
triggerRefresh();
|
|
1529
|
+
setFocusedItem(null);
|
|
1535
1530
|
} else {
|
|
1536
1531
|
const error = await response.json();
|
|
1537
1532
|
setAlertMessage({
|
|
@@ -1547,155 +1542,97 @@ function StudioPreview() {
|
|
|
1547
1542
|
});
|
|
1548
1543
|
}
|
|
1549
1544
|
};
|
|
1550
|
-
const
|
|
1551
|
-
|
|
1545
|
+
const handleSync = () => {
|
|
1546
|
+
console.log("Sync to CDN:", focusedItem.path);
|
|
1547
|
+
};
|
|
1548
|
+
const handleRegenerate = () => {
|
|
1549
|
+
console.log("Regenerate:", focusedItem.path);
|
|
1550
|
+
};
|
|
1551
|
+
const renderMedia = () => {
|
|
1552
|
+
if (isImage) {
|
|
1553
|
+
return /* @__PURE__ */ jsx5("img", { css: styles5.image, src: imageSrc, alt: focusedItem.name });
|
|
1554
|
+
}
|
|
1555
|
+
if (isVideo) {
|
|
1556
|
+
return /* @__PURE__ */ jsx5("video", { css: styles5.video, src: imageSrc, controls: true });
|
|
1557
|
+
}
|
|
1558
|
+
return /* @__PURE__ */ jsxs5("div", { css: styles5.filePlaceholder, children: [
|
|
1559
|
+
/* @__PURE__ */ jsx5("svg", { css: styles5.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) }),
|
|
1560
|
+
/* @__PURE__ */ jsx5("p", { css: styles5.fileName, children: focusedItem.name })
|
|
1561
|
+
] });
|
|
1562
|
+
};
|
|
1563
|
+
return /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
1564
|
+
showDeleteConfirm && /* @__PURE__ */ jsx5(
|
|
1552
1565
|
ConfirmModal,
|
|
1553
1566
|
{
|
|
1554
|
-
title: "Delete
|
|
1555
|
-
message: `Are you sure you want to delete ${
|
|
1567
|
+
title: "Delete File",
|
|
1568
|
+
message: `Are you sure you want to delete "${focusedItem.name}"? This action cannot be undone.`,
|
|
1556
1569
|
confirmLabel: "Delete",
|
|
1557
1570
|
variant: "danger",
|
|
1558
|
-
onConfirm:
|
|
1571
|
+
onConfirm: handleDelete,
|
|
1559
1572
|
onCancel: () => setShowDeleteConfirm(false)
|
|
1560
1573
|
}
|
|
1561
1574
|
),
|
|
1562
|
-
alertMessage && /* @__PURE__ */
|
|
1575
|
+
alertMessage && /* @__PURE__ */ jsx5(
|
|
1563
1576
|
AlertModal,
|
|
1564
1577
|
{
|
|
1565
1578
|
title: alertMessage.title,
|
|
1566
1579
|
message: alertMessage.message,
|
|
1567
1580
|
onClose: () => setAlertMessage(null)
|
|
1568
1581
|
}
|
|
1569
|
-
)
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
/* @__PURE__ */ jsx6("div", { css: styles6.emptyState, children: /* @__PURE__ */ jsx6("p", { css: styles6.emptyText, children: "Select an image to preview" }) })
|
|
1577
|
-
] })
|
|
1578
|
-
] });
|
|
1579
|
-
}
|
|
1580
|
-
if (selectedItems.size > 1) {
|
|
1581
|
-
return /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
1582
|
-
modals,
|
|
1583
|
-
/* @__PURE__ */ jsxs6("div", { css: styles6.panel, children: [
|
|
1584
|
-
/* @__PURE__ */ jsxs6("h3", { css: styles6.title, children: [
|
|
1585
|
-
selectedItems.size,
|
|
1586
|
-
" items selected"
|
|
1582
|
+
),
|
|
1583
|
+
/* @__PURE__ */ jsxs5("div", { css: styles5.container, children: [
|
|
1584
|
+
/* @__PURE__ */ jsx5("div", { css: styles5.main, children: /* @__PURE__ */ jsx5("div", { css: styles5.mediaWrapper, children: renderMedia() }) }),
|
|
1585
|
+
/* @__PURE__ */ jsxs5("div", { css: styles5.sidebar, children: [
|
|
1586
|
+
/* @__PURE__ */ jsxs5("div", { css: styles5.sidebarHeader, children: [
|
|
1587
|
+
/* @__PURE__ */ jsx5("h3", { css: styles5.sidebarTitle, children: "Details" }),
|
|
1588
|
+
/* @__PURE__ */ jsx5("button", { css: styles5.closeBtn, onClick: handleClose, "aria-label": "Close", children: /* @__PURE__ */ jsx5("svg", { css: styles5.closeIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
|
|
1587
1589
|
] }),
|
|
1588
|
-
/* @__PURE__ */
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
] })
|
|
1594
|
-
] });
|
|
1595
|
-
}
|
|
1596
|
-
const selectedPath = Array.from(selectedItems)[0];
|
|
1597
|
-
const isFolder = !selectedPath.includes(".") || selectedPath.endsWith("/");
|
|
1598
|
-
const filename = selectedPath.split("/").pop() || "";
|
|
1599
|
-
const isImage = isImageFile(filename);
|
|
1600
|
-
const isVideo = isVideoFile(filename);
|
|
1601
|
-
const imageKey = selectedPath.replace(/^public\/images\//, "").replace(/^public\/originals\//, "").replace(/^public\//, "");
|
|
1602
|
-
const imageData = meta?.images?.[imageKey];
|
|
1603
|
-
const renderPreview = () => {
|
|
1604
|
-
if (isFolder) {
|
|
1605
|
-
return /* @__PURE__ */ jsx6("div", { css: styles6.filePlaceholder, children: /* @__PURE__ */ jsx6("svg", { css: styles6.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }) });
|
|
1606
|
-
}
|
|
1607
|
-
if (isImage) {
|
|
1608
|
-
return /* @__PURE__ */ jsx6(
|
|
1609
|
-
"img",
|
|
1610
|
-
{
|
|
1611
|
-
css: styles6.image,
|
|
1612
|
-
src: selectedPath.replace("public", ""),
|
|
1613
|
-
alt: "Preview"
|
|
1614
|
-
}
|
|
1615
|
-
);
|
|
1616
|
-
}
|
|
1617
|
-
if (isVideo) {
|
|
1618
|
-
return /* @__PURE__ */ jsx6(
|
|
1619
|
-
"video",
|
|
1620
|
-
{
|
|
1621
|
-
css: styles6.video,
|
|
1622
|
-
src: selectedPath.replace("public", ""),
|
|
1623
|
-
controls: true,
|
|
1624
|
-
muted: true
|
|
1625
|
-
}
|
|
1626
|
-
);
|
|
1627
|
-
}
|
|
1628
|
-
return /* @__PURE__ */ jsx6("div", { css: styles6.filePlaceholder, children: /* @__PURE__ */ jsx6("svg", { css: styles6.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) }) });
|
|
1629
|
-
};
|
|
1630
|
-
return /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
1631
|
-
modals,
|
|
1632
|
-
/* @__PURE__ */ jsxs6("div", { css: styles6.panel, children: [
|
|
1633
|
-
/* @__PURE__ */ jsx6("h3", { css: styles6.title, children: "Preview" }),
|
|
1634
|
-
/* @__PURE__ */ jsx6("div", { css: styles6.imageContainer, children: renderPreview() }),
|
|
1635
|
-
/* @__PURE__ */ jsxs6("div", { css: styles6.info, children: [
|
|
1636
|
-
/* @__PURE__ */ jsx6(InfoRow, { label: "Filename", value: selectedPath.split("/").pop() || "" }),
|
|
1637
|
-
imageData && /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
1638
|
-
/* @__PURE__ */ jsx6(
|
|
1639
|
-
InfoRow,
|
|
1640
|
-
{
|
|
1641
|
-
label: "Original",
|
|
1642
|
-
value: `${imageData.original.width}x${imageData.original.height}`
|
|
1643
|
-
}
|
|
1644
|
-
),
|
|
1645
|
-
/* @__PURE__ */ jsx6(
|
|
1646
|
-
InfoRow,
|
|
1647
|
-
{
|
|
1648
|
-
label: "File size",
|
|
1649
|
-
value: formatFileSize3(imageData.original.fileSize)
|
|
1650
|
-
}
|
|
1651
|
-
),
|
|
1652
|
-
/* @__PURE__ */ jsxs6("div", { css: styles6.section, children: [
|
|
1653
|
-
/* @__PURE__ */ jsx6("p", { css: styles6.sectionTitle, children: "Generated sizes" }),
|
|
1654
|
-
Object.entries(imageData.sizes).map(([size, data]) => /* @__PURE__ */ jsx6(InfoRow, { label: size, value: `${data.width}x${data.height}` }, size))
|
|
1655
|
-
] }),
|
|
1656
|
-
imageData.cdn?.synced && /* @__PURE__ */ jsxs6("div", { css: styles6.section, children: [
|
|
1657
|
-
/* @__PURE__ */ jsx6("p", { css: styles6.sectionTitle, children: "CDN" }),
|
|
1658
|
-
/* @__PURE__ */ jsxs6("div", { css: styles6.cdnStatus, children: [
|
|
1659
|
-
/* @__PURE__ */ jsx6("svg", { css: styles6.cdnIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx6("path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }),
|
|
1660
|
-
"Synced to CDN"
|
|
1590
|
+
/* @__PURE__ */ jsxs5("div", { css: styles5.sidebarContent, children: [
|
|
1591
|
+
/* @__PURE__ */ jsxs5("div", { css: styles5.info, children: [
|
|
1592
|
+
/* @__PURE__ */ jsxs5("div", { css: styles5.infoRow, children: [
|
|
1593
|
+
/* @__PURE__ */ jsx5("span", { css: styles5.infoLabel, children: "Name" }),
|
|
1594
|
+
/* @__PURE__ */ jsx5("span", { css: styles5.infoValue, title: focusedItem.name, children: focusedItem.name })
|
|
1661
1595
|
] }),
|
|
1662
|
-
/* @__PURE__ */
|
|
1663
|
-
"
|
|
1664
|
-
{
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1596
|
+
focusedItem.size !== void 0 && /* @__PURE__ */ jsxs5("div", { css: styles5.infoRow, children: [
|
|
1597
|
+
/* @__PURE__ */ jsx5("span", { css: styles5.infoLabel, children: "Size" }),
|
|
1598
|
+
/* @__PURE__ */ jsx5("span", { css: styles5.infoValue, children: formatFileSize3(focusedItem.size) })
|
|
1599
|
+
] }),
|
|
1600
|
+
focusedItem.dimensions && /* @__PURE__ */ jsxs5("div", { css: styles5.infoRow, children: [
|
|
1601
|
+
/* @__PURE__ */ jsx5("span", { css: styles5.infoLabel, children: "Dimensions" }),
|
|
1602
|
+
/* @__PURE__ */ jsxs5("span", { css: styles5.infoValue, children: [
|
|
1603
|
+
focusedItem.dimensions.width,
|
|
1604
|
+
" \xD7 ",
|
|
1605
|
+
focusedItem.dimensions.height
|
|
1606
|
+
] })
|
|
1607
|
+
] }),
|
|
1608
|
+
/* @__PURE__ */ jsxs5("div", { css: styles5.infoRow, children: [
|
|
1609
|
+
/* @__PURE__ */ jsx5("span", { css: styles5.infoLabel, children: "CDN Status" }),
|
|
1610
|
+
/* @__PURE__ */ jsx5("span", { css: styles5.infoValue, children: focusedItem.cdnSynced ? "Synced" : "Not synced" })
|
|
1611
|
+
] })
|
|
1672
1612
|
] }),
|
|
1673
|
-
|
|
1674
|
-
/* @__PURE__ */
|
|
1675
|
-
|
|
1676
|
-
"
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1613
|
+
/* @__PURE__ */ jsxs5("div", { css: styles5.actions, children: [
|
|
1614
|
+
/* @__PURE__ */ jsxs5("button", { css: styles5.actionBtn, onClick: handleRename, children: [
|
|
1615
|
+
/* @__PURE__ */ jsx5("svg", { css: styles5.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" }) }),
|
|
1616
|
+
"Rename"
|
|
1617
|
+
] }),
|
|
1618
|
+
/* @__PURE__ */ jsxs5("button", { css: styles5.actionBtn, onClick: handleSync, children: [
|
|
1619
|
+
/* @__PURE__ */ jsx5("svg", { css: styles5.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" }) }),
|
|
1620
|
+
"Sync to CDN"
|
|
1621
|
+
] }),
|
|
1622
|
+
/* @__PURE__ */ jsxs5("button", { css: styles5.actionBtn, onClick: handleRegenerate, children: [
|
|
1623
|
+
/* @__PURE__ */ jsx5("svg", { css: styles5.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" }) }),
|
|
1624
|
+
"Regenerate"
|
|
1625
|
+
] }),
|
|
1626
|
+
/* @__PURE__ */ jsxs5("button", { css: [styles5.actionBtn, styles5.actionBtnDanger], onClick: () => setShowDeleteConfirm(true), children: [
|
|
1627
|
+
/* @__PURE__ */ jsx5("svg", { css: styles5.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) }),
|
|
1628
|
+
"Delete"
|
|
1629
|
+
] })
|
|
1683
1630
|
] })
|
|
1684
1631
|
] })
|
|
1685
|
-
] }),
|
|
1686
|
-
/* @__PURE__ */ jsxs6("div", { css: styles6.actions, children: [
|
|
1687
|
-
/* @__PURE__ */ jsx6("button", { css: styles6.actionBtn, children: "Rename" }),
|
|
1688
|
-
/* @__PURE__ */ jsx6("button", { css: [styles6.actionBtn, styles6.actionBtnDanger], onClick: handleDeleteClick, children: "Delete" })
|
|
1689
1632
|
] })
|
|
1690
1633
|
] })
|
|
1691
1634
|
] });
|
|
1692
1635
|
}
|
|
1693
|
-
function InfoRow({ label, value, truncate }) {
|
|
1694
|
-
return /* @__PURE__ */ jsxs6("div", { css: styles6.row, children: [
|
|
1695
|
-
/* @__PURE__ */ jsx6("span", { css: styles6.label, children: label }),
|
|
1696
|
-
/* @__PURE__ */ jsx6("span", { css: [styles6.value, truncate && styles6.valueTruncate], title: truncate ? value : void 0, children: value })
|
|
1697
|
-
] });
|
|
1698
|
-
}
|
|
1699
1636
|
function formatFileSize3(bytes) {
|
|
1700
1637
|
if (bytes < 1024) return `${bytes} B`;
|
|
1701
1638
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
@@ -1704,11 +1641,13 @@ function formatFileSize3(bytes) {
|
|
|
1704
1641
|
|
|
1705
1642
|
// src/components/StudioSettings.tsx
|
|
1706
1643
|
import { useState as useState5 } from "react";
|
|
1707
|
-
import { css as
|
|
1708
|
-
import { Fragment as Fragment3, jsx as
|
|
1709
|
-
var
|
|
1710
|
-
|
|
1711
|
-
|
|
1644
|
+
import { css as css6 } from "@emotion/react";
|
|
1645
|
+
import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs6 } from "@emotion/react/jsx-runtime";
|
|
1646
|
+
var btnHeight2 = "36px";
|
|
1647
|
+
var styles6 = {
|
|
1648
|
+
btn: css6`
|
|
1649
|
+
height: ${btnHeight2};
|
|
1650
|
+
padding: 0 12px;
|
|
1712
1651
|
background: ${colors.surface};
|
|
1713
1652
|
border: 1px solid ${colors.border};
|
|
1714
1653
|
border-radius: 6px;
|
|
@@ -1723,12 +1662,12 @@ var styles7 = {
|
|
|
1723
1662
|
border-color: ${colors.borderHover};
|
|
1724
1663
|
}
|
|
1725
1664
|
`,
|
|
1726
|
-
icon:
|
|
1727
|
-
width:
|
|
1728
|
-
height:
|
|
1665
|
+
icon: css6`
|
|
1666
|
+
width: 16px;
|
|
1667
|
+
height: 16px;
|
|
1729
1668
|
color: ${colors.textSecondary};
|
|
1730
1669
|
`,
|
|
1731
|
-
overlay:
|
|
1670
|
+
overlay: css6`
|
|
1732
1671
|
position: fixed;
|
|
1733
1672
|
top: 0;
|
|
1734
1673
|
right: 0;
|
|
@@ -1741,7 +1680,7 @@ var styles7 = {
|
|
|
1741
1680
|
background-color: rgba(26, 31, 54, 0.4);
|
|
1742
1681
|
backdrop-filter: blur(4px);
|
|
1743
1682
|
`,
|
|
1744
|
-
panel:
|
|
1683
|
+
panel: css6`
|
|
1745
1684
|
${baseReset}
|
|
1746
1685
|
position: relative;
|
|
1747
1686
|
background-color: ${colors.surface};
|
|
@@ -1751,20 +1690,20 @@ var styles7 = {
|
|
|
1751
1690
|
max-width: 512px;
|
|
1752
1691
|
padding: 24px;
|
|
1753
1692
|
`,
|
|
1754
|
-
header:
|
|
1693
|
+
header: css6`
|
|
1755
1694
|
display: flex;
|
|
1756
1695
|
align-items: center;
|
|
1757
1696
|
justify-content: space-between;
|
|
1758
1697
|
margin-bottom: 24px;
|
|
1759
1698
|
`,
|
|
1760
|
-
title:
|
|
1699
|
+
title: css6`
|
|
1761
1700
|
font-size: ${fontSize.xl};
|
|
1762
1701
|
font-weight: 600;
|
|
1763
1702
|
color: ${colors.text};
|
|
1764
1703
|
margin: 0;
|
|
1765
1704
|
letter-spacing: -0.02em;
|
|
1766
1705
|
`,
|
|
1767
|
-
closeBtn:
|
|
1706
|
+
closeBtn: css6`
|
|
1768
1707
|
padding: 6px;
|
|
1769
1708
|
background: ${colors.surface};
|
|
1770
1709
|
border: 1px solid ${colors.border};
|
|
@@ -1780,23 +1719,23 @@ var styles7 = {
|
|
|
1780
1719
|
border-color: ${colors.borderHover};
|
|
1781
1720
|
}
|
|
1782
1721
|
`,
|
|
1783
|
-
sections:
|
|
1722
|
+
sections: css6`
|
|
1784
1723
|
display: flex;
|
|
1785
1724
|
flex-direction: column;
|
|
1786
1725
|
gap: 24px;
|
|
1787
1726
|
`,
|
|
1788
|
-
sectionTitle:
|
|
1727
|
+
sectionTitle: css6`
|
|
1789
1728
|
font-size: ${fontSize.base};
|
|
1790
1729
|
font-weight: 600;
|
|
1791
1730
|
color: ${colors.text};
|
|
1792
1731
|
margin: 0 0 12px 0;
|
|
1793
1732
|
`,
|
|
1794
|
-
description:
|
|
1733
|
+
description: css6`
|
|
1795
1734
|
font-size: ${fontSize.sm};
|
|
1796
1735
|
color: ${colors.textSecondary};
|
|
1797
1736
|
margin: 0 0 12px 0;
|
|
1798
1737
|
`,
|
|
1799
|
-
code:
|
|
1738
|
+
code: css6`
|
|
1800
1739
|
background-color: ${colors.background};
|
|
1801
1740
|
border-radius: 8px;
|
|
1802
1741
|
padding: 12px;
|
|
@@ -1805,14 +1744,14 @@ var styles7 = {
|
|
|
1805
1744
|
color: ${colors.textSecondary};
|
|
1806
1745
|
border: 1px solid ${colors.border};
|
|
1807
1746
|
`,
|
|
1808
|
-
codeLine:
|
|
1747
|
+
codeLine: css6`
|
|
1809
1748
|
margin: 0 0 4px 0;
|
|
1810
1749
|
|
|
1811
1750
|
&:last-child {
|
|
1812
1751
|
margin: 0;
|
|
1813
1752
|
}
|
|
1814
1753
|
`,
|
|
1815
|
-
input:
|
|
1754
|
+
input: css6`
|
|
1816
1755
|
width: 100%;
|
|
1817
1756
|
padding: 10px 14px;
|
|
1818
1757
|
border: 1px solid ${colors.border};
|
|
@@ -1832,19 +1771,19 @@ var styles7 = {
|
|
|
1832
1771
|
color: ${colors.textMuted};
|
|
1833
1772
|
}
|
|
1834
1773
|
`,
|
|
1835
|
-
grid:
|
|
1774
|
+
grid: css6`
|
|
1836
1775
|
display: grid;
|
|
1837
1776
|
grid-template-columns: repeat(3, 1fr);
|
|
1838
1777
|
gap: 12px;
|
|
1839
1778
|
`,
|
|
1840
|
-
label:
|
|
1779
|
+
label: css6`
|
|
1841
1780
|
font-size: ${fontSize.xs};
|
|
1842
1781
|
font-weight: 500;
|
|
1843
1782
|
color: ${colors.textSecondary};
|
|
1844
1783
|
display: block;
|
|
1845
1784
|
margin-bottom: 6px;
|
|
1846
1785
|
`,
|
|
1847
|
-
footer:
|
|
1786
|
+
footer: css6`
|
|
1848
1787
|
margin-top: 24px;
|
|
1849
1788
|
padding-top: 20px;
|
|
1850
1789
|
border-top: 1px solid ${colors.border};
|
|
@@ -1852,7 +1791,7 @@ var styles7 = {
|
|
|
1852
1791
|
justify-content: flex-end;
|
|
1853
1792
|
gap: 12px;
|
|
1854
1793
|
`,
|
|
1855
|
-
cancelBtn:
|
|
1794
|
+
cancelBtn: css6`
|
|
1856
1795
|
padding: 10px 18px;
|
|
1857
1796
|
font-size: ${fontSize.base};
|
|
1858
1797
|
font-weight: 500;
|
|
@@ -1868,7 +1807,7 @@ var styles7 = {
|
|
|
1868
1807
|
border-color: ${colors.borderHover};
|
|
1869
1808
|
}
|
|
1870
1809
|
`,
|
|
1871
|
-
saveBtn:
|
|
1810
|
+
saveBtn: css6`
|
|
1872
1811
|
padding: 10px 18px;
|
|
1873
1812
|
font-size: ${fontSize.base};
|
|
1874
1813
|
font-weight: 500;
|
|
@@ -1887,11 +1826,11 @@ var styles7 = {
|
|
|
1887
1826
|
};
|
|
1888
1827
|
function StudioSettings() {
|
|
1889
1828
|
const [isOpen, setIsOpen] = useState5(false);
|
|
1890
|
-
return /* @__PURE__ */
|
|
1891
|
-
/* @__PURE__ */
|
|
1829
|
+
return /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
1830
|
+
/* @__PURE__ */ jsx6("button", { css: styles6.btn, onClick: () => setIsOpen(true), "aria-label": "Settings", children: /* @__PURE__ */ jsxs6(
|
|
1892
1831
|
"svg",
|
|
1893
1832
|
{
|
|
1894
|
-
css:
|
|
1833
|
+
css: styles6.icon,
|
|
1895
1834
|
xmlns: "http://www.w3.org/2000/svg",
|
|
1896
1835
|
viewBox: "0 0 24 24",
|
|
1897
1836
|
fill: "none",
|
|
@@ -1900,94 +1839,96 @@ function StudioSettings() {
|
|
|
1900
1839
|
strokeLinecap: "round",
|
|
1901
1840
|
strokeLinejoin: "round",
|
|
1902
1841
|
children: [
|
|
1903
|
-
/* @__PURE__ */
|
|
1904
|
-
/* @__PURE__ */
|
|
1842
|
+
/* @__PURE__ */ jsx6("circle", { cx: "12", cy: "12", r: "3" }),
|
|
1843
|
+
/* @__PURE__ */ jsx6("path", { d: "M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-2 2 2 2 0 01-2-2v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83 0 2 2 0 010-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 01-2-2 2 2 0 012-2h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 010-2.83 2 2 0 012.83 0l.06.06a1.65 1.65 0 001.82.33H9a1.65 1.65 0 001-1.51V3a2 2 0 012-2 2 2 0 012 2v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 0 2 2 0 010 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9a1.65 1.65 0 001.51 1H21a2 2 0 012 2 2 2 0 01-2 2h-.09a1.65 1.65 0 00-1.51 1z" })
|
|
1905
1844
|
]
|
|
1906
1845
|
}
|
|
1907
1846
|
) }),
|
|
1908
|
-
isOpen && /* @__PURE__ */
|
|
1847
|
+
isOpen && /* @__PURE__ */ jsx6(SettingsPanel, { onClose: () => setIsOpen(false) })
|
|
1909
1848
|
] });
|
|
1910
1849
|
}
|
|
1911
1850
|
function SettingsPanel({ onClose }) {
|
|
1912
|
-
return /* @__PURE__ */
|
|
1913
|
-
/* @__PURE__ */
|
|
1914
|
-
/* @__PURE__ */
|
|
1915
|
-
/* @__PURE__ */
|
|
1851
|
+
return /* @__PURE__ */ jsx6("div", { css: styles6.overlay, onClick: onClose, children: /* @__PURE__ */ jsxs6("div", { css: styles6.panel, onClick: (e) => e.stopPropagation(), children: [
|
|
1852
|
+
/* @__PURE__ */ jsxs6("div", { css: styles6.header, children: [
|
|
1853
|
+
/* @__PURE__ */ jsx6("h2", { css: styles6.title, children: "Settings" }),
|
|
1854
|
+
/* @__PURE__ */ jsx6("button", { css: styles6.closeBtn, onClick: onClose, children: /* @__PURE__ */ jsx6("svg", { css: styles6.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
|
|
1916
1855
|
] }),
|
|
1917
|
-
/* @__PURE__ */
|
|
1918
|
-
/* @__PURE__ */
|
|
1919
|
-
/* @__PURE__ */
|
|
1920
|
-
/* @__PURE__ */
|
|
1921
|
-
/* @__PURE__ */
|
|
1922
|
-
/* @__PURE__ */
|
|
1923
|
-
/* @__PURE__ */
|
|
1924
|
-
/* @__PURE__ */
|
|
1925
|
-
/* @__PURE__ */
|
|
1926
|
-
/* @__PURE__ */
|
|
1856
|
+
/* @__PURE__ */ jsxs6("div", { css: styles6.sections, children: [
|
|
1857
|
+
/* @__PURE__ */ jsxs6("section", { children: [
|
|
1858
|
+
/* @__PURE__ */ jsx6("h3", { css: styles6.sectionTitle, children: "Cloudflare R2" }),
|
|
1859
|
+
/* @__PURE__ */ jsx6("p", { css: styles6.description, children: "Configure in .env.local file:" }),
|
|
1860
|
+
/* @__PURE__ */ jsxs6("div", { css: styles6.code, children: [
|
|
1861
|
+
/* @__PURE__ */ jsx6("p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_ACCOUNT_ID" }),
|
|
1862
|
+
/* @__PURE__ */ jsx6("p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_ACCESS_KEY_ID" }),
|
|
1863
|
+
/* @__PURE__ */ jsx6("p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_SECRET_ACCESS_KEY" }),
|
|
1864
|
+
/* @__PURE__ */ jsx6("p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_BUCKET_NAME" }),
|
|
1865
|
+
/* @__PURE__ */ jsx6("p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_PUBLIC_URL" })
|
|
1927
1866
|
] })
|
|
1928
1867
|
] }),
|
|
1929
|
-
/* @__PURE__ */
|
|
1930
|
-
/* @__PURE__ */
|
|
1931
|
-
/* @__PURE__ */
|
|
1932
|
-
/* @__PURE__ */
|
|
1868
|
+
/* @__PURE__ */ jsxs6("section", { children: [
|
|
1869
|
+
/* @__PURE__ */ jsx6("h3", { css: styles6.sectionTitle, children: "Custom CDN URL" }),
|
|
1870
|
+
/* @__PURE__ */ jsx6("p", { css: styles6.description, children: "Override the default R2 URL with a custom domain:" }),
|
|
1871
|
+
/* @__PURE__ */ jsx6("input", { css: styles6.input, type: "text", placeholder: "https://cdn.yourdomain.com" })
|
|
1933
1872
|
] }),
|
|
1934
|
-
/* @__PURE__ */
|
|
1935
|
-
/* @__PURE__ */
|
|
1936
|
-
/* @__PURE__ */
|
|
1937
|
-
/* @__PURE__ */
|
|
1938
|
-
/* @__PURE__ */
|
|
1939
|
-
/* @__PURE__ */
|
|
1873
|
+
/* @__PURE__ */ jsxs6("section", { children: [
|
|
1874
|
+
/* @__PURE__ */ jsx6("h3", { css: styles6.sectionTitle, children: "Thumbnail Sizes" }),
|
|
1875
|
+
/* @__PURE__ */ jsxs6("div", { css: styles6.grid, children: [
|
|
1876
|
+
/* @__PURE__ */ jsxs6("div", { children: [
|
|
1877
|
+
/* @__PURE__ */ jsx6("label", { css: styles6.label, children: "Small" }),
|
|
1878
|
+
/* @__PURE__ */ jsx6("input", { css: styles6.input, type: "number", defaultValue: 300 })
|
|
1940
1879
|
] }),
|
|
1941
|
-
/* @__PURE__ */
|
|
1942
|
-
/* @__PURE__ */
|
|
1943
|
-
/* @__PURE__ */
|
|
1880
|
+
/* @__PURE__ */ jsxs6("div", { children: [
|
|
1881
|
+
/* @__PURE__ */ jsx6("label", { css: styles6.label, children: "Medium" }),
|
|
1882
|
+
/* @__PURE__ */ jsx6("input", { css: styles6.input, type: "number", defaultValue: 700 })
|
|
1944
1883
|
] }),
|
|
1945
|
-
/* @__PURE__ */
|
|
1946
|
-
/* @__PURE__ */
|
|
1947
|
-
/* @__PURE__ */
|
|
1884
|
+
/* @__PURE__ */ jsxs6("div", { children: [
|
|
1885
|
+
/* @__PURE__ */ jsx6("label", { css: styles6.label, children: "Large" }),
|
|
1886
|
+
/* @__PURE__ */ jsx6("input", { css: styles6.input, type: "number", defaultValue: 1400 })
|
|
1948
1887
|
] })
|
|
1949
1888
|
] })
|
|
1950
1889
|
] })
|
|
1951
1890
|
] }),
|
|
1952
|
-
/* @__PURE__ */
|
|
1953
|
-
/* @__PURE__ */
|
|
1954
|
-
/* @__PURE__ */
|
|
1891
|
+
/* @__PURE__ */ jsxs6("div", { css: styles6.footer, children: [
|
|
1892
|
+
/* @__PURE__ */ jsx6("button", { css: styles6.cancelBtn, onClick: onClose, children: "Cancel" }),
|
|
1893
|
+
/* @__PURE__ */ jsx6("button", { css: styles6.saveBtn, children: "Save Changes" })
|
|
1955
1894
|
] })
|
|
1956
1895
|
] }) });
|
|
1957
1896
|
}
|
|
1958
1897
|
|
|
1959
1898
|
// src/components/StudioUI.tsx
|
|
1960
|
-
import { jsx as
|
|
1961
|
-
var
|
|
1962
|
-
|
|
1899
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "@emotion/react/jsx-runtime";
|
|
1900
|
+
var btnHeight3 = "36px";
|
|
1901
|
+
var styles7 = {
|
|
1902
|
+
container: css7`
|
|
1963
1903
|
${baseReset}
|
|
1964
1904
|
display: flex;
|
|
1965
1905
|
flex-direction: column;
|
|
1966
1906
|
height: 100%;
|
|
1967
1907
|
background: ${colors.background};
|
|
1968
1908
|
`,
|
|
1969
|
-
header:
|
|
1909
|
+
header: css7`
|
|
1970
1910
|
display: flex;
|
|
1971
1911
|
align-items: center;
|
|
1972
1912
|
justify-content: space-between;
|
|
1973
|
-
padding:
|
|
1913
|
+
padding: 12px 24px;
|
|
1974
1914
|
background: ${colors.surface};
|
|
1975
1915
|
border-bottom: 1px solid ${colors.border};
|
|
1976
1916
|
`,
|
|
1977
|
-
title:
|
|
1978
|
-
font-size: ${fontSize.
|
|
1917
|
+
title: css7`
|
|
1918
|
+
font-size: ${fontSize.lg};
|
|
1979
1919
|
font-weight: 600;
|
|
1980
1920
|
color: ${colors.text};
|
|
1981
1921
|
margin: 0;
|
|
1982
1922
|
letter-spacing: -0.02em;
|
|
1983
1923
|
`,
|
|
1984
|
-
headerActions:
|
|
1924
|
+
headerActions: css7`
|
|
1985
1925
|
display: flex;
|
|
1986
1926
|
align-items: center;
|
|
1987
1927
|
gap: 8px;
|
|
1988
1928
|
`,
|
|
1989
|
-
|
|
1990
|
-
|
|
1929
|
+
headerBtn: css7`
|
|
1930
|
+
height: ${btnHeight3};
|
|
1931
|
+
padding: 0 12px;
|
|
1991
1932
|
background: ${colors.surface};
|
|
1992
1933
|
border: 1px solid ${colors.border};
|
|
1993
1934
|
border-radius: 6px;
|
|
@@ -2002,17 +1943,17 @@ var styles8 = {
|
|
|
2002
1943
|
border-color: ${colors.borderHover};
|
|
2003
1944
|
}
|
|
2004
1945
|
`,
|
|
2005
|
-
|
|
2006
|
-
width:
|
|
2007
|
-
height:
|
|
1946
|
+
headerIcon: css7`
|
|
1947
|
+
width: 16px;
|
|
1948
|
+
height: 16px;
|
|
2008
1949
|
color: ${colors.textSecondary};
|
|
2009
1950
|
`,
|
|
2010
|
-
content:
|
|
1951
|
+
content: css7`
|
|
2011
1952
|
flex: 1;
|
|
2012
1953
|
display: flex;
|
|
2013
1954
|
overflow: hidden;
|
|
2014
1955
|
`,
|
|
2015
|
-
fileBrowser:
|
|
1956
|
+
fileBrowser: css7`
|
|
2016
1957
|
flex: 1;
|
|
2017
1958
|
min-width: 0;
|
|
2018
1959
|
overflow: auto;
|
|
@@ -2024,6 +1965,7 @@ function StudioUI({ onClose }) {
|
|
|
2024
1965
|
const [selectedItems, setSelectedItems] = useState6(/* @__PURE__ */ new Set());
|
|
2025
1966
|
const [lastSelectedPath, setLastSelectedPath] = useState6(null);
|
|
2026
1967
|
const [viewMode, setViewMode] = useState6("grid");
|
|
1968
|
+
const [focusedItem, setFocusedItem] = useState6(null);
|
|
2027
1969
|
const [meta, setMeta] = useState6(null);
|
|
2028
1970
|
const [isLoading, setIsLoading] = useState6(false);
|
|
2029
1971
|
const [refreshKey, setRefreshKey] = useState6(0);
|
|
@@ -2040,6 +1982,7 @@ function StudioUI({ onClose }) {
|
|
|
2040
1982
|
const setCurrentPath = useCallback2((path) => {
|
|
2041
1983
|
setCurrentPathInternal(path);
|
|
2042
1984
|
setSelectedItems(/* @__PURE__ */ new Set());
|
|
1985
|
+
setFocusedItem(null);
|
|
2043
1986
|
}, []);
|
|
2044
1987
|
const toggleSelection = useCallback2((path) => {
|
|
2045
1988
|
setSelectedItems((prev) => {
|
|
@@ -2077,10 +2020,14 @@ function StudioUI({ onClose }) {
|
|
|
2077
2020
|
const handleKeyDown = useCallback2(
|
|
2078
2021
|
(e) => {
|
|
2079
2022
|
if (e.key === "Escape") {
|
|
2080
|
-
|
|
2023
|
+
if (focusedItem) {
|
|
2024
|
+
setFocusedItem(null);
|
|
2025
|
+
} else {
|
|
2026
|
+
onClose();
|
|
2027
|
+
}
|
|
2081
2028
|
}
|
|
2082
2029
|
},
|
|
2083
|
-
[onClose]
|
|
2030
|
+
[onClose, focusedItem]
|
|
2084
2031
|
);
|
|
2085
2032
|
useEffect3(() => {
|
|
2086
2033
|
document.addEventListener("keydown", handleKeyDown);
|
|
@@ -2107,6 +2054,8 @@ function StudioUI({ onClose }) {
|
|
|
2107
2054
|
lastSelectedPath,
|
|
2108
2055
|
viewMode,
|
|
2109
2056
|
setViewMode,
|
|
2057
|
+
focusedItem,
|
|
2058
|
+
setFocusedItem,
|
|
2110
2059
|
meta,
|
|
2111
2060
|
setMeta,
|
|
2112
2061
|
isLoading,
|
|
@@ -2114,35 +2063,31 @@ function StudioUI({ onClose }) {
|
|
|
2114
2063
|
refreshKey,
|
|
2115
2064
|
triggerRefresh
|
|
2116
2065
|
};
|
|
2117
|
-
return /* @__PURE__ */
|
|
2118
|
-
/* @__PURE__ */
|
|
2119
|
-
/* @__PURE__ */
|
|
2120
|
-
/* @__PURE__ */
|
|
2121
|
-
/* @__PURE__ */
|
|
2122
|
-
/* @__PURE__ */
|
|
2066
|
+
return /* @__PURE__ */ jsx7(StudioContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs7("div", { css: styles7.container, children: [
|
|
2067
|
+
/* @__PURE__ */ jsxs7("div", { css: styles7.header, children: [
|
|
2068
|
+
/* @__PURE__ */ jsx7("h1", { css: styles7.title, children: "Studio" }),
|
|
2069
|
+
/* @__PURE__ */ jsxs7("div", { css: styles7.headerActions, children: [
|
|
2070
|
+
/* @__PURE__ */ jsx7(StudioSettings, {}),
|
|
2071
|
+
/* @__PURE__ */ jsx7(
|
|
2123
2072
|
"button",
|
|
2124
2073
|
{
|
|
2125
|
-
css:
|
|
2074
|
+
css: styles7.headerBtn,
|
|
2126
2075
|
onClick: onClose,
|
|
2127
2076
|
"aria-label": "Close Studio",
|
|
2128
|
-
children: /* @__PURE__ */
|
|
2077
|
+
children: /* @__PURE__ */ jsx7(CloseIcon, {})
|
|
2129
2078
|
}
|
|
2130
2079
|
)
|
|
2131
2080
|
] })
|
|
2132
2081
|
] }),
|
|
2133
|
-
/* @__PURE__ */
|
|
2134
|
-
/* @__PURE__ */
|
|
2135
|
-
/* @__PURE__ */ jsxs8("div", { css: styles8.content, children: [
|
|
2136
|
-
/* @__PURE__ */ jsx8("div", { css: styles8.fileBrowser, children: viewMode === "grid" ? /* @__PURE__ */ jsx8(StudioFileGrid, {}) : /* @__PURE__ */ jsx8(StudioFileList, {}) }),
|
|
2137
|
-
/* @__PURE__ */ jsx8(StudioPreview, {})
|
|
2138
|
-
] })
|
|
2082
|
+
/* @__PURE__ */ jsx7(StudioToolbar, {}),
|
|
2083
|
+
/* @__PURE__ */ jsx7("div", { css: styles7.content, children: focusedItem ? /* @__PURE__ */ jsx7(StudioDetailView, {}) : /* @__PURE__ */ jsx7("div", { css: styles7.fileBrowser, children: viewMode === "grid" ? /* @__PURE__ */ jsx7(StudioFileGrid, {}) : /* @__PURE__ */ jsx7(StudioFileList, {}) }) })
|
|
2139
2084
|
] }) });
|
|
2140
2085
|
}
|
|
2141
2086
|
function CloseIcon() {
|
|
2142
|
-
return /* @__PURE__ */
|
|
2087
|
+
return /* @__PURE__ */ jsxs7(
|
|
2143
2088
|
"svg",
|
|
2144
2089
|
{
|
|
2145
|
-
css:
|
|
2090
|
+
css: styles7.headerIcon,
|
|
2146
2091
|
xmlns: "http://www.w3.org/2000/svg",
|
|
2147
2092
|
viewBox: "0 0 24 24",
|
|
2148
2093
|
fill: "none",
|
|
@@ -2151,8 +2096,8 @@ function CloseIcon() {
|
|
|
2151
2096
|
strokeLinecap: "round",
|
|
2152
2097
|
strokeLinejoin: "round",
|
|
2153
2098
|
children: [
|
|
2154
|
-
/* @__PURE__ */
|
|
2155
|
-
/* @__PURE__ */
|
|
2099
|
+
/* @__PURE__ */ jsx7("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
|
|
2100
|
+
/* @__PURE__ */ jsx7("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
|
|
2156
2101
|
]
|
|
2157
2102
|
}
|
|
2158
2103
|
);
|
|
@@ -2162,4 +2107,4 @@ export {
|
|
|
2162
2107
|
StudioUI,
|
|
2163
2108
|
StudioUI_default as default
|
|
2164
2109
|
};
|
|
2165
|
-
//# sourceMappingURL=StudioUI-
|
|
2110
|
+
//# sourceMappingURL=StudioUI-QPAHJJ64.mjs.map
|