@gallop.software/studio 1.4.7 → 1.5.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.
@@ -4282,7 +4282,16 @@ function StudioDetailView() {
4282
4282
  const [showR2SetupModal, setShowR2SetupModal] = useState8(false);
4283
4283
  const [alertMessage, setAlertMessage] = useState8(null);
4284
4284
  const [showCopied, setShowCopied] = useState8(false);
4285
+ const [showFaviconProgress, setShowFaviconProgress] = useState8(false);
4286
+ const [faviconProgress, setFaviconProgress] = useState8({
4287
+ current: 0,
4288
+ total: 3,
4289
+ percent: 0,
4290
+ status: "processing",
4291
+ message: "Generating favicons..."
4292
+ });
4285
4293
  const isActionInProgress = actionState.showProgress;
4294
+ const isFaviconSource = focusedItem ? focusedItem.name.toLowerCase() === "favicon.png" || focusedItem.name.toLowerCase() === "favicon.jpg" : false;
4286
4295
  if (!focusedItem) return null;
4287
4296
  const isImage = isImageFile(focusedItem.name);
4288
4297
  const isVideo = isVideoFile(focusedItem.name);
@@ -4329,6 +4338,94 @@ function StudioDetailView() {
4329
4338
  }
4330
4339
  }
4331
4340
  };
4341
+ const handleGenerateFavicons = async () => {
4342
+ if (!focusedItem) return;
4343
+ setShowFaviconProgress(true);
4344
+ setFaviconProgress({
4345
+ current: 0,
4346
+ total: 3,
4347
+ percent: 0,
4348
+ status: "processing",
4349
+ message: "Generating favicons..."
4350
+ });
4351
+ try {
4352
+ const response = await fetch("/api/studio/generate-favicon", {
4353
+ method: "POST",
4354
+ headers: { "Content-Type": "application/json" },
4355
+ body: JSON.stringify({
4356
+ imagePath: "/" + focusedItem.path.replace(/^public\//, "")
4357
+ })
4358
+ });
4359
+ if (!response.ok) {
4360
+ const error = await response.json();
4361
+ setFaviconProgress({
4362
+ current: 0,
4363
+ total: 3,
4364
+ percent: 0,
4365
+ status: "error",
4366
+ message: error.error || "Failed to generate favicons"
4367
+ });
4368
+ return;
4369
+ }
4370
+ const reader = response.body?.getReader();
4371
+ const decoder = new TextDecoder();
4372
+ if (reader) {
4373
+ let buffer = "";
4374
+ while (true) {
4375
+ const { done, value } = await reader.read();
4376
+ if (done) break;
4377
+ buffer += decoder.decode(value, { stream: true });
4378
+ const lines = buffer.split("\n");
4379
+ buffer = lines.pop() || "";
4380
+ for (const line of lines) {
4381
+ if (line.startsWith("data: ")) {
4382
+ try {
4383
+ const data = JSON.parse(line.slice(6));
4384
+ if (data.type === "start") {
4385
+ setFaviconProgress((prev) => ({
4386
+ ...prev,
4387
+ total: data.total
4388
+ }));
4389
+ } else if (data.type === "progress") {
4390
+ setFaviconProgress({
4391
+ current: data.current,
4392
+ total: data.total,
4393
+ percent: data.percent,
4394
+ status: "processing",
4395
+ message: data.message
4396
+ });
4397
+ } else if (data.type === "complete") {
4398
+ setFaviconProgress({
4399
+ current: data.processed,
4400
+ total: data.processed,
4401
+ percent: 100,
4402
+ status: data.errors > 0 ? "error" : "complete",
4403
+ message: data.message
4404
+ });
4405
+ } else if (data.type === "error") {
4406
+ setFaviconProgress((prev) => ({
4407
+ ...prev,
4408
+ status: "error",
4409
+ message: data.message
4410
+ }));
4411
+ }
4412
+ } catch {
4413
+ }
4414
+ }
4415
+ }
4416
+ }
4417
+ }
4418
+ } catch (error) {
4419
+ console.error("Favicon generation error:", error);
4420
+ setFaviconProgress({
4421
+ current: 0,
4422
+ total: 3,
4423
+ percent: 0,
4424
+ status: "error",
4425
+ message: "An error occurred while generating favicons"
4426
+ });
4427
+ }
4428
+ };
4332
4429
  const renderMedia = () => {
4333
4430
  if (isImage) {
4334
4431
  return /* @__PURE__ */ jsx8("img", { css: styles8.image, src: imageSrc, alt: focusedItem.name });
@@ -4369,6 +4466,14 @@ function StudioDetailView() {
4369
4466
  onCancel: () => setShowRenameModal(false)
4370
4467
  }
4371
4468
  ),
4469
+ showFaviconProgress && /* @__PURE__ */ jsx8(
4470
+ ProgressModal,
4471
+ {
4472
+ title: "Generating Favicons",
4473
+ progress: faviconProgress,
4474
+ onClose: () => setShowFaviconProgress(false)
4475
+ }
4476
+ ),
4372
4477
  /* @__PURE__ */ jsx8("div", { css: styles8.overlay, onClick: handleClose, children: /* @__PURE__ */ jsxs8("div", { css: styles8.container, onClick: (e) => e.stopPropagation(), children: [
4373
4478
  /* @__PURE__ */ jsxs8("div", { css: styles8.main, children: [
4374
4479
  /* @__PURE__ */ jsxs8("div", { css: styles8.headerButtons, children: [
@@ -4475,6 +4580,18 @@ function StudioDetailView() {
4475
4580
  ]
4476
4581
  }
4477
4582
  ),
4583
+ isFaviconSource && /* @__PURE__ */ jsxs8(
4584
+ "button",
4585
+ {
4586
+ css: styles8.actionBtn,
4587
+ onClick: handleGenerateFavicons,
4588
+ disabled: showFaviconProgress || focusedItem.isProtected,
4589
+ children: [
4590
+ /* @__PURE__ */ jsx8("svg", { css: styles8.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx8("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 3v4M3 5h4M6 17v4m-2-2h4m5-16l2.286 6.857L21 12l-5.714 2.143L13 21l-2.286-6.857L5 12l5.714-2.143L13 3z" }) }),
4591
+ "Generate Favicons"
4592
+ ]
4593
+ }
4594
+ ),
4478
4595
  /* @__PURE__ */ jsxs8(
4479
4596
  "button",
4480
4597
  {
@@ -6104,4 +6221,4 @@ export {
6104
6221
  StudioUI,
6105
6222
  StudioUI_default as default
6106
6223
  };
6107
- //# sourceMappingURL=StudioUI-TP2Y3ZEL.mjs.map
6224
+ //# sourceMappingURL=StudioUI-BHFZVR57.mjs.map