@gallop.software/studio 0.1.21 → 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-QMBOCTJD.js → StudioUI-2BWLIO4W.js} +654 -779
- package/dist/StudioUI-2BWLIO4W.js.map +1 -0
- package/dist/{StudioUI-WRFD73YR.mjs → StudioUI-QPAHJJ64.mjs} +746 -871
- package/dist/StudioUI-QPAHJJ64.mjs.map +1 -0
- package/dist/chunk-AY2DAS6W.js +64 -0
- package/dist/chunk-AY2DAS6W.js.map +1 -0
- package/dist/chunk-R5WKNVEV.mjs +64 -0
- package/dist/chunk-R5WKNVEV.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 +20 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +11 -14
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/StudioUI-QMBOCTJD.js.map +0 -1
- package/dist/StudioUI-WRFD73YR.mjs.map +0 -1
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import {
|
|
3
|
+
baseReset,
|
|
4
|
+
colors,
|
|
5
|
+
fontSize,
|
|
6
|
+
fontStack
|
|
7
|
+
} from "./chunk-R5WKNVEV.mjs";
|
|
2
8
|
|
|
3
9
|
// src/components/StudioUI.tsx
|
|
4
10
|
import { useEffect as useEffect3, useCallback as useCallback2, useState as useState6 } from "react";
|
|
5
|
-
import { css as
|
|
11
|
+
import { css as css7 } from "@emotion/react";
|
|
6
12
|
|
|
7
13
|
// src/components/StudioContext.tsx
|
|
8
14
|
import { createContext, useContext } from "react";
|
|
@@ -32,6 +38,9 @@ var defaultState = {
|
|
|
32
38
|
viewMode: "grid",
|
|
33
39
|
setViewMode: () => {
|
|
34
40
|
},
|
|
41
|
+
focusedItem: null,
|
|
42
|
+
setFocusedItem: () => {
|
|
43
|
+
},
|
|
35
44
|
meta: null,
|
|
36
45
|
setMeta: () => {
|
|
37
46
|
},
|
|
@@ -54,18 +63,6 @@ import { css as css2, keyframes as keyframes2 } from "@emotion/react";
|
|
|
54
63
|
// src/components/StudioModal.tsx
|
|
55
64
|
import { css, keyframes } from "@emotion/react";
|
|
56
65
|
import { jsx, jsxs } from "@emotion/react/jsx-runtime";
|
|
57
|
-
var colors = {
|
|
58
|
-
primary: "#635bff",
|
|
59
|
-
primaryHover: "#5851e5",
|
|
60
|
-
background: "#f6f9fc",
|
|
61
|
-
surface: "#ffffff",
|
|
62
|
-
surfaceHover: "#f6f9fc",
|
|
63
|
-
border: "#e3e8ee",
|
|
64
|
-
text: "#1a1f36",
|
|
65
|
-
textSecondary: "#697386",
|
|
66
|
-
danger: "#df1b41",
|
|
67
|
-
dangerHover: "#c41535"
|
|
68
|
-
};
|
|
69
66
|
var fadeIn = keyframes`
|
|
70
67
|
from { opacity: 0; }
|
|
71
68
|
to { opacity: 1; }
|
|
@@ -91,8 +88,10 @@ var styles = {
|
|
|
91
88
|
justify-content: center;
|
|
92
89
|
z-index: 10000;
|
|
93
90
|
animation: ${fadeIn} 0.15s ease-out;
|
|
91
|
+
font-family: ${fontStack};
|
|
94
92
|
`,
|
|
95
93
|
modal: css`
|
|
94
|
+
${baseReset}
|
|
96
95
|
background-color: ${colors.surface};
|
|
97
96
|
border-radius: 12px;
|
|
98
97
|
box-shadow: 0 30px 60px -12px rgba(50, 50, 93, 0.25), 0 18px 36px -18px rgba(0, 0, 0, 0.3);
|
|
@@ -105,7 +104,7 @@ var styles = {
|
|
|
105
104
|
padding: 24px 24px 0;
|
|
106
105
|
`,
|
|
107
106
|
title: css`
|
|
108
|
-
font-size:
|
|
107
|
+
font-size: ${fontSize.lg};
|
|
109
108
|
font-weight: 600;
|
|
110
109
|
color: ${colors.text};
|
|
111
110
|
margin: 0;
|
|
@@ -115,7 +114,7 @@ var styles = {
|
|
|
115
114
|
padding: 12px 24px 24px;
|
|
116
115
|
`,
|
|
117
116
|
message: css`
|
|
118
|
-
font-size:
|
|
117
|
+
font-size: ${fontSize.base};
|
|
119
118
|
color: ${colors.textSecondary};
|
|
120
119
|
margin: 0;
|
|
121
120
|
line-height: 1.6;
|
|
@@ -130,7 +129,7 @@ var styles = {
|
|
|
130
129
|
`,
|
|
131
130
|
btn: css`
|
|
132
131
|
padding: 10px 18px;
|
|
133
|
-
font-size:
|
|
132
|
+
font-size: ${fontSize.base};
|
|
134
133
|
font-weight: 500;
|
|
135
134
|
border-radius: 6px;
|
|
136
135
|
cursor: pointer;
|
|
@@ -144,7 +143,7 @@ var styles = {
|
|
|
144
143
|
|
|
145
144
|
&:hover {
|
|
146
145
|
background-color: ${colors.surfaceHover};
|
|
147
|
-
border-color:
|
|
146
|
+
border-color: ${colors.borderHover};
|
|
148
147
|
}
|
|
149
148
|
`,
|
|
150
149
|
btnConfirm: css`
|
|
@@ -208,19 +207,7 @@ function AlertModal({
|
|
|
208
207
|
|
|
209
208
|
// src/components/StudioToolbar.tsx
|
|
210
209
|
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "@emotion/react/jsx-runtime";
|
|
211
|
-
var
|
|
212
|
-
primary: "#635bff",
|
|
213
|
-
primaryHover: "#5851e5",
|
|
214
|
-
primaryLight: "#f0f0ff",
|
|
215
|
-
background: "#ffffff",
|
|
216
|
-
surface: "#ffffff",
|
|
217
|
-
surfaceHover: "#f6f9fc",
|
|
218
|
-
border: "#e3e8ee",
|
|
219
|
-
text: "#1a1f36",
|
|
220
|
-
textSecondary: "#697386",
|
|
221
|
-
danger: "#df1b41",
|
|
222
|
-
dangerLight: "#fff5f7"
|
|
223
|
-
};
|
|
210
|
+
var btnHeight = "36px";
|
|
224
211
|
var spin = keyframes2`
|
|
225
212
|
to { transform: rotate(360deg); }
|
|
226
213
|
`;
|
|
@@ -230,37 +217,39 @@ var styles2 = {
|
|
|
230
217
|
align-items: center;
|
|
231
218
|
justify-content: space-between;
|
|
232
219
|
padding: 12px 24px;
|
|
233
|
-
background-color: ${
|
|
234
|
-
border-bottom: 1px solid ${
|
|
220
|
+
background-color: ${colors.surface};
|
|
221
|
+
border-bottom: 1px solid ${colors.border};
|
|
235
222
|
`,
|
|
236
223
|
left: css2`
|
|
237
224
|
display: flex;
|
|
238
225
|
align-items: center;
|
|
239
|
-
gap:
|
|
226
|
+
gap: 8px;
|
|
240
227
|
`,
|
|
241
228
|
right: css2`
|
|
242
229
|
display: flex;
|
|
243
230
|
align-items: center;
|
|
244
|
-
gap:
|
|
231
|
+
gap: 8px;
|
|
245
232
|
`,
|
|
246
233
|
btn: css2`
|
|
247
234
|
display: inline-flex;
|
|
248
235
|
align-items: center;
|
|
236
|
+
justify-content: center;
|
|
249
237
|
gap: 6px;
|
|
250
|
-
|
|
238
|
+
height: ${btnHeight};
|
|
239
|
+
padding: 0 14px;
|
|
251
240
|
border-radius: 6px;
|
|
252
|
-
font-size:
|
|
241
|
+
font-size: ${fontSize.base};
|
|
253
242
|
font-weight: 500;
|
|
254
|
-
background: ${
|
|
255
|
-
border: 1px solid ${
|
|
243
|
+
background: ${colors.surface};
|
|
244
|
+
border: 1px solid ${colors.border};
|
|
256
245
|
cursor: pointer;
|
|
257
246
|
transition: all 0.15s ease;
|
|
258
|
-
color: ${
|
|
247
|
+
color: ${colors.text};
|
|
259
248
|
letter-spacing: -0.01em;
|
|
260
249
|
|
|
261
250
|
&:hover:not(:disabled) {
|
|
262
|
-
background-color: ${
|
|
263
|
-
border-color:
|
|
251
|
+
background-color: ${colors.surfaceHover};
|
|
252
|
+
border-color: ${colors.borderHover};
|
|
264
253
|
}
|
|
265
254
|
|
|
266
255
|
&:disabled {
|
|
@@ -268,53 +257,48 @@ var styles2 = {
|
|
|
268
257
|
opacity: 0.5;
|
|
269
258
|
}
|
|
270
259
|
`,
|
|
260
|
+
btnIconOnly: css2`
|
|
261
|
+
padding: 0 10px;
|
|
262
|
+
`,
|
|
271
263
|
btnPrimary: css2`
|
|
272
|
-
background: ${
|
|
273
|
-
border-color: ${
|
|
264
|
+
background: ${colors.primary};
|
|
265
|
+
border-color: ${colors.primary};
|
|
274
266
|
color: white;
|
|
275
267
|
|
|
276
268
|
&:hover:not(:disabled) {
|
|
277
|
-
background: ${
|
|
278
|
-
border-color: ${
|
|
269
|
+
background: ${colors.primaryHover};
|
|
270
|
+
border-color: ${colors.primaryHover};
|
|
279
271
|
}
|
|
280
272
|
`,
|
|
281
273
|
btnDanger: css2`
|
|
282
|
-
color: ${
|
|
283
|
-
|
|
284
|
-
&:hover:not(:disabled) {
|
|
285
|
-
background-color: ${colors2.dangerLight};
|
|
286
|
-
border-color: ${colors2.danger};
|
|
287
|
-
}
|
|
288
|
-
`,
|
|
289
|
-
btnGhost: css2`
|
|
290
|
-
border-color: transparent;
|
|
291
|
-
background: transparent;
|
|
274
|
+
color: ${colors.danger};
|
|
292
275
|
|
|
293
276
|
&:hover:not(:disabled) {
|
|
294
|
-
background-color: ${
|
|
295
|
-
border-color:
|
|
277
|
+
background-color: ${colors.dangerLight};
|
|
278
|
+
border-color: ${colors.danger};
|
|
296
279
|
}
|
|
297
280
|
`,
|
|
298
281
|
icon: css2`
|
|
299
|
-
width:
|
|
300
|
-
height:
|
|
282
|
+
width: 16px;
|
|
283
|
+
height: 16px;
|
|
301
284
|
`,
|
|
302
285
|
iconSpin: css2`
|
|
303
286
|
animation: ${spin} 1s linear infinite;
|
|
304
287
|
`,
|
|
305
288
|
selectionCount: css2`
|
|
306
|
-
font-size:
|
|
307
|
-
color: ${
|
|
289
|
+
font-size: ${fontSize.base};
|
|
290
|
+
color: ${colors.textSecondary};
|
|
308
291
|
display: flex;
|
|
309
292
|
align-items: center;
|
|
310
293
|
gap: 8px;
|
|
294
|
+
margin-right: 8px;
|
|
311
295
|
`,
|
|
312
296
|
clearBtn: css2`
|
|
313
|
-
color: ${
|
|
297
|
+
color: ${colors.primary};
|
|
314
298
|
background: none;
|
|
315
299
|
border: none;
|
|
316
300
|
cursor: pointer;
|
|
317
|
-
font-size:
|
|
301
|
+
font-size: ${fontSize.base};
|
|
318
302
|
font-weight: 500;
|
|
319
303
|
padding: 0;
|
|
320
304
|
|
|
@@ -324,41 +308,43 @@ var styles2 = {
|
|
|
324
308
|
`,
|
|
325
309
|
divider: css2`
|
|
326
310
|
width: 1px;
|
|
327
|
-
height:
|
|
328
|
-
background: ${
|
|
311
|
+
height: 24px;
|
|
312
|
+
background: ${colors.border};
|
|
329
313
|
margin: 0 4px;
|
|
330
314
|
`,
|
|
331
315
|
viewToggle: css2`
|
|
332
316
|
display: flex;
|
|
333
317
|
align-items: center;
|
|
334
|
-
|
|
318
|
+
height: ${btnHeight};
|
|
319
|
+
background-color: ${colors.surface};
|
|
320
|
+
border: 1px solid ${colors.border};
|
|
335
321
|
border-radius: 6px;
|
|
336
|
-
|
|
322
|
+
overflow: hidden;
|
|
337
323
|
`,
|
|
338
324
|
viewBtn: css2`
|
|
339
|
-
|
|
325
|
+
height: 100%;
|
|
326
|
+
padding: 0 10px;
|
|
340
327
|
background: transparent;
|
|
341
328
|
border: none;
|
|
342
|
-
border-radius: 4px;
|
|
343
329
|
cursor: pointer;
|
|
344
|
-
color: ${
|
|
330
|
+
color: ${colors.textSecondary};
|
|
345
331
|
transition: all 0.15s ease;
|
|
346
332
|
display: flex;
|
|
347
333
|
align-items: center;
|
|
348
334
|
justify-content: center;
|
|
349
335
|
|
|
350
336
|
&:hover {
|
|
351
|
-
color: ${
|
|
337
|
+
color: ${colors.text};
|
|
338
|
+
background-color: ${colors.surfaceHover};
|
|
352
339
|
}
|
|
353
340
|
`,
|
|
354
341
|
viewBtnActive: css2`
|
|
355
|
-
background-color: ${
|
|
356
|
-
color: ${
|
|
357
|
-
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
342
|
+
background-color: ${colors.background};
|
|
343
|
+
color: ${colors.text};
|
|
358
344
|
`
|
|
359
345
|
};
|
|
360
346
|
function StudioToolbar() {
|
|
361
|
-
const { selectedItems, viewMode, setViewMode, clearSelection, currentPath, triggerRefresh } = useStudio();
|
|
347
|
+
const { selectedItems, viewMode, setViewMode, clearSelection, currentPath, triggerRefresh, focusedItem } = useStudio();
|
|
362
348
|
const fileInputRef = useRef(null);
|
|
363
349
|
const [uploading, setUploading] = useState(false);
|
|
364
350
|
const [refreshing, setRefreshing] = useState(false);
|
|
@@ -456,6 +442,9 @@ function StudioToolbar() {
|
|
|
456
442
|
console.log("Scan clicked");
|
|
457
443
|
}, []);
|
|
458
444
|
const hasSelection = selectedItems.size > 0;
|
|
445
|
+
if (focusedItem) {
|
|
446
|
+
return null;
|
|
447
|
+
}
|
|
459
448
|
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
460
449
|
showDeleteConfirm && /* @__PURE__ */ jsx2(
|
|
461
450
|
ConfirmModal,
|
|
@@ -505,7 +494,7 @@ function StudioToolbar() {
|
|
|
505
494
|
/* @__PURE__ */ jsxs2(
|
|
506
495
|
"button",
|
|
507
496
|
{
|
|
508
|
-
css:
|
|
497
|
+
css: styles2.btn,
|
|
509
498
|
onClick: handleReprocess,
|
|
510
499
|
disabled: !hasSelection,
|
|
511
500
|
children: [
|
|
@@ -517,7 +506,7 @@ function StudioToolbar() {
|
|
|
517
506
|
/* @__PURE__ */ jsxs2(
|
|
518
507
|
"button",
|
|
519
508
|
{
|
|
520
|
-
css: [styles2.btn, styles2.
|
|
509
|
+
css: [styles2.btn, styles2.btnDanger],
|
|
521
510
|
onClick: handleDeleteClick,
|
|
522
511
|
disabled: !hasSelection,
|
|
523
512
|
children: [
|
|
@@ -529,7 +518,7 @@ function StudioToolbar() {
|
|
|
529
518
|
/* @__PURE__ */ jsxs2(
|
|
530
519
|
"button",
|
|
531
520
|
{
|
|
532
|
-
css:
|
|
521
|
+
css: styles2.btn,
|
|
533
522
|
onClick: handleSyncCdn,
|
|
534
523
|
disabled: !hasSelection,
|
|
535
524
|
children: [
|
|
@@ -538,7 +527,7 @@ function StudioToolbar() {
|
|
|
538
527
|
]
|
|
539
528
|
}
|
|
540
529
|
),
|
|
541
|
-
/* @__PURE__ */ jsxs2("button", { css:
|
|
530
|
+
/* @__PURE__ */ jsxs2("button", { css: styles2.btn, onClick: handleScan, children: [
|
|
542
531
|
/* @__PURE__ */ jsx2(ScanIcon, {}),
|
|
543
532
|
"Scan"
|
|
544
533
|
] })
|
|
@@ -552,7 +541,7 @@ function StudioToolbar() {
|
|
|
552
541
|
/* @__PURE__ */ jsx2(
|
|
553
542
|
"button",
|
|
554
543
|
{
|
|
555
|
-
css: [styles2.btn, styles2.
|
|
544
|
+
css: [styles2.btn, styles2.btnIconOnly],
|
|
556
545
|
onClick: handleRefresh,
|
|
557
546
|
children: /* @__PURE__ */ jsx2(RefreshIcon, { spinning: refreshing })
|
|
558
547
|
}
|
|
@@ -603,174 +592,52 @@ function ListIcon() {
|
|
|
603
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" }) });
|
|
604
593
|
}
|
|
605
594
|
|
|
606
|
-
// src/components/StudioBreadcrumb.tsx
|
|
607
|
-
import { css as css3 } from "@emotion/react";
|
|
608
|
-
import { jsx as jsx3, jsxs as jsxs3 } from "@emotion/react/jsx-runtime";
|
|
609
|
-
var colors3 = {
|
|
610
|
-
primary: "#635bff",
|
|
611
|
-
background: "#ffffff",
|
|
612
|
-
surface: "#ffffff",
|
|
613
|
-
surfaceHover: "#f6f9fc",
|
|
614
|
-
border: "#e3e8ee",
|
|
615
|
-
borderLight: "#eef1f6",
|
|
616
|
-
text: "#1a1f36",
|
|
617
|
-
textSecondary: "#697386",
|
|
618
|
-
textMuted: "#8792a2"
|
|
619
|
-
};
|
|
620
|
-
var styles3 = {
|
|
621
|
-
container: css3`
|
|
622
|
-
display: flex;
|
|
623
|
-
align-items: center;
|
|
624
|
-
gap: 8px;
|
|
625
|
-
padding: 10px 24px;
|
|
626
|
-
background-color: ${colors3.surface};
|
|
627
|
-
border-bottom: 1px solid ${colors3.borderLight};
|
|
628
|
-
`,
|
|
629
|
-
backBtn: css3`
|
|
630
|
-
padding: 6px;
|
|
631
|
-
background: none;
|
|
632
|
-
border: none;
|
|
633
|
-
border-radius: 6px;
|
|
634
|
-
cursor: pointer;
|
|
635
|
-
transition: all 0.15s ease;
|
|
636
|
-
display: flex;
|
|
637
|
-
align-items: center;
|
|
638
|
-
justify-content: center;
|
|
639
|
-
|
|
640
|
-
&:hover {
|
|
641
|
-
background-color: ${colors3.surfaceHover};
|
|
642
|
-
}
|
|
643
|
-
`,
|
|
644
|
-
backIcon: css3`
|
|
645
|
-
width: 16px;
|
|
646
|
-
height: 16px;
|
|
647
|
-
color: ${colors3.textSecondary};
|
|
648
|
-
`,
|
|
649
|
-
nav: css3`
|
|
650
|
-
display: flex;
|
|
651
|
-
align-items: center;
|
|
652
|
-
gap: 2px;
|
|
653
|
-
font-size: 13px;
|
|
654
|
-
`,
|
|
655
|
-
item: css3`
|
|
656
|
-
display: flex;
|
|
657
|
-
align-items: center;
|
|
658
|
-
gap: 2px;
|
|
659
|
-
`,
|
|
660
|
-
separator: css3`
|
|
661
|
-
color: ${colors3.textMuted};
|
|
662
|
-
margin: 0 2px;
|
|
663
|
-
`,
|
|
664
|
-
btn: css3`
|
|
665
|
-
padding: 4px 8px;
|
|
666
|
-
background: none;
|
|
667
|
-
border: none;
|
|
668
|
-
border-radius: 4px;
|
|
669
|
-
cursor: pointer;
|
|
670
|
-
transition: all 0.15s ease;
|
|
671
|
-
font-size: 13px;
|
|
672
|
-
letter-spacing: -0.01em;
|
|
673
|
-
|
|
674
|
-
&:hover {
|
|
675
|
-
background-color: ${colors3.surfaceHover};
|
|
676
|
-
}
|
|
677
|
-
`,
|
|
678
|
-
btnActive: css3`
|
|
679
|
-
color: ${colors3.text};
|
|
680
|
-
font-weight: 600;
|
|
681
|
-
`,
|
|
682
|
-
btnInactive: css3`
|
|
683
|
-
color: ${colors3.textSecondary};
|
|
684
|
-
|
|
685
|
-
&:hover {
|
|
686
|
-
color: ${colors3.text};
|
|
687
|
-
}
|
|
688
|
-
`
|
|
689
|
-
};
|
|
690
|
-
function StudioBreadcrumb() {
|
|
691
|
-
const { currentPath, setCurrentPath, navigateUp } = useStudio();
|
|
692
|
-
const parts = currentPath.split("/").filter(Boolean);
|
|
693
|
-
const handleClick = (index) => {
|
|
694
|
-
const newPath = parts.slice(0, index + 1).join("/");
|
|
695
|
-
setCurrentPath(newPath);
|
|
696
|
-
};
|
|
697
|
-
return /* @__PURE__ */ jsxs3("div", { css: styles3.container, children: [
|
|
698
|
-
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" }) }) }),
|
|
699
|
-
/* @__PURE__ */ jsx3("nav", { css: styles3.nav, children: parts.map((part, index) => /* @__PURE__ */ jsxs3("span", { css: styles3.item, children: [
|
|
700
|
-
index > 0 && /* @__PURE__ */ jsx3("span", { css: styles3.separator, children: "/" }),
|
|
701
|
-
/* @__PURE__ */ jsx3(
|
|
702
|
-
"button",
|
|
703
|
-
{
|
|
704
|
-
css: [styles3.btn, index === parts.length - 1 ? styles3.btnActive : styles3.btnInactive],
|
|
705
|
-
onClick: () => handleClick(index),
|
|
706
|
-
children: part
|
|
707
|
-
}
|
|
708
|
-
)
|
|
709
|
-
] }, index)) })
|
|
710
|
-
] });
|
|
711
|
-
}
|
|
712
|
-
|
|
713
595
|
// src/components/StudioFileGrid.tsx
|
|
714
596
|
import { useEffect, useState as useState2 } from "react";
|
|
715
|
-
import { css as
|
|
716
|
-
import { jsx as
|
|
717
|
-
var colors4 = {
|
|
718
|
-
primary: "#635bff",
|
|
719
|
-
primaryHover: "#5851e5",
|
|
720
|
-
primaryLight: "#f0f0ff",
|
|
721
|
-
background: "#f6f9fc",
|
|
722
|
-
surface: "#ffffff",
|
|
723
|
-
surfaceHover: "#f6f9fc",
|
|
724
|
-
border: "#e3e8ee",
|
|
725
|
-
borderLight: "#eef1f6",
|
|
726
|
-
text: "#1a1f36",
|
|
727
|
-
textSecondary: "#697386",
|
|
728
|
-
textMuted: "#8792a2",
|
|
729
|
-
success: "#0d7d4d",
|
|
730
|
-
successLight: "#e6f7ef"
|
|
731
|
-
};
|
|
597
|
+
import { css as css3, keyframes as keyframes3 } from "@emotion/react";
|
|
598
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "@emotion/react/jsx-runtime";
|
|
732
599
|
var spin2 = keyframes3`
|
|
733
600
|
to { transform: rotate(360deg); }
|
|
734
601
|
`;
|
|
735
|
-
var
|
|
736
|
-
loading:
|
|
602
|
+
var styles3 = {
|
|
603
|
+
loading: css3`
|
|
737
604
|
display: flex;
|
|
738
605
|
align-items: center;
|
|
739
606
|
justify-content: center;
|
|
740
607
|
height: 256px;
|
|
741
608
|
`,
|
|
742
|
-
spinner:
|
|
609
|
+
spinner: css3`
|
|
743
610
|
width: 32px;
|
|
744
611
|
height: 32px;
|
|
745
612
|
border-radius: 50%;
|
|
746
|
-
border: 3px solid ${
|
|
747
|
-
border-top-color: ${
|
|
613
|
+
border: 3px solid ${colors.border};
|
|
614
|
+
border-top-color: ${colors.primary};
|
|
748
615
|
animation: ${spin2} 0.8s linear infinite;
|
|
749
616
|
`,
|
|
750
|
-
empty:
|
|
617
|
+
empty: css3`
|
|
751
618
|
display: flex;
|
|
752
619
|
flex-direction: column;
|
|
753
620
|
align-items: center;
|
|
754
621
|
justify-content: center;
|
|
755
622
|
height: 256px;
|
|
756
|
-
color: ${
|
|
623
|
+
color: ${colors.textSecondary};
|
|
757
624
|
`,
|
|
758
|
-
emptyIcon:
|
|
625
|
+
emptyIcon: css3`
|
|
759
626
|
width: 48px;
|
|
760
627
|
height: 48px;
|
|
761
628
|
margin-bottom: 16px;
|
|
762
629
|
opacity: 0.5;
|
|
763
630
|
`,
|
|
764
|
-
emptyText:
|
|
765
|
-
font-size:
|
|
631
|
+
emptyText: css3`
|
|
632
|
+
font-size: ${fontSize.base};
|
|
766
633
|
margin: 0 0 4px 0;
|
|
767
634
|
|
|
768
635
|
&:last-child {
|
|
769
|
-
color: ${
|
|
770
|
-
font-size:
|
|
636
|
+
color: ${colors.textMuted};
|
|
637
|
+
font-size: ${fontSize.sm};
|
|
771
638
|
}
|
|
772
639
|
`,
|
|
773
|
-
grid:
|
|
640
|
+
grid: css3`
|
|
774
641
|
display: grid;
|
|
775
642
|
grid-template-columns: repeat(2, 1fr);
|
|
776
643
|
gap: 12px;
|
|
@@ -780,14 +647,14 @@ var styles4 = {
|
|
|
780
647
|
@media (min-width: 1024px) { grid-template-columns: repeat(5, 1fr); }
|
|
781
648
|
@media (min-width: 1280px) { grid-template-columns: repeat(6, 1fr); }
|
|
782
649
|
`,
|
|
783
|
-
item:
|
|
650
|
+
item: css3`
|
|
784
651
|
position: relative;
|
|
785
652
|
border-radius: 8px;
|
|
786
|
-
border: 1px solid ${
|
|
653
|
+
border: 1px solid ${colors.border};
|
|
787
654
|
overflow: hidden;
|
|
788
655
|
cursor: pointer;
|
|
789
656
|
transition: all 0.15s ease;
|
|
790
|
-
background-color: ${
|
|
657
|
+
background-color: ${colors.surface};
|
|
791
658
|
user-select: none;
|
|
792
659
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
|
|
793
660
|
|
|
@@ -796,15 +663,22 @@ var styles4 = {
|
|
|
796
663
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.06);
|
|
797
664
|
}
|
|
798
665
|
`,
|
|
799
|
-
itemSelected:
|
|
800
|
-
border-color: ${
|
|
801
|
-
box-shadow: 0 0 0 1px ${
|
|
666
|
+
itemSelected: css3`
|
|
667
|
+
border-color: ${colors.primary};
|
|
668
|
+
box-shadow: 0 0 0 1px ${colors.primary};
|
|
669
|
+
|
|
670
|
+
&:hover {
|
|
671
|
+
border-color: ${colors.primary};
|
|
672
|
+
}
|
|
673
|
+
`,
|
|
674
|
+
parentItem: css3`
|
|
675
|
+
cursor: pointer;
|
|
802
676
|
|
|
803
677
|
&:hover {
|
|
804
|
-
border-color: ${
|
|
678
|
+
border-color: ${colors.primary};
|
|
805
679
|
}
|
|
806
680
|
`,
|
|
807
|
-
checkboxWrapper:
|
|
681
|
+
checkboxWrapper: css3`
|
|
808
682
|
position: absolute;
|
|
809
683
|
top: 0;
|
|
810
684
|
left: 0;
|
|
@@ -812,124 +686,133 @@ var styles4 = {
|
|
|
812
686
|
padding: 8px;
|
|
813
687
|
cursor: pointer;
|
|
814
688
|
`,
|
|
815
|
-
checkbox:
|
|
689
|
+
checkbox: css3`
|
|
816
690
|
width: 16px;
|
|
817
691
|
height: 16px;
|
|
818
|
-
accent-color: ${
|
|
692
|
+
accent-color: ${colors.primary};
|
|
819
693
|
cursor: pointer;
|
|
820
694
|
`,
|
|
821
|
-
cdnBadge:
|
|
695
|
+
cdnBadge: css3`
|
|
822
696
|
position: absolute;
|
|
823
697
|
top: 8px;
|
|
824
698
|
right: 8px;
|
|
825
699
|
z-index: 10;
|
|
826
|
-
background-color: ${
|
|
827
|
-
color: ${
|
|
700
|
+
background-color: ${colors.successLight};
|
|
701
|
+
color: ${colors.success};
|
|
828
702
|
font-size: 11px;
|
|
829
703
|
font-weight: 500;
|
|
830
704
|
padding: 2px 8px;
|
|
831
705
|
border-radius: 4px;
|
|
832
706
|
`,
|
|
833
|
-
content:
|
|
707
|
+
content: css3`
|
|
834
708
|
aspect-ratio: 1;
|
|
835
709
|
display: flex;
|
|
836
710
|
align-items: center;
|
|
837
711
|
justify-content: center;
|
|
838
712
|
padding: 16px;
|
|
839
|
-
background: ${
|
|
713
|
+
background: ${colors.background};
|
|
840
714
|
`,
|
|
841
|
-
folderIcon:
|
|
715
|
+
folderIcon: css3`
|
|
842
716
|
width: 56px;
|
|
843
717
|
height: 56px;
|
|
844
718
|
color: #f5a623;
|
|
845
719
|
`,
|
|
846
|
-
|
|
720
|
+
parentIcon: css3`
|
|
721
|
+
width: 56px;
|
|
722
|
+
height: 56px;
|
|
723
|
+
color: ${colors.textMuted};
|
|
724
|
+
`,
|
|
725
|
+
fileIcon: css3`
|
|
847
726
|
width: 40px;
|
|
848
727
|
height: 40px;
|
|
849
|
-
color: ${
|
|
728
|
+
color: ${colors.textMuted};
|
|
850
729
|
`,
|
|
851
|
-
image:
|
|
730
|
+
image: css3`
|
|
852
731
|
max-width: 100%;
|
|
853
732
|
max-height: 100%;
|
|
854
733
|
object-fit: contain;
|
|
855
734
|
border-radius: 4px;
|
|
856
735
|
`,
|
|
857
|
-
label:
|
|
736
|
+
label: css3`
|
|
858
737
|
padding: 10px 12px;
|
|
859
|
-
background-color: ${
|
|
860
|
-
border-top: 1px solid ${
|
|
738
|
+
background-color: ${colors.surface};
|
|
739
|
+
border-top: 1px solid ${colors.borderLight};
|
|
861
740
|
`,
|
|
862
|
-
labelRow:
|
|
741
|
+
labelRow: css3`
|
|
863
742
|
display: flex;
|
|
864
743
|
align-items: center;
|
|
865
744
|
justify-content: space-between;
|
|
866
745
|
gap: 8px;
|
|
867
746
|
`,
|
|
868
|
-
labelText:
|
|
747
|
+
labelText: css3`
|
|
869
748
|
flex: 1;
|
|
870
749
|
min-width: 0;
|
|
871
750
|
`,
|
|
872
|
-
name:
|
|
873
|
-
font-size:
|
|
751
|
+
name: css3`
|
|
752
|
+
font-size: ${fontSize.sm};
|
|
874
753
|
font-weight: 500;
|
|
875
|
-
color: ${
|
|
754
|
+
color: ${colors.text};
|
|
876
755
|
white-space: nowrap;
|
|
877
756
|
overflow: hidden;
|
|
878
757
|
text-overflow: ellipsis;
|
|
879
758
|
margin: 0;
|
|
880
759
|
letter-spacing: -0.01em;
|
|
881
760
|
`,
|
|
882
|
-
size:
|
|
883
|
-
font-size:
|
|
884
|
-
color: ${
|
|
761
|
+
size: css3`
|
|
762
|
+
font-size: ${fontSize.xs};
|
|
763
|
+
color: ${colors.textMuted};
|
|
885
764
|
margin: 2px 0 0 0;
|
|
886
765
|
`,
|
|
887
|
-
openBtn:
|
|
766
|
+
openBtn: css3`
|
|
888
767
|
flex-shrink: 0;
|
|
889
|
-
|
|
768
|
+
height: 28px;
|
|
769
|
+
font-size: ${fontSize.xs};
|
|
890
770
|
font-weight: 500;
|
|
891
|
-
color: ${
|
|
892
|
-
background:
|
|
893
|
-
border:
|
|
894
|
-
padding:
|
|
771
|
+
color: ${colors.primary};
|
|
772
|
+
background: ${colors.surface};
|
|
773
|
+
border: 1px solid ${colors.border};
|
|
774
|
+
padding: 0 10px;
|
|
895
775
|
cursor: pointer;
|
|
896
776
|
border-radius: 4px;
|
|
897
|
-
transition:
|
|
777
|
+
transition: all 0.15s ease;
|
|
778
|
+
display: inline-flex;
|
|
779
|
+
align-items: center;
|
|
898
780
|
|
|
899
781
|
&:hover {
|
|
900
|
-
background-color: ${
|
|
782
|
+
background-color: ${colors.primaryLight};
|
|
783
|
+
border-color: ${colors.primary};
|
|
901
784
|
}
|
|
902
785
|
`,
|
|
903
|
-
selectAllRow:
|
|
786
|
+
selectAllRow: css3`
|
|
904
787
|
display: flex;
|
|
905
788
|
align-items: center;
|
|
906
789
|
margin-bottom: 16px;
|
|
907
790
|
padding: 12px 16px;
|
|
908
|
-
background: ${
|
|
791
|
+
background: ${colors.surface};
|
|
909
792
|
border-radius: 8px;
|
|
910
|
-
border: 1px solid ${
|
|
793
|
+
border: 1px solid ${colors.border};
|
|
911
794
|
`,
|
|
912
|
-
selectAllLabel:
|
|
795
|
+
selectAllLabel: css3`
|
|
913
796
|
display: flex;
|
|
914
797
|
align-items: center;
|
|
915
798
|
gap: 10px;
|
|
916
|
-
font-size:
|
|
799
|
+
font-size: ${fontSize.base};
|
|
917
800
|
font-weight: 500;
|
|
918
|
-
color: ${
|
|
801
|
+
color: ${colors.textSecondary};
|
|
919
802
|
cursor: pointer;
|
|
920
803
|
|
|
921
804
|
&:hover {
|
|
922
|
-
color: ${
|
|
805
|
+
color: ${colors.text};
|
|
923
806
|
}
|
|
924
807
|
`,
|
|
925
|
-
selectAllCheckbox:
|
|
808
|
+
selectAllCheckbox: css3`
|
|
926
809
|
width: 16px;
|
|
927
810
|
height: 16px;
|
|
928
|
-
accent-color: ${
|
|
811
|
+
accent-color: ${colors.primary};
|
|
929
812
|
`
|
|
930
813
|
};
|
|
931
814
|
function StudioFileGrid() {
|
|
932
|
-
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();
|
|
933
816
|
const [items, setItems] = useState2([]);
|
|
934
817
|
const [loading, setLoading] = useState2(true);
|
|
935
818
|
useEffect(() => {
|
|
@@ -949,13 +832,14 @@ function StudioFileGrid() {
|
|
|
949
832
|
loadItems();
|
|
950
833
|
}, [currentPath, refreshKey]);
|
|
951
834
|
if (loading) {
|
|
952
|
-
return /* @__PURE__ */
|
|
835
|
+
return /* @__PURE__ */ jsx3("div", { css: styles3.loading, children: /* @__PURE__ */ jsx3("div", { css: styles3.spinner }) });
|
|
953
836
|
}
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
/* @__PURE__ */
|
|
958
|
-
/* @__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" })
|
|
959
843
|
] });
|
|
960
844
|
}
|
|
961
845
|
const sortedItems = [...items].sort((a, b) => {
|
|
@@ -970,9 +854,11 @@ function StudioFileGrid() {
|
|
|
970
854
|
toggleSelection(item.path);
|
|
971
855
|
}
|
|
972
856
|
};
|
|
973
|
-
const
|
|
857
|
+
const handleOpen = (item) => {
|
|
974
858
|
if (item.type === "folder") {
|
|
975
859
|
setCurrentPath(item.path);
|
|
860
|
+
} else {
|
|
861
|
+
setFocusedItem(item);
|
|
976
862
|
}
|
|
977
863
|
};
|
|
978
864
|
const allItemsSelected = sortedItems.length > 0 && sortedItems.every((item) => selectedItems.has(item.path));
|
|
@@ -984,13 +870,13 @@ function StudioFileGrid() {
|
|
|
984
870
|
selectAll(sortedItems);
|
|
985
871
|
}
|
|
986
872
|
};
|
|
987
|
-
return /* @__PURE__ */
|
|
988
|
-
sortedItems.length > 0 && /* @__PURE__ */
|
|
989
|
-
/* @__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(
|
|
990
876
|
"input",
|
|
991
877
|
{
|
|
992
878
|
type: "checkbox",
|
|
993
|
-
css:
|
|
879
|
+
css: styles3.selectAllCheckbox,
|
|
994
880
|
checked: allItemsSelected,
|
|
995
881
|
ref: (el) => {
|
|
996
882
|
if (el) el.indeterminate = someItemsSelected && !allItemsSelected;
|
|
@@ -1002,65 +888,81 @@ function StudioFileGrid() {
|
|
|
1002
888
|
sortedItems.length,
|
|
1003
889
|
")"
|
|
1004
890
|
] }) }),
|
|
1005
|
-
/* @__PURE__ */
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
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
|
+
] })
|
|
1015
917
|
] });
|
|
1016
918
|
}
|
|
1017
919
|
function GridItem({ item, isSelected, onClick, onOpen }) {
|
|
1018
920
|
const isFolder = item.type === "folder";
|
|
1019
|
-
return /* @__PURE__ */
|
|
921
|
+
return /* @__PURE__ */ jsxs3(
|
|
1020
922
|
"div",
|
|
1021
923
|
{
|
|
1022
|
-
css: [
|
|
924
|
+
css: [styles3.item, isSelected && styles3.itemSelected],
|
|
1023
925
|
onClick,
|
|
1024
926
|
children: [
|
|
1025
|
-
/* @__PURE__ */
|
|
927
|
+
/* @__PURE__ */ jsx3(
|
|
1026
928
|
"div",
|
|
1027
929
|
{
|
|
1028
|
-
css:
|
|
930
|
+
css: styles3.checkboxWrapper,
|
|
1029
931
|
onClick: (e) => e.stopPropagation(),
|
|
1030
|
-
children: /* @__PURE__ */
|
|
932
|
+
children: /* @__PURE__ */ jsx3(
|
|
1031
933
|
"input",
|
|
1032
934
|
{
|
|
1033
935
|
type: "checkbox",
|
|
1034
|
-
css:
|
|
936
|
+
css: styles3.checkbox,
|
|
1035
937
|
checked: isSelected,
|
|
1036
938
|
onChange: () => onClick({})
|
|
1037
939
|
}
|
|
1038
940
|
)
|
|
1039
941
|
}
|
|
1040
942
|
),
|
|
1041
|
-
item.cdnSynced && /* @__PURE__ */
|
|
1042
|
-
/* @__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(
|
|
1043
945
|
"img",
|
|
1044
946
|
{
|
|
1045
|
-
css:
|
|
947
|
+
css: styles3.image,
|
|
1046
948
|
src: item.thumbnail,
|
|
1047
949
|
alt: item.name,
|
|
1048
950
|
loading: "lazy"
|
|
1049
951
|
}
|
|
1050
|
-
) : /* @__PURE__ */
|
|
1051
|
-
/* @__PURE__ */
|
|
1052
|
-
/* @__PURE__ */
|
|
1053
|
-
/* @__PURE__ */
|
|
1054
|
-
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: [
|
|
1055
957
|
item.fileCount !== void 0 ? `${item.fileCount} files` : "",
|
|
1056
958
|
item.fileCount !== void 0 && item.totalSize !== void 0 ? " \xB7 " : "",
|
|
1057
959
|
item.totalSize !== void 0 ? formatFileSize(item.totalSize) : ""
|
|
1058
|
-
] }) : item.size !== void 0 && /* @__PURE__ */
|
|
960
|
+
] }) : item.size !== void 0 && /* @__PURE__ */ jsx3("p", { css: styles3.size, children: formatFileSize(item.size) })
|
|
1059
961
|
] }),
|
|
1060
|
-
|
|
962
|
+
/* @__PURE__ */ jsx3(
|
|
1061
963
|
"button",
|
|
1062
964
|
{
|
|
1063
|
-
css:
|
|
965
|
+
css: styles3.openBtn,
|
|
1064
966
|
onClick: (e) => {
|
|
1065
967
|
e.stopPropagation();
|
|
1066
968
|
onOpen();
|
|
@@ -1081,183 +983,188 @@ function formatFileSize(bytes) {
|
|
|
1081
983
|
|
|
1082
984
|
// src/components/StudioFileList.tsx
|
|
1083
985
|
import { useEffect as useEffect2, useState as useState3 } from "react";
|
|
1084
|
-
import { css as
|
|
1085
|
-
import { jsx as
|
|
1086
|
-
var colors5 = {
|
|
1087
|
-
primary: "#635bff",
|
|
1088
|
-
primaryLight: "#f0f0ff",
|
|
1089
|
-
background: "#f6f9fc",
|
|
1090
|
-
surface: "#ffffff",
|
|
1091
|
-
surfaceHover: "#f6f9fc",
|
|
1092
|
-
border: "#e3e8ee",
|
|
1093
|
-
borderLight: "#eef1f6",
|
|
1094
|
-
text: "#1a1f36",
|
|
1095
|
-
textSecondary: "#697386",
|
|
1096
|
-
textMuted: "#8792a2",
|
|
1097
|
-
success: "#0d7d4d"
|
|
1098
|
-
};
|
|
986
|
+
import { css as css4, keyframes as keyframes4 } from "@emotion/react";
|
|
987
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "@emotion/react/jsx-runtime";
|
|
1099
988
|
var spin3 = keyframes4`
|
|
1100
989
|
to { transform: rotate(360deg); }
|
|
1101
990
|
`;
|
|
1102
|
-
var
|
|
1103
|
-
loading:
|
|
991
|
+
var styles4 = {
|
|
992
|
+
loading: css4`
|
|
1104
993
|
display: flex;
|
|
1105
994
|
align-items: center;
|
|
1106
995
|
justify-content: center;
|
|
1107
996
|
height: 256px;
|
|
1108
997
|
`,
|
|
1109
|
-
spinner:
|
|
998
|
+
spinner: css4`
|
|
1110
999
|
width: 32px;
|
|
1111
1000
|
height: 32px;
|
|
1112
1001
|
border-radius: 50%;
|
|
1113
|
-
border: 3px solid ${
|
|
1114
|
-
border-top-color: ${
|
|
1002
|
+
border: 3px solid ${colors.border};
|
|
1003
|
+
border-top-color: ${colors.primary};
|
|
1115
1004
|
animation: ${spin3} 0.8s linear infinite;
|
|
1116
1005
|
`,
|
|
1117
|
-
empty:
|
|
1006
|
+
empty: css4`
|
|
1118
1007
|
display: flex;
|
|
1119
1008
|
flex-direction: column;
|
|
1120
1009
|
align-items: center;
|
|
1121
1010
|
justify-content: center;
|
|
1122
1011
|
height: 256px;
|
|
1123
|
-
color: ${
|
|
1012
|
+
color: ${colors.textSecondary};
|
|
1124
1013
|
`,
|
|
1125
|
-
tableWrapper:
|
|
1126
|
-
background: ${
|
|
1014
|
+
tableWrapper: css4`
|
|
1015
|
+
background: ${colors.surface};
|
|
1127
1016
|
border-radius: 8px;
|
|
1128
|
-
border: 1px solid ${
|
|
1017
|
+
border: 1px solid ${colors.border};
|
|
1129
1018
|
overflow: hidden;
|
|
1130
1019
|
`,
|
|
1131
|
-
table:
|
|
1020
|
+
table: css4`
|
|
1132
1021
|
width: 100%;
|
|
1133
1022
|
border-collapse: collapse;
|
|
1134
1023
|
`,
|
|
1135
|
-
th:
|
|
1024
|
+
th: css4`
|
|
1136
1025
|
text-align: left;
|
|
1137
1026
|
font-size: 11px;
|
|
1138
|
-
color: ${
|
|
1027
|
+
color: ${colors.textMuted};
|
|
1139
1028
|
text-transform: uppercase;
|
|
1140
1029
|
letter-spacing: 0.05em;
|
|
1141
1030
|
padding: 12px 16px;
|
|
1142
1031
|
font-weight: 600;
|
|
1143
|
-
background: ${
|
|
1144
|
-
border-bottom: 1px solid ${
|
|
1032
|
+
background: ${colors.background};
|
|
1033
|
+
border-bottom: 1px solid ${colors.border};
|
|
1145
1034
|
`,
|
|
1146
|
-
thCheckbox:
|
|
1035
|
+
thCheckbox: css4`
|
|
1147
1036
|
width: 48px;
|
|
1148
1037
|
`,
|
|
1149
|
-
thSize:
|
|
1038
|
+
thSize: css4`
|
|
1150
1039
|
width: 96px;
|
|
1151
1040
|
`,
|
|
1152
|
-
thDimensions:
|
|
1041
|
+
thDimensions: css4`
|
|
1153
1042
|
width: 128px;
|
|
1154
1043
|
`,
|
|
1155
|
-
thCdn:
|
|
1044
|
+
thCdn: css4`
|
|
1156
1045
|
width: 96px;
|
|
1157
1046
|
`,
|
|
1158
|
-
tbody:
|
|
1159
|
-
row:
|
|
1047
|
+
tbody: css4``,
|
|
1048
|
+
row: css4`
|
|
1160
1049
|
cursor: pointer;
|
|
1161
1050
|
transition: background-color 0.15s ease;
|
|
1162
1051
|
user-select: none;
|
|
1163
1052
|
|
|
1164
1053
|
&:hover {
|
|
1165
|
-
background-color: ${
|
|
1054
|
+
background-color: ${colors.surfaceHover};
|
|
1166
1055
|
}
|
|
1167
1056
|
|
|
1168
1057
|
&:not(:last-child) td {
|
|
1169
|
-
border-bottom: 1px solid ${
|
|
1058
|
+
border-bottom: 1px solid ${colors.borderLight};
|
|
1170
1059
|
}
|
|
1171
1060
|
`,
|
|
1172
|
-
rowSelected:
|
|
1173
|
-
background-color: ${
|
|
1061
|
+
rowSelected: css4`
|
|
1062
|
+
background-color: ${colors.primaryLight};
|
|
1174
1063
|
|
|
1175
1064
|
&:hover {
|
|
1176
|
-
background-color: ${
|
|
1065
|
+
background-color: ${colors.primaryLight};
|
|
1177
1066
|
}
|
|
1178
1067
|
`,
|
|
1179
|
-
|
|
1068
|
+
parentRow: css4`
|
|
1069
|
+
cursor: pointer;
|
|
1070
|
+
|
|
1071
|
+
&:hover {
|
|
1072
|
+
background-color: ${colors.surfaceHover};
|
|
1073
|
+
}
|
|
1074
|
+
`,
|
|
1075
|
+
td: css4`
|
|
1180
1076
|
padding: 12px 16px;
|
|
1181
1077
|
`,
|
|
1182
|
-
checkboxCell:
|
|
1078
|
+
checkboxCell: css4`
|
|
1183
1079
|
padding: 12px 16px;
|
|
1184
1080
|
cursor: pointer;
|
|
1185
1081
|
`,
|
|
1186
|
-
checkbox:
|
|
1082
|
+
checkbox: css4`
|
|
1187
1083
|
width: 16px;
|
|
1188
1084
|
height: 16px;
|
|
1189
|
-
accent-color: ${
|
|
1085
|
+
accent-color: ${colors.primary};
|
|
1190
1086
|
cursor: pointer;
|
|
1191
1087
|
`,
|
|
1192
|
-
nameCell:
|
|
1088
|
+
nameCell: css4`
|
|
1193
1089
|
display: flex;
|
|
1194
1090
|
align-items: center;
|
|
1195
1091
|
gap: 12px;
|
|
1196
1092
|
`,
|
|
1197
|
-
folderIcon:
|
|
1093
|
+
folderIcon: css4`
|
|
1198
1094
|
width: 20px;
|
|
1199
1095
|
height: 20px;
|
|
1200
1096
|
color: #f5a623;
|
|
1201
1097
|
flex-shrink: 0;
|
|
1202
1098
|
`,
|
|
1203
|
-
|
|
1099
|
+
parentIcon: css4`
|
|
1100
|
+
width: 20px;
|
|
1101
|
+
height: 20px;
|
|
1102
|
+
color: ${colors.textMuted};
|
|
1103
|
+
flex-shrink: 0;
|
|
1104
|
+
`,
|
|
1105
|
+
fileIcon: css4`
|
|
1204
1106
|
width: 20px;
|
|
1205
1107
|
height: 20px;
|
|
1206
|
-
color: ${
|
|
1108
|
+
color: ${colors.textMuted};
|
|
1207
1109
|
flex-shrink: 0;
|
|
1208
1110
|
`,
|
|
1209
|
-
thumbnail:
|
|
1111
|
+
thumbnail: css4`
|
|
1210
1112
|
width: 36px;
|
|
1211
1113
|
height: 36px;
|
|
1212
1114
|
object-fit: cover;
|
|
1213
1115
|
border-radius: 6px;
|
|
1214
1116
|
flex-shrink: 0;
|
|
1215
|
-
border: 1px solid ${
|
|
1117
|
+
border: 1px solid ${colors.borderLight};
|
|
1216
1118
|
`,
|
|
1217
|
-
name:
|
|
1218
|
-
font-size:
|
|
1119
|
+
name: css4`
|
|
1120
|
+
font-size: ${fontSize.base};
|
|
1219
1121
|
font-weight: 500;
|
|
1220
|
-
color: ${
|
|
1122
|
+
color: ${colors.text};
|
|
1221
1123
|
letter-spacing: -0.01em;
|
|
1222
1124
|
`,
|
|
1223
|
-
meta:
|
|
1224
|
-
font-size:
|
|
1225
|
-
color: ${
|
|
1125
|
+
meta: css4`
|
|
1126
|
+
font-size: ${fontSize.sm};
|
|
1127
|
+
color: ${colors.textSecondary};
|
|
1226
1128
|
`,
|
|
1227
|
-
cdnBadge:
|
|
1129
|
+
cdnBadge: css4`
|
|
1228
1130
|
display: inline-flex;
|
|
1229
1131
|
align-items: center;
|
|
1230
1132
|
gap: 4px;
|
|
1231
|
-
font-size:
|
|
1133
|
+
font-size: ${fontSize.xs};
|
|
1232
1134
|
font-weight: 500;
|
|
1233
|
-
color: ${
|
|
1135
|
+
color: ${colors.success};
|
|
1234
1136
|
`,
|
|
1235
|
-
cdnIcon:
|
|
1137
|
+
cdnIcon: css4`
|
|
1236
1138
|
width: 12px;
|
|
1237
1139
|
height: 12px;
|
|
1238
1140
|
`,
|
|
1239
|
-
cdnEmpty:
|
|
1240
|
-
font-size:
|
|
1241
|
-
color: ${
|
|
1141
|
+
cdnEmpty: css4`
|
|
1142
|
+
font-size: ${fontSize.sm};
|
|
1143
|
+
color: ${colors.textMuted};
|
|
1242
1144
|
`,
|
|
1243
|
-
openBtn:
|
|
1244
|
-
|
|
1145
|
+
openBtn: css4`
|
|
1146
|
+
height: 28px;
|
|
1147
|
+
font-size: ${fontSize.xs};
|
|
1245
1148
|
font-weight: 500;
|
|
1246
|
-
color: ${
|
|
1247
|
-
background:
|
|
1248
|
-
border:
|
|
1249
|
-
padding:
|
|
1149
|
+
color: ${colors.primary};
|
|
1150
|
+
background: ${colors.surface};
|
|
1151
|
+
border: 1px solid ${colors.border};
|
|
1152
|
+
padding: 0 12px;
|
|
1250
1153
|
cursor: pointer;
|
|
1251
1154
|
border-radius: 4px;
|
|
1252
|
-
transition:
|
|
1155
|
+
transition: all 0.15s ease;
|
|
1156
|
+
display: inline-flex;
|
|
1157
|
+
align-items: center;
|
|
1158
|
+
margin-left: auto;
|
|
1253
1159
|
|
|
1254
1160
|
&:hover {
|
|
1255
|
-
background-color: ${
|
|
1161
|
+
background-color: ${colors.primaryLight};
|
|
1162
|
+
border-color: ${colors.primary};
|
|
1256
1163
|
}
|
|
1257
1164
|
`
|
|
1258
1165
|
};
|
|
1259
1166
|
function StudioFileList() {
|
|
1260
|
-
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();
|
|
1261
1168
|
const [items, setItems] = useState3([]);
|
|
1262
1169
|
const [loading, setLoading] = useState3(true);
|
|
1263
1170
|
useEffect2(() => {
|
|
@@ -1277,10 +1184,11 @@ function StudioFileList() {
|
|
|
1277
1184
|
loadItems();
|
|
1278
1185
|
}, [currentPath, refreshKey]);
|
|
1279
1186
|
if (loading) {
|
|
1280
|
-
return /* @__PURE__ */
|
|
1187
|
+
return /* @__PURE__ */ jsx4("div", { css: styles4.loading, children: /* @__PURE__ */ jsx4("div", { css: styles4.spinner }) });
|
|
1281
1188
|
}
|
|
1282
|
-
|
|
1283
|
-
|
|
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" }) });
|
|
1284
1192
|
}
|
|
1285
1193
|
const sortedItems = [...items].sort((a, b) => {
|
|
1286
1194
|
if (a.type === "folder" && b.type !== "folder") return -1;
|
|
@@ -1294,9 +1202,11 @@ function StudioFileList() {
|
|
|
1294
1202
|
toggleSelection(item.path);
|
|
1295
1203
|
}
|
|
1296
1204
|
};
|
|
1297
|
-
const
|
|
1205
|
+
const handleOpen = (item) => {
|
|
1298
1206
|
if (item.type === "folder") {
|
|
1299
1207
|
setCurrentPath(item.path);
|
|
1208
|
+
} else {
|
|
1209
|
+
setFocusedItem(item);
|
|
1300
1210
|
}
|
|
1301
1211
|
};
|
|
1302
1212
|
const allItemsSelected = sortedItems.length > 0 && sortedItems.every((item) => selectedItems.has(item.path));
|
|
@@ -1308,13 +1218,13 @@ function StudioFileList() {
|
|
|
1308
1218
|
selectAll(sortedItems);
|
|
1309
1219
|
}
|
|
1310
1220
|
};
|
|
1311
|
-
return /* @__PURE__ */
|
|
1312
|
-
/* @__PURE__ */
|
|
1313
|
-
/* @__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(
|
|
1314
1224
|
"input",
|
|
1315
1225
|
{
|
|
1316
1226
|
type: "checkbox",
|
|
1317
|
-
css:
|
|
1227
|
+
css: styles4.checkbox,
|
|
1318
1228
|
checked: allItemsSelected,
|
|
1319
1229
|
ref: (el) => {
|
|
1320
1230
|
if (el) el.indeterminate = someItemsSelected && !allItemsSelected;
|
|
@@ -1322,54 +1232,66 @@ function StudioFileList() {
|
|
|
1322
1232
|
onChange: handleSelectAll
|
|
1323
1233
|
}
|
|
1324
1234
|
) }),
|
|
1325
|
-
/* @__PURE__ */
|
|
1326
|
-
/* @__PURE__ */
|
|
1327
|
-
/* @__PURE__ */
|
|
1328
|
-
/* @__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" })
|
|
1329
1239
|
] }) }),
|
|
1330
|
-
/* @__PURE__ */
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
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
|
+
] }) });
|
|
1341
1263
|
}
|
|
1342
1264
|
function ListRow({ item, isSelected, onClick, onOpen }) {
|
|
1343
1265
|
const isFolder = item.type === "folder";
|
|
1344
|
-
return /* @__PURE__ */
|
|
1266
|
+
return /* @__PURE__ */ jsxs4(
|
|
1345
1267
|
"tr",
|
|
1346
1268
|
{
|
|
1347
|
-
css: [
|
|
1269
|
+
css: [styles4.row, isSelected && styles4.rowSelected],
|
|
1348
1270
|
onClick,
|
|
1349
1271
|
children: [
|
|
1350
|
-
/* @__PURE__ */
|
|
1272
|
+
/* @__PURE__ */ jsx4(
|
|
1351
1273
|
"td",
|
|
1352
1274
|
{
|
|
1353
|
-
css: [
|
|
1275
|
+
css: [styles4.td, styles4.checkboxCell],
|
|
1354
1276
|
onClick: (e) => e.stopPropagation(),
|
|
1355
|
-
children: /* @__PURE__ */
|
|
1277
|
+
children: /* @__PURE__ */ jsx4(
|
|
1356
1278
|
"input",
|
|
1357
1279
|
{
|
|
1358
1280
|
type: "checkbox",
|
|
1359
|
-
css:
|
|
1281
|
+
css: styles4.checkbox,
|
|
1360
1282
|
checked: isSelected,
|
|
1361
1283
|
onChange: () => onClick({})
|
|
1362
1284
|
}
|
|
1363
1285
|
)
|
|
1364
1286
|
}
|
|
1365
1287
|
),
|
|
1366
|
-
/* @__PURE__ */
|
|
1367
|
-
isFolder ? /* @__PURE__ */
|
|
1368
|
-
/* @__PURE__ */
|
|
1369
|
-
|
|
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(
|
|
1370
1292
|
"button",
|
|
1371
1293
|
{
|
|
1372
|
-
css:
|
|
1294
|
+
css: styles4.openBtn,
|
|
1373
1295
|
onClick: (e) => {
|
|
1374
1296
|
e.stopPropagation();
|
|
1375
1297
|
onOpen();
|
|
@@ -1378,12 +1300,12 @@ function ListRow({ item, isSelected, onClick, onOpen }) {
|
|
|
1378
1300
|
}
|
|
1379
1301
|
)
|
|
1380
1302
|
] }) }),
|
|
1381
|
-
/* @__PURE__ */
|
|
1382
|
-
/* @__PURE__ */
|
|
1383
|
-
/* @__PURE__ */
|
|
1384
|
-
/* @__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" }) }),
|
|
1385
1307
|
"Synced"
|
|
1386
|
-
] }) : /* @__PURE__ */
|
|
1308
|
+
] }) : /* @__PURE__ */ jsx4("span", { css: styles4.cdnEmpty, children: "--" }) })
|
|
1387
1309
|
]
|
|
1388
1310
|
}
|
|
1389
1311
|
);
|
|
@@ -1394,10 +1316,10 @@ function formatFileSize2(bytes) {
|
|
|
1394
1316
|
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
1395
1317
|
}
|
|
1396
1318
|
|
|
1397
|
-
// src/components/
|
|
1319
|
+
// src/components/StudioDetailView.tsx
|
|
1398
1320
|
import { useState as useState4 } from "react";
|
|
1399
|
-
import { css as
|
|
1400
|
-
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";
|
|
1401
1323
|
var IMAGE_EXTENSIONS = [".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg", ".ico", ".bmp", ".tiff", ".tif"];
|
|
1402
1324
|
var VIDEO_EXTENSIONS = [".mp4", ".webm", ".mov", ".avi", ".mkv", ".m4v"];
|
|
1403
1325
|
function isImageFile(filename) {
|
|
@@ -1408,208 +1330,203 @@ function isVideoFile(filename) {
|
|
|
1408
1330
|
const ext = filename.toLowerCase().substring(filename.lastIndexOf("."));
|
|
1409
1331
|
return VIDEO_EXTENSIONS.includes(ext);
|
|
1410
1332
|
}
|
|
1411
|
-
var
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
danger: "#df1b41",
|
|
1426
|
-
dangerLight: "#fff5f7"
|
|
1427
|
-
};
|
|
1428
|
-
var styles6 = {
|
|
1429
|
-
panel: css6`
|
|
1430
|
-
width: 320px;
|
|
1431
|
-
border-left: 1px solid ${colors6.border};
|
|
1432
|
-
background-color: ${colors6.surface};
|
|
1433
|
-
padding: 20px;
|
|
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};
|
|
1434
1347
|
overflow: auto;
|
|
1435
1348
|
`,
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
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;
|
|
1443
1355
|
`,
|
|
1444
|
-
|
|
1445
|
-
|
|
1356
|
+
image: css5`
|
|
1357
|
+
max-width: 100%;
|
|
1358
|
+
max-height: calc(100vh - 200px);
|
|
1359
|
+
object-fit: contain;
|
|
1446
1360
|
border-radius: 8px;
|
|
1447
|
-
|
|
1448
|
-
padding: 12px;
|
|
1449
|
-
margin-bottom: 20px;
|
|
1361
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
|
1450
1362
|
`,
|
|
1451
|
-
|
|
1452
|
-
width: 100%;
|
|
1453
|
-
height:
|
|
1454
|
-
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);
|
|
1455
1368
|
`,
|
|
1456
|
-
|
|
1369
|
+
filePlaceholder: css5`
|
|
1457
1370
|
display: flex;
|
|
1458
1371
|
flex-direction: column;
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
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};
|
|
1465
1378
|
`,
|
|
1466
|
-
|
|
1467
|
-
|
|
1379
|
+
fileIcon: css5`
|
|
1380
|
+
width: 80px;
|
|
1381
|
+
height: 80px;
|
|
1382
|
+
color: ${colors.textMuted};
|
|
1383
|
+
margin-bottom: 16px;
|
|
1468
1384
|
`,
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
font-weight:
|
|
1385
|
+
fileName: css5`
|
|
1386
|
+
font-size: ${fontSize.lg};
|
|
1387
|
+
font-weight: 600;
|
|
1388
|
+
color: ${colors.text};
|
|
1389
|
+
margin: 0;
|
|
1472
1390
|
`,
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1391
|
+
sidebar: css5`
|
|
1392
|
+
width: 280px;
|
|
1393
|
+
background: ${colors.surface};
|
|
1394
|
+
border-left: 1px solid ${colors.border};
|
|
1395
|
+
display: flex;
|
|
1396
|
+
flex-direction: column;
|
|
1476
1397
|
overflow: hidden;
|
|
1477
|
-
text-overflow: ellipsis;
|
|
1478
|
-
`,
|
|
1479
|
-
section: css6`
|
|
1480
|
-
padding-top: 12px;
|
|
1481
|
-
margin-top: 4px;
|
|
1482
|
-
border-top: 1px solid ${colors6.borderLight};
|
|
1483
|
-
`,
|
|
1484
|
-
sectionTitle: css6`
|
|
1485
|
-
font-size: 11px;
|
|
1486
|
-
font-weight: 600;
|
|
1487
|
-
color: ${colors6.textMuted};
|
|
1488
|
-
text-transform: uppercase;
|
|
1489
|
-
letter-spacing: 0.05em;
|
|
1490
|
-
margin: 0 0 10px 0;
|
|
1491
1398
|
`,
|
|
1492
|
-
|
|
1399
|
+
sidebarHeader: css5`
|
|
1400
|
+
padding: 16px 20px;
|
|
1401
|
+
border-bottom: 1px solid ${colors.border};
|
|
1493
1402
|
display: flex;
|
|
1494
1403
|
align-items: center;
|
|
1495
|
-
|
|
1496
|
-
font-size: 13px;
|
|
1497
|
-
color: ${colors6.success};
|
|
1498
|
-
font-weight: 500;
|
|
1404
|
+
justify-content: space-between;
|
|
1499
1405
|
`,
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1406
|
+
sidebarTitle: css5`
|
|
1407
|
+
font-size: ${fontSize.base};
|
|
1408
|
+
font-weight: 600;
|
|
1409
|
+
color: ${colors.text};
|
|
1410
|
+
margin: 0;
|
|
1503
1411
|
`,
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
background: none;
|
|
1510
|
-
border: none;
|
|
1412
|
+
closeBtn: css5`
|
|
1413
|
+
padding: 6px;
|
|
1414
|
+
background: ${colors.surface};
|
|
1415
|
+
border: 1px solid ${colors.border};
|
|
1416
|
+
border-radius: 6px;
|
|
1511
1417
|
cursor: pointer;
|
|
1512
|
-
|
|
1418
|
+
transition: all 0.15s ease;
|
|
1419
|
+
display: flex;
|
|
1420
|
+
align-items: center;
|
|
1421
|
+
justify-content: center;
|
|
1513
1422
|
|
|
1514
1423
|
&:hover {
|
|
1515
|
-
|
|
1424
|
+
background-color: ${colors.surfaceHover};
|
|
1425
|
+
border-color: ${colors.borderHover};
|
|
1516
1426
|
}
|
|
1517
1427
|
`,
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
height:
|
|
1521
|
-
|
|
1522
|
-
|
|
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;
|
|
1523
1437
|
`,
|
|
1524
|
-
|
|
1438
|
+
info: css5`
|
|
1525
1439
|
display: flex;
|
|
1526
1440
|
flex-direction: column;
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
height: 200px;
|
|
1530
|
-
text-align: center;
|
|
1531
|
-
`,
|
|
1532
|
-
emptyText: css6`
|
|
1533
|
-
font-size: 13px;
|
|
1534
|
-
color: ${colors6.textMuted};
|
|
1535
|
-
margin: 0;
|
|
1441
|
+
gap: 12px;
|
|
1442
|
+
margin-bottom: 24px;
|
|
1536
1443
|
`,
|
|
1537
|
-
|
|
1444
|
+
infoRow: css5`
|
|
1538
1445
|
display: flex;
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
height: 120px;
|
|
1542
|
-
background: ${colors6.background};
|
|
1543
|
-
border-radius: 6px;
|
|
1544
|
-
`,
|
|
1545
|
-
fileIcon: css6`
|
|
1546
|
-
width: 56px;
|
|
1547
|
-
height: 56px;
|
|
1548
|
-
color: ${colors6.textMuted};
|
|
1446
|
+
justify-content: space-between;
|
|
1447
|
+
font-size: ${fontSize.sm};
|
|
1549
1448
|
`,
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
height: 56px;
|
|
1553
|
-
color: #f5a623;
|
|
1449
|
+
infoLabel: css5`
|
|
1450
|
+
color: ${colors.textSecondary};
|
|
1554
1451
|
`,
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
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;
|
|
1559
1460
|
`,
|
|
1560
|
-
actions:
|
|
1561
|
-
margin-top: 20px;
|
|
1562
|
-
padding-top: 20px;
|
|
1563
|
-
border-top: 1px solid ${colors6.border};
|
|
1461
|
+
actions: css5`
|
|
1564
1462
|
display: flex;
|
|
1565
1463
|
flex-direction: column;
|
|
1566
1464
|
gap: 8px;
|
|
1567
1465
|
`,
|
|
1568
|
-
actionBtn:
|
|
1466
|
+
actionBtn: css5`
|
|
1467
|
+
display: flex;
|
|
1468
|
+
align-items: center;
|
|
1469
|
+
gap: 10px;
|
|
1569
1470
|
width: 100%;
|
|
1570
|
-
padding:
|
|
1571
|
-
font-size:
|
|
1471
|
+
padding: 12px 14px;
|
|
1472
|
+
font-size: ${fontSize.base};
|
|
1572
1473
|
font-weight: 500;
|
|
1573
|
-
background
|
|
1574
|
-
border: 1px solid ${
|
|
1474
|
+
background: ${colors.surface};
|
|
1475
|
+
border: 1px solid ${colors.border};
|
|
1575
1476
|
border-radius: 6px;
|
|
1576
1477
|
cursor: pointer;
|
|
1577
1478
|
transition: all 0.15s ease;
|
|
1578
|
-
color: ${
|
|
1479
|
+
color: ${colors.text};
|
|
1480
|
+
text-align: left;
|
|
1579
1481
|
|
|
1580
1482
|
&:hover {
|
|
1581
|
-
background-color: ${
|
|
1582
|
-
border-color:
|
|
1483
|
+
background-color: ${colors.surfaceHover};
|
|
1484
|
+
border-color: ${colors.borderHover};
|
|
1583
1485
|
}
|
|
1584
1486
|
`,
|
|
1585
|
-
actionBtnDanger:
|
|
1586
|
-
color: ${
|
|
1487
|
+
actionBtnDanger: css5`
|
|
1488
|
+
color: ${colors.danger};
|
|
1587
1489
|
|
|
1588
1490
|
&:hover {
|
|
1589
|
-
background-color: ${
|
|
1590
|
-
border-color: ${
|
|
1491
|
+
background-color: ${colors.dangerLight};
|
|
1492
|
+
border-color: ${colors.danger};
|
|
1591
1493
|
}
|
|
1494
|
+
`,
|
|
1495
|
+
actionIcon: css5`
|
|
1496
|
+
width: 16px;
|
|
1497
|
+
height: 16px;
|
|
1498
|
+
flex-shrink: 0;
|
|
1592
1499
|
`
|
|
1593
1500
|
};
|
|
1594
|
-
function
|
|
1595
|
-
const {
|
|
1501
|
+
function StudioDetailView() {
|
|
1502
|
+
const { focusedItem, setFocusedItem, triggerRefresh, clearSelection } = useStudio();
|
|
1596
1503
|
const [showDeleteConfirm, setShowDeleteConfirm] = useState4(false);
|
|
1597
1504
|
const [alertMessage, setAlertMessage] = useState4(null);
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
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);
|
|
1511
|
+
};
|
|
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
|
+
}
|
|
1601
1517
|
};
|
|
1602
|
-
const
|
|
1518
|
+
const handleDelete = async () => {
|
|
1603
1519
|
setShowDeleteConfirm(false);
|
|
1604
1520
|
try {
|
|
1605
1521
|
const response = await fetch("/api/studio/delete", {
|
|
1606
1522
|
method: "POST",
|
|
1607
1523
|
headers: { "Content-Type": "application/json" },
|
|
1608
|
-
body: JSON.stringify({ paths:
|
|
1524
|
+
body: JSON.stringify({ paths: [focusedItem.path] })
|
|
1609
1525
|
});
|
|
1610
1526
|
if (response.ok) {
|
|
1611
1527
|
clearSelection();
|
|
1612
1528
|
triggerRefresh();
|
|
1529
|
+
setFocusedItem(null);
|
|
1613
1530
|
} else {
|
|
1614
1531
|
const error = await response.json();
|
|
1615
1532
|
setAlertMessage({
|
|
@@ -1625,155 +1542,97 @@ function StudioPreview() {
|
|
|
1625
1542
|
});
|
|
1626
1543
|
}
|
|
1627
1544
|
};
|
|
1628
|
-
const
|
|
1629
|
-
|
|
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(
|
|
1630
1565
|
ConfirmModal,
|
|
1631
1566
|
{
|
|
1632
|
-
title: "Delete
|
|
1633
|
-
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.`,
|
|
1634
1569
|
confirmLabel: "Delete",
|
|
1635
1570
|
variant: "danger",
|
|
1636
|
-
onConfirm:
|
|
1571
|
+
onConfirm: handleDelete,
|
|
1637
1572
|
onCancel: () => setShowDeleteConfirm(false)
|
|
1638
1573
|
}
|
|
1639
1574
|
),
|
|
1640
|
-
alertMessage && /* @__PURE__ */
|
|
1575
|
+
alertMessage && /* @__PURE__ */ jsx5(
|
|
1641
1576
|
AlertModal,
|
|
1642
1577
|
{
|
|
1643
1578
|
title: alertMessage.title,
|
|
1644
1579
|
message: alertMessage.message,
|
|
1645
1580
|
onClose: () => setAlertMessage(null)
|
|
1646
1581
|
}
|
|
1647
|
-
)
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
/* @__PURE__ */ jsx6("div", { css: styles6.emptyState, children: /* @__PURE__ */ jsx6("p", { css: styles6.emptyText, children: "Select an image to preview" }) })
|
|
1655
|
-
] })
|
|
1656
|
-
] });
|
|
1657
|
-
}
|
|
1658
|
-
if (selectedItems.size > 1) {
|
|
1659
|
-
return /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
1660
|
-
modals,
|
|
1661
|
-
/* @__PURE__ */ jsxs6("div", { css: styles6.panel, children: [
|
|
1662
|
-
/* @__PURE__ */ jsxs6("h3", { css: styles6.title, children: [
|
|
1663
|
-
selectedItems.size,
|
|
1664
|
-
" 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" }) }) })
|
|
1665
1589
|
] }),
|
|
1666
|
-
/* @__PURE__ */
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
] })
|
|
1672
|
-
] });
|
|
1673
|
-
}
|
|
1674
|
-
const selectedPath = Array.from(selectedItems)[0];
|
|
1675
|
-
const isFolder = !selectedPath.includes(".") || selectedPath.endsWith("/");
|
|
1676
|
-
const filename = selectedPath.split("/").pop() || "";
|
|
1677
|
-
const isImage = isImageFile(filename);
|
|
1678
|
-
const isVideo = isVideoFile(filename);
|
|
1679
|
-
const imageKey = selectedPath.replace(/^public\/images\//, "").replace(/^public\/originals\//, "").replace(/^public\//, "");
|
|
1680
|
-
const imageData = meta?.images?.[imageKey];
|
|
1681
|
-
const renderPreview = () => {
|
|
1682
|
-
if (isFolder) {
|
|
1683
|
-
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" }) }) });
|
|
1684
|
-
}
|
|
1685
|
-
if (isImage) {
|
|
1686
|
-
return /* @__PURE__ */ jsx6(
|
|
1687
|
-
"img",
|
|
1688
|
-
{
|
|
1689
|
-
css: styles6.image,
|
|
1690
|
-
src: selectedPath.replace("public", ""),
|
|
1691
|
-
alt: "Preview"
|
|
1692
|
-
}
|
|
1693
|
-
);
|
|
1694
|
-
}
|
|
1695
|
-
if (isVideo) {
|
|
1696
|
-
return /* @__PURE__ */ jsx6(
|
|
1697
|
-
"video",
|
|
1698
|
-
{
|
|
1699
|
-
css: styles6.video,
|
|
1700
|
-
src: selectedPath.replace("public", ""),
|
|
1701
|
-
controls: true,
|
|
1702
|
-
muted: true
|
|
1703
|
-
}
|
|
1704
|
-
);
|
|
1705
|
-
}
|
|
1706
|
-
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" }) }) });
|
|
1707
|
-
};
|
|
1708
|
-
return /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
1709
|
-
modals,
|
|
1710
|
-
/* @__PURE__ */ jsxs6("div", { css: styles6.panel, children: [
|
|
1711
|
-
/* @__PURE__ */ jsx6("h3", { css: styles6.title, children: "Preview" }),
|
|
1712
|
-
/* @__PURE__ */ jsx6("div", { css: styles6.imageContainer, children: renderPreview() }),
|
|
1713
|
-
/* @__PURE__ */ jsxs6("div", { css: styles6.info, children: [
|
|
1714
|
-
/* @__PURE__ */ jsx6(InfoRow, { label: "Filename", value: selectedPath.split("/").pop() || "" }),
|
|
1715
|
-
imageData && /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
1716
|
-
/* @__PURE__ */ jsx6(
|
|
1717
|
-
InfoRow,
|
|
1718
|
-
{
|
|
1719
|
-
label: "Original",
|
|
1720
|
-
value: `${imageData.original.width}x${imageData.original.height}`
|
|
1721
|
-
}
|
|
1722
|
-
),
|
|
1723
|
-
/* @__PURE__ */ jsx6(
|
|
1724
|
-
InfoRow,
|
|
1725
|
-
{
|
|
1726
|
-
label: "File size",
|
|
1727
|
-
value: formatFileSize3(imageData.original.fileSize)
|
|
1728
|
-
}
|
|
1729
|
-
),
|
|
1730
|
-
/* @__PURE__ */ jsxs6("div", { css: styles6.section, children: [
|
|
1731
|
-
/* @__PURE__ */ jsx6("p", { css: styles6.sectionTitle, children: "Generated sizes" }),
|
|
1732
|
-
Object.entries(imageData.sizes).map(([size, data]) => /* @__PURE__ */ jsx6(InfoRow, { label: size, value: `${data.width}x${data.height}` }, size))
|
|
1733
|
-
] }),
|
|
1734
|
-
imageData.cdn?.synced && /* @__PURE__ */ jsxs6("div", { css: styles6.section, children: [
|
|
1735
|
-
/* @__PURE__ */ jsx6("p", { css: styles6.sectionTitle, children: "CDN" }),
|
|
1736
|
-
/* @__PURE__ */ jsxs6("div", { css: styles6.cdnStatus, children: [
|
|
1737
|
-
/* @__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" }) }),
|
|
1738
|
-
"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 })
|
|
1739
1595
|
] }),
|
|
1740
|
-
/* @__PURE__ */
|
|
1741
|
-
"
|
|
1742
|
-
{
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
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
|
+
] })
|
|
1750
1612
|
] }),
|
|
1751
|
-
|
|
1752
|
-
/* @__PURE__ */
|
|
1753
|
-
|
|
1754
|
-
"
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
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
|
+
] })
|
|
1761
1630
|
] })
|
|
1762
1631
|
] })
|
|
1763
|
-
] }),
|
|
1764
|
-
/* @__PURE__ */ jsxs6("div", { css: styles6.actions, children: [
|
|
1765
|
-
/* @__PURE__ */ jsx6("button", { css: styles6.actionBtn, children: "Rename" }),
|
|
1766
|
-
/* @__PURE__ */ jsx6("button", { css: [styles6.actionBtn, styles6.actionBtnDanger], onClick: handleDeleteClick, children: "Delete" })
|
|
1767
1632
|
] })
|
|
1768
1633
|
] })
|
|
1769
1634
|
] });
|
|
1770
1635
|
}
|
|
1771
|
-
function InfoRow({ label, value, truncate }) {
|
|
1772
|
-
return /* @__PURE__ */ jsxs6("div", { css: styles6.row, children: [
|
|
1773
|
-
/* @__PURE__ */ jsx6("span", { css: styles6.label, children: label }),
|
|
1774
|
-
/* @__PURE__ */ jsx6("span", { css: [styles6.value, truncate && styles6.valueTruncate], title: truncate ? value : void 0, children: value })
|
|
1775
|
-
] });
|
|
1776
|
-
}
|
|
1777
1636
|
function formatFileSize3(bytes) {
|
|
1778
1637
|
if (bytes < 1024) return `${bytes} B`;
|
|
1779
1638
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
@@ -1782,27 +1641,33 @@ function formatFileSize3(bytes) {
|
|
|
1782
1641
|
|
|
1783
1642
|
// src/components/StudioSettings.tsx
|
|
1784
1643
|
import { useState as useState5 } from "react";
|
|
1785
|
-
import { css as
|
|
1786
|
-
import { Fragment as Fragment3, jsx as
|
|
1787
|
-
var
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
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;
|
|
1651
|
+
background: ${colors.surface};
|
|
1652
|
+
border: 1px solid ${colors.border};
|
|
1653
|
+
border-radius: 6px;
|
|
1793
1654
|
cursor: pointer;
|
|
1794
|
-
transition:
|
|
1655
|
+
transition: all 0.15s ease;
|
|
1656
|
+
display: flex;
|
|
1657
|
+
align-items: center;
|
|
1658
|
+
justify-content: center;
|
|
1795
1659
|
|
|
1796
1660
|
&:hover {
|
|
1797
|
-
background-color:
|
|
1661
|
+
background-color: ${colors.surfaceHover};
|
|
1662
|
+
border-color: ${colors.borderHover};
|
|
1798
1663
|
}
|
|
1799
1664
|
`,
|
|
1800
|
-
icon:
|
|
1801
|
-
width:
|
|
1802
|
-
height:
|
|
1803
|
-
color:
|
|
1665
|
+
icon: css6`
|
|
1666
|
+
width: 16px;
|
|
1667
|
+
height: 16px;
|
|
1668
|
+
color: ${colors.textSecondary};
|
|
1804
1669
|
`,
|
|
1805
|
-
overlay:
|
|
1670
|
+
overlay: css6`
|
|
1806
1671
|
position: fixed;
|
|
1807
1672
|
top: 0;
|
|
1808
1673
|
right: 0;
|
|
@@ -1812,140 +1677,160 @@ var styles7 = {
|
|
|
1812
1677
|
display: flex;
|
|
1813
1678
|
align-items: center;
|
|
1814
1679
|
justify-content: center;
|
|
1680
|
+
background-color: rgba(26, 31, 54, 0.4);
|
|
1681
|
+
backdrop-filter: blur(4px);
|
|
1815
1682
|
`,
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
top: 0;
|
|
1819
|
-
right: 0;
|
|
1820
|
-
bottom: 0;
|
|
1821
|
-
left: 0;
|
|
1822
|
-
background-color: rgba(0, 0, 0, 0.3);
|
|
1823
|
-
`,
|
|
1824
|
-
panel: css7`
|
|
1683
|
+
panel: css6`
|
|
1684
|
+
${baseReset}
|
|
1825
1685
|
position: relative;
|
|
1826
|
-
background-color:
|
|
1686
|
+
background-color: ${colors.surface};
|
|
1827
1687
|
border-radius: 12px;
|
|
1828
|
-
box-shadow: 0
|
|
1688
|
+
box-shadow: 0 30px 60px -12px rgba(50, 50, 93, 0.25), 0 18px 36px -18px rgba(0, 0, 0, 0.3);
|
|
1829
1689
|
width: 100%;
|
|
1830
1690
|
max-width: 512px;
|
|
1831
1691
|
padding: 24px;
|
|
1832
1692
|
`,
|
|
1833
|
-
header:
|
|
1693
|
+
header: css6`
|
|
1834
1694
|
display: flex;
|
|
1835
1695
|
align-items: center;
|
|
1836
1696
|
justify-content: space-between;
|
|
1837
1697
|
margin-bottom: 24px;
|
|
1838
1698
|
`,
|
|
1839
|
-
title:
|
|
1840
|
-
font-size:
|
|
1699
|
+
title: css6`
|
|
1700
|
+
font-size: ${fontSize.xl};
|
|
1841
1701
|
font-weight: 600;
|
|
1702
|
+
color: ${colors.text};
|
|
1842
1703
|
margin: 0;
|
|
1704
|
+
letter-spacing: -0.02em;
|
|
1843
1705
|
`,
|
|
1844
|
-
closeBtn:
|
|
1845
|
-
padding:
|
|
1846
|
-
background:
|
|
1847
|
-
border:
|
|
1848
|
-
border-radius:
|
|
1706
|
+
closeBtn: css6`
|
|
1707
|
+
padding: 6px;
|
|
1708
|
+
background: ${colors.surface};
|
|
1709
|
+
border: 1px solid ${colors.border};
|
|
1710
|
+
border-radius: 6px;
|
|
1849
1711
|
cursor: pointer;
|
|
1712
|
+
transition: all 0.15s ease;
|
|
1713
|
+
display: flex;
|
|
1714
|
+
align-items: center;
|
|
1715
|
+
justify-content: center;
|
|
1850
1716
|
|
|
1851
1717
|
&:hover {
|
|
1852
|
-
background-color:
|
|
1718
|
+
background-color: ${colors.surfaceHover};
|
|
1719
|
+
border-color: ${colors.borderHover};
|
|
1853
1720
|
}
|
|
1854
1721
|
`,
|
|
1855
|
-
sections:
|
|
1722
|
+
sections: css6`
|
|
1856
1723
|
display: flex;
|
|
1857
1724
|
flex-direction: column;
|
|
1858
1725
|
gap: 24px;
|
|
1859
1726
|
`,
|
|
1860
|
-
sectionTitle:
|
|
1861
|
-
font-size:
|
|
1862
|
-
font-weight:
|
|
1863
|
-
color:
|
|
1727
|
+
sectionTitle: css6`
|
|
1728
|
+
font-size: ${fontSize.base};
|
|
1729
|
+
font-weight: 600;
|
|
1730
|
+
color: ${colors.text};
|
|
1864
1731
|
margin: 0 0 12px 0;
|
|
1865
1732
|
`,
|
|
1866
|
-
description:
|
|
1867
|
-
font-size:
|
|
1868
|
-
color:
|
|
1733
|
+
description: css6`
|
|
1734
|
+
font-size: ${fontSize.sm};
|
|
1735
|
+
color: ${colors.textSecondary};
|
|
1869
1736
|
margin: 0 0 12px 0;
|
|
1870
1737
|
`,
|
|
1871
|
-
code:
|
|
1872
|
-
background-color:
|
|
1738
|
+
code: css6`
|
|
1739
|
+
background-color: ${colors.background};
|
|
1873
1740
|
border-radius: 8px;
|
|
1874
1741
|
padding: 12px;
|
|
1875
|
-
font-family: monospace;
|
|
1876
|
-
font-size:
|
|
1877
|
-
color:
|
|
1742
|
+
font-family: 'SF Mono', Monaco, Consolas, monospace;
|
|
1743
|
+
font-size: ${fontSize.xs};
|
|
1744
|
+
color: ${colors.textSecondary};
|
|
1745
|
+
border: 1px solid ${colors.border};
|
|
1878
1746
|
`,
|
|
1879
|
-
codeLine:
|
|
1747
|
+
codeLine: css6`
|
|
1880
1748
|
margin: 0 0 4px 0;
|
|
1881
1749
|
|
|
1882
1750
|
&:last-child {
|
|
1883
1751
|
margin: 0;
|
|
1884
1752
|
}
|
|
1885
1753
|
`,
|
|
1886
|
-
input:
|
|
1754
|
+
input: css6`
|
|
1887
1755
|
width: 100%;
|
|
1888
|
-
padding:
|
|
1889
|
-
border: 1px solid
|
|
1890
|
-
border-radius:
|
|
1891
|
-
font-size:
|
|
1756
|
+
padding: 10px 14px;
|
|
1757
|
+
border: 1px solid ${colors.border};
|
|
1758
|
+
border-radius: 6px;
|
|
1759
|
+
font-size: ${fontSize.base};
|
|
1760
|
+
color: ${colors.text};
|
|
1761
|
+
background: ${colors.surface};
|
|
1762
|
+
transition: all 0.15s ease;
|
|
1892
1763
|
|
|
1893
1764
|
&:focus {
|
|
1894
1765
|
outline: none;
|
|
1895
|
-
|
|
1766
|
+
border-color: ${colors.primary};
|
|
1767
|
+
box-shadow: 0 0 0 3px ${colors.primaryLight};
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1770
|
+
&::placeholder {
|
|
1771
|
+
color: ${colors.textMuted};
|
|
1896
1772
|
}
|
|
1897
1773
|
`,
|
|
1898
|
-
grid:
|
|
1774
|
+
grid: css6`
|
|
1899
1775
|
display: grid;
|
|
1900
1776
|
grid-template-columns: repeat(3, 1fr);
|
|
1901
1777
|
gap: 12px;
|
|
1902
1778
|
`,
|
|
1903
|
-
label:
|
|
1904
|
-
font-size:
|
|
1905
|
-
|
|
1779
|
+
label: css6`
|
|
1780
|
+
font-size: ${fontSize.xs};
|
|
1781
|
+
font-weight: 500;
|
|
1782
|
+
color: ${colors.textSecondary};
|
|
1906
1783
|
display: block;
|
|
1907
|
-
margin-bottom:
|
|
1784
|
+
margin-bottom: 6px;
|
|
1908
1785
|
`,
|
|
1909
|
-
footer:
|
|
1786
|
+
footer: css6`
|
|
1910
1787
|
margin-top: 24px;
|
|
1788
|
+
padding-top: 20px;
|
|
1789
|
+
border-top: 1px solid ${colors.border};
|
|
1911
1790
|
display: flex;
|
|
1912
1791
|
justify-content: flex-end;
|
|
1913
1792
|
gap: 12px;
|
|
1914
1793
|
`,
|
|
1915
|
-
cancelBtn:
|
|
1916
|
-
padding:
|
|
1917
|
-
font-size:
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
border
|
|
1794
|
+
cancelBtn: css6`
|
|
1795
|
+
padding: 10px 18px;
|
|
1796
|
+
font-size: ${fontSize.base};
|
|
1797
|
+
font-weight: 500;
|
|
1798
|
+
color: ${colors.text};
|
|
1799
|
+
background: ${colors.surface};
|
|
1800
|
+
border: 1px solid ${colors.border};
|
|
1801
|
+
border-radius: 6px;
|
|
1922
1802
|
cursor: pointer;
|
|
1803
|
+
transition: all 0.15s ease;
|
|
1923
1804
|
|
|
1924
1805
|
&:hover {
|
|
1925
|
-
background-color:
|
|
1806
|
+
background-color: ${colors.surfaceHover};
|
|
1807
|
+
border-color: ${colors.borderHover};
|
|
1926
1808
|
}
|
|
1927
1809
|
`,
|
|
1928
|
-
saveBtn:
|
|
1929
|
-
padding:
|
|
1930
|
-
font-size:
|
|
1810
|
+
saveBtn: css6`
|
|
1811
|
+
padding: 10px 18px;
|
|
1812
|
+
font-size: ${fontSize.base};
|
|
1813
|
+
font-weight: 500;
|
|
1931
1814
|
color: white;
|
|
1932
|
-
background-color:
|
|
1933
|
-
border:
|
|
1934
|
-
border-radius:
|
|
1815
|
+
background-color: ${colors.primary};
|
|
1816
|
+
border: 1px solid ${colors.primary};
|
|
1817
|
+
border-radius: 6px;
|
|
1935
1818
|
cursor: pointer;
|
|
1819
|
+
transition: all 0.15s ease;
|
|
1936
1820
|
|
|
1937
1821
|
&:hover {
|
|
1938
|
-
background-color:
|
|
1822
|
+
background-color: ${colors.primaryHover};
|
|
1823
|
+
border-color: ${colors.primaryHover};
|
|
1939
1824
|
}
|
|
1940
1825
|
`
|
|
1941
1826
|
};
|
|
1942
1827
|
function StudioSettings() {
|
|
1943
1828
|
const [isOpen, setIsOpen] = useState5(false);
|
|
1944
|
-
return /* @__PURE__ */
|
|
1945
|
-
/* @__PURE__ */
|
|
1829
|
+
return /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
1830
|
+
/* @__PURE__ */ jsx6("button", { css: styles6.btn, onClick: () => setIsOpen(true), "aria-label": "Settings", children: /* @__PURE__ */ jsxs6(
|
|
1946
1831
|
"svg",
|
|
1947
1832
|
{
|
|
1948
|
-
css:
|
|
1833
|
+
css: styles6.icon,
|
|
1949
1834
|
xmlns: "http://www.w3.org/2000/svg",
|
|
1950
1835
|
viewBox: "0 0 24 24",
|
|
1951
1836
|
fill: "none",
|
|
@@ -1954,113 +1839,98 @@ function StudioSettings() {
|
|
|
1954
1839
|
strokeLinecap: "round",
|
|
1955
1840
|
strokeLinejoin: "round",
|
|
1956
1841
|
children: [
|
|
1957
|
-
/* @__PURE__ */
|
|
1958
|
-
/* @__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" })
|
|
1959
1844
|
]
|
|
1960
1845
|
}
|
|
1961
1846
|
) }),
|
|
1962
|
-
isOpen && /* @__PURE__ */
|
|
1847
|
+
isOpen && /* @__PURE__ */ jsx6(SettingsPanel, { onClose: () => setIsOpen(false) })
|
|
1963
1848
|
] });
|
|
1964
1849
|
}
|
|
1965
1850
|
function SettingsPanel({ onClose }) {
|
|
1966
|
-
return /* @__PURE__ */
|
|
1967
|
-
/* @__PURE__ */
|
|
1968
|
-
|
|
1969
|
-
/* @__PURE__ */
|
|
1970
|
-
|
|
1971
|
-
|
|
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" }) }) })
|
|
1855
|
+
] }),
|
|
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" })
|
|
1866
|
+
] })
|
|
1972
1867
|
] }),
|
|
1973
|
-
/* @__PURE__ */
|
|
1974
|
-
/* @__PURE__ */
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
/* @__PURE__ */
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
/* @__PURE__ */ jsxs7("div", { css: styles7.grid, children: [
|
|
1993
|
-
/* @__PURE__ */ jsxs7("div", { children: [
|
|
1994
|
-
/* @__PURE__ */ jsx7("label", { css: styles7.label, children: "Small" }),
|
|
1995
|
-
/* @__PURE__ */ jsx7("input", { css: styles7.input, type: "number", defaultValue: 300 })
|
|
1996
|
-
] }),
|
|
1997
|
-
/* @__PURE__ */ jsxs7("div", { children: [
|
|
1998
|
-
/* @__PURE__ */ jsx7("label", { css: styles7.label, children: "Medium" }),
|
|
1999
|
-
/* @__PURE__ */ jsx7("input", { css: styles7.input, type: "number", defaultValue: 700 })
|
|
2000
|
-
] }),
|
|
2001
|
-
/* @__PURE__ */ jsxs7("div", { children: [
|
|
2002
|
-
/* @__PURE__ */ jsx7("label", { css: styles7.label, children: "Large" }),
|
|
2003
|
-
/* @__PURE__ */ jsx7("input", { css: styles7.input, type: "number", defaultValue: 1400 })
|
|
2004
|
-
] })
|
|
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" })
|
|
1872
|
+
] }),
|
|
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 })
|
|
1879
|
+
] }),
|
|
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 })
|
|
1883
|
+
] }),
|
|
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 })
|
|
2005
1887
|
] })
|
|
2006
1888
|
] })
|
|
2007
|
-
] }),
|
|
2008
|
-
/* @__PURE__ */ jsxs7("div", { css: styles7.footer, children: [
|
|
2009
|
-
/* @__PURE__ */ jsx7("button", { css: styles7.cancelBtn, onClick: onClose, children: "Cancel" }),
|
|
2010
|
-
/* @__PURE__ */ jsx7("button", { css: styles7.saveBtn, children: "Save Changes" })
|
|
2011
1889
|
] })
|
|
1890
|
+
] }),
|
|
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" })
|
|
2012
1894
|
] })
|
|
2013
|
-
] });
|
|
1895
|
+
] }) });
|
|
2014
1896
|
}
|
|
2015
1897
|
|
|
2016
1898
|
// src/components/StudioUI.tsx
|
|
2017
|
-
import { jsx as
|
|
2018
|
-
var
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
surface: "#ffffff",
|
|
2023
|
-
surfaceHover: "#f6f9fc",
|
|
2024
|
-
border: "#e3e8ee",
|
|
2025
|
-
borderLight: "#eef1f6",
|
|
2026
|
-
text: "#1a1f36",
|
|
2027
|
-
textSecondary: "#697386",
|
|
2028
|
-
textMuted: "#8792a2"
|
|
2029
|
-
};
|
|
2030
|
-
var styles8 = {
|
|
2031
|
-
container: css8`
|
|
1899
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "@emotion/react/jsx-runtime";
|
|
1900
|
+
var btnHeight3 = "36px";
|
|
1901
|
+
var styles7 = {
|
|
1902
|
+
container: css7`
|
|
1903
|
+
${baseReset}
|
|
2032
1904
|
display: flex;
|
|
2033
1905
|
flex-direction: column;
|
|
2034
1906
|
height: 100%;
|
|
2035
|
-
|
|
2036
|
-
background: ${colors7.background};
|
|
2037
|
-
-webkit-font-smoothing: antialiased;
|
|
2038
|
-
-moz-osx-font-smoothing: grayscale;
|
|
1907
|
+
background: ${colors.background};
|
|
2039
1908
|
`,
|
|
2040
|
-
header:
|
|
1909
|
+
header: css7`
|
|
2041
1910
|
display: flex;
|
|
2042
1911
|
align-items: center;
|
|
2043
1912
|
justify-content: space-between;
|
|
2044
|
-
padding:
|
|
2045
|
-
background: ${
|
|
2046
|
-
border-bottom: 1px solid ${
|
|
1913
|
+
padding: 12px 24px;
|
|
1914
|
+
background: ${colors.surface};
|
|
1915
|
+
border-bottom: 1px solid ${colors.border};
|
|
2047
1916
|
`,
|
|
2048
|
-
title:
|
|
2049
|
-
font-size:
|
|
1917
|
+
title: css7`
|
|
1918
|
+
font-size: ${fontSize.lg};
|
|
2050
1919
|
font-weight: 600;
|
|
2051
|
-
color: ${
|
|
1920
|
+
color: ${colors.text};
|
|
2052
1921
|
margin: 0;
|
|
2053
1922
|
letter-spacing: -0.02em;
|
|
2054
1923
|
`,
|
|
2055
|
-
headerActions:
|
|
1924
|
+
headerActions: css7`
|
|
2056
1925
|
display: flex;
|
|
2057
1926
|
align-items: center;
|
|
2058
1927
|
gap: 8px;
|
|
2059
1928
|
`,
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
1929
|
+
headerBtn: css7`
|
|
1930
|
+
height: ${btnHeight3};
|
|
1931
|
+
padding: 0 12px;
|
|
1932
|
+
background: ${colors.surface};
|
|
1933
|
+
border: 1px solid ${colors.border};
|
|
2064
1934
|
border-radius: 6px;
|
|
2065
1935
|
cursor: pointer;
|
|
2066
1936
|
transition: all 0.15s ease;
|
|
@@ -2069,20 +1939,21 @@ var styles8 = {
|
|
|
2069
1939
|
justify-content: center;
|
|
2070
1940
|
|
|
2071
1941
|
&:hover {
|
|
2072
|
-
background-color: ${
|
|
1942
|
+
background-color: ${colors.surfaceHover};
|
|
1943
|
+
border-color: ${colors.borderHover};
|
|
2073
1944
|
}
|
|
2074
1945
|
`,
|
|
2075
|
-
|
|
2076
|
-
width:
|
|
2077
|
-
height:
|
|
2078
|
-
color: ${
|
|
1946
|
+
headerIcon: css7`
|
|
1947
|
+
width: 16px;
|
|
1948
|
+
height: 16px;
|
|
1949
|
+
color: ${colors.textSecondary};
|
|
2079
1950
|
`,
|
|
2080
|
-
content:
|
|
1951
|
+
content: css7`
|
|
2081
1952
|
flex: 1;
|
|
2082
1953
|
display: flex;
|
|
2083
1954
|
overflow: hidden;
|
|
2084
1955
|
`,
|
|
2085
|
-
fileBrowser:
|
|
1956
|
+
fileBrowser: css7`
|
|
2086
1957
|
flex: 1;
|
|
2087
1958
|
min-width: 0;
|
|
2088
1959
|
overflow: auto;
|
|
@@ -2094,6 +1965,7 @@ function StudioUI({ onClose }) {
|
|
|
2094
1965
|
const [selectedItems, setSelectedItems] = useState6(/* @__PURE__ */ new Set());
|
|
2095
1966
|
const [lastSelectedPath, setLastSelectedPath] = useState6(null);
|
|
2096
1967
|
const [viewMode, setViewMode] = useState6("grid");
|
|
1968
|
+
const [focusedItem, setFocusedItem] = useState6(null);
|
|
2097
1969
|
const [meta, setMeta] = useState6(null);
|
|
2098
1970
|
const [isLoading, setIsLoading] = useState6(false);
|
|
2099
1971
|
const [refreshKey, setRefreshKey] = useState6(0);
|
|
@@ -2110,6 +1982,7 @@ function StudioUI({ onClose }) {
|
|
|
2110
1982
|
const setCurrentPath = useCallback2((path) => {
|
|
2111
1983
|
setCurrentPathInternal(path);
|
|
2112
1984
|
setSelectedItems(/* @__PURE__ */ new Set());
|
|
1985
|
+
setFocusedItem(null);
|
|
2113
1986
|
}, []);
|
|
2114
1987
|
const toggleSelection = useCallback2((path) => {
|
|
2115
1988
|
setSelectedItems((prev) => {
|
|
@@ -2147,10 +2020,14 @@ function StudioUI({ onClose }) {
|
|
|
2147
2020
|
const handleKeyDown = useCallback2(
|
|
2148
2021
|
(e) => {
|
|
2149
2022
|
if (e.key === "Escape") {
|
|
2150
|
-
|
|
2023
|
+
if (focusedItem) {
|
|
2024
|
+
setFocusedItem(null);
|
|
2025
|
+
} else {
|
|
2026
|
+
onClose();
|
|
2027
|
+
}
|
|
2151
2028
|
}
|
|
2152
2029
|
},
|
|
2153
|
-
[onClose]
|
|
2030
|
+
[onClose, focusedItem]
|
|
2154
2031
|
);
|
|
2155
2032
|
useEffect3(() => {
|
|
2156
2033
|
document.addEventListener("keydown", handleKeyDown);
|
|
@@ -2177,6 +2054,8 @@ function StudioUI({ onClose }) {
|
|
|
2177
2054
|
lastSelectedPath,
|
|
2178
2055
|
viewMode,
|
|
2179
2056
|
setViewMode,
|
|
2057
|
+
focusedItem,
|
|
2058
|
+
setFocusedItem,
|
|
2180
2059
|
meta,
|
|
2181
2060
|
setMeta,
|
|
2182
2061
|
isLoading,
|
|
@@ -2184,35 +2063,31 @@ function StudioUI({ onClose }) {
|
|
|
2184
2063
|
refreshKey,
|
|
2185
2064
|
triggerRefresh
|
|
2186
2065
|
};
|
|
2187
|
-
return /* @__PURE__ */
|
|
2188
|
-
/* @__PURE__ */
|
|
2189
|
-
/* @__PURE__ */
|
|
2190
|
-
/* @__PURE__ */
|
|
2191
|
-
/* @__PURE__ */
|
|
2192
|
-
/* @__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(
|
|
2193
2072
|
"button",
|
|
2194
2073
|
{
|
|
2195
|
-
css:
|
|
2074
|
+
css: styles7.headerBtn,
|
|
2196
2075
|
onClick: onClose,
|
|
2197
2076
|
"aria-label": "Close Studio",
|
|
2198
|
-
children: /* @__PURE__ */
|
|
2077
|
+
children: /* @__PURE__ */ jsx7(CloseIcon, {})
|
|
2199
2078
|
}
|
|
2200
2079
|
)
|
|
2201
2080
|
] })
|
|
2202
2081
|
] }),
|
|
2203
|
-
/* @__PURE__ */
|
|
2204
|
-
/* @__PURE__ */
|
|
2205
|
-
/* @__PURE__ */ jsxs8("div", { css: styles8.content, children: [
|
|
2206
|
-
/* @__PURE__ */ jsx8("div", { css: styles8.fileBrowser, children: viewMode === "grid" ? /* @__PURE__ */ jsx8(StudioFileGrid, {}) : /* @__PURE__ */ jsx8(StudioFileList, {}) }),
|
|
2207
|
-
/* @__PURE__ */ jsx8(StudioPreview, {})
|
|
2208
|
-
] })
|
|
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, {}) }) })
|
|
2209
2084
|
] }) });
|
|
2210
2085
|
}
|
|
2211
2086
|
function CloseIcon() {
|
|
2212
|
-
return /* @__PURE__ */
|
|
2087
|
+
return /* @__PURE__ */ jsxs7(
|
|
2213
2088
|
"svg",
|
|
2214
2089
|
{
|
|
2215
|
-
css:
|
|
2090
|
+
css: styles7.headerIcon,
|
|
2216
2091
|
xmlns: "http://www.w3.org/2000/svg",
|
|
2217
2092
|
viewBox: "0 0 24 24",
|
|
2218
2093
|
fill: "none",
|
|
@@ -2221,8 +2096,8 @@ function CloseIcon() {
|
|
|
2221
2096
|
strokeLinecap: "round",
|
|
2222
2097
|
strokeLinejoin: "round",
|
|
2223
2098
|
children: [
|
|
2224
|
-
/* @__PURE__ */
|
|
2225
|
-
/* @__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" })
|
|
2226
2101
|
]
|
|
2227
2102
|
}
|
|
2228
2103
|
);
|
|
@@ -2232,4 +2107,4 @@ export {
|
|
|
2232
2107
|
StudioUI,
|
|
2233
2108
|
StudioUI_default as default
|
|
2234
2109
|
};
|
|
2235
|
-
//# sourceMappingURL=StudioUI-
|
|
2110
|
+
//# sourceMappingURL=StudioUI-QPAHJJ64.mjs.map
|