@gallop.software/studio 0.1.38 → 0.1.40
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-DADFQY6I.mjs → StudioUI-4RENMCDG.mjs} +524 -57
- package/dist/StudioUI-4RENMCDG.mjs.map +1 -0
- package/dist/{StudioUI-X7VS2R5F.js → StudioUI-JYVMD7QS.js} +739 -272
- package/dist/StudioUI-JYVMD7QS.js.map +1 -0
- package/dist/{chunk-R5WKNVEV.mjs → chunk-HXE6XCG2.mjs} +11 -8
- package/dist/chunk-HXE6XCG2.mjs.map +1 -0
- package/dist/{chunk-AY2DAS6W.js → chunk-UFCWGUAG.js} +11 -8
- package/dist/chunk-UFCWGUAG.js.map +1 -0
- package/dist/index.js +15 -15
- package/dist/index.mjs +2 -2
- package/package.json +1 -1
- package/dist/StudioUI-DADFQY6I.mjs.map +0 -1
- package/dist/StudioUI-X7VS2R5F.js.map +0 -1
- package/dist/chunk-AY2DAS6W.js.map +0 -1
- package/dist/chunk-R5WKNVEV.mjs.map +0 -1
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
colors,
|
|
5
5
|
fontSize,
|
|
6
6
|
fontStack
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-HXE6XCG2.mjs";
|
|
8
8
|
|
|
9
9
|
// src/components/StudioUI.tsx
|
|
10
10
|
import { useEffect as useEffect3, useCallback as useCallback2, useState as useState6 } from "react";
|
|
@@ -49,6 +49,9 @@ var defaultState = {
|
|
|
49
49
|
},
|
|
50
50
|
refreshKey: 0,
|
|
51
51
|
triggerRefresh: () => {
|
|
52
|
+
},
|
|
53
|
+
searchQuery: "",
|
|
54
|
+
setSearchQuery: () => {
|
|
52
55
|
}
|
|
53
56
|
};
|
|
54
57
|
var StudioContext = createContext(defaultState);
|
|
@@ -318,13 +321,15 @@ var spin = keyframes2`
|
|
|
318
321
|
var styles2 = {
|
|
319
322
|
toolbar: css2`
|
|
320
323
|
display: flex;
|
|
321
|
-
flex-wrap:
|
|
324
|
+
flex-wrap: nowrap;
|
|
322
325
|
align-items: center;
|
|
323
326
|
justify-content: space-between;
|
|
324
327
|
gap: 8px;
|
|
325
328
|
padding: 12px 16px;
|
|
326
329
|
background-color: ${colors.surface};
|
|
327
330
|
border-bottom: 1px solid ${colors.border};
|
|
331
|
+
overflow-x: auto;
|
|
332
|
+
min-width: 0;
|
|
328
333
|
|
|
329
334
|
@media (min-width: 768px) {
|
|
330
335
|
padding: 12px 24px;
|
|
@@ -332,13 +337,15 @@ var styles2 = {
|
|
|
332
337
|
`,
|
|
333
338
|
left: css2`
|
|
334
339
|
display: flex;
|
|
335
|
-
flex-wrap:
|
|
340
|
+
flex-wrap: nowrap;
|
|
341
|
+
flex-shrink: 0;
|
|
336
342
|
align-items: center;
|
|
337
343
|
gap: 8px;
|
|
338
344
|
`,
|
|
339
345
|
right: css2`
|
|
340
346
|
display: flex;
|
|
341
|
-
flex-wrap:
|
|
347
|
+
flex-wrap: nowrap;
|
|
348
|
+
flex-shrink: 0;
|
|
342
349
|
align-items: center;
|
|
343
350
|
gap: 8px;
|
|
344
351
|
`,
|
|
@@ -433,6 +440,27 @@ var styles2 = {
|
|
|
433
440
|
border-radius: 6px;
|
|
434
441
|
overflow: hidden;
|
|
435
442
|
`,
|
|
443
|
+
searchInput: css2`
|
|
444
|
+
height: ${btnHeight};
|
|
445
|
+
padding: 0 12px;
|
|
446
|
+
border: 1px solid ${colors.border};
|
|
447
|
+
border-radius: 6px;
|
|
448
|
+
font-size: ${fontSize.base};
|
|
449
|
+
background: ${colors.surface};
|
|
450
|
+
color: ${colors.text};
|
|
451
|
+
width: 180px;
|
|
452
|
+
transition: all 0.15s ease;
|
|
453
|
+
|
|
454
|
+
&:focus {
|
|
455
|
+
outline: none;
|
|
456
|
+
border-color: ${colors.primary};
|
|
457
|
+
box-shadow: 0 0 0 2px ${colors.primaryLight};
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
&::placeholder {
|
|
461
|
+
color: ${colors.textMuted};
|
|
462
|
+
}
|
|
463
|
+
`,
|
|
436
464
|
viewBtn: css2`
|
|
437
465
|
height: 100%;
|
|
438
466
|
padding: 0 10px;
|
|
@@ -451,8 +479,13 @@ var styles2 = {
|
|
|
451
479
|
}
|
|
452
480
|
`,
|
|
453
481
|
viewBtnActive: css2`
|
|
454
|
-
background-color: ${colors.
|
|
455
|
-
color: ${colors.
|
|
482
|
+
background-color: ${colors.primaryLight};
|
|
483
|
+
color: ${colors.primary};
|
|
484
|
+
|
|
485
|
+
&:hover {
|
|
486
|
+
background-color: ${colors.primaryLight};
|
|
487
|
+
color: ${colors.primary};
|
|
488
|
+
}
|
|
456
489
|
`
|
|
457
490
|
};
|
|
458
491
|
function StudioToolbar() {
|
|
@@ -774,10 +807,14 @@ function StudioToolbar() {
|
|
|
774
807
|
const handleSyncCdn = useCallback(() => {
|
|
775
808
|
console.log("Sync CDN clicked", selectedItems);
|
|
776
809
|
}, [selectedItems]);
|
|
777
|
-
const
|
|
778
|
-
|
|
779
|
-
|
|
810
|
+
const { searchQuery, setSearchQuery } = useStudio();
|
|
811
|
+
const handleSearch = useCallback((e) => {
|
|
812
|
+
setSearchQuery(e.target.value);
|
|
813
|
+
}, [setSearchQuery]);
|
|
780
814
|
const hasSelection = selectedItems.size > 0;
|
|
815
|
+
const hasImagesSelected = Array.from(selectedItems).some(
|
|
816
|
+
(path) => path === "public/images" || path.startsWith("public/images/")
|
|
817
|
+
);
|
|
781
818
|
if (focusedItem) {
|
|
782
819
|
return null;
|
|
783
820
|
}
|
|
@@ -859,8 +896,8 @@ function StudioToolbar() {
|
|
|
859
896
|
{
|
|
860
897
|
css: styles2.btn,
|
|
861
898
|
onClick: handleProcessImages,
|
|
862
|
-
disabled: processing || isInImagesFolder,
|
|
863
|
-
title: isInImagesFolder ? "Cannot process
|
|
899
|
+
disabled: processing || isInImagesFolder || hasImagesSelected,
|
|
900
|
+
title: isInImagesFolder || hasImagesSelected ? "Cannot process protected images folder" : void 0,
|
|
864
901
|
children: [
|
|
865
902
|
/* @__PURE__ */ jsx2(ImageStackIcon, {}),
|
|
866
903
|
processing ? "Processing..." : "Process Images"
|
|
@@ -872,7 +909,8 @@ function StudioToolbar() {
|
|
|
872
909
|
{
|
|
873
910
|
css: [styles2.btn, styles2.btnDanger],
|
|
874
911
|
onClick: handleDeleteClick,
|
|
875
|
-
disabled: !hasSelection,
|
|
912
|
+
disabled: !hasSelection || hasImagesSelected,
|
|
913
|
+
title: hasImagesSelected ? "Cannot delete protected images folder items" : void 0,
|
|
876
914
|
children: [
|
|
877
915
|
/* @__PURE__ */ jsx2(TrashIcon, {}),
|
|
878
916
|
"Delete"
|
|
@@ -891,10 +929,16 @@ function StudioToolbar() {
|
|
|
891
929
|
]
|
|
892
930
|
}
|
|
893
931
|
),
|
|
894
|
-
/* @__PURE__ */
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
932
|
+
/* @__PURE__ */ jsx2(
|
|
933
|
+
"input",
|
|
934
|
+
{
|
|
935
|
+
css: styles2.searchInput,
|
|
936
|
+
type: "text",
|
|
937
|
+
placeholder: "Search images...",
|
|
938
|
+
value: searchQuery,
|
|
939
|
+
onChange: handleSearch
|
|
940
|
+
}
|
|
941
|
+
)
|
|
898
942
|
] }),
|
|
899
943
|
/* @__PURE__ */ jsxs2("div", { css: styles2.right, children: [
|
|
900
944
|
hasSelection && /* @__PURE__ */ jsxs2("span", { css: styles2.selectionCount, children: [
|
|
@@ -946,9 +990,6 @@ function TrashIcon() {
|
|
|
946
990
|
function CloudIcon() {
|
|
947
991
|
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: "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" }) });
|
|
948
992
|
}
|
|
949
|
-
function ScanIcon() {
|
|
950
|
-
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: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) });
|
|
951
|
-
}
|
|
952
993
|
function GridIcon() {
|
|
953
994
|
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 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z" }) });
|
|
954
995
|
}
|
|
@@ -1006,13 +1047,13 @@ var styles3 = {
|
|
|
1006
1047
|
`,
|
|
1007
1048
|
grid: css3`
|
|
1008
1049
|
display: grid;
|
|
1009
|
-
grid-template-columns:
|
|
1050
|
+
grid-template-columns: 1fr;
|
|
1010
1051
|
gap: 12px;
|
|
1011
1052
|
|
|
1012
|
-
@media (min-width:
|
|
1013
|
-
@media (min-width: 768px) { grid-template-columns: repeat(
|
|
1014
|
-
@media (min-width: 1024px) { grid-template-columns: repeat(
|
|
1015
|
-
@media (min-width: 1280px) { grid-template-columns: repeat(
|
|
1053
|
+
@media (min-width: 480px) { grid-template-columns: repeat(2, 1fr); }
|
|
1054
|
+
@media (min-width: 768px) { grid-template-columns: repeat(3, 1fr); }
|
|
1055
|
+
@media (min-width: 1024px) { grid-template-columns: repeat(4, 1fr); }
|
|
1056
|
+
@media (min-width: 1280px) { grid-template-columns: repeat(5, 1fr); }
|
|
1016
1057
|
`,
|
|
1017
1058
|
item: css3`
|
|
1018
1059
|
position: relative;
|
|
@@ -1084,6 +1125,25 @@ var styles3 = {
|
|
|
1084
1125
|
height: 56px;
|
|
1085
1126
|
color: #f5a623;
|
|
1086
1127
|
`,
|
|
1128
|
+
imagesFolderIcon: css3`
|
|
1129
|
+
width: 56px;
|
|
1130
|
+
height: 56px;
|
|
1131
|
+
color: ${colors.imagesFolder};
|
|
1132
|
+
`,
|
|
1133
|
+
imagesFolderWrapper: css3`
|
|
1134
|
+
position: relative;
|
|
1135
|
+
`,
|
|
1136
|
+
lockIcon: css3`
|
|
1137
|
+
position: absolute;
|
|
1138
|
+
bottom: 4px;
|
|
1139
|
+
right: 4px;
|
|
1140
|
+
width: 16px;
|
|
1141
|
+
height: 16px;
|
|
1142
|
+
color: ${colors.imagesFolder};
|
|
1143
|
+
background: white;
|
|
1144
|
+
border-radius: 50%;
|
|
1145
|
+
padding: 2px;
|
|
1146
|
+
`,
|
|
1087
1147
|
parentIcon: css3`
|
|
1088
1148
|
width: 56px;
|
|
1089
1149
|
height: 56px;
|
|
@@ -1137,14 +1197,69 @@ var styles3 = {
|
|
|
1137
1197
|
`,
|
|
1138
1198
|
labelRow: css3`
|
|
1139
1199
|
display: flex;
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
gap: 8px;
|
|
1200
|
+
flex-direction: column;
|
|
1201
|
+
gap: 6px;
|
|
1143
1202
|
`,
|
|
1144
1203
|
labelText: css3`
|
|
1145
1204
|
flex: 1;
|
|
1146
1205
|
min-width: 0;
|
|
1147
1206
|
`,
|
|
1207
|
+
buttonRow: css3`
|
|
1208
|
+
display: flex;
|
|
1209
|
+
gap: 6px;
|
|
1210
|
+
`,
|
|
1211
|
+
copyBtn: css3`
|
|
1212
|
+
position: relative;
|
|
1213
|
+
flex-shrink: 0;
|
|
1214
|
+
height: 28px;
|
|
1215
|
+
width: 28px;
|
|
1216
|
+
font-size: ${fontSize.xs};
|
|
1217
|
+
color: ${colors.textSecondary};
|
|
1218
|
+
background: ${colors.surface};
|
|
1219
|
+
border: 1px solid ${colors.border};
|
|
1220
|
+
padding: 0;
|
|
1221
|
+
cursor: pointer;
|
|
1222
|
+
border-radius: 4px;
|
|
1223
|
+
transition: all 0.15s ease;
|
|
1224
|
+
display: inline-flex;
|
|
1225
|
+
align-items: center;
|
|
1226
|
+
justify-content: center;
|
|
1227
|
+
|
|
1228
|
+
&:hover {
|
|
1229
|
+
background: ${colors.surfaceHover};
|
|
1230
|
+
border-color: ${colors.borderHover};
|
|
1231
|
+
color: ${colors.text};
|
|
1232
|
+
}
|
|
1233
|
+
`,
|
|
1234
|
+
copyIcon: css3`
|
|
1235
|
+
width: 14px;
|
|
1236
|
+
height: 14px;
|
|
1237
|
+
`,
|
|
1238
|
+
tooltip: css3`
|
|
1239
|
+
position: absolute;
|
|
1240
|
+
bottom: 100%;
|
|
1241
|
+
left: 50%;
|
|
1242
|
+
transform: translateX(-50%);
|
|
1243
|
+
background: #1a1f36;
|
|
1244
|
+
color: white;
|
|
1245
|
+
padding: 4px 8px;
|
|
1246
|
+
border-radius: 4px;
|
|
1247
|
+
font-size: 12px;
|
|
1248
|
+
white-space: nowrap;
|
|
1249
|
+
margin-bottom: 6px;
|
|
1250
|
+
pointer-events: none;
|
|
1251
|
+
z-index: 100;
|
|
1252
|
+
|
|
1253
|
+
&::after {
|
|
1254
|
+
content: '';
|
|
1255
|
+
position: absolute;
|
|
1256
|
+
top: 100%;
|
|
1257
|
+
left: 50%;
|
|
1258
|
+
transform: translateX(-50%);
|
|
1259
|
+
border: 4px solid transparent;
|
|
1260
|
+
border-top-color: #1a1f36;
|
|
1261
|
+
}
|
|
1262
|
+
`,
|
|
1148
1263
|
name: css3`
|
|
1149
1264
|
font-size: ${fontSize.sm};
|
|
1150
1265
|
font-weight: 500;
|
|
@@ -1209,7 +1324,7 @@ var styles3 = {
|
|
|
1209
1324
|
`
|
|
1210
1325
|
};
|
|
1211
1326
|
function StudioFileGrid() {
|
|
1212
|
-
const { currentPath, setCurrentPath, navigateUp, selectedItems, toggleSelection, selectRange, lastSelectedPath, selectAll, clearSelection, refreshKey, setFocusedItem, triggerRefresh } = useStudio();
|
|
1327
|
+
const { currentPath, setCurrentPath, navigateUp, selectedItems, toggleSelection, selectRange, lastSelectedPath, selectAll, clearSelection, refreshKey, setFocusedItem, triggerRefresh, searchQuery } = useStudio();
|
|
1213
1328
|
const [items, setItems] = useState2([]);
|
|
1214
1329
|
const [loading, setLoading] = useState2(true);
|
|
1215
1330
|
const isInitialLoad = useRef2(true);
|
|
@@ -1246,7 +1361,12 @@ function StudioFileGrid() {
|
|
|
1246
1361
|
/* @__PURE__ */ jsx3("p", { css: styles3.emptyText, children: "Upload images to get started" })
|
|
1247
1362
|
] });
|
|
1248
1363
|
}
|
|
1249
|
-
const
|
|
1364
|
+
const filteredItems = searchQuery ? items.filter((item) => {
|
|
1365
|
+
if (item.type === "folder") return true;
|
|
1366
|
+
const query = searchQuery.toLowerCase();
|
|
1367
|
+
return item.name.toLowerCase().includes(query);
|
|
1368
|
+
}) : items;
|
|
1369
|
+
const sortedItems = [...filteredItems].sort((a, b) => {
|
|
1250
1370
|
if (a.type === "folder" && b.type !== "folder") return -1;
|
|
1251
1371
|
if (a.type !== "folder" && b.type === "folder") return 1;
|
|
1252
1372
|
return a.name.localeCompare(b.name);
|
|
@@ -1335,8 +1455,17 @@ function StudioFileGrid() {
|
|
|
1335
1455
|
] });
|
|
1336
1456
|
}
|
|
1337
1457
|
function GridItem({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
|
|
1458
|
+
const [showCopied, setShowCopied] = useState2(false);
|
|
1338
1459
|
const isFolder = item.type === "folder";
|
|
1339
1460
|
const isImage = !isFolder && item.thumbnail !== void 0;
|
|
1461
|
+
const isImagesFolder = isFolder && (item.name === "images" || item.path.includes("/images/"));
|
|
1462
|
+
const handleCopyPath = (e) => {
|
|
1463
|
+
e.stopPropagation();
|
|
1464
|
+
const pathToCopy = "/" + item.path;
|
|
1465
|
+
navigator.clipboard.writeText(pathToCopy);
|
|
1466
|
+
setShowCopied(true);
|
|
1467
|
+
setTimeout(() => setShowCopied(false), 1500);
|
|
1468
|
+
};
|
|
1340
1469
|
return /* @__PURE__ */ jsxs3(
|
|
1341
1470
|
"div",
|
|
1342
1471
|
{
|
|
@@ -1360,7 +1489,10 @@ function GridItem({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
|
|
|
1360
1489
|
}
|
|
1361
1490
|
),
|
|
1362
1491
|
item.cdnSynced && /* @__PURE__ */ jsx3("span", { css: styles3.cdnBadge, children: "CDN" }),
|
|
1363
|
-
/* @__PURE__ */ jsx3("div", { css: styles3.content, children: isFolder ? /* @__PURE__ */
|
|
1492
|
+
/* @__PURE__ */ jsx3("div", { css: styles3.content, children: isFolder ? isImagesFolder ? /* @__PURE__ */ jsxs3("div", { css: styles3.imagesFolderWrapper, children: [
|
|
1493
|
+
/* @__PURE__ */ jsx3("svg", { css: styles3.imagesFolderIcon, 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" }) }),
|
|
1494
|
+
/* @__PURE__ */ jsx3("svg", { css: styles3.lockIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx3("path", { fillRule: "evenodd", d: "M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z", clipRule: "evenodd" }) })
|
|
1495
|
+
] }) : /* @__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" }) }) : isImage && item.hasThumbnail ? /* @__PURE__ */ jsx3(
|
|
1364
1496
|
"img",
|
|
1365
1497
|
{
|
|
1366
1498
|
css: styles3.image,
|
|
@@ -1392,17 +1524,31 @@ function GridItem({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
|
|
|
1392
1524
|
item.totalSize !== void 0 ? formatFileSize(item.totalSize) : ""
|
|
1393
1525
|
] }) : item.size !== void 0 && /* @__PURE__ */ jsx3("p", { css: styles3.size, children: formatFileSize(item.size) })
|
|
1394
1526
|
] }),
|
|
1395
|
-
/* @__PURE__ */
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1527
|
+
/* @__PURE__ */ jsxs3("div", { css: styles3.buttonRow, children: [
|
|
1528
|
+
/* @__PURE__ */ jsxs3(
|
|
1529
|
+
"button",
|
|
1530
|
+
{
|
|
1531
|
+
css: styles3.copyBtn,
|
|
1532
|
+
onClick: handleCopyPath,
|
|
1533
|
+
title: "Copy file path",
|
|
1534
|
+
children: [
|
|
1535
|
+
showCopied && /* @__PURE__ */ jsx3("span", { css: styles3.tooltip, children: "Copied!" }),
|
|
1536
|
+
/* @__PURE__ */ jsx3("svg", { css: styles3.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" }) })
|
|
1537
|
+
]
|
|
1538
|
+
}
|
|
1539
|
+
),
|
|
1540
|
+
/* @__PURE__ */ jsx3(
|
|
1541
|
+
"button",
|
|
1542
|
+
{
|
|
1543
|
+
css: styles3.openBtn,
|
|
1544
|
+
onClick: (e) => {
|
|
1545
|
+
e.stopPropagation();
|
|
1546
|
+
onOpen();
|
|
1547
|
+
},
|
|
1548
|
+
children: "Open"
|
|
1549
|
+
}
|
|
1550
|
+
)
|
|
1551
|
+
] })
|
|
1406
1552
|
] }) })
|
|
1407
1553
|
]
|
|
1408
1554
|
}
|
|
@@ -1513,6 +1659,7 @@ var styles4 = {
|
|
|
1513
1659
|
`,
|
|
1514
1660
|
parentRow: css4`
|
|
1515
1661
|
cursor: pointer;
|
|
1662
|
+
border-bottom: 1px solid ${colors.border};
|
|
1516
1663
|
|
|
1517
1664
|
&:hover {
|
|
1518
1665
|
background-color: ${colors.surfaceHover};
|
|
@@ -1524,12 +1671,66 @@ var styles4 = {
|
|
|
1524
1671
|
checkboxCell: css4`
|
|
1525
1672
|
padding: 12px 16px;
|
|
1526
1673
|
cursor: pointer;
|
|
1674
|
+
vertical-align: middle;
|
|
1527
1675
|
`,
|
|
1528
1676
|
checkbox: css4`
|
|
1529
1677
|
width: 16px;
|
|
1530
1678
|
height: 16px;
|
|
1531
1679
|
accent-color: ${colors.primary};
|
|
1532
1680
|
cursor: pointer;
|
|
1681
|
+
display: block;
|
|
1682
|
+
`,
|
|
1683
|
+
copyBtn: css4`
|
|
1684
|
+
position: relative;
|
|
1685
|
+
flex-shrink: 0;
|
|
1686
|
+
height: 28px;
|
|
1687
|
+
width: 28px;
|
|
1688
|
+
font-size: ${fontSize.xs};
|
|
1689
|
+
color: ${colors.textSecondary};
|
|
1690
|
+
background: ${colors.surface};
|
|
1691
|
+
border: 1px solid ${colors.border};
|
|
1692
|
+
padding: 0;
|
|
1693
|
+
cursor: pointer;
|
|
1694
|
+
border-radius: 4px;
|
|
1695
|
+
transition: all 0.15s ease;
|
|
1696
|
+
display: inline-flex;
|
|
1697
|
+
align-items: center;
|
|
1698
|
+
justify-content: center;
|
|
1699
|
+
|
|
1700
|
+
&:hover {
|
|
1701
|
+
background: ${colors.surfaceHover};
|
|
1702
|
+
border-color: ${colors.borderHover};
|
|
1703
|
+
color: ${colors.text};
|
|
1704
|
+
}
|
|
1705
|
+
`,
|
|
1706
|
+
copyIcon: css4`
|
|
1707
|
+
width: 14px;
|
|
1708
|
+
height: 14px;
|
|
1709
|
+
`,
|
|
1710
|
+
tooltip: css4`
|
|
1711
|
+
position: absolute;
|
|
1712
|
+
bottom: 100%;
|
|
1713
|
+
left: 50%;
|
|
1714
|
+
transform: translateX(-50%);
|
|
1715
|
+
background: #1a1f36;
|
|
1716
|
+
color: white;
|
|
1717
|
+
padding: 4px 8px;
|
|
1718
|
+
border-radius: 4px;
|
|
1719
|
+
font-size: 12px;
|
|
1720
|
+
white-space: nowrap;
|
|
1721
|
+
margin-bottom: 6px;
|
|
1722
|
+
pointer-events: none;
|
|
1723
|
+
z-index: 100;
|
|
1724
|
+
|
|
1725
|
+
&::after {
|
|
1726
|
+
content: '';
|
|
1727
|
+
position: absolute;
|
|
1728
|
+
top: 100%;
|
|
1729
|
+
left: 50%;
|
|
1730
|
+
transform: translateX(-50%);
|
|
1731
|
+
border: 4px solid transparent;
|
|
1732
|
+
border-top-color: #1a1f36;
|
|
1733
|
+
}
|
|
1533
1734
|
`,
|
|
1534
1735
|
nameCell: css4`
|
|
1535
1736
|
display: flex;
|
|
@@ -1542,6 +1743,24 @@ var styles4 = {
|
|
|
1542
1743
|
color: #f5a623;
|
|
1543
1744
|
flex-shrink: 0;
|
|
1544
1745
|
`,
|
|
1746
|
+
imagesFolderWrapper: css4`
|
|
1747
|
+
position: relative;
|
|
1748
|
+
display: flex;
|
|
1749
|
+
align-items: center;
|
|
1750
|
+
`,
|
|
1751
|
+
imagesFolderIcon: css4`
|
|
1752
|
+
width: 20px;
|
|
1753
|
+
height: 20px;
|
|
1754
|
+
color: ${colors.imagesFolder};
|
|
1755
|
+
flex-shrink: 0;
|
|
1756
|
+
`,
|
|
1757
|
+
lockIcon: css4`
|
|
1758
|
+
width: 10px;
|
|
1759
|
+
height: 10px;
|
|
1760
|
+
color: ${colors.imagesFolder};
|
|
1761
|
+
margin-left: -6px;
|
|
1762
|
+
margin-top: 8px;
|
|
1763
|
+
`,
|
|
1545
1764
|
parentIcon: css4`
|
|
1546
1765
|
width: 20px;
|
|
1547
1766
|
height: 20px;
|
|
@@ -1635,7 +1854,7 @@ var styles4 = {
|
|
|
1635
1854
|
`
|
|
1636
1855
|
};
|
|
1637
1856
|
function StudioFileList() {
|
|
1638
|
-
const { currentPath, setCurrentPath, navigateUp, selectedItems, toggleSelection, selectRange, lastSelectedPath, selectAll, clearSelection, refreshKey, setFocusedItem, triggerRefresh } = useStudio();
|
|
1857
|
+
const { currentPath, setCurrentPath, navigateUp, selectedItems, toggleSelection, selectRange, lastSelectedPath, selectAll, clearSelection, refreshKey, setFocusedItem, triggerRefresh, searchQuery } = useStudio();
|
|
1639
1858
|
const [items, setItems] = useState3([]);
|
|
1640
1859
|
const [loading, setLoading] = useState3(true);
|
|
1641
1860
|
const isInitialLoad = useRef3(true);
|
|
@@ -1668,7 +1887,12 @@ function StudioFileList() {
|
|
|
1668
1887
|
if (items.length === 0 && isAtRoot) {
|
|
1669
1888
|
return /* @__PURE__ */ jsx4("div", { css: styles4.empty, children: /* @__PURE__ */ jsx4("p", { children: "No files in this folder" }) });
|
|
1670
1889
|
}
|
|
1671
|
-
const
|
|
1890
|
+
const filteredItems = searchQuery ? items.filter((item) => {
|
|
1891
|
+
if (item.type === "folder") return true;
|
|
1892
|
+
const query = searchQuery.toLowerCase();
|
|
1893
|
+
return item.name.toLowerCase().includes(query);
|
|
1894
|
+
}) : items;
|
|
1895
|
+
const sortedItems = [...filteredItems].sort((a, b) => {
|
|
1672
1896
|
if (a.type === "folder" && b.type !== "folder") return -1;
|
|
1673
1897
|
if (a.type !== "folder" && b.type === "folder") return 1;
|
|
1674
1898
|
return a.name.localeCompare(b.name);
|
|
@@ -1754,8 +1978,17 @@ function StudioFileList() {
|
|
|
1754
1978
|
] }) });
|
|
1755
1979
|
}
|
|
1756
1980
|
function ListRow({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
|
|
1981
|
+
const [showCopied, setShowCopied] = useState3(false);
|
|
1757
1982
|
const isFolder = item.type === "folder";
|
|
1758
1983
|
const isImage = !isFolder && item.thumbnail !== void 0;
|
|
1984
|
+
const isImagesFolder = isFolder && (item.name === "images" || item.path.includes("/images/"));
|
|
1985
|
+
const handleCopyPath = (e) => {
|
|
1986
|
+
e.stopPropagation();
|
|
1987
|
+
const pathToCopy = "/" + item.path;
|
|
1988
|
+
navigator.clipboard.writeText(pathToCopy);
|
|
1989
|
+
setShowCopied(true);
|
|
1990
|
+
setTimeout(() => setShowCopied(false), 1500);
|
|
1991
|
+
};
|
|
1759
1992
|
return /* @__PURE__ */ jsxs4(
|
|
1760
1993
|
"tr",
|
|
1761
1994
|
{
|
|
@@ -1779,7 +2012,10 @@ function ListRow({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
|
|
|
1779
2012
|
}
|
|
1780
2013
|
),
|
|
1781
2014
|
/* @__PURE__ */ jsx4("td", { css: styles4.td, children: /* @__PURE__ */ jsxs4("div", { css: styles4.nameCell, children: [
|
|
1782
|
-
isFolder ?
|
|
2015
|
+
isFolder ? isImagesFolder ? /* @__PURE__ */ jsxs4("div", { css: styles4.imagesFolderWrapper, children: [
|
|
2016
|
+
/* @__PURE__ */ jsx4("svg", { css: styles4.imagesFolderIcon, 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" }) }),
|
|
2017
|
+
/* @__PURE__ */ jsx4("svg", { css: styles4.lockIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx4("path", { fillRule: "evenodd", d: "M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z", clipRule: "evenodd" }) })
|
|
2018
|
+
] }) : /* @__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" }) }) : isImage && item.hasThumbnail ? /* @__PURE__ */ jsx4("img", { css: styles4.thumbnail, src: item.thumbnail, alt: item.name, loading: "lazy" }) : isImage && !item.hasThumbnail ? /* @__PURE__ */ jsx4(
|
|
1783
2019
|
"button",
|
|
1784
2020
|
{
|
|
1785
2021
|
css: styles4.noThumbnail,
|
|
@@ -1792,6 +2028,18 @@ function ListRow({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
|
|
|
1792
2028
|
}
|
|
1793
2029
|
) : /* @__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" }) }),
|
|
1794
2030
|
/* @__PURE__ */ jsx4("span", { css: styles4.name, title: item.name, children: truncateMiddle2(item.name) }),
|
|
2031
|
+
/* @__PURE__ */ jsxs4(
|
|
2032
|
+
"button",
|
|
2033
|
+
{
|
|
2034
|
+
css: styles4.copyBtn,
|
|
2035
|
+
onClick: handleCopyPath,
|
|
2036
|
+
title: "Copy file path",
|
|
2037
|
+
children: [
|
|
2038
|
+
showCopied && /* @__PURE__ */ jsx4("span", { css: styles4.tooltip, children: "Copied!" }),
|
|
2039
|
+
/* @__PURE__ */ jsx4("svg", { css: styles4.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" }) })
|
|
2040
|
+
]
|
|
2041
|
+
}
|
|
2042
|
+
),
|
|
1795
2043
|
/* @__PURE__ */ jsx4(
|
|
1796
2044
|
"button",
|
|
1797
2045
|
{
|
|
@@ -1863,6 +2111,7 @@ var styles5 = {
|
|
|
1863
2111
|
flex: 1;
|
|
1864
2112
|
margin: 24px;
|
|
1865
2113
|
background: ${colors.surface};
|
|
2114
|
+
border: 1px solid ${colors.border};
|
|
1866
2115
|
border-radius: 12px;
|
|
1867
2116
|
overflow: hidden;
|
|
1868
2117
|
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);
|
|
@@ -1878,10 +2127,16 @@ var styles5 = {
|
|
|
1878
2127
|
background: ${colors.background};
|
|
1879
2128
|
overflow: auto;
|
|
1880
2129
|
`,
|
|
1881
|
-
|
|
2130
|
+
headerButtons: css5`
|
|
1882
2131
|
position: absolute;
|
|
1883
2132
|
top: 16px;
|
|
1884
2133
|
right: 16px;
|
|
2134
|
+
display: flex;
|
|
2135
|
+
gap: 8px;
|
|
2136
|
+
z-index: 10;
|
|
2137
|
+
`,
|
|
2138
|
+
copyBtn: css5`
|
|
2139
|
+
position: relative;
|
|
1885
2140
|
padding: 8px;
|
|
1886
2141
|
background: ${colors.surface};
|
|
1887
2142
|
border: 1px solid ${colors.border};
|
|
@@ -1891,7 +2146,6 @@ var styles5 = {
|
|
|
1891
2146
|
display: flex;
|
|
1892
2147
|
align-items: center;
|
|
1893
2148
|
justify-content: center;
|
|
1894
|
-
z-index: 10;
|
|
1895
2149
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
|
|
1896
2150
|
|
|
1897
2151
|
&:hover {
|
|
@@ -1899,11 +2153,58 @@ var styles5 = {
|
|
|
1899
2153
|
border-color: ${colors.borderHover};
|
|
1900
2154
|
}
|
|
1901
2155
|
`,
|
|
1902
|
-
|
|
2156
|
+
copyIcon: css5`
|
|
1903
2157
|
width: 20px;
|
|
1904
2158
|
height: 20px;
|
|
1905
2159
|
color: ${colors.textSecondary};
|
|
1906
2160
|
`,
|
|
2161
|
+
tooltip: css5`
|
|
2162
|
+
position: absolute;
|
|
2163
|
+
bottom: 100%;
|
|
2164
|
+
left: 50%;
|
|
2165
|
+
transform: translateX(-50%);
|
|
2166
|
+
background: #1a1f36;
|
|
2167
|
+
color: white;
|
|
2168
|
+
padding: 4px 8px;
|
|
2169
|
+
border-radius: 4px;
|
|
2170
|
+
font-size: 12px;
|
|
2171
|
+
white-space: nowrap;
|
|
2172
|
+
margin-bottom: 6px;
|
|
2173
|
+
pointer-events: none;
|
|
2174
|
+
z-index: 100;
|
|
2175
|
+
|
|
2176
|
+
&::after {
|
|
2177
|
+
content: '';
|
|
2178
|
+
position: absolute;
|
|
2179
|
+
top: 100%;
|
|
2180
|
+
left: 50%;
|
|
2181
|
+
transform: translateX(-50%);
|
|
2182
|
+
border: 4px solid transparent;
|
|
2183
|
+
border-top-color: #1a1f36;
|
|
2184
|
+
}
|
|
2185
|
+
`,
|
|
2186
|
+
mainCloseBtn: css5`
|
|
2187
|
+
padding: 8px;
|
|
2188
|
+
background: ${colors.danger};
|
|
2189
|
+
border: 1px solid ${colors.danger};
|
|
2190
|
+
border-radius: 8px;
|
|
2191
|
+
cursor: pointer;
|
|
2192
|
+
transition: all 0.15s ease;
|
|
2193
|
+
display: flex;
|
|
2194
|
+
align-items: center;
|
|
2195
|
+
justify-content: center;
|
|
2196
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
|
|
2197
|
+
|
|
2198
|
+
&:hover {
|
|
2199
|
+
background-color: ${colors.dangerHover};
|
|
2200
|
+
border-color: ${colors.dangerHover};
|
|
2201
|
+
}
|
|
2202
|
+
`,
|
|
2203
|
+
mainCloseIcon: css5`
|
|
2204
|
+
width: 20px;
|
|
2205
|
+
height: 20px;
|
|
2206
|
+
color: white;
|
|
2207
|
+
`,
|
|
1907
2208
|
mediaWrapper: css5`
|
|
1908
2209
|
max-width: 100%;
|
|
1909
2210
|
max-height: 100%;
|
|
@@ -2044,6 +2345,7 @@ function StudioDetailView() {
|
|
|
2044
2345
|
const { focusedItem, setFocusedItem, triggerRefresh, clearSelection } = useStudio();
|
|
2045
2346
|
const [showDeleteConfirm, setShowDeleteConfirm] = useState4(false);
|
|
2046
2347
|
const [alertMessage, setAlertMessage] = useState4(null);
|
|
2348
|
+
const [showCopied, setShowCopied] = useState4(false);
|
|
2047
2349
|
if (!focusedItem) return null;
|
|
2048
2350
|
const isImage = isImageFile(focusedItem.name);
|
|
2049
2351
|
const isVideo = isVideoFile(focusedItem.name);
|
|
@@ -2051,6 +2353,12 @@ function StudioDetailView() {
|
|
|
2051
2353
|
const handleClose = () => {
|
|
2052
2354
|
setFocusedItem(null);
|
|
2053
2355
|
};
|
|
2356
|
+
const handleCopyPath = () => {
|
|
2357
|
+
const pathToCopy = "/" + focusedItem.path;
|
|
2358
|
+
navigator.clipboard.writeText(pathToCopy);
|
|
2359
|
+
setShowCopied(true);
|
|
2360
|
+
setTimeout(() => setShowCopied(false), 1500);
|
|
2361
|
+
};
|
|
2054
2362
|
const handleRename = () => {
|
|
2055
2363
|
const newName = prompt("Enter new name:", focusedItem.name);
|
|
2056
2364
|
if (newName && newName !== focusedItem.name) {
|
|
@@ -2124,7 +2432,13 @@ function StudioDetailView() {
|
|
|
2124
2432
|
),
|
|
2125
2433
|
/* @__PURE__ */ jsx5("div", { css: styles5.overlay, onClick: handleClose, children: /* @__PURE__ */ jsxs5("div", { css: styles5.container, onClick: (e) => e.stopPropagation(), children: [
|
|
2126
2434
|
/* @__PURE__ */ jsxs5("div", { css: styles5.main, children: [
|
|
2127
|
-
/* @__PURE__ */
|
|
2435
|
+
/* @__PURE__ */ jsxs5("div", { css: styles5.headerButtons, children: [
|
|
2436
|
+
/* @__PURE__ */ jsxs5("button", { css: styles5.copyBtn, onClick: handleCopyPath, title: "Copy file path", children: [
|
|
2437
|
+
showCopied && /* @__PURE__ */ jsx5("span", { css: styles5.tooltip, children: "Copied!" }),
|
|
2438
|
+
/* @__PURE__ */ jsx5("svg", { css: styles5.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" }) })
|
|
2439
|
+
] }),
|
|
2440
|
+
/* @__PURE__ */ jsx5("button", { css: styles5.mainCloseBtn, onClick: handleClose, "aria-label": "Close", children: /* @__PURE__ */ jsx5("svg", { css: styles5.mainCloseIcon, 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" }) }) })
|
|
2441
|
+
] }),
|
|
2128
2442
|
/* @__PURE__ */ jsx5("div", { css: styles5.mediaWrapper, children: renderMedia() })
|
|
2129
2443
|
] }),
|
|
2130
2444
|
/* @__PURE__ */ jsxs5("div", { css: styles5.sidebar, children: [
|
|
@@ -2281,14 +2595,69 @@ var styles6 = {
|
|
|
2281
2595
|
color: ${colors.textSecondary};
|
|
2282
2596
|
margin: 0 0 12px 0;
|
|
2283
2597
|
`,
|
|
2598
|
+
codeWrapper: css6`
|
|
2599
|
+
position: relative;
|
|
2600
|
+
`,
|
|
2284
2601
|
code: css6`
|
|
2285
2602
|
background-color: ${colors.background};
|
|
2286
2603
|
border-radius: 8px;
|
|
2287
2604
|
padding: 12px;
|
|
2605
|
+
padding-right: 40px;
|
|
2288
2606
|
font-family: 'SF Mono', Monaco, Consolas, monospace;
|
|
2289
2607
|
font-size: ${fontSize.xs};
|
|
2290
2608
|
color: ${colors.textSecondary};
|
|
2291
2609
|
border: 1px solid ${colors.border};
|
|
2610
|
+
overflow-x: auto;
|
|
2611
|
+
white-space: nowrap;
|
|
2612
|
+
`,
|
|
2613
|
+
copyBtn: css6`
|
|
2614
|
+
position: absolute;
|
|
2615
|
+
top: 8px;
|
|
2616
|
+
right: 8px;
|
|
2617
|
+
padding: 4px;
|
|
2618
|
+
background: ${colors.surface};
|
|
2619
|
+
border: 1px solid ${colors.border};
|
|
2620
|
+
border-radius: 4px;
|
|
2621
|
+
cursor: pointer;
|
|
2622
|
+
transition: all 0.15s ease;
|
|
2623
|
+
display: flex;
|
|
2624
|
+
align-items: center;
|
|
2625
|
+
justify-content: center;
|
|
2626
|
+
|
|
2627
|
+
&:hover {
|
|
2628
|
+
background-color: ${colors.surfaceHover};
|
|
2629
|
+
border-color: ${colors.borderHover};
|
|
2630
|
+
}
|
|
2631
|
+
`,
|
|
2632
|
+
tooltip: css6`
|
|
2633
|
+
position: absolute;
|
|
2634
|
+
bottom: 100%;
|
|
2635
|
+
left: 50%;
|
|
2636
|
+
transform: translateX(-50%);
|
|
2637
|
+
background: #1a1f36;
|
|
2638
|
+
color: white;
|
|
2639
|
+
padding: 4px 8px;
|
|
2640
|
+
border-radius: 4px;
|
|
2641
|
+
font-size: 12px;
|
|
2642
|
+
white-space: nowrap;
|
|
2643
|
+
margin-bottom: 6px;
|
|
2644
|
+
pointer-events: none;
|
|
2645
|
+
z-index: 100;
|
|
2646
|
+
|
|
2647
|
+
&::after {
|
|
2648
|
+
content: '';
|
|
2649
|
+
position: absolute;
|
|
2650
|
+
top: 100%;
|
|
2651
|
+
left: 50%;
|
|
2652
|
+
transform: translateX(-50%);
|
|
2653
|
+
border: 4px solid transparent;
|
|
2654
|
+
border-top-color: #1a1f36;
|
|
2655
|
+
}
|
|
2656
|
+
`,
|
|
2657
|
+
copyIcon: css6`
|
|
2658
|
+
width: 14px;
|
|
2659
|
+
height: 14px;
|
|
2660
|
+
color: ${colors.textSecondary};
|
|
2292
2661
|
`,
|
|
2293
2662
|
codeLine: css6`
|
|
2294
2663
|
margin: 0 0 4px 0;
|
|
@@ -2393,7 +2762,18 @@ function StudioSettings() {
|
|
|
2393
2762
|
isOpen && /* @__PURE__ */ jsx6(SettingsPanel, { onClose: () => setIsOpen(false) })
|
|
2394
2763
|
] });
|
|
2395
2764
|
}
|
|
2765
|
+
var envTemplate = `CLOUDFLARE_R2_ACCOUNT_ID=abc123def456ghi789
|
|
2766
|
+
CLOUDFLARE_R2_ACCESS_KEY_ID=your_access_key_id_here
|
|
2767
|
+
CLOUDFLARE_R2_SECRET_ACCESS_KEY=your_secret_access_key_here
|
|
2768
|
+
CLOUDFLARE_R2_BUCKET_NAME=my-images-bucket
|
|
2769
|
+
CLOUDFLARE_R2_PUBLIC_URL=https://cdn.yourdomain.com`;
|
|
2396
2770
|
function SettingsPanel({ onClose }) {
|
|
2771
|
+
const [copied, setCopied] = useState5(false);
|
|
2772
|
+
const handleCopy = () => {
|
|
2773
|
+
navigator.clipboard.writeText(envTemplate);
|
|
2774
|
+
setCopied(true);
|
|
2775
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
2776
|
+
};
|
|
2397
2777
|
return /* @__PURE__ */ jsx6("div", { css: styles6.overlay, onClick: onClose, children: /* @__PURE__ */ jsxs6("div", { css: styles6.panel, onClick: (e) => e.stopPropagation(), children: [
|
|
2398
2778
|
/* @__PURE__ */ jsxs6("div", { css: styles6.header, children: [
|
|
2399
2779
|
/* @__PURE__ */ jsx6("h2", { css: styles6.title, children: "Settings" }),
|
|
@@ -2403,12 +2783,18 @@ function SettingsPanel({ onClose }) {
|
|
|
2403
2783
|
/* @__PURE__ */ jsxs6("section", { children: [
|
|
2404
2784
|
/* @__PURE__ */ jsx6("h3", { css: styles6.sectionTitle, children: "Cloudflare R2" }),
|
|
2405
2785
|
/* @__PURE__ */ jsx6("p", { css: styles6.description, children: "Configure in .env.local file:" }),
|
|
2406
|
-
/* @__PURE__ */ jsxs6("div", { css: styles6.
|
|
2407
|
-
/* @__PURE__ */
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
/* @__PURE__ */
|
|
2786
|
+
/* @__PURE__ */ jsxs6("div", { css: styles6.codeWrapper, children: [
|
|
2787
|
+
/* @__PURE__ */ jsxs6("button", { css: styles6.copyBtn, onClick: handleCopy, title: "Copy to clipboard", children: [
|
|
2788
|
+
copied && /* @__PURE__ */ jsx6("span", { css: styles6.tooltip, children: "Copied!" }),
|
|
2789
|
+
copied ? /* @__PURE__ */ jsx6("svg", { css: styles6.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }) : /* @__PURE__ */ jsx6("svg", { css: styles6.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" }) })
|
|
2790
|
+
] }),
|
|
2791
|
+
/* @__PURE__ */ jsxs6("div", { css: styles6.code, children: [
|
|
2792
|
+
/* @__PURE__ */ jsx6("p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_ACCOUNT_ID=abc123def456ghi789" }),
|
|
2793
|
+
/* @__PURE__ */ jsx6("p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_ACCESS_KEY_ID=your_access_key_id_here" }),
|
|
2794
|
+
/* @__PURE__ */ jsx6("p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_SECRET_ACCESS_KEY=your_secret_access_key_here" }),
|
|
2795
|
+
/* @__PURE__ */ jsx6("p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_BUCKET_NAME=my-images-bucket" }),
|
|
2796
|
+
/* @__PURE__ */ jsx6("p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_PUBLIC_URL=https://cdn.yourdomain.com" })
|
|
2797
|
+
] })
|
|
2412
2798
|
] })
|
|
2413
2799
|
] }),
|
|
2414
2800
|
/* @__PURE__ */ jsxs6("section", { children: [
|
|
@@ -2504,6 +2890,34 @@ var styles7 = {
|
|
|
2504
2890
|
min-width: 0;
|
|
2505
2891
|
overflow: auto;
|
|
2506
2892
|
padding: 20px 24px;
|
|
2893
|
+
`,
|
|
2894
|
+
dropOverlay: css7`
|
|
2895
|
+
position: absolute;
|
|
2896
|
+
top: 0;
|
|
2897
|
+
left: 0;
|
|
2898
|
+
right: 0;
|
|
2899
|
+
bottom: 0;
|
|
2900
|
+
background: rgba(99, 91, 255, 0.1);
|
|
2901
|
+
border: 3px dashed ${colors.primary};
|
|
2902
|
+
border-radius: 8px;
|
|
2903
|
+
display: flex;
|
|
2904
|
+
align-items: center;
|
|
2905
|
+
justify-content: center;
|
|
2906
|
+
z-index: 50;
|
|
2907
|
+
pointer-events: none;
|
|
2908
|
+
`,
|
|
2909
|
+
dropMessage: css7`
|
|
2910
|
+
display: flex;
|
|
2911
|
+
flex-direction: column;
|
|
2912
|
+
align-items: center;
|
|
2913
|
+
gap: 12px;
|
|
2914
|
+
color: ${colors.primary};
|
|
2915
|
+
font-size: ${fontSize.lg};
|
|
2916
|
+
font-weight: 600;
|
|
2917
|
+
`,
|
|
2918
|
+
dropIcon: css7`
|
|
2919
|
+
width: 48px;
|
|
2920
|
+
height: 48px;
|
|
2507
2921
|
`
|
|
2508
2922
|
};
|
|
2509
2923
|
function StudioUI({ onClose, isVisible = true }) {
|
|
@@ -2515,9 +2929,45 @@ function StudioUI({ onClose, isVisible = true }) {
|
|
|
2515
2929
|
const [meta, setMeta] = useState6(null);
|
|
2516
2930
|
const [isLoading, setIsLoading] = useState6(false);
|
|
2517
2931
|
const [refreshKey, setRefreshKey] = useState6(0);
|
|
2932
|
+
const [searchQuery, setSearchQuery] = useState6("");
|
|
2933
|
+
const [isDragging, setIsDragging] = useState6(false);
|
|
2518
2934
|
const triggerRefresh = useCallback2(() => {
|
|
2519
2935
|
setRefreshKey((k) => k + 1);
|
|
2520
2936
|
}, []);
|
|
2937
|
+
const handleDragOver = useCallback2((e) => {
|
|
2938
|
+
e.preventDefault();
|
|
2939
|
+
e.stopPropagation();
|
|
2940
|
+
setIsDragging(true);
|
|
2941
|
+
}, []);
|
|
2942
|
+
const handleDragLeave = useCallback2((e) => {
|
|
2943
|
+
e.preventDefault();
|
|
2944
|
+
e.stopPropagation();
|
|
2945
|
+
setIsDragging(false);
|
|
2946
|
+
}, []);
|
|
2947
|
+
const handleDrop = useCallback2(async (e) => {
|
|
2948
|
+
e.preventDefault();
|
|
2949
|
+
e.stopPropagation();
|
|
2950
|
+
setIsDragging(false);
|
|
2951
|
+
const files = Array.from(e.dataTransfer.files);
|
|
2952
|
+
if (files.length === 0) return;
|
|
2953
|
+
if (currentPath === "public/images" || currentPath.startsWith("public/images/")) {
|
|
2954
|
+
return;
|
|
2955
|
+
}
|
|
2956
|
+
for (const file of files) {
|
|
2957
|
+
const formData = new FormData();
|
|
2958
|
+
formData.append("file", file);
|
|
2959
|
+
formData.append("path", currentPath);
|
|
2960
|
+
try {
|
|
2961
|
+
await fetch("/api/studio/upload", {
|
|
2962
|
+
method: "POST",
|
|
2963
|
+
body: formData
|
|
2964
|
+
});
|
|
2965
|
+
} catch (error) {
|
|
2966
|
+
console.error("Upload error:", error);
|
|
2967
|
+
}
|
|
2968
|
+
}
|
|
2969
|
+
triggerRefresh();
|
|
2970
|
+
}, [currentPath, triggerRefresh]);
|
|
2521
2971
|
const navigateUp = useCallback2(() => {
|
|
2522
2972
|
if (currentPath === "public") return;
|
|
2523
2973
|
const parts = currentPath.split("/");
|
|
@@ -2609,7 +3059,9 @@ function StudioUI({ onClose, isVisible = true }) {
|
|
|
2609
3059
|
isLoading,
|
|
2610
3060
|
setIsLoading,
|
|
2611
3061
|
refreshKey,
|
|
2612
|
-
triggerRefresh
|
|
3062
|
+
triggerRefresh,
|
|
3063
|
+
searchQuery,
|
|
3064
|
+
setSearchQuery
|
|
2613
3065
|
};
|
|
2614
3066
|
return /* @__PURE__ */ jsx7(StudioContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs7("div", { css: styles7.container, children: [
|
|
2615
3067
|
/* @__PURE__ */ jsxs7("div", { css: styles7.header, children: [
|
|
@@ -2628,7 +3080,22 @@ function StudioUI({ onClose, isVisible = true }) {
|
|
|
2628
3080
|
] })
|
|
2629
3081
|
] }),
|
|
2630
3082
|
/* @__PURE__ */ jsx7(StudioToolbar, {}),
|
|
2631
|
-
/* @__PURE__ */
|
|
3083
|
+
/* @__PURE__ */ jsxs7(
|
|
3084
|
+
"div",
|
|
3085
|
+
{
|
|
3086
|
+
css: styles7.content,
|
|
3087
|
+
onDragOver: handleDragOver,
|
|
3088
|
+
onDragLeave: handleDragLeave,
|
|
3089
|
+
onDrop: handleDrop,
|
|
3090
|
+
children: [
|
|
3091
|
+
isDragging && /* @__PURE__ */ jsx7("div", { css: styles7.dropOverlay, children: /* @__PURE__ */ jsxs7("div", { css: styles7.dropMessage, children: [
|
|
3092
|
+
/* @__PURE__ */ jsx7("svg", { css: styles7.dropIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" }) }),
|
|
3093
|
+
/* @__PURE__ */ jsx7("span", { children: "Drop files to upload" })
|
|
3094
|
+
] }) }),
|
|
3095
|
+
/* @__PURE__ */ jsx7("div", { css: styles7.fileBrowser, children: viewMode === "grid" ? /* @__PURE__ */ jsx7(StudioFileGrid, {}) : /* @__PURE__ */ jsx7(StudioFileList, {}) })
|
|
3096
|
+
]
|
|
3097
|
+
}
|
|
3098
|
+
),
|
|
2632
3099
|
focusedItem && /* @__PURE__ */ jsx7(StudioDetailView, {})
|
|
2633
3100
|
] }) });
|
|
2634
3101
|
}
|
|
@@ -2656,4 +3123,4 @@ export {
|
|
|
2656
3123
|
StudioUI,
|
|
2657
3124
|
StudioUI_default as default
|
|
2658
3125
|
};
|
|
2659
|
-
//# sourceMappingURL=StudioUI-
|
|
3126
|
+
//# sourceMappingURL=StudioUI-4RENMCDG.mjs.map
|