@gallop.software/studio 1.3.6 → 1.4.1

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.
@@ -23,7 +23,8 @@ var defaultActionState = {
23
23
  actionPaths: [],
24
24
  syncImageCount: 0,
25
25
  syncHasRemote: false,
26
- syncHasLocal: false
26
+ syncHasLocal: false,
27
+ processMode: "generate"
27
28
  };
28
29
  var defaultState = {
29
30
  isOpen: false,
@@ -90,6 +91,8 @@ var defaultState = {
90
91
  },
91
92
  requestProcess: () => {
92
93
  },
94
+ setProcessMode: () => {
95
+ },
93
96
  confirmDelete: async () => {
94
97
  },
95
98
  confirmMove: async () => {
@@ -5294,7 +5297,8 @@ var defaultActionState2 = {
5294
5297
  actionPaths: [],
5295
5298
  syncImageCount: 0,
5296
5299
  syncHasRemote: false,
5297
- syncHasLocal: false
5300
+ syncHasLocal: false,
5301
+ processMode: "generate"
5298
5302
  };
5299
5303
  function useStudioActions({
5300
5304
  triggerRefresh,
@@ -5351,7 +5355,15 @@ function useStudioActions({
5351
5355
  setActionState((prev) => ({
5352
5356
  ...prev,
5353
5357
  actionPaths: paths,
5354
- showProcessConfirm: true
5358
+ showProcessConfirm: true,
5359
+ processMode: "generate"
5360
+ // Reset to default when opening modal
5361
+ }));
5362
+ }, []);
5363
+ const setProcessMode = _react.useCallback.call(void 0, (mode) => {
5364
+ setActionState((prev) => ({
5365
+ ...prev,
5366
+ processMode: mode
5355
5367
  }));
5356
5368
  }, []);
5357
5369
  const cancelAction = _react.useCallback.call(void 0, () => {
@@ -5538,27 +5550,32 @@ function useStudioActions({
5538
5550
  }, [actionState.actionPaths, clearSelection, triggerRefresh, showError, setProgressState]);
5539
5551
  const confirmProcess = _react.useCallback.call(void 0, async () => {
5540
5552
  const paths = actionState.actionPaths;
5553
+ const mode = actionState.processMode;
5541
5554
  const imageKeys = paths.map((p) => {
5542
5555
  const key = p.replace(/^public\//, "");
5543
5556
  return key.startsWith("/") ? key : `/${key}`;
5544
5557
  });
5558
+ const isRemove = mode === "remove";
5559
+ const endpoint = isRemove ? "/api/studio/unprocess-stream" : "/api/studio/reprocess-stream";
5560
+ const progressTitle = isRemove ? "Removing Thumbnails" : "Processing Images";
5561
+ const progressMessage = isRemove ? "Removing thumbnails..." : "Processing images...";
5545
5562
  setActionState((prev) => ({
5546
5563
  ...prev,
5547
5564
  showProcessConfirm: false,
5548
5565
  showProgress: true,
5549
- progressTitle: "Processing Images",
5566
+ progressTitle,
5550
5567
  progressState: {
5551
5568
  current: 0,
5552
5569
  total: imageKeys.length,
5553
5570
  percent: 0,
5554
5571
  status: "processing",
5555
- message: "Processing images..."
5572
+ message: progressMessage
5556
5573
  }
5557
5574
  }));
5558
5575
  abortControllerRef.current = new AbortController();
5559
5576
  const signal = abortControllerRef.current.signal;
5560
5577
  try {
5561
- const response = await fetch("/api/studio/reprocess-stream", {
5578
+ const response = await fetch(endpoint, {
5562
5579
  method: "POST",
5563
5580
  headers: { "Content-Type": "application/json" },
5564
5581
  body: JSON.stringify({ imageKeys }),
@@ -5571,7 +5588,7 @@ function useStudioActions({
5571
5588
  total: imageKeys.length,
5572
5589
  percent: 0,
5573
5590
  status: "error",
5574
- message: error.error || "Processing failed"
5591
+ message: error.error || (isRemove ? "Failed to remove thumbnails" : "Processing failed")
5575
5592
  });
5576
5593
  return;
5577
5594
  }
@@ -5635,7 +5652,7 @@ function useStudioActions({
5635
5652
  setProgressState((prev) => ({
5636
5653
  ...prev,
5637
5654
  status: "stopped",
5638
- message: "Processing stopped by user"
5655
+ message: isRemove ? "Removal stopped by user" : "Processing stopped by user"
5639
5656
  }));
5640
5657
  } else {
5641
5658
  console.error("Processing error:", error);
@@ -5644,13 +5661,13 @@ function useStudioActions({
5644
5661
  total: imageKeys.length,
5645
5662
  percent: 0,
5646
5663
  status: "error",
5647
- message: "Processing failed. Check console for details."
5664
+ message: isRemove ? "Failed to remove thumbnails. Check console for details." : "Processing failed. Check console for details."
5648
5665
  });
5649
5666
  }
5650
5667
  } finally {
5651
5668
  abortControllerRef.current = null;
5652
5669
  }
5653
- }, [actionState.actionPaths, triggerRefresh, setProgressState]);
5670
+ }, [actionState.actionPaths, actionState.processMode, triggerRefresh, setProgressState]);
5654
5671
  const deleteOrphans = _react.useCallback.call(void 0, async () => {
5655
5672
  const orphanedFiles = actionState.progressState.orphanedFiles;
5656
5673
  if (!orphanedFiles || orphanedFiles.length === 0) return;
@@ -5684,6 +5701,7 @@ function useStudioActions({
5684
5701
  requestMove,
5685
5702
  requestSync,
5686
5703
  requestProcess,
5704
+ setProcessMode,
5687
5705
  cancelAction,
5688
5706
  closeProgress,
5689
5707
  stopProcessing,
@@ -6021,6 +6039,7 @@ function StudioUI({ onClose, isVisible = true }) {
6021
6039
  requestMove: actions.requestMove,
6022
6040
  requestSync: actions.requestSync,
6023
6041
  requestProcess: actions.requestProcess,
6042
+ setProcessMode: actions.setProcessMode,
6024
6043
  confirmDelete: actions.confirmDelete,
6025
6044
  confirmMove: actions.confirmMove,
6026
6045
  confirmSync: actions.confirmSync,
@@ -6089,11 +6108,11 @@ function StudioUI({ onClose, isVisible = true }) {
6089
6108
  }
6090
6109
  ),
6091
6110
  actions.actionState.showProcessConfirm && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6092
- ConfirmModal,
6111
+ ProcessConfirmModal,
6093
6112
  {
6094
- title: "Process Images",
6095
- message: `Generate thumbnails for ${actions.actionState.actionPaths.length} image${actions.actionState.actionPaths.length !== 1 ? "s" : ""}?`,
6096
- confirmLabel: "Process",
6113
+ imageCount: actions.actionState.actionPaths.length,
6114
+ mode: actions.actionState.processMode,
6115
+ onModeChange: actions.setProcessMode,
6097
6116
  onConfirm: actions.confirmProcess,
6098
6117
  onCancel: actions.cancelAction
6099
6118
  }
@@ -6119,6 +6138,150 @@ function StudioUI({ onClose, isVisible = true }) {
6119
6138
  )
6120
6139
  ] }) });
6121
6140
  }
6141
+ function ProcessConfirmModal({ imageCount, mode, onModeChange, onConfirm, onCancel }) {
6142
+ const processModalStyles = {
6143
+ overlay: _react3.css`
6144
+ position: fixed;
6145
+ inset: 0;
6146
+ background: rgba(0, 0, 0, 0.5);
6147
+ display: flex;
6148
+ align-items: center;
6149
+ justify-content: center;
6150
+ z-index: 10000;
6151
+ `,
6152
+ container: _react3.css`
6153
+ background: ${_chunkN6JYTJCBjs.colors.surface};
6154
+ border-radius: 12px;
6155
+ padding: 24px;
6156
+ max-width: 420px;
6157
+ width: 90%;
6158
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
6159
+ `,
6160
+ title: _react3.css`
6161
+ font-size: ${_chunkN6JYTJCBjs.fontSize.lg};
6162
+ font-weight: 600;
6163
+ color: ${_chunkN6JYTJCBjs.colors.text};
6164
+ margin: 0 0 16px;
6165
+ `,
6166
+ modeToggle: _react3.css`
6167
+ display: flex;
6168
+ gap: 8px;
6169
+ margin-bottom: 16px;
6170
+ `,
6171
+ modeBtn: _react3.css`
6172
+ flex: 1;
6173
+ padding: 10px 16px;
6174
+ border: 2px solid ${_chunkN6JYTJCBjs.colors.border};
6175
+ border-radius: 8px;
6176
+ background: ${_chunkN6JYTJCBjs.colors.background};
6177
+ color: ${_chunkN6JYTJCBjs.colors.textSecondary};
6178
+ font-size: ${_chunkN6JYTJCBjs.fontSize.base};
6179
+ font-weight: 500;
6180
+ cursor: pointer;
6181
+ transition: all 0.15s ease;
6182
+
6183
+ &:hover {
6184
+ border-color: ${_chunkN6JYTJCBjs.colors.borderHover};
6185
+ }
6186
+ `,
6187
+ modeBtnActive: _react3.css`
6188
+ border-color: ${_chunkN6JYTJCBjs.colors.primary};
6189
+ background: rgba(99, 91, 255, 0.1);
6190
+ color: ${_chunkN6JYTJCBjs.colors.primary};
6191
+ `,
6192
+ modeBtnDanger: _react3.css`
6193
+ border-color: ${_chunkN6JYTJCBjs.colors.danger};
6194
+ background: rgba(239, 68, 68, 0.1);
6195
+ color: ${_chunkN6JYTJCBjs.colors.danger};
6196
+ `,
6197
+ message: _react3.css`
6198
+ font-size: ${_chunkN6JYTJCBjs.fontSize.base};
6199
+ color: ${_chunkN6JYTJCBjs.colors.textSecondary};
6200
+ margin: 0 0 20px;
6201
+ line-height: 1.5;
6202
+ `,
6203
+ actions: _react3.css`
6204
+ display: flex;
6205
+ gap: 12px;
6206
+ justify-content: flex-end;
6207
+ `,
6208
+ cancelBtn: _react3.css`
6209
+ padding: 10px 20px;
6210
+ border: 1px solid ${_chunkN6JYTJCBjs.colors.border};
6211
+ border-radius: 8px;
6212
+ background: ${_chunkN6JYTJCBjs.colors.background};
6213
+ color: ${_chunkN6JYTJCBjs.colors.text};
6214
+ font-size: ${_chunkN6JYTJCBjs.fontSize.base};
6215
+ font-weight: 500;
6216
+ cursor: pointer;
6217
+ transition: all 0.15s ease;
6218
+
6219
+ &:hover {
6220
+ background: ${_chunkN6JYTJCBjs.colors.surfaceHover};
6221
+ border-color: ${_chunkN6JYTJCBjs.colors.borderHover};
6222
+ }
6223
+ `,
6224
+ confirmBtn: _react3.css`
6225
+ padding: 10px 20px;
6226
+ border: none;
6227
+ border-radius: 8px;
6228
+ background: ${_chunkN6JYTJCBjs.colors.primary};
6229
+ color: white;
6230
+ font-size: ${_chunkN6JYTJCBjs.fontSize.base};
6231
+ font-weight: 500;
6232
+ cursor: pointer;
6233
+ transition: all 0.15s ease;
6234
+
6235
+ &:hover {
6236
+ background: ${_chunkN6JYTJCBjs.colors.primaryHover};
6237
+ }
6238
+ `,
6239
+ confirmBtnDanger: _react3.css`
6240
+ background: ${_chunkN6JYTJCBjs.colors.danger};
6241
+
6242
+ &:hover {
6243
+ background: #dc2626;
6244
+ }
6245
+ `
6246
+ };
6247
+ const isRemove = mode === "remove";
6248
+ const title = "Process Images";
6249
+ const message = isRemove ? `Remove generated thumbnails for ${imageCount} image${imageCount !== 1 ? "s" : ""}? Original images will be kept.` : `Generate thumbnails for ${imageCount} image${imageCount !== 1 ? "s" : ""}?`;
6250
+ const confirmLabel = isRemove ? "Remove" : "Process";
6251
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: processModalStyles.overlay, onClick: onCancel, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: processModalStyles.container, onClick: (e) => e.stopPropagation(), children: [
6252
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { css: processModalStyles.title, children: title }),
6253
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: processModalStyles.modeToggle, children: [
6254
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6255
+ "button",
6256
+ {
6257
+ css: [processModalStyles.modeBtn, mode === "generate" && processModalStyles.modeBtnActive],
6258
+ onClick: () => onModeChange("generate"),
6259
+ children: "Generate Thumbnails"
6260
+ }
6261
+ ),
6262
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6263
+ "button",
6264
+ {
6265
+ css: [processModalStyles.modeBtn, mode === "remove" && processModalStyles.modeBtnDanger],
6266
+ onClick: () => onModeChange("remove"),
6267
+ children: "Remove Thumbnails"
6268
+ }
6269
+ )
6270
+ ] }),
6271
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: processModalStyles.message, children: message }),
6272
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: processModalStyles.actions, children: [
6273
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: processModalStyles.cancelBtn, onClick: onCancel, children: "Cancel" }),
6274
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
6275
+ "button",
6276
+ {
6277
+ css: [processModalStyles.confirmBtn, isRemove && processModalStyles.confirmBtnDanger],
6278
+ onClick: onConfirm,
6279
+ children: confirmLabel
6280
+ }
6281
+ )
6282
+ ] })
6283
+ ] }) });
6284
+ }
6122
6285
  function Breadcrumbs({ currentPath, onNavigate }) {
6123
6286
  const parts = currentPath.split("/").filter(Boolean);
6124
6287
  const breadcrumbs = parts.map((part, index) => ({
@@ -6161,4 +6324,4 @@ var StudioUI_default = StudioUI;
6161
6324
 
6162
6325
 
6163
6326
  exports.StudioUI = StudioUI; exports.default = StudioUI_default;
6164
- //# sourceMappingURL=StudioUI-OY33OEG2.js.map
6327
+ //# sourceMappingURL=StudioUI-DBZLGGPL.js.map