@gallop.software/studio 0.1.89 → 0.1.90

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.
@@ -50,6 +50,11 @@ var defaultState = {
50
50
  refreshKey: 0,
51
51
  triggerRefresh: () => {
52
52
  },
53
+ scanRequested: false,
54
+ triggerScan: () => {
55
+ },
56
+ clearScanRequest: () => {
57
+ },
53
58
  searchQuery: "",
54
59
  setSearchQuery: () => {
55
60
  },
@@ -1285,7 +1290,7 @@ var styles4 = {
1285
1290
  `
1286
1291
  };
1287
1292
  function StudioToolbar() {
1288
- const { selectedItems, viewMode, setViewMode, clearSelection, currentPath, triggerRefresh, focusedItem } = useStudio();
1293
+ const { selectedItems, viewMode, setViewMode, clearSelection, currentPath, triggerRefresh, focusedItem, scanRequested, clearScanRequest } = useStudio();
1289
1294
  const fileInputRef = _react.useRef.call(void 0, null);
1290
1295
  const abortControllerRef = _react.useRef.call(void 0, null);
1291
1296
  const [uploading, setUploading] = _react.useState.call(void 0, false);
@@ -1391,6 +1396,12 @@ function StudioToolbar() {
1391
1396
  setScanning(false);
1392
1397
  }
1393
1398
  }, [triggerRefresh]);
1399
+ _react.useEffect.call(void 0, () => {
1400
+ if (scanRequested && !scanning) {
1401
+ clearScanRequest();
1402
+ handleScan();
1403
+ }
1404
+ }, [scanRequested, scanning, clearScanRequest, handleScan]);
1394
1405
  const handleFileChange = _react.useCallback.call(void 0, async (e) => {
1395
1406
  const files = e.target.files;
1396
1407
  if (!files || files.length === 0) return;
@@ -1974,8 +1985,8 @@ function StudioToolbar() {
1974
1985
  showSyncConfirm && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1975
1986
  ConfirmModal,
1976
1987
  {
1977
- title: "Sync to CDN",
1978
- message: `Sync ${syncImageCount} image${syncImageCount !== 1 ? "s" : ""} to Cloudflare R2? Images must be processed first. After syncing, local thumbnails will be deleted.`,
1988
+ title: "Push to CDN",
1989
+ message: `Push ${syncImageCount} image${syncImageCount !== 1 ? "s" : ""} to Cloudflare R2? Images must be processed first. After pushing, local files will be deleted.`,
1979
1990
  confirmLabel: "Sync",
1980
1991
  onConfirm: handleSyncConfirm,
1981
1992
  onCancel: () => setShowSyncConfirm(false)
@@ -2142,7 +2153,7 @@ function StudioToolbar() {
2142
2153
  disabled: !hasSelection,
2143
2154
  children: [
2144
2155
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CloudIcon, {}),
2145
- "Sync CDN"
2156
+ "Push CDN"
2146
2157
  ]
2147
2158
  }
2148
2159
  ),
@@ -2343,6 +2354,7 @@ function useFileList() {
2343
2354
  refreshKey,
2344
2355
  setFocusedItem,
2345
2356
  triggerRefresh,
2357
+ triggerScan,
2346
2358
  searchQuery,
2347
2359
  showError
2348
2360
  } = useStudio();
@@ -2432,7 +2444,8 @@ function useFileList() {
2432
2444
  handleItemClick,
2433
2445
  handleOpen,
2434
2446
  handleGenerateThumbnail,
2435
- handleSelectAll
2447
+ handleSelectAll,
2448
+ triggerScan
2436
2449
  };
2437
2450
  }
2438
2451
 
@@ -2446,7 +2459,8 @@ var styles5 = {
2446
2459
  display: flex;
2447
2460
  align-items: center;
2448
2461
  justify-content: center;
2449
- height: 256px;
2462
+ flex: 1;
2463
+ min-height: 300px;
2450
2464
  `,
2451
2465
  spinner: _react3.css`
2452
2466
  width: 32px;
@@ -2461,7 +2475,8 @@ var styles5 = {
2461
2475
  flex-direction: column;
2462
2476
  align-items: center;
2463
2477
  justify-content: center;
2464
- height: 256px;
2478
+ flex: 1;
2479
+ min-height: 300px;
2465
2480
  color: ${_chunkUFCWGUAGjs.colors.textSecondary};
2466
2481
  `,
2467
2482
  emptyIcon: _react3.css`
@@ -2793,20 +2808,9 @@ function StudioFileGrid() {
2793
2808
  handleItemClick,
2794
2809
  handleOpen,
2795
2810
  handleGenerateThumbnail,
2796
- handleSelectAll
2811
+ handleSelectAll,
2812
+ triggerScan
2797
2813
  } = 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
- };
2810
2814
  if (loading) {
2811
2815
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.loading, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.spinner }) });
2812
2816
  }
@@ -2819,9 +2823,8 @@ function StudioFileGrid() {
2819
2823
  "button",
2820
2824
  {
2821
2825
  css: styles5.scanButton,
2822
- onClick: handleScan,
2823
- disabled: scanning,
2824
- children: scanning ? "Scanning..." : "Scan for Files"
2826
+ onClick: triggerScan,
2827
+ children: "Scan for Files"
2825
2828
  }
2826
2829
  )
2827
2830
  ] });
@@ -3009,7 +3012,8 @@ var styles6 = {
3009
3012
  display: flex;
3010
3013
  align-items: center;
3011
3014
  justify-content: center;
3012
- height: 256px;
3015
+ flex: 1;
3016
+ min-height: 300px;
3013
3017
  `,
3014
3018
  spinner: _react3.css`
3015
3019
  width: 32px;
@@ -3024,7 +3028,8 @@ var styles6 = {
3024
3028
  flex-direction: column;
3025
3029
  align-items: center;
3026
3030
  justify-content: center;
3027
- height: 256px;
3031
+ flex: 1;
3032
+ min-height: 300px;
3028
3033
  color: ${_chunkUFCWGUAGjs.colors.textSecondary};
3029
3034
  `,
3030
3035
  emptyHint: _react3.css`
@@ -3349,20 +3354,9 @@ function StudioFileList() {
3349
3354
  handleItemClick,
3350
3355
  handleOpen,
3351
3356
  handleGenerateThumbnail,
3352
- handleSelectAll
3357
+ handleSelectAll,
3358
+ triggerScan
3353
3359
  } = 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
- };
3366
3360
  if (loading) {
3367
3361
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.loading, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.spinner }) });
3368
3362
  }
@@ -3374,9 +3368,8 @@ function StudioFileList() {
3374
3368
  "button",
3375
3369
  {
3376
3370
  css: styles6.scanButton,
3377
- onClick: handleScan,
3378
- disabled: scanning,
3379
- children: scanning ? "Scanning..." : "Scan for Files"
3371
+ onClick: triggerScan,
3372
+ children: "Scan for Files"
3380
3373
  }
3381
3374
  )
3382
3375
  ] });
@@ -4084,7 +4077,7 @@ function StudioDetailView() {
4084
4077
  ] }),
4085
4078
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles7.actionBtn, onClick: handleSync, disabled: syncing, children: [
4086
4079
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "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" }) }),
4087
- syncing ? "Syncing..." : "Sync to CDN"
4080
+ syncing ? "Pushing..." : "Push to CDN"
4088
4081
  ] }),
4089
4082
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles7.actionBtn, onClick: () => setShowProcessConfirm(true), children: [
4090
4083
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.actionIcon, 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 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" }) }),
@@ -4614,6 +4607,8 @@ var styles10 = {
4614
4607
  min-width: 0;
4615
4608
  overflow: auto;
4616
4609
  padding: 20px 24px;
4610
+ display: flex;
4611
+ flex-direction: column;
4617
4612
  `,
4618
4613
  dropOverlay: _react3.css`
4619
4614
  position: absolute;
@@ -4653,12 +4648,19 @@ function StudioUI({ onClose, isVisible = true }) {
4653
4648
  const [meta, setMeta] = _react.useState.call(void 0, null);
4654
4649
  const [isLoading, setIsLoading] = _react.useState.call(void 0, false);
4655
4650
  const [refreshKey, setRefreshKey] = _react.useState.call(void 0, 0);
4651
+ const [scanRequested, setScanRequested] = _react.useState.call(void 0, false);
4656
4652
  const [searchQuery, setSearchQuery] = _react.useState.call(void 0, "");
4657
4653
  const [error, setError] = _react.useState.call(void 0, null);
4658
4654
  const [isDragging, setIsDragging] = _react.useState.call(void 0, false);
4659
4655
  const triggerRefresh = _react.useCallback.call(void 0, () => {
4660
4656
  setRefreshKey((k) => k + 1);
4661
4657
  }, []);
4658
+ const triggerScan = _react.useCallback.call(void 0, () => {
4659
+ setScanRequested(true);
4660
+ }, []);
4661
+ const clearScanRequest = _react.useCallback.call(void 0, () => {
4662
+ setScanRequested(false);
4663
+ }, []);
4662
4664
  const showError = _react.useCallback.call(void 0, (title, message) => {
4663
4665
  setError({ title, message });
4664
4666
  }, []);
@@ -4795,6 +4797,9 @@ function StudioUI({ onClose, isVisible = true }) {
4795
4797
  setIsLoading,
4796
4798
  refreshKey,
4797
4799
  triggerRefresh,
4800
+ scanRequested,
4801
+ triggerScan,
4802
+ clearScanRequest,
4798
4803
  searchQuery,
4799
4804
  setSearchQuery,
4800
4805
  error,
@@ -4881,4 +4886,4 @@ var StudioUI_default = StudioUI;
4881
4886
 
4882
4887
 
4883
4888
  exports.StudioUI = StudioUI; exports.default = StudioUI_default;
4884
- //# sourceMappingURL=StudioUI-JQHRTF45.js.map
4889
+ //# sourceMappingURL=StudioUI-HWUO2H6J.js.map