@gallop.software/studio 0.1.88 → 0.1.89

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.
@@ -1289,7 +1289,7 @@ function StudioToolbar() {
1289
1289
  const fileInputRef = _react.useRef.call(void 0, null);
1290
1290
  const abortControllerRef = _react.useRef.call(void 0, null);
1291
1291
  const [uploading, setUploading] = _react.useState.call(void 0, false);
1292
- const [refreshing, setRefreshing] = _react.useState.call(void 0, false);
1292
+ const [scanning, setScanning] = _react.useState.call(void 0, false);
1293
1293
  const [processing, setProcessing] = _react.useState.call(void 0, false);
1294
1294
  const [showDeleteConfirm, setShowDeleteConfirm] = _react.useState.call(void 0, false);
1295
1295
  const [showProcessConfirm, setShowProcessConfirm] = _react.useState.call(void 0, false);
@@ -1315,10 +1315,81 @@ function StudioToolbar() {
1315
1315
  const handleUpload = _react.useCallback.call(void 0, () => {
1316
1316
  _optionalChain([fileInputRef, 'access', _2 => _2.current, 'optionalAccess', _3 => _3.click, 'call', _4 => _4()]);
1317
1317
  }, []);
1318
- const handleRefresh = _react.useCallback.call(void 0, () => {
1319
- setRefreshing(true);
1320
- triggerRefresh();
1321
- setTimeout(() => setRefreshing(false), 600);
1318
+ const handleScan = _react.useCallback.call(void 0, async () => {
1319
+ setScanning(true);
1320
+ setShowProgress(true);
1321
+ setProgressState({
1322
+ current: 0,
1323
+ total: 0,
1324
+ percent: 0,
1325
+ status: "processing",
1326
+ message: "Scanning for files..."
1327
+ });
1328
+ try {
1329
+ const response = await fetch("/api/studio/scan", { method: "POST" });
1330
+ const reader = _optionalChain([response, 'access', _5 => _5.body, 'optionalAccess', _6 => _6.getReader, 'call', _7 => _7()]);
1331
+ if (!reader) throw new Error("No reader");
1332
+ const decoder = new TextDecoder();
1333
+ let buffer = "";
1334
+ while (true) {
1335
+ const { done, value } = await reader.read();
1336
+ if (done) break;
1337
+ buffer += decoder.decode(value, { stream: true });
1338
+ const lines = buffer.split("\n\n");
1339
+ buffer = lines.pop() || "";
1340
+ for (const line of lines) {
1341
+ if (!line.startsWith("data: ")) continue;
1342
+ const data = JSON.parse(line.slice(6));
1343
+ if (data.type === "start") {
1344
+ setProgressState({
1345
+ current: 0,
1346
+ total: data.total,
1347
+ percent: 0,
1348
+ status: "processing",
1349
+ message: `Scanning ${data.total} files...`
1350
+ });
1351
+ } else if (data.type === "progress") {
1352
+ setProgressState({
1353
+ current: data.current,
1354
+ total: data.total,
1355
+ percent: data.percent,
1356
+ status: "processing",
1357
+ currentFile: data.currentFile
1358
+ });
1359
+ } else if (data.type === "complete") {
1360
+ setProgressState({
1361
+ current: data.total || 0,
1362
+ total: data.total || 0,
1363
+ percent: 100,
1364
+ status: "complete",
1365
+ processed: data.added,
1366
+ errors: data.errors,
1367
+ message: data.renamed > 0 ? `${data.renamed} file(s) renamed due to conflicts` : void 0
1368
+ });
1369
+ triggerRefresh();
1370
+ } else if (data.type === "error") {
1371
+ setProgressState({
1372
+ current: 0,
1373
+ total: 0,
1374
+ percent: 0,
1375
+ status: "error",
1376
+ message: data.message || "Scan failed"
1377
+ });
1378
+ }
1379
+ }
1380
+ }
1381
+ } catch (error) {
1382
+ console.error("Scan error:", error);
1383
+ setProgressState({
1384
+ current: 0,
1385
+ total: 0,
1386
+ percent: 0,
1387
+ status: "error",
1388
+ message: "Scan failed"
1389
+ });
1390
+ } finally {
1391
+ setScanning(false);
1392
+ }
1322
1393
  }, [triggerRefresh]);
1323
1394
  const handleFileChange = _react.useCallback.call(void 0, async (e) => {
1324
1395
  const files = e.target.files;
@@ -1422,7 +1493,7 @@ function StudioToolbar() {
1422
1493
  const selectedPaths2 = Array.from(selectedItems);
1423
1494
  const imageExtensions = ["jpg", "jpeg", "png", "gif", "webp", "svg", "ico", "bmp", "tiff", "tif"];
1424
1495
  const selectedImagePaths = selectedPaths2.filter((p) => {
1425
- const ext = _optionalChain([p, 'access', _5 => _5.split, 'call', _6 => _6("."), 'access', _7 => _7.pop, 'call', _8 => _8(), 'optionalAccess', _9 => _9.toLowerCase, 'call', _10 => _10()]) || "";
1496
+ const ext = _optionalChain([p, 'access', _8 => _8.split, 'call', _9 => _9("."), 'access', _10 => _10.pop, 'call', _11 => _11(), 'optionalAccess', _12 => _12.toLowerCase, 'call', _13 => _13()]) || "";
1426
1497
  return imageExtensions.includes(ext);
1427
1498
  });
1428
1499
  const selectedFolders = selectedPaths2.filter((p) => !p.includes(".") || p.endsWith("/"));
@@ -1583,12 +1654,12 @@ function StudioToolbar() {
1583
1654
  const data = await response.json();
1584
1655
  if (response.ok) {
1585
1656
  setProgressState({
1586
- current: _optionalChain([data, 'access', _11 => _11.processed, 'optionalAccess', _12 => _12.length]) || 0,
1587
- total: _optionalChain([data, 'access', _13 => _13.processed, 'optionalAccess', _14 => _14.length]) || 0,
1657
+ current: _optionalChain([data, 'access', _14 => _14.processed, 'optionalAccess', _15 => _15.length]) || 0,
1658
+ total: _optionalChain([data, 'access', _16 => _16.processed, 'optionalAccess', _17 => _17.length]) || 0,
1588
1659
  percent: 100,
1589
1660
  status: "complete",
1590
- processed: _optionalChain([data, 'access', _15 => _15.processed, 'optionalAccess', _16 => _16.length]) || 0,
1591
- errors: _optionalChain([data, 'access', _17 => _17.errors, 'optionalAccess', _18 => _18.length]) || 0
1661
+ processed: _optionalChain([data, 'access', _18 => _18.processed, 'optionalAccess', _19 => _19.length]) || 0,
1662
+ errors: _optionalChain([data, 'access', _20 => _20.errors, 'optionalAccess', _21 => _21.length]) || 0
1592
1663
  });
1593
1664
  clearSelection();
1594
1665
  triggerRefresh();
@@ -1665,7 +1736,7 @@ function StudioToolbar() {
1665
1736
  const selectedPaths2 = Array.from(selectedItems);
1666
1737
  const imageExtensions = ["jpg", "jpeg", "png", "gif", "webp", "svg", "ico", "bmp", "tiff", "tif"];
1667
1738
  const selectedImagePaths = selectedPaths2.filter((p) => {
1668
- const ext = _optionalChain([p, 'access', _19 => _19.split, 'call', _20 => _20("."), 'access', _21 => _21.pop, 'call', _22 => _22(), 'optionalAccess', _23 => _23.toLowerCase, 'call', _24 => _24()]) || "";
1739
+ const ext = _optionalChain([p, 'access', _22 => _22.split, 'call', _23 => _23("."), 'access', _24 => _24.pop, 'call', _25 => _25(), 'optionalAccess', _26 => _26.toLowerCase, 'call', _27 => _27()]) || "";
1669
1740
  return imageExtensions.includes(ext);
1670
1741
  });
1671
1742
  const selectedFolders = selectedPaths2.filter((p) => !p.includes(".") || p.endsWith("/"));
@@ -1700,7 +1771,7 @@ function StudioToolbar() {
1700
1771
  const selectedPaths2 = Array.from(selectedItems);
1701
1772
  const imageExtensions = ["jpg", "jpeg", "png", "gif", "webp", "svg", "ico", "bmp", "tiff", "tif"];
1702
1773
  const selectedImagePaths = selectedPaths2.filter((p) => {
1703
- const ext = _optionalChain([p, 'access', _25 => _25.split, 'call', _26 => _26("."), 'access', _27 => _27.pop, 'call', _28 => _28(), 'optionalAccess', _29 => _29.toLowerCase, 'call', _30 => _30()]) || "";
1774
+ const ext = _optionalChain([p, 'access', _28 => _28.split, 'call', _29 => _29("."), 'access', _30 => _30.pop, 'call', _31 => _31(), 'optionalAccess', _32 => _32.toLowerCase, 'call', _33 => _33()]) || "";
1704
1775
  return imageExtensions.includes(ext);
1705
1776
  });
1706
1777
  const selectedFolders = selectedPaths2.filter((p) => !p.includes(".") || p.endsWith("/"));
@@ -1750,16 +1821,16 @@ function StudioToolbar() {
1750
1821
  });
1751
1822
  const data = await response.json();
1752
1823
  if (!response.ok) {
1753
- if (_optionalChain([data, 'access', _31 => _31.error, 'optionalAccess', _32 => _32.includes, 'call', _33 => _33("R2 not configured")]) || _optionalChain([data, 'access', _34 => _34.error, 'optionalAccess', _35 => _35.includes, 'call', _36 => _36("CLOUDFLARE_R2")])) {
1824
+ if (_optionalChain([data, 'access', _34 => _34.error, 'optionalAccess', _35 => _35.includes, 'call', _36 => _36("R2 not configured")]) || _optionalChain([data, 'access', _37 => _37.error, 'optionalAccess', _38 => _38.includes, 'call', _39 => _39("CLOUDFLARE_R2")])) {
1754
1825
  setShowProgress(false);
1755
1826
  setShowR2SetupModal(true);
1756
1827
  return;
1757
1828
  }
1758
1829
  errors++;
1759
1830
  errorMessages.push(data.error || `Failed: ${imageKey}`);
1760
- } else if (_optionalChain([data, 'access', _37 => _37.synced, 'optionalAccess', _38 => _38.length]) > 0) {
1831
+ } else if (_optionalChain([data, 'access', _40 => _40.synced, 'optionalAccess', _41 => _41.length]) > 0) {
1761
1832
  synced++;
1762
- } else if (_optionalChain([data, 'access', _39 => _39.errors, 'optionalAccess', _40 => _40.length]) > 0) {
1833
+ } else if (_optionalChain([data, 'access', _42 => _42.errors, 'optionalAccess', _43 => _43.length]) > 0) {
1763
1834
  errors++;
1764
1835
  for (const errMsg of data.errors) {
1765
1836
  errorMessages.push(errMsg);
@@ -2104,12 +2175,16 @@ function StudioToolbar() {
2104
2175
  " selected",
2105
2176
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles4.clearBtn, onClick: clearSelection, children: "Clear" })
2106
2177
  ] }),
2107
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2178
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2108
2179
  "button",
2109
2180
  {
2110
- css: [styles4.btn, styles4.btnIconOnly],
2111
- onClick: handleRefresh,
2112
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, RefreshIcon, { spinning: refreshing })
2181
+ css: styles4.btn,
2182
+ onClick: handleScan,
2183
+ disabled: scanning,
2184
+ children: [
2185
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ScanIcon, { spinning: scanning }),
2186
+ "Scan"
2187
+ ]
2113
2188
  }
2114
2189
  ),
2115
2190
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.viewToggle, children: [
@@ -2139,7 +2214,7 @@ function StudioToolbar() {
2139
2214
  function UploadIcon() {
2140
2215
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "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" }) });
2141
2216
  }
2142
- function RefreshIcon({ spinning }) {
2217
+ function ScanIcon({ spinning }) {
2143
2218
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: [styles4.icon, spinning && styles4.iconSpin], fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "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" }) });
2144
2219
  }
2145
2220
  function TrashIcon() {
@@ -2273,6 +2348,7 @@ function useFileList() {
2273
2348
  } = useStudio();
2274
2349
  const [items, setItems] = _react.useState.call(void 0, []);
2275
2350
  const [loading, setLoading] = _react.useState.call(void 0, true);
2351
+ const [metaEmpty, setMetaEmpty] = _react.useState.call(void 0, false);
2276
2352
  const isInitialLoad = _react.useRef.call(void 0, true);
2277
2353
  const lastPath = _react.useRef.call(void 0, currentPath);
2278
2354
  _react.useEffect.call(void 0, () => {
@@ -2285,10 +2361,12 @@ function useFileList() {
2285
2361
  try {
2286
2362
  const data = searchQuery && searchQuery.length >= 2 ? await studioApi.search(searchQuery) : await studioApi.list(currentPath);
2287
2363
  setItems(data.items || []);
2364
+ setMetaEmpty(data.isEmpty === true);
2288
2365
  } catch (error) {
2289
2366
  const message = error instanceof Error ? error.message : "Failed to load items";
2290
2367
  showError("Load Error", message);
2291
2368
  setItems([]);
2369
+ setMetaEmpty(false);
2292
2370
  }
2293
2371
  setLoading(false);
2294
2372
  isInitialLoad.current = false;
@@ -2340,6 +2418,7 @@ function useFileList() {
2340
2418
  items,
2341
2419
  loading,
2342
2420
  sortedItems,
2421
+ metaEmpty,
2343
2422
  // Computed
2344
2423
  isAtRoot,
2345
2424
  isSearching,
@@ -2400,6 +2479,27 @@ var styles5 = {
2400
2479
  font-size: ${_chunkUFCWGUAGjs.fontSize.sm};
2401
2480
  }
2402
2481
  `,
2482
+ scanButton: _react3.css`
2483
+ margin-top: 16px;
2484
+ padding: 10px 24px;
2485
+ font-size: ${_chunkUFCWGUAGjs.fontSize.base};
2486
+ font-weight: 500;
2487
+ background: ${_chunkUFCWGUAGjs.colors.primary};
2488
+ color: white;
2489
+ border: none;
2490
+ border-radius: 8px;
2491
+ cursor: pointer;
2492
+ transition: background 0.15s ease;
2493
+
2494
+ &:hover:not(:disabled) {
2495
+ background: ${_chunkUFCWGUAGjs.colors.primaryHover};
2496
+ }
2497
+
2498
+ &:disabled {
2499
+ opacity: 0.6;
2500
+ cursor: not-allowed;
2501
+ }
2502
+ `,
2403
2503
  grid: _react3.css`
2404
2504
  display: grid;
2405
2505
  grid-template-columns: 1fr;
@@ -2683,6 +2783,7 @@ function StudioFileGrid() {
2683
2783
  const {
2684
2784
  loading,
2685
2785
  sortedItems,
2786
+ metaEmpty,
2686
2787
  isAtRoot,
2687
2788
  isSearching,
2688
2789
  allItemsSelected,
@@ -2694,14 +2795,42 @@ function StudioFileGrid() {
2694
2795
  handleGenerateThumbnail,
2695
2796
  handleSelectAll
2696
2797
  } = useFileList();
2798
+ const [scanning, setScanning] = _react.useState.call(void 0, false);
2799
+ const handleScan = async () => {
2800
+ setScanning(true);
2801
+ try {
2802
+ await fetch("/api/studio/scan", { method: "POST" });
2803
+ window.location.reload();
2804
+ } catch (error) {
2805
+ console.error("Scan failed:", error);
2806
+ } finally {
2807
+ setScanning(false);
2808
+ }
2809
+ };
2697
2810
  if (loading) {
2698
2811
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.loading, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.spinner }) });
2699
2812
  }
2813
+ if (metaEmpty && isAtRoot) {
2814
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.empty, children: [
2815
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.emptyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) }),
2816
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles5.emptyText, children: "No files tracked yet" }),
2817
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles5.emptyText, children: "Click Scan to discover files in your public folder" }),
2818
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2819
+ "button",
2820
+ {
2821
+ css: styles5.scanButton,
2822
+ onClick: handleScan,
2823
+ disabled: scanning,
2824
+ children: scanning ? "Scanning..." : "Scan for Files"
2825
+ }
2826
+ )
2827
+ ] });
2828
+ }
2700
2829
  if (sortedItems.length === 0 && isAtRoot) {
2701
2830
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.empty, children: [
2702
2831
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.emptyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "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" }) }),
2703
2832
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles5.emptyText, children: "No files in this folder" }),
2704
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles5.emptyText, children: "Upload images to get started" })
2833
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles5.emptyText, children: "Upload images or click Scan in the toolbar" })
2705
2834
  ] });
2706
2835
  }
2707
2836
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
@@ -2898,6 +3027,32 @@ var styles6 = {
2898
3027
  height: 256px;
2899
3028
  color: ${_chunkUFCWGUAGjs.colors.textSecondary};
2900
3029
  `,
3030
+ emptyHint: _react3.css`
3031
+ font-size: ${_chunkUFCWGUAGjs.fontSize.sm};
3032
+ color: ${_chunkUFCWGUAGjs.colors.textMuted};
3033
+ margin-top: 4px;
3034
+ `,
3035
+ scanButton: _react3.css`
3036
+ margin-top: 16px;
3037
+ padding: 10px 24px;
3038
+ font-size: ${_chunkUFCWGUAGjs.fontSize.base};
3039
+ font-weight: 500;
3040
+ background: ${_chunkUFCWGUAGjs.colors.primary};
3041
+ color: white;
3042
+ border: none;
3043
+ border-radius: 8px;
3044
+ cursor: pointer;
3045
+ transition: background 0.15s ease;
3046
+
3047
+ &:hover:not(:disabled) {
3048
+ background: ${_chunkUFCWGUAGjs.colors.primaryHover};
3049
+ }
3050
+
3051
+ &:disabled {
3052
+ opacity: 0.6;
3053
+ cursor: not-allowed;
3054
+ }
3055
+ `,
2901
3056
  tableWrapper: _react3.css`
2902
3057
  background: ${_chunkUFCWGUAGjs.colors.surface};
2903
3058
  border-radius: 8px;
@@ -3184,6 +3339,7 @@ function StudioFileList() {
3184
3339
  const {
3185
3340
  loading,
3186
3341
  sortedItems,
3342
+ metaEmpty,
3187
3343
  isAtRoot,
3188
3344
  isSearching,
3189
3345
  allItemsSelected,
@@ -3195,11 +3351,41 @@ function StudioFileList() {
3195
3351
  handleGenerateThumbnail,
3196
3352
  handleSelectAll
3197
3353
  } = useFileList();
3354
+ const [scanning, setScanning] = _react.useState.call(void 0, false);
3355
+ const handleScan = async () => {
3356
+ setScanning(true);
3357
+ try {
3358
+ await fetch("/api/studio/scan", { method: "POST" });
3359
+ window.location.reload();
3360
+ } catch (error) {
3361
+ console.error("Scan failed:", error);
3362
+ } finally {
3363
+ setScanning(false);
3364
+ }
3365
+ };
3198
3366
  if (loading) {
3199
3367
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.loading, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.spinner }) });
3200
3368
  }
3369
+ if (metaEmpty && isAtRoot) {
3370
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.empty, children: [
3371
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { children: "No files tracked yet" }),
3372
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.emptyHint, children: "Click Scan to discover files in your public folder" }),
3373
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3374
+ "button",
3375
+ {
3376
+ css: styles6.scanButton,
3377
+ onClick: handleScan,
3378
+ disabled: scanning,
3379
+ children: scanning ? "Scanning..." : "Scan for Files"
3380
+ }
3381
+ )
3382
+ ] });
3383
+ }
3201
3384
  if (sortedItems.length === 0 && isAtRoot) {
3202
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.empty, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { children: "No files in this folder" }) });
3385
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.empty, children: [
3386
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { children: "No files in this folder" }),
3387
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.emptyHint, children: "Upload images or click Scan in the toolbar" })
3388
+ ] });
3203
3389
  }
3204
3390
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.tableWrapper, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "table", { css: styles6.table, children: [
3205
3391
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "thead", { children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tr", { children: [
@@ -3709,7 +3895,7 @@ function StudioDetailView() {
3709
3895
  });
3710
3896
  triggerRefresh();
3711
3897
  } else {
3712
- if (_optionalChain([data, 'access', _41 => _41.error, 'optionalAccess', _42 => _42.includes, 'call', _43 => _43("R2 not configured")]) || _optionalChain([data, 'access', _44 => _44.error, 'optionalAccess', _45 => _45.includes, 'call', _46 => _46("CLOUDFLARE_R2")])) {
3898
+ if (_optionalChain([data, 'access', _44 => _44.error, 'optionalAccess', _45 => _45.includes, 'call', _46 => _46("R2 not configured")]) || _optionalChain([data, 'access', _47 => _47.error, 'optionalAccess', _48 => _48.includes, 'call', _49 => _49("CLOUDFLARE_R2")])) {
3713
3899
  setShowR2SetupModal(true);
3714
3900
  } else {
3715
3901
  setAlertMessage({
@@ -3748,7 +3934,7 @@ function StudioDetailView() {
3748
3934
  if (!response.ok) {
3749
3935
  throw new Error("Processing failed");
3750
3936
  }
3751
- const reader = _optionalChain([response, 'access', _47 => _47.body, 'optionalAccess', _48 => _48.getReader, 'call', _49 => _49()]);
3937
+ const reader = _optionalChain([response, 'access', _50 => _50.body, 'optionalAccess', _51 => _51.getReader, 'call', _52 => _52()]);
3752
3938
  if (!reader) {
3753
3939
  throw new Error("No response body");
3754
3940
  }
@@ -4695,4 +4881,4 @@ var StudioUI_default = StudioUI;
4695
4881
 
4696
4882
 
4697
4883
  exports.StudioUI = StudioUI; exports.default = StudioUI_default;
4698
- //# sourceMappingURL=StudioUI-Y35A2T7S.js.map
4884
+ //# sourceMappingURL=StudioUI-JQHRTF45.js.map