@gallop.software/studio 1.4.1 → 1.4.2
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-DBZLGGPL.js → StudioUI-MAOXE72P.js} +23 -243
- package/dist/StudioUI-MAOXE72P.js.map +1 -0
- package/dist/{StudioUI-HLMTACHJ.mjs → StudioUI-TTBNASM5.mjs} +11 -231
- package/dist/StudioUI-TTBNASM5.mjs.map +1 -0
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/dist/StudioUI-DBZLGGPL.js.map +0 -1
- package/dist/StudioUI-HLMTACHJ.mjs.map +0 -1
|
@@ -1741,15 +1741,13 @@ var styles5 = {
|
|
|
1741
1741
|
`
|
|
1742
1742
|
};
|
|
1743
1743
|
function StudioToolbar() {
|
|
1744
|
-
const { selectedItems, viewMode, setViewMode, clearSelection, currentPath, triggerRefresh, focusedItem, scanRequested, clearScanRequest, fileItems } = useStudio();
|
|
1744
|
+
const { selectedItems, viewMode, setViewMode, clearSelection, currentPath, triggerRefresh, focusedItem, scanRequested, clearScanRequest, fileItems, requestProcess, actionState } = useStudio();
|
|
1745
1745
|
const fileInputRef = useRef2(null);
|
|
1746
1746
|
const abortControllerRef = useRef2(null);
|
|
1747
1747
|
const [showAddNewModal, setShowAddNewModal] = useState4(false);
|
|
1748
1748
|
const [uploading, setUploading] = useState4(false);
|
|
1749
1749
|
const [scanning, setScanning] = useState4(false);
|
|
1750
|
-
const [processing, setProcessing] = useState4(false);
|
|
1751
1750
|
const [showDeleteConfirm, setShowDeleteConfirm] = useState4(false);
|
|
1752
|
-
const [showProcessConfirm, setShowProcessConfirm] = useState4(false);
|
|
1753
1751
|
const [showSyncConfirm, setShowSyncConfirm] = useState4(false);
|
|
1754
1752
|
const [syncImageCount, setSyncImageCount] = useState4(0);
|
|
1755
1753
|
const [syncHasRemote, setSyncHasRemote] = useState4(false);
|
|
@@ -1762,9 +1760,6 @@ function StudioToolbar() {
|
|
|
1762
1760
|
percent: 0,
|
|
1763
1761
|
status: "processing"
|
|
1764
1762
|
});
|
|
1765
|
-
const [processCount, setProcessCount] = useState4(0);
|
|
1766
|
-
const [processMode, setProcessMode] = useState4("all");
|
|
1767
|
-
const [imagesToProcess, setImagesToProcess] = useState4([]);
|
|
1768
1763
|
const [alertMessage, setAlertMessage] = useState4(null);
|
|
1769
1764
|
const [showNewFolderModal, setShowNewFolderModal] = useState4(false);
|
|
1770
1765
|
const [showRenameFolderModal, setShowRenameFolderModal] = useState4(false);
|
|
@@ -1999,234 +1994,29 @@ function StudioToolbar() {
|
|
|
1999
1994
|
});
|
|
2000
1995
|
return;
|
|
2001
1996
|
}
|
|
2002
|
-
|
|
2003
|
-
setImagesToProcess(selectedImagePaths);
|
|
2004
|
-
setProcessMode("selected");
|
|
2005
|
-
setShowProcessConfirm(true);
|
|
1997
|
+
requestProcess(selectedImagePaths);
|
|
2006
1998
|
} else {
|
|
2007
1999
|
try {
|
|
2008
2000
|
const response = await fetch("/api/studio/count-images");
|
|
2009
2001
|
const data = await response.json();
|
|
2010
|
-
if (data.
|
|
2002
|
+
if (!data.images || data.images.length === 0) {
|
|
2011
2003
|
setAlertMessage({
|
|
2012
2004
|
title: "No Images Found",
|
|
2013
2005
|
message: "No images found in the public folder to process."
|
|
2014
2006
|
});
|
|
2015
2007
|
return;
|
|
2016
2008
|
}
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
setShowProcessConfirm(true);
|
|
2009
|
+
const allImagePaths = data.images.map((img) => `public/${img}`);
|
|
2010
|
+
requestProcess(allImagePaths);
|
|
2020
2011
|
} catch (error) {
|
|
2021
|
-
console.error("Failed to
|
|
2012
|
+
console.error("Failed to get images:", error);
|
|
2022
2013
|
setAlertMessage({
|
|
2023
2014
|
title: "Error",
|
|
2024
|
-
message: "Failed to
|
|
2015
|
+
message: "Failed to get images."
|
|
2025
2016
|
});
|
|
2026
2017
|
}
|
|
2027
2018
|
}
|
|
2028
|
-
}, [selectedItems]);
|
|
2029
|
-
const handleProcessConfirm = useCallback2(async () => {
|
|
2030
|
-
setShowProcessConfirm(false);
|
|
2031
|
-
setProcessing(true);
|
|
2032
|
-
abortControllerRef.current = new AbortController();
|
|
2033
|
-
const signal = abortControllerRef.current.signal;
|
|
2034
|
-
try {
|
|
2035
|
-
if (processMode === "all") {
|
|
2036
|
-
setProgressTitle("Processing Images");
|
|
2037
|
-
setShowProgress(true);
|
|
2038
|
-
setProgressState({
|
|
2039
|
-
current: 0,
|
|
2040
|
-
total: processCount,
|
|
2041
|
-
percent: 0,
|
|
2042
|
-
status: "processing"
|
|
2043
|
-
});
|
|
2044
|
-
const response = await fetch("/api/studio/process-all", {
|
|
2045
|
-
method: "POST",
|
|
2046
|
-
signal
|
|
2047
|
-
});
|
|
2048
|
-
if (!response.body) {
|
|
2049
|
-
throw new Error("No response body");
|
|
2050
|
-
}
|
|
2051
|
-
const reader = response.body.getReader();
|
|
2052
|
-
const decoder = new TextDecoder();
|
|
2053
|
-
try {
|
|
2054
|
-
while (true) {
|
|
2055
|
-
const { done, value } = await reader.read();
|
|
2056
|
-
if (done) break;
|
|
2057
|
-
if (signal.aborted) {
|
|
2058
|
-
reader.cancel();
|
|
2059
|
-
break;
|
|
2060
|
-
}
|
|
2061
|
-
const text = decoder.decode(value);
|
|
2062
|
-
const lines = text.split("\n\n").filter((line) => line.startsWith("data: "));
|
|
2063
|
-
for (const line of lines) {
|
|
2064
|
-
try {
|
|
2065
|
-
const data = JSON.parse(line.replace("data: ", ""));
|
|
2066
|
-
if (data.type === "start") {
|
|
2067
|
-
setProgressState((prev) => ({
|
|
2068
|
-
...prev,
|
|
2069
|
-
total: data.total
|
|
2070
|
-
}));
|
|
2071
|
-
} else if (data.type === "progress") {
|
|
2072
|
-
setProgressState({
|
|
2073
|
-
current: data.current,
|
|
2074
|
-
total: data.total,
|
|
2075
|
-
percent: data.percent,
|
|
2076
|
-
currentFile: data.currentFile,
|
|
2077
|
-
status: "processing"
|
|
2078
|
-
});
|
|
2079
|
-
} else if (data.type === "cleanup") {
|
|
2080
|
-
setProgressState((prev) => ({
|
|
2081
|
-
...prev,
|
|
2082
|
-
status: "cleanup",
|
|
2083
|
-
currentFile: void 0
|
|
2084
|
-
}));
|
|
2085
|
-
} else if (data.type === "complete") {
|
|
2086
|
-
setProgressState({
|
|
2087
|
-
current: data.processed,
|
|
2088
|
-
total: data.processed,
|
|
2089
|
-
percent: 100,
|
|
2090
|
-
status: "complete",
|
|
2091
|
-
processed: data.processed,
|
|
2092
|
-
alreadyProcessed: data.alreadyProcessed,
|
|
2093
|
-
orphansRemoved: data.orphansRemoved,
|
|
2094
|
-
errors: data.errors
|
|
2095
|
-
});
|
|
2096
|
-
triggerRefresh();
|
|
2097
|
-
} else if (data.type === "error") {
|
|
2098
|
-
setProgressState((prev) => ({
|
|
2099
|
-
...prev,
|
|
2100
|
-
status: "error",
|
|
2101
|
-
message: data.message
|
|
2102
|
-
}));
|
|
2103
|
-
}
|
|
2104
|
-
} catch {
|
|
2105
|
-
}
|
|
2106
|
-
}
|
|
2107
|
-
}
|
|
2108
|
-
} catch (err) {
|
|
2109
|
-
if (signal.aborted) {
|
|
2110
|
-
setProgressState((prev) => ({
|
|
2111
|
-
...prev,
|
|
2112
|
-
status: "stopped",
|
|
2113
|
-
processed: prev.current
|
|
2114
|
-
}));
|
|
2115
|
-
triggerRefresh();
|
|
2116
|
-
} else {
|
|
2117
|
-
throw err;
|
|
2118
|
-
}
|
|
2119
|
-
}
|
|
2120
|
-
} else {
|
|
2121
|
-
setShowProgress(true);
|
|
2122
|
-
setProgressState({
|
|
2123
|
-
current: 0,
|
|
2124
|
-
total: processCount,
|
|
2125
|
-
percent: 0,
|
|
2126
|
-
status: "processing"
|
|
2127
|
-
});
|
|
2128
|
-
const selectedImageKeys = imagesToProcess.map((p) => {
|
|
2129
|
-
const key = p.replace(/^public\//, "");
|
|
2130
|
-
return key.startsWith("/") ? key : `/${key}`;
|
|
2131
|
-
});
|
|
2132
|
-
const response = await fetch("/api/studio/reprocess-stream", {
|
|
2133
|
-
method: "POST",
|
|
2134
|
-
headers: { "Content-Type": "application/json" },
|
|
2135
|
-
body: JSON.stringify({ imageKeys: selectedImageKeys }),
|
|
2136
|
-
signal
|
|
2137
|
-
});
|
|
2138
|
-
if (!response.ok) {
|
|
2139
|
-
const error = await response.json();
|
|
2140
|
-
setProgressState({
|
|
2141
|
-
current: 0,
|
|
2142
|
-
total: 0,
|
|
2143
|
-
percent: 0,
|
|
2144
|
-
status: "error",
|
|
2145
|
-
message: error.error || "Unknown error"
|
|
2146
|
-
});
|
|
2147
|
-
} else {
|
|
2148
|
-
const reader = response.body?.getReader();
|
|
2149
|
-
const decoder = new TextDecoder();
|
|
2150
|
-
if (reader) {
|
|
2151
|
-
let buffer = "";
|
|
2152
|
-
while (true) {
|
|
2153
|
-
const { done, value } = await reader.read();
|
|
2154
|
-
if (done) break;
|
|
2155
|
-
buffer += decoder.decode(value, { stream: true });
|
|
2156
|
-
const lines = buffer.split("\n");
|
|
2157
|
-
buffer = lines.pop() || "";
|
|
2158
|
-
for (const line of lines) {
|
|
2159
|
-
if (line.startsWith("data: ")) {
|
|
2160
|
-
try {
|
|
2161
|
-
const data = JSON.parse(line.slice(6));
|
|
2162
|
-
if (data.type === "start") {
|
|
2163
|
-
setProgressState((prev) => ({
|
|
2164
|
-
...prev,
|
|
2165
|
-
total: data.total
|
|
2166
|
-
}));
|
|
2167
|
-
} else if (data.type === "progress") {
|
|
2168
|
-
setProgressState({
|
|
2169
|
-
current: data.current,
|
|
2170
|
-
total: data.total,
|
|
2171
|
-
percent: data.percent,
|
|
2172
|
-
status: "processing",
|
|
2173
|
-
message: data.message
|
|
2174
|
-
});
|
|
2175
|
-
} else if (data.type === "cleanup") {
|
|
2176
|
-
setProgressState((prev) => ({
|
|
2177
|
-
...prev,
|
|
2178
|
-
status: "cleanup",
|
|
2179
|
-
message: data.message
|
|
2180
|
-
}));
|
|
2181
|
-
} else if (data.type === "complete") {
|
|
2182
|
-
setProgressState({
|
|
2183
|
-
current: data.processed,
|
|
2184
|
-
total: data.processed,
|
|
2185
|
-
percent: 100,
|
|
2186
|
-
status: data.errors > 0 ? "error" : "complete",
|
|
2187
|
-
processed: data.processed,
|
|
2188
|
-
message: data.message
|
|
2189
|
-
});
|
|
2190
|
-
clearSelection();
|
|
2191
|
-
triggerRefresh();
|
|
2192
|
-
} else if (data.type === "error") {
|
|
2193
|
-
setProgressState((prev) => ({
|
|
2194
|
-
...prev,
|
|
2195
|
-
status: "error",
|
|
2196
|
-
message: data.message
|
|
2197
|
-
}));
|
|
2198
|
-
}
|
|
2199
|
-
} catch {
|
|
2200
|
-
}
|
|
2201
|
-
}
|
|
2202
|
-
}
|
|
2203
|
-
}
|
|
2204
|
-
}
|
|
2205
|
-
}
|
|
2206
|
-
}
|
|
2207
|
-
} catch (error) {
|
|
2208
|
-
if (signal.aborted) {
|
|
2209
|
-
setProgressState((prev) => ({
|
|
2210
|
-
...prev,
|
|
2211
|
-
status: "stopped",
|
|
2212
|
-
processed: prev.current
|
|
2213
|
-
}));
|
|
2214
|
-
triggerRefresh();
|
|
2215
|
-
} else {
|
|
2216
|
-
console.error("Processing error:", error);
|
|
2217
|
-
setProgressState({
|
|
2218
|
-
current: 0,
|
|
2219
|
-
total: 0,
|
|
2220
|
-
percent: 0,
|
|
2221
|
-
status: "error",
|
|
2222
|
-
message: "Processing failed. Check console for details."
|
|
2223
|
-
});
|
|
2224
|
-
}
|
|
2225
|
-
} finally {
|
|
2226
|
-
setProcessing(false);
|
|
2227
|
-
abortControllerRef.current = null;
|
|
2228
|
-
}
|
|
2229
|
-
}, [processMode, processCount, imagesToProcess, clearSelection, triggerRefresh]);
|
|
2019
|
+
}, [selectedItems, requestProcess]);
|
|
2230
2020
|
const handleStopProcessing = useCallback2(() => {
|
|
2231
2021
|
if (abortControllerRef.current) {
|
|
2232
2022
|
abortControllerRef.current.abort();
|
|
@@ -2605,16 +2395,6 @@ function StudioToolbar() {
|
|
|
2605
2395
|
onCancel: () => setShowSyncConfirm(false)
|
|
2606
2396
|
}
|
|
2607
2397
|
),
|
|
2608
|
-
showProcessConfirm && /* @__PURE__ */ jsx5(
|
|
2609
|
-
ConfirmModal,
|
|
2610
|
-
{
|
|
2611
|
-
title: "Process Images",
|
|
2612
|
-
message: processMode === "all" ? `Found ${processCount} image${processCount !== 1 ? "s" : ""} in the public folder. This will regenerate all thumbnails and remove any orphaned files from the images folder.` : `Process ${processCount} selected image${processCount !== 1 ? "s" : ""}? This will regenerate thumbnails for these files.`,
|
|
2613
|
-
confirmLabel: processing ? "Processing..." : "Process",
|
|
2614
|
-
onConfirm: handleProcessConfirm,
|
|
2615
|
-
onCancel: () => setShowProcessConfirm(false)
|
|
2616
|
-
}
|
|
2617
|
-
),
|
|
2618
2398
|
showProgress && /* @__PURE__ */ jsx5(
|
|
2619
2399
|
ProgressModal,
|
|
2620
2400
|
{
|
|
@@ -2738,11 +2518,11 @@ function StudioToolbar() {
|
|
|
2738
2518
|
{
|
|
2739
2519
|
css: styles5.btn,
|
|
2740
2520
|
onClick: handleProcessImages,
|
|
2741
|
-
disabled:
|
|
2521
|
+
disabled: actionState.showProgress || isInImagesFolder,
|
|
2742
2522
|
title: isInImagesFolder ? "Cannot process images folder" : void 0,
|
|
2743
2523
|
children: [
|
|
2744
2524
|
/* @__PURE__ */ jsx5(ImageStackIcon, {}),
|
|
2745
|
-
|
|
2525
|
+
"Process Images"
|
|
2746
2526
|
]
|
|
2747
2527
|
}
|
|
2748
2528
|
),
|
|
@@ -6324,4 +6104,4 @@ export {
|
|
|
6324
6104
|
StudioUI,
|
|
6325
6105
|
StudioUI_default as default
|
|
6326
6106
|
};
|
|
6327
|
-
//# sourceMappingURL=StudioUI-
|
|
6107
|
+
//# sourceMappingURL=StudioUI-TTBNASM5.mjs.map
|