afterbefore 0.2.15 → 0.2.17
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/{chunk-XSDO6N5Q.js → chunk-CC6QEACR.js} +102 -16
- package/dist/chunk-CC6QEACR.js.map +1 -0
- package/dist/overlay/index.js +714 -606
- package/dist/overlay/index.js.map +1 -1
- package/dist/server/middleware.js +9 -1
- package/dist/server/middleware.js.map +1 -1
- package/dist/server/route.js +17 -2
- package/dist/server/route.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-XSDO6N5Q.js.map +0 -1
package/dist/overlay/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
// src/overlay/index.tsx
|
|
4
|
-
import { useState as
|
|
4
|
+
import { useState as useState4, useCallback as useCallback4, useEffect as useEffect3 } from "react";
|
|
5
5
|
|
|
6
6
|
// src/overlay/state.ts
|
|
7
7
|
import { useState, useCallback } from "react";
|
|
@@ -34,10 +34,10 @@ var DEFAULT_FRAME_SETTINGS = {
|
|
|
34
34
|
padding: 40
|
|
35
35
|
};
|
|
36
36
|
var FRAME_SIZE_PRESETS = [
|
|
37
|
-
{ label: "1920 x 1080", w: 1920, h: 1080 },
|
|
38
|
-
{ label: "1080 x 1080", w: 1080, h: 1080 },
|
|
39
|
-
{ label: "1200 x 630", w: 1200, h: 630 },
|
|
40
|
-
{ label: "1080 x 1920", w: 1080, h: 1920 }
|
|
37
|
+
{ label: "1920 x 1080", hint: "Desktop / HD", w: 1920, h: 1080 },
|
|
38
|
+
{ label: "1080 x 1080", hint: "Social square", w: 1080, h: 1080 },
|
|
39
|
+
{ label: "1200 x 630", hint: "Open Graph / link preview", w: 1200, h: 630 },
|
|
40
|
+
{ label: "1080 x 1920", hint: "Story / portrait", w: 1080, h: 1920 }
|
|
41
41
|
];
|
|
42
42
|
var DEV_UI_SELECTORS = [
|
|
43
43
|
// Afterbefore overlay
|
|
@@ -177,48 +177,131 @@ function loadImage(src) {
|
|
|
177
177
|
});
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
-
// src/overlay/ui/
|
|
181
|
-
import {
|
|
182
|
-
import {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
180
|
+
// src/overlay/ui/toolbar.tsx
|
|
181
|
+
import { useCallback as useCallback2, useEffect, useRef, useState as useState2 } from "react";
|
|
182
|
+
import {
|
|
183
|
+
ArrowUp,
|
|
184
|
+
Camera,
|
|
185
|
+
Check,
|
|
186
|
+
ChevronDown,
|
|
187
|
+
Clock,
|
|
188
|
+
Eye,
|
|
189
|
+
FolderOpen,
|
|
190
|
+
Frame,
|
|
191
|
+
ImageIcon,
|
|
192
|
+
LoaderCircle,
|
|
193
|
+
Maximize,
|
|
194
|
+
Monitor,
|
|
195
|
+
MousePointer2,
|
|
196
|
+
Palette,
|
|
197
|
+
Settings,
|
|
198
|
+
Trash2,
|
|
199
|
+
Upload,
|
|
200
|
+
X
|
|
201
|
+
} from "lucide-react";
|
|
202
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
186
203
|
var EDGE_MARGIN = 24;
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
204
|
+
var CONTAINER_SIZE = 38;
|
|
205
|
+
function getCornerStyle(corner) {
|
|
206
|
+
switch (corner) {
|
|
207
|
+
case "bottom-right":
|
|
208
|
+
return { bottom: EDGE_MARGIN, right: EDGE_MARGIN };
|
|
209
|
+
case "bottom-left":
|
|
210
|
+
return { bottom: EDGE_MARGIN, left: EDGE_MARGIN };
|
|
211
|
+
case "top-right":
|
|
212
|
+
return { top: EDGE_MARGIN, right: EDGE_MARGIN };
|
|
213
|
+
case "top-left":
|
|
214
|
+
return { top: EDGE_MARGIN, left: EDGE_MARGIN };
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
function isBottomCorner(corner) {
|
|
218
|
+
return corner === "bottom-right" || corner === "bottom-left";
|
|
219
|
+
}
|
|
220
|
+
function isRightCorner(corner) {
|
|
221
|
+
return corner === "bottom-right" || corner === "top-right";
|
|
222
|
+
}
|
|
223
|
+
function snapToCorner(x, y) {
|
|
224
|
+
const cx = window.innerWidth / 2;
|
|
225
|
+
const cy = window.innerHeight / 2;
|
|
226
|
+
if (x < cx) {
|
|
227
|
+
return y < cy ? "top-left" : "bottom-left";
|
|
228
|
+
}
|
|
229
|
+
return y < cy ? "top-right" : "bottom-right";
|
|
230
|
+
}
|
|
231
|
+
var MODES = [
|
|
232
|
+
{ mode: "component", label: "Component", icon: MousePointer2 },
|
|
233
|
+
{ mode: "viewport", label: "Viewport", icon: Monitor },
|
|
234
|
+
{ mode: "fullpage", label: "Full Page", icon: Maximize }
|
|
235
|
+
];
|
|
236
|
+
function Toolbar({
|
|
237
|
+
expanded,
|
|
238
|
+
onToggle,
|
|
239
|
+
phase,
|
|
240
|
+
loading,
|
|
241
|
+
selectedMode,
|
|
242
|
+
onModeChange,
|
|
243
|
+
onCapture,
|
|
244
|
+
onCancel,
|
|
245
|
+
frameSettings,
|
|
246
|
+
onFrameSettingsChange
|
|
247
|
+
}) {
|
|
248
|
+
const [settingsOpen, setSettingsOpen] = useState2(false);
|
|
249
|
+
const [historyOpen, setHistoryOpen] = useState2(false);
|
|
250
|
+
const [corner, setCorner] = useState2(() => {
|
|
251
|
+
try {
|
|
252
|
+
const stored = localStorage.getItem("ab-toolbar-corner");
|
|
253
|
+
if (stored && ["bottom-right", "bottom-left", "top-right", "top-left"].includes(stored)) {
|
|
254
|
+
return stored;
|
|
255
|
+
}
|
|
256
|
+
} catch {
|
|
257
|
+
}
|
|
258
|
+
return "bottom-right";
|
|
259
|
+
});
|
|
190
260
|
const [dragging, setDragging] = useState2(false);
|
|
261
|
+
const [dragPos, setDragPos] = useState2(null);
|
|
191
262
|
const dragState = useRef(null);
|
|
263
|
+
const toolbarRef = useRef(null);
|
|
264
|
+
const [cameraHovered, setCameraHovered] = useState2(false);
|
|
192
265
|
useEffect(() => {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
}
|
|
266
|
+
if (!expanded) return;
|
|
267
|
+
const onKey = (e) => {
|
|
268
|
+
if (e.target?.tagName === "INPUT") {
|
|
269
|
+
if (e.key === "Escape") {
|
|
270
|
+
e.target.blur();
|
|
271
|
+
}
|
|
272
|
+
return;
|
|
199
273
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
274
|
+
if (e.key === "Escape") {
|
|
275
|
+
if (settingsOpen) {
|
|
276
|
+
setSettingsOpen(false);
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
onCancel();
|
|
280
|
+
} else if (e.key === "Enter") {
|
|
281
|
+
onCapture(selectedMode);
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
document.addEventListener("keydown", onKey);
|
|
285
|
+
return () => document.removeEventListener("keydown", onKey);
|
|
286
|
+
}, [expanded, onCancel, onCapture, selectedMode, settingsOpen]);
|
|
208
287
|
const handleMouseDown = useCallback2(
|
|
209
288
|
(e) => {
|
|
210
289
|
e.preventDefault();
|
|
290
|
+
const el = toolbarRef.current;
|
|
291
|
+
if (!el) return;
|
|
292
|
+
const rect = el.getBoundingClientRect();
|
|
211
293
|
setDragging(true);
|
|
294
|
+
setDragPos({ x: rect.left, y: rect.top });
|
|
212
295
|
dragState.current = {
|
|
213
296
|
dragging: true,
|
|
214
297
|
startX: e.clientX,
|
|
215
298
|
startY: e.clientY,
|
|
216
|
-
origX:
|
|
217
|
-
origY:
|
|
299
|
+
origX: rect.left,
|
|
300
|
+
origY: rect.top,
|
|
218
301
|
distance: 0
|
|
219
302
|
};
|
|
220
303
|
},
|
|
221
|
-
[
|
|
304
|
+
[]
|
|
222
305
|
);
|
|
223
306
|
useEffect(() => {
|
|
224
307
|
const handleMouseMove = (e) => {
|
|
@@ -227,23 +310,31 @@ function Icon({ phase, onClick, loading, onPositionChange }) {
|
|
|
227
310
|
const dx = e.clientX - ds.startX;
|
|
228
311
|
const dy = e.clientY - ds.startY;
|
|
229
312
|
ds.distance = Math.sqrt(dx * dx + dy * dy);
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
);
|
|
234
|
-
const newY = Math.max(
|
|
235
|
-
0,
|
|
236
|
-
Math.min(window.innerHeight - ICON_SIZE, ds.origY + dy)
|
|
237
|
-
);
|
|
238
|
-
setPos({ x: newX, y: newY });
|
|
313
|
+
setDragPos({
|
|
314
|
+
x: ds.origX + dx,
|
|
315
|
+
y: ds.origY + dy
|
|
316
|
+
});
|
|
239
317
|
};
|
|
240
|
-
const handleMouseUp = () => {
|
|
318
|
+
const handleMouseUp = (e) => {
|
|
241
319
|
const ds = dragState.current;
|
|
242
320
|
if (!ds) return;
|
|
243
321
|
if (ds.distance < 5) {
|
|
244
|
-
|
|
322
|
+
onToggle();
|
|
323
|
+
} else {
|
|
324
|
+
const el = toolbarRef.current;
|
|
325
|
+
const w = el?.offsetWidth ?? CONTAINER_SIZE;
|
|
326
|
+
const h = el?.offsetHeight ?? CONTAINER_SIZE;
|
|
327
|
+
const centerX = ds.origX + (e.clientX - ds.startX) + w / 2;
|
|
328
|
+
const centerY = ds.origY + (e.clientY - ds.startY) + h / 2;
|
|
329
|
+
const newCorner = snapToCorner(centerX, centerY);
|
|
330
|
+
setCorner(newCorner);
|
|
331
|
+
try {
|
|
332
|
+
localStorage.setItem("ab-toolbar-corner", newCorner);
|
|
333
|
+
} catch {
|
|
334
|
+
}
|
|
245
335
|
}
|
|
246
336
|
setDragging(false);
|
|
337
|
+
setDragPos(null);
|
|
247
338
|
dragState.current = null;
|
|
248
339
|
};
|
|
249
340
|
window.addEventListener("mousemove", handleMouseMove);
|
|
@@ -252,39 +343,27 @@ function Icon({ phase, onClick, loading, onPositionChange }) {
|
|
|
252
343
|
window.removeEventListener("mousemove", handleMouseMove);
|
|
253
344
|
window.removeEventListener("mouseup", handleMouseUp);
|
|
254
345
|
};
|
|
255
|
-
}, [
|
|
256
|
-
|
|
257
|
-
|
|
346
|
+
}, [onToggle]);
|
|
347
|
+
const panelSide = isRightCorner(corner) ? "left" : "right";
|
|
348
|
+
const tooltipSide = panelSide;
|
|
349
|
+
const bottom = isBottomCorner(corner);
|
|
350
|
+
const positionStyle = dragging && dragPos ? { left: dragPos.x, top: dragPos.y } : getCornerStyle(corner);
|
|
351
|
+
const cameraButton = /* @__PURE__ */ jsxs(
|
|
258
352
|
"div",
|
|
259
353
|
{
|
|
260
|
-
ref,
|
|
261
|
-
"data-afterbefore": "true",
|
|
262
354
|
onMouseDown: handleMouseDown,
|
|
355
|
+
onMouseEnter: () => setCameraHovered(true),
|
|
356
|
+
onMouseLeave: () => setCameraHovered(false),
|
|
263
357
|
style: {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
top: pos.y,
|
|
267
|
-
width: CONTAINER_SIZE,
|
|
268
|
-
height: CONTAINER_SIZE,
|
|
358
|
+
width: 32,
|
|
359
|
+
height: 32,
|
|
269
360
|
borderRadius: "50%",
|
|
270
|
-
background: "rgba(32, 32, 36, 0.92)",
|
|
271
|
-
backdropFilter: "blur(20px)",
|
|
272
|
-
WebkitBackdropFilter: "blur(20px)",
|
|
273
|
-
border: "none",
|
|
274
361
|
display: "flex",
|
|
275
362
|
alignItems: "center",
|
|
276
363
|
justifyContent: "center",
|
|
277
364
|
cursor: dragging ? "grabbing" : "pointer",
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
transition: "background 0.15s",
|
|
281
|
-
userSelect: "none"
|
|
282
|
-
},
|
|
283
|
-
onMouseEnter: (e) => {
|
|
284
|
-
e.currentTarget.style.background = "rgba(32, 32, 36, 0.98)";
|
|
285
|
-
},
|
|
286
|
-
onMouseLeave: (e) => {
|
|
287
|
-
e.currentTarget.style.background = "rgba(32, 32, 36, 0.92)";
|
|
365
|
+
background: cameraHovered ? "rgba(255, 255, 255, 0.12)" : "transparent",
|
|
366
|
+
transition: "background 0.12s ease"
|
|
288
367
|
},
|
|
289
368
|
children: [
|
|
290
369
|
/* @__PURE__ */ jsx(
|
|
@@ -306,218 +385,136 @@ function Icon({ phase, onClick, loading, onPositionChange }) {
|
|
|
306
385
|
strokeWidth: 2,
|
|
307
386
|
style: { animation: "ab-spin 0.8s linear infinite", color: "white" }
|
|
308
387
|
}
|
|
309
|
-
) : phase === "ready" ? /* @__PURE__ */ jsx(Check, { size: 16, strokeWidth: 2.6, color: "#4ade80" }) : /* @__PURE__ */ jsx(
|
|
388
|
+
) : phase === "ready" ? /* @__PURE__ */ jsx(Check, { size: 16, strokeWidth: 2.6, color: "#4ade80" }) : /* @__PURE__ */ jsx(
|
|
389
|
+
Camera,
|
|
390
|
+
{
|
|
391
|
+
size: 16,
|
|
392
|
+
strokeWidth: 1.9,
|
|
393
|
+
color: cameraHovered ? "rgba(255, 255, 255, 0.96)" : "rgba(255, 255, 255, 0.52)"
|
|
394
|
+
}
|
|
395
|
+
)
|
|
310
396
|
]
|
|
311
397
|
}
|
|
312
398
|
);
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
var CAMERA_CURSOR = `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32' viewBox='0 0 32 32'%3E%3Cpath d='M6 12h4l2-3h8l2 3h4a3 3 0 0 1 3 3v9a3 3 0 0 1-3 3H6a3 3 0 0 1-3-3v-9a3 3 0 0 1 3-3z' fill='black' fill-opacity='0.25' transform='translate(0,1)'/%3E%3Cpath d='M6 12h4l2-3h8l2 3h4a3 3 0 0 1 3 3v9a3 3 0 0 1-3 3H6a3 3 0 0 1-3-3v-9a3 3 0 0 1 3-3z' fill='white'/%3E%3Ccircle cx='16' cy='19' r='4.5' fill='none' stroke='%23555' stroke-width='1.5'/%3E%3Ccircle cx='16' cy='19' r='1.5' fill='%23999'/%3E%3C/svg%3E") 16 16, pointer`;
|
|
318
|
-
function CapturePreview({ mode, onClick }) {
|
|
319
|
-
if (mode === "viewport" || mode === "fullpage") {
|
|
320
|
-
return /* @__PURE__ */ jsx2(
|
|
321
|
-
"div",
|
|
399
|
+
const toolbarButtons = expanded ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
400
|
+
/* @__PURE__ */ jsx(IconButton, { tooltipSide, tooltip: "Close", onClick: onCancel, children: /* @__PURE__ */ jsx(X, { size: 16, strokeWidth: 1.7 }) }),
|
|
401
|
+
/* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", gap: 2, padding: "4px 0" }, children: MODES.map(({ mode, label, icon: ModeIcon }) => /* @__PURE__ */ jsx(
|
|
402
|
+
IconButton,
|
|
322
403
|
{
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
Upload,
|
|
355
|
-
X
|
|
356
|
-
} from "lucide-react";
|
|
357
|
-
import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
358
|
-
var MODES = [
|
|
359
|
-
{ mode: "component", label: "Capture Component", icon: MousePointer2 },
|
|
360
|
-
{ mode: "viewport", label: "Capture Viewport", icon: Monitor },
|
|
361
|
-
{ mode: "fullpage", label: "Capture Full Page", icon: Maximize }
|
|
362
|
-
];
|
|
363
|
-
function Toolbar({
|
|
364
|
-
selectedMode,
|
|
365
|
-
onModeChange,
|
|
366
|
-
onCapture,
|
|
367
|
-
onCancel,
|
|
368
|
-
frameSettings,
|
|
369
|
-
onFrameSettingsChange
|
|
370
|
-
}) {
|
|
371
|
-
const [settingsOpen, setSettingsOpen] = useState3(false);
|
|
372
|
-
const [historyOpen, setHistoryOpen] = useState3(false);
|
|
373
|
-
useEffect2(() => {
|
|
374
|
-
const onKey = (e) => {
|
|
375
|
-
if (e.target?.tagName === "INPUT") {
|
|
376
|
-
if (e.key === "Escape") {
|
|
377
|
-
e.target.blur();
|
|
378
|
-
}
|
|
379
|
-
return;
|
|
404
|
+
active: selectedMode === mode,
|
|
405
|
+
tooltipSide,
|
|
406
|
+
tooltip: label,
|
|
407
|
+
onClick: () => {
|
|
408
|
+
setSettingsOpen(false);
|
|
409
|
+
setHistoryOpen(false);
|
|
410
|
+
if (mode === "viewport" || mode === "fullpage") {
|
|
411
|
+
onModeChange(mode);
|
|
412
|
+
onCapture(mode);
|
|
413
|
+
} else {
|
|
414
|
+
onModeChange(mode);
|
|
415
|
+
}
|
|
416
|
+
},
|
|
417
|
+
children: /* @__PURE__ */ jsx(ModeIcon, { size: 16, strokeWidth: 1.7 })
|
|
418
|
+
},
|
|
419
|
+
mode
|
|
420
|
+
)) }),
|
|
421
|
+
/* @__PURE__ */ jsx(Separator, { vertical: false }),
|
|
422
|
+
/* @__PURE__ */ jsx(
|
|
423
|
+
SettingsButton,
|
|
424
|
+
{
|
|
425
|
+
open: settingsOpen,
|
|
426
|
+
onClick: () => {
|
|
427
|
+
setSettingsOpen((prev) => !prev);
|
|
428
|
+
setHistoryOpen(false);
|
|
429
|
+
},
|
|
430
|
+
selectedMode,
|
|
431
|
+
frameSettings,
|
|
432
|
+
onFrameSettingsChange,
|
|
433
|
+
panelSide,
|
|
434
|
+
tooltipSide
|
|
380
435
|
}
|
|
381
|
-
|
|
382
|
-
|
|
436
|
+
),
|
|
437
|
+
/* @__PURE__ */ jsx(
|
|
438
|
+
HistoryButton,
|
|
439
|
+
{
|
|
440
|
+
open: historyOpen,
|
|
441
|
+
onClick: () => {
|
|
442
|
+
setHistoryOpen((prev) => !prev);
|
|
383
443
|
setSettingsOpen(false);
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
} else if (e.key === "Enter") {
|
|
388
|
-
onCapture(selectedMode);
|
|
444
|
+
},
|
|
445
|
+
panelSide,
|
|
446
|
+
tooltipSide
|
|
389
447
|
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
return /* @__PURE__ */ jsx3(
|
|
448
|
+
),
|
|
449
|
+
/* @__PURE__ */ jsx(Separator, { vertical: false })
|
|
450
|
+
] }) : null;
|
|
451
|
+
return /* @__PURE__ */ jsx(
|
|
395
452
|
"div",
|
|
396
453
|
{
|
|
454
|
+
ref: toolbarRef,
|
|
397
455
|
"data-afterbefore": "true",
|
|
398
456
|
style: {
|
|
399
457
|
position: "fixed",
|
|
400
|
-
|
|
401
|
-
left: "50%",
|
|
402
|
-
transform: "translateX(-50%)",
|
|
458
|
+
...positionStyle,
|
|
403
459
|
zIndex: 2147483647,
|
|
404
460
|
display: "flex",
|
|
461
|
+
flexDirection: "column",
|
|
405
462
|
alignItems: "center",
|
|
406
|
-
|
|
407
|
-
flexWrap: "wrap",
|
|
408
|
-
justifyContent: "center",
|
|
409
|
-
maxWidth: "min(calc(100vw - 32px), 1120px)",
|
|
410
|
-
background: "rgba(32, 32, 36, 0.92)",
|
|
411
|
-
backdropFilter: "blur(20px)",
|
|
412
|
-
WebkitBackdropFilter: "blur(20px)",
|
|
413
|
-
border: "none",
|
|
463
|
+
background: "rgb(32, 32, 36)",
|
|
414
464
|
borderRadius: 999,
|
|
415
465
|
padding: 6,
|
|
416
466
|
boxShadow: "0 8px 32px rgba(0, 0, 0, 0.4)",
|
|
417
|
-
fontFamily: "system-ui, -apple-system, sans-serif"
|
|
467
|
+
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
468
|
+
userSelect: "none"
|
|
418
469
|
},
|
|
419
|
-
children: /* @__PURE__ */
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
selected: selectedMode === mode,
|
|
426
|
-
onClick: () => {
|
|
427
|
-
setSettingsOpen(false);
|
|
428
|
-
setHistoryOpen(false);
|
|
429
|
-
onModeChange(mode);
|
|
430
|
-
},
|
|
431
|
-
children: /* @__PURE__ */ jsx3(Icon2, { size: 16, strokeWidth: 1.7 })
|
|
432
|
-
},
|
|
433
|
-
mode
|
|
434
|
-
)) }),
|
|
435
|
-
/* @__PURE__ */ jsx3(Separator, {}),
|
|
436
|
-
/* @__PURE__ */ jsx3(
|
|
437
|
-
SettingsButton,
|
|
438
|
-
{
|
|
439
|
-
open: settingsOpen,
|
|
440
|
-
onClick: () => {
|
|
441
|
-
setSettingsOpen((prev) => !prev);
|
|
442
|
-
setHistoryOpen(false);
|
|
443
|
-
},
|
|
444
|
-
selectedMode,
|
|
445
|
-
frameSettings,
|
|
446
|
-
onFrameSettingsChange
|
|
447
|
-
}
|
|
448
|
-
),
|
|
449
|
-
/* @__PURE__ */ jsx3(
|
|
450
|
-
HistoryButton,
|
|
451
|
-
{
|
|
452
|
-
open: historyOpen,
|
|
453
|
-
onClick: () => {
|
|
454
|
-
setHistoryOpen((prev) => !prev);
|
|
455
|
-
setSettingsOpen(false);
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
)
|
|
470
|
+
children: bottom ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
471
|
+
toolbarButtons,
|
|
472
|
+
cameraButton
|
|
473
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
474
|
+
cameraButton,
|
|
475
|
+
toolbarButtons
|
|
459
476
|
] })
|
|
460
477
|
}
|
|
461
478
|
);
|
|
462
479
|
}
|
|
463
|
-
function
|
|
464
|
-
const [hovered, setHovered] = useState3(false);
|
|
465
|
-
return /* @__PURE__ */ jsx3(
|
|
466
|
-
"button",
|
|
467
|
-
{
|
|
468
|
-
onClick,
|
|
469
|
-
onMouseEnter: () => setHovered(true),
|
|
470
|
-
onMouseLeave: () => setHovered(false),
|
|
471
|
-
style: {
|
|
472
|
-
width: 32,
|
|
473
|
-
height: 32,
|
|
474
|
-
borderRadius: "50%",
|
|
475
|
-
border: "none",
|
|
476
|
-
background: hovered ? "rgba(255, 255, 255, 0.12)" : "transparent",
|
|
477
|
-
display: "flex",
|
|
478
|
-
alignItems: "center",
|
|
479
|
-
justifyContent: "center",
|
|
480
|
-
cursor: "pointer",
|
|
481
|
-
padding: 0,
|
|
482
|
-
color: hovered ? "rgba(255, 255, 255, 0.96)" : "rgba(255, 255, 255, 0.52)",
|
|
483
|
-
transition: "background 0.12s ease, color 0.12s ease"
|
|
484
|
-
},
|
|
485
|
-
children: /* @__PURE__ */ jsx3(X, { size: 16, strokeWidth: 1.7 })
|
|
486
|
-
}
|
|
487
|
-
);
|
|
488
|
-
}
|
|
489
|
-
function ModeButton({
|
|
480
|
+
function IconButton({
|
|
490
481
|
children,
|
|
491
|
-
|
|
492
|
-
|
|
482
|
+
active,
|
|
483
|
+
tooltip,
|
|
484
|
+
tooltipSide = "left",
|
|
493
485
|
onClick
|
|
494
486
|
}) {
|
|
495
|
-
const [hovered, setHovered] =
|
|
496
|
-
|
|
497
|
-
|
|
487
|
+
const [hovered, setHovered] = useState2(false);
|
|
488
|
+
const tooltipStyle = tooltipSide === "left" ? {
|
|
489
|
+
right: "calc(100% + 10px)",
|
|
490
|
+
top: "50%",
|
|
491
|
+
transform: "translateY(-50%)"
|
|
492
|
+
} : {
|
|
493
|
+
left: "calc(100% + 10px)",
|
|
494
|
+
top: "50%",
|
|
495
|
+
transform: "translateY(-50%)"
|
|
496
|
+
};
|
|
497
|
+
return /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
|
|
498
|
+
tooltip && hovered && /* @__PURE__ */ jsx(
|
|
498
499
|
"div",
|
|
499
500
|
{
|
|
500
501
|
style: {
|
|
501
502
|
position: "absolute",
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
transform: "translateX(-50%)",
|
|
505
|
-
background: "rgba(32, 32, 36, 0.96)",
|
|
506
|
-
backdropFilter: "blur(20px)",
|
|
507
|
-
WebkitBackdropFilter: "blur(20px)",
|
|
503
|
+
...tooltipStyle,
|
|
504
|
+
background: "rgb(32, 32, 36)",
|
|
508
505
|
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
509
|
-
borderRadius:
|
|
510
|
-
padding: "
|
|
506
|
+
borderRadius: 6,
|
|
507
|
+
padding: "3px 8px",
|
|
511
508
|
color: "rgba(255, 255, 255, 0.88)",
|
|
512
|
-
fontSize:
|
|
509
|
+
fontSize: 11,
|
|
513
510
|
whiteSpace: "nowrap",
|
|
514
511
|
boxShadow: "0 8px 28px rgba(0, 0, 0, 0.28)",
|
|
515
512
|
pointerEvents: "none"
|
|
516
513
|
},
|
|
517
|
-
children:
|
|
514
|
+
children: tooltip
|
|
518
515
|
}
|
|
519
516
|
),
|
|
520
|
-
/* @__PURE__ */
|
|
517
|
+
/* @__PURE__ */ jsx(
|
|
521
518
|
"button",
|
|
522
519
|
{
|
|
523
520
|
onClick,
|
|
@@ -528,13 +525,13 @@ function ModeButton({
|
|
|
528
525
|
height: 32,
|
|
529
526
|
borderRadius: "50%",
|
|
530
527
|
border: "none",
|
|
531
|
-
background:
|
|
528
|
+
background: active || hovered ? "rgba(255, 255, 255, 0.12)" : "transparent",
|
|
532
529
|
display: "flex",
|
|
533
530
|
alignItems: "center",
|
|
534
531
|
justifyContent: "center",
|
|
535
532
|
cursor: "pointer",
|
|
536
533
|
padding: 0,
|
|
537
|
-
color:
|
|
534
|
+
color: active || hovered ? "rgba(255, 255, 255, 0.96)" : "rgba(255, 255, 255, 0.52)",
|
|
538
535
|
transition: "background 0.12s ease, color 0.12s ease"
|
|
539
536
|
},
|
|
540
537
|
children
|
|
@@ -547,12 +544,13 @@ function SettingsButton({
|
|
|
547
544
|
onClick,
|
|
548
545
|
selectedMode,
|
|
549
546
|
frameSettings,
|
|
550
|
-
onFrameSettingsChange
|
|
547
|
+
onFrameSettingsChange,
|
|
548
|
+
panelSide,
|
|
549
|
+
tooltipSide
|
|
551
550
|
}) {
|
|
552
|
-
const [
|
|
553
|
-
const [
|
|
554
|
-
|
|
555
|
-
useEffect2(() => {
|
|
551
|
+
const [saveDir, setSaveDir] = useState2(null);
|
|
552
|
+
const [picking, setPicking] = useState2(false);
|
|
553
|
+
useEffect(() => {
|
|
556
554
|
if (!open) return;
|
|
557
555
|
fetch("/__afterbefore/config").then((r) => r.json()).then((data) => setSaveDir(data.saveDir)).catch(() => {
|
|
558
556
|
});
|
|
@@ -576,49 +574,24 @@ function SettingsButton({
|
|
|
576
574
|
}
|
|
577
575
|
};
|
|
578
576
|
const shortDir = saveDir ? saveDir.replace(/^\/Users\/[^/]+/, "~") : "~/Desktop";
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
onClick,
|
|
584
|
-
onMouseEnter: () => setHovered(true),
|
|
585
|
-
onMouseLeave: () => setHovered(false),
|
|
586
|
-
style: {
|
|
587
|
-
width: 32,
|
|
588
|
-
height: 32,
|
|
589
|
-
borderRadius: "50%",
|
|
590
|
-
border: "none",
|
|
591
|
-
background: open || hovered ? "rgba(255, 255, 255, 0.12)" : "transparent",
|
|
592
|
-
display: "flex",
|
|
593
|
-
alignItems: "center",
|
|
594
|
-
justifyContent: "center",
|
|
595
|
-
cursor: "pointer",
|
|
596
|
-
padding: 0,
|
|
597
|
-
color: open || hovered ? "rgba(255, 255, 255, 0.96)" : "rgba(255, 255, 255, 0.52)",
|
|
598
|
-
transition: "background 0.12s ease, color 0.12s ease"
|
|
599
|
-
},
|
|
600
|
-
children: /* @__PURE__ */ jsx3(Settings, { size: 16, strokeWidth: 1.7 })
|
|
601
|
-
}
|
|
602
|
-
),
|
|
603
|
-
open && /* @__PURE__ */ jsxs2(
|
|
577
|
+
const panelStyle = panelSide === "left" ? { right: "calc(100% + 10px)", top: 0 } : { left: "calc(100% + 10px)", top: 0 };
|
|
578
|
+
return /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
|
|
579
|
+
/* @__PURE__ */ jsx(IconButton, { active: open, tooltipSide, tooltip: !open ? "Settings" : void 0, onClick, children: /* @__PURE__ */ jsx(Settings, { size: 16, strokeWidth: 1.7 }) }),
|
|
580
|
+
open && /* @__PURE__ */ jsxs(
|
|
604
581
|
"div",
|
|
605
582
|
{
|
|
606
583
|
style: {
|
|
607
584
|
position: "absolute",
|
|
608
|
-
|
|
609
|
-
bottom: "calc(100% + 12px)",
|
|
610
|
-
transform: "translateX(-50%)",
|
|
585
|
+
...panelStyle,
|
|
611
586
|
minWidth: 260,
|
|
612
587
|
padding: "10px 12px",
|
|
613
588
|
borderRadius: 12,
|
|
614
|
-
background: "
|
|
589
|
+
background: "rgb(32, 32, 36)",
|
|
615
590
|
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
616
|
-
boxShadow: "0 14px 36px rgba(0, 0, 0, 0.32)"
|
|
617
|
-
backdropFilter: "blur(20px)",
|
|
618
|
-
WebkitBackdropFilter: "blur(20px)"
|
|
591
|
+
boxShadow: "0 14px 36px rgba(0, 0, 0, 0.32)"
|
|
619
592
|
},
|
|
620
593
|
children: [
|
|
621
|
-
/* @__PURE__ */
|
|
594
|
+
/* @__PURE__ */ jsx(
|
|
622
595
|
"div",
|
|
623
596
|
{
|
|
624
597
|
style: {
|
|
@@ -631,25 +604,26 @@ function SettingsButton({
|
|
|
631
604
|
children: "Settings"
|
|
632
605
|
}
|
|
633
606
|
),
|
|
634
|
-
selectedMode === "component" && /* @__PURE__ */
|
|
635
|
-
/* @__PURE__ */
|
|
607
|
+
selectedMode === "component" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
608
|
+
/* @__PURE__ */ jsx(
|
|
636
609
|
ToggleRow,
|
|
637
610
|
{
|
|
638
|
-
icon: /* @__PURE__ */
|
|
611
|
+
icon: /* @__PURE__ */ jsx(Frame, { size: 15, strokeWidth: 1.8 }),
|
|
639
612
|
label: "Frame",
|
|
613
|
+
hint: "Wrap component in a sized canvas with background",
|
|
640
614
|
enabled: frameSettings.enabled,
|
|
641
615
|
onChange: () => onFrameSettingsChange({ ...frameSettings, enabled: !frameSettings.enabled })
|
|
642
616
|
}
|
|
643
617
|
),
|
|
644
|
-
frameSettings.enabled && /* @__PURE__ */
|
|
645
|
-
/* @__PURE__ */
|
|
618
|
+
frameSettings.enabled && /* @__PURE__ */ jsxs("div", { style: { marginTop: 8, display: "flex", flexDirection: "column", gap: 10 }, children: [
|
|
619
|
+
/* @__PURE__ */ jsx(
|
|
646
620
|
FrameSizeControl,
|
|
647
621
|
{
|
|
648
622
|
size: frameSettings.size,
|
|
649
623
|
onChange: (size) => onFrameSettingsChange({ ...frameSettings, size })
|
|
650
624
|
}
|
|
651
625
|
),
|
|
652
|
-
/* @__PURE__ */
|
|
626
|
+
/* @__PURE__ */ jsx(
|
|
653
627
|
FrameBackgroundControl,
|
|
654
628
|
{
|
|
655
629
|
bgType: frameSettings.bgType,
|
|
@@ -661,8 +635,8 @@ function SettingsButton({
|
|
|
661
635
|
)
|
|
662
636
|
] })
|
|
663
637
|
] }),
|
|
664
|
-
selectedMode === "component" && /* @__PURE__ */
|
|
665
|
-
/* @__PURE__ */
|
|
638
|
+
selectedMode === "component" && /* @__PURE__ */ jsx("div", { style: { height: 1, background: "rgba(255,255,255,0.08)", margin: "8px 0" } }),
|
|
639
|
+
/* @__PURE__ */ jsx(
|
|
666
640
|
SaveLocationRow,
|
|
667
641
|
{
|
|
668
642
|
dir: shortDir,
|
|
@@ -679,13 +653,13 @@ function FrameSizeControl({
|
|
|
679
653
|
size,
|
|
680
654
|
onChange
|
|
681
655
|
}) {
|
|
682
|
-
const [sizeOpen, setSizeOpen] =
|
|
656
|
+
const [sizeOpen, setSizeOpen] = useState2(false);
|
|
683
657
|
const currentPreset = FRAME_SIZE_PRESETS.find((p) => p.w === size.w && p.h === size.h);
|
|
684
658
|
const isCustom = !currentPreset;
|
|
685
|
-
return /* @__PURE__ */
|
|
686
|
-
/* @__PURE__ */
|
|
687
|
-
/* @__PURE__ */
|
|
688
|
-
/* @__PURE__ */
|
|
659
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
660
|
+
/* @__PURE__ */ jsx(SettingsLabel, { children: "Size" }),
|
|
661
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 4, marginTop: 4 }, children: [
|
|
662
|
+
/* @__PURE__ */ jsx(
|
|
689
663
|
NumInput,
|
|
690
664
|
{
|
|
691
665
|
value: size.w,
|
|
@@ -695,8 +669,8 @@ function FrameSizeControl({
|
|
|
695
669
|
}
|
|
696
670
|
}
|
|
697
671
|
),
|
|
698
|
-
/* @__PURE__ */
|
|
699
|
-
/* @__PURE__ */
|
|
672
|
+
/* @__PURE__ */ jsx(StaticText, { children: "x" }),
|
|
673
|
+
/* @__PURE__ */ jsx(
|
|
700
674
|
NumInput,
|
|
701
675
|
{
|
|
702
676
|
value: size.h,
|
|
@@ -707,8 +681,8 @@ function FrameSizeControl({
|
|
|
707
681
|
}
|
|
708
682
|
)
|
|
709
683
|
] }),
|
|
710
|
-
/* @__PURE__ */
|
|
711
|
-
/* @__PURE__ */
|
|
684
|
+
/* @__PURE__ */ jsxs("div", { style: { position: "relative", marginTop: 6 }, children: [
|
|
685
|
+
/* @__PURE__ */ jsxs(
|
|
712
686
|
"button",
|
|
713
687
|
{
|
|
714
688
|
onClick: () => setSizeOpen((prev) => !prev),
|
|
@@ -730,11 +704,11 @@ function FrameSizeControl({
|
|
|
730
704
|
},
|
|
731
705
|
children: [
|
|
732
706
|
currentPreset ? currentPreset.label : "Custom",
|
|
733
|
-
/* @__PURE__ */
|
|
707
|
+
/* @__PURE__ */ jsx(ChevronDown, { size: 12, strokeWidth: 2 })
|
|
734
708
|
]
|
|
735
709
|
}
|
|
736
710
|
),
|
|
737
|
-
sizeOpen && /* @__PURE__ */
|
|
711
|
+
sizeOpen && /* @__PURE__ */ jsx(
|
|
738
712
|
"div",
|
|
739
713
|
{
|
|
740
714
|
style: {
|
|
@@ -742,16 +716,14 @@ function FrameSizeControl({
|
|
|
742
716
|
bottom: "calc(100% + 4px)",
|
|
743
717
|
left: 0,
|
|
744
718
|
right: 0,
|
|
745
|
-
background: "
|
|
719
|
+
background: "rgb(32, 32, 36)",
|
|
746
720
|
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
747
721
|
borderRadius: 8,
|
|
748
722
|
padding: "4px 0",
|
|
749
723
|
boxShadow: "0 10px 30px rgba(0, 0, 0, 0.3)",
|
|
750
|
-
backdropFilter: "blur(20px)",
|
|
751
|
-
WebkitBackdropFilter: "blur(20px)",
|
|
752
724
|
zIndex: 1
|
|
753
725
|
},
|
|
754
|
-
children: FRAME_SIZE_PRESETS.map((preset) => /* @__PURE__ */
|
|
726
|
+
children: FRAME_SIZE_PRESETS.map((preset) => /* @__PURE__ */ jsxs(
|
|
755
727
|
DropItem,
|
|
756
728
|
{
|
|
757
729
|
active: !isCustom && preset.w === size.w && preset.h === size.h,
|
|
@@ -759,7 +731,10 @@ function FrameSizeControl({
|
|
|
759
731
|
onChange({ w: preset.w, h: preset.h });
|
|
760
732
|
setSizeOpen(false);
|
|
761
733
|
},
|
|
762
|
-
children:
|
|
734
|
+
children: [
|
|
735
|
+
/* @__PURE__ */ jsx("span", { children: preset.label }),
|
|
736
|
+
/* @__PURE__ */ jsx("span", { style: { marginLeft: 6, fontSize: 10, color: "rgba(255,255,255,0.34)" }, children: preset.hint })
|
|
737
|
+
]
|
|
763
738
|
},
|
|
764
739
|
preset.label
|
|
765
740
|
))
|
|
@@ -775,7 +750,7 @@ function FrameBackgroundControl({
|
|
|
775
750
|
frameSize,
|
|
776
751
|
onChange
|
|
777
752
|
}) {
|
|
778
|
-
const fileInputRef =
|
|
753
|
+
const fileInputRef = useRef(null);
|
|
779
754
|
const handleFileSelect = (e) => {
|
|
780
755
|
const file = e.target.files?.[0];
|
|
781
756
|
if (!file) return;
|
|
@@ -793,40 +768,40 @@ function FrameBackgroundControl({
|
|
|
793
768
|
reader.readAsDataURL(file);
|
|
794
769
|
e.target.value = "";
|
|
795
770
|
};
|
|
796
|
-
return /* @__PURE__ */
|
|
797
|
-
/* @__PURE__ */
|
|
798
|
-
/* @__PURE__ */
|
|
799
|
-
/* @__PURE__ */
|
|
771
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
772
|
+
/* @__PURE__ */ jsx(SettingsLabel, { children: "Background" }),
|
|
773
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 2, marginTop: 4 }, children: [
|
|
774
|
+
/* @__PURE__ */ jsxs(
|
|
800
775
|
SegmentButton,
|
|
801
776
|
{
|
|
802
777
|
active: bgType === "color",
|
|
803
778
|
onClick: () => onChange({ bgType: "color" }),
|
|
804
779
|
style: { borderRadius: "6px 0 0 6px" },
|
|
805
780
|
children: [
|
|
806
|
-
/* @__PURE__ */
|
|
781
|
+
/* @__PURE__ */ jsx(Palette, { size: 12, strokeWidth: 2 }),
|
|
807
782
|
"Color"
|
|
808
783
|
]
|
|
809
784
|
}
|
|
810
785
|
),
|
|
811
|
-
/* @__PURE__ */
|
|
786
|
+
/* @__PURE__ */ jsxs(
|
|
812
787
|
SegmentButton,
|
|
813
788
|
{
|
|
814
789
|
active: bgType === "image",
|
|
815
790
|
onClick: () => onChange({ bgType: "image" }),
|
|
816
791
|
style: { borderRadius: "0 6px 6px 0" },
|
|
817
792
|
children: [
|
|
818
|
-
/* @__PURE__ */
|
|
793
|
+
/* @__PURE__ */ jsx(ImageIcon, { size: 12, strokeWidth: 2 }),
|
|
819
794
|
"Image"
|
|
820
795
|
]
|
|
821
796
|
}
|
|
822
797
|
)
|
|
823
798
|
] }),
|
|
824
|
-
bgType === "color" && /* @__PURE__ */
|
|
825
|
-
/* @__PURE__ */
|
|
826
|
-
/* @__PURE__ */
|
|
799
|
+
bgType === "color" && /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8, marginTop: 6 }, children: [
|
|
800
|
+
/* @__PURE__ */ jsx(ColorSwatch, { color: bgColor, onChange: (c) => onChange({ bgColor: c }) }),
|
|
801
|
+
/* @__PURE__ */ jsx(HexInput, { value: bgColor, onChange: (c) => onChange({ bgColor: c }) })
|
|
827
802
|
] }),
|
|
828
|
-
bgType === "image" && /* @__PURE__ */
|
|
829
|
-
/* @__PURE__ */
|
|
803
|
+
bgType === "image" && /* @__PURE__ */ jsxs("div", { style: { marginTop: 6 }, children: [
|
|
804
|
+
/* @__PURE__ */ jsx(
|
|
830
805
|
"input",
|
|
831
806
|
{
|
|
832
807
|
ref: fileInputRef,
|
|
@@ -836,8 +811,8 @@ function FrameBackgroundControl({
|
|
|
836
811
|
style: { display: "none" }
|
|
837
812
|
}
|
|
838
813
|
),
|
|
839
|
-
bgImage ? /* @__PURE__ */
|
|
840
|
-
/* @__PURE__ */
|
|
814
|
+
bgImage ? /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
|
|
815
|
+
/* @__PURE__ */ jsx(
|
|
841
816
|
"img",
|
|
842
817
|
{
|
|
843
818
|
src: bgImage,
|
|
@@ -851,20 +826,20 @@ function FrameBackgroundControl({
|
|
|
851
826
|
}
|
|
852
827
|
}
|
|
853
828
|
),
|
|
854
|
-
/* @__PURE__ */
|
|
855
|
-
/* @__PURE__ */
|
|
829
|
+
/* @__PURE__ */ jsxs(SmallButton, { onClick: () => fileInputRef.current?.click(), children: [
|
|
830
|
+
/* @__PURE__ */ jsx(Upload, { size: 11, strokeWidth: 2 }),
|
|
856
831
|
"Replace"
|
|
857
832
|
] }),
|
|
858
|
-
/* @__PURE__ */
|
|
859
|
-
] }) : /* @__PURE__ */
|
|
860
|
-
/* @__PURE__ */
|
|
833
|
+
/* @__PURE__ */ jsx(SmallButton, { onClick: () => onChange({ bgImage: null }), children: /* @__PURE__ */ jsx(Trash2, { size: 11, strokeWidth: 2 }) })
|
|
834
|
+
] }) : /* @__PURE__ */ jsxs(SmallButton, { onClick: () => fileInputRef.current?.click(), children: [
|
|
835
|
+
/* @__PURE__ */ jsx(Upload, { size: 11, strokeWidth: 2 }),
|
|
861
836
|
"Upload image"
|
|
862
837
|
] })
|
|
863
838
|
] })
|
|
864
839
|
] });
|
|
865
840
|
}
|
|
866
841
|
function SettingsLabel({ children }) {
|
|
867
|
-
return /* @__PURE__ */
|
|
842
|
+
return /* @__PURE__ */ jsx(
|
|
868
843
|
"div",
|
|
869
844
|
{
|
|
870
845
|
style: {
|
|
@@ -882,7 +857,7 @@ function SegmentButton({
|
|
|
882
857
|
onClick,
|
|
883
858
|
style
|
|
884
859
|
}) {
|
|
885
|
-
return /* @__PURE__ */
|
|
860
|
+
return /* @__PURE__ */ jsx(
|
|
886
861
|
"button",
|
|
887
862
|
{
|
|
888
863
|
onClick,
|
|
@@ -909,9 +884,9 @@ function ColorSwatch({
|
|
|
909
884
|
color,
|
|
910
885
|
onChange
|
|
911
886
|
}) {
|
|
912
|
-
const inputRef =
|
|
913
|
-
return /* @__PURE__ */
|
|
914
|
-
/* @__PURE__ */
|
|
887
|
+
const inputRef = useRef(null);
|
|
888
|
+
return /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
|
|
889
|
+
/* @__PURE__ */ jsx(
|
|
915
890
|
"button",
|
|
916
891
|
{
|
|
917
892
|
onClick: () => inputRef.current?.click(),
|
|
@@ -926,7 +901,7 @@ function ColorSwatch({
|
|
|
926
901
|
}
|
|
927
902
|
}
|
|
928
903
|
),
|
|
929
|
-
/* @__PURE__ */
|
|
904
|
+
/* @__PURE__ */ jsx(
|
|
930
905
|
"input",
|
|
931
906
|
{
|
|
932
907
|
ref: inputRef,
|
|
@@ -950,8 +925,8 @@ function SmallButton({
|
|
|
950
925
|
children,
|
|
951
926
|
onClick
|
|
952
927
|
}) {
|
|
953
|
-
const [hovered, setHovered] =
|
|
954
|
-
return /* @__PURE__ */
|
|
928
|
+
const [hovered, setHovered] = useState2(false);
|
|
929
|
+
return /* @__PURE__ */ jsx(
|
|
955
930
|
"button",
|
|
956
931
|
{
|
|
957
932
|
onClick,
|
|
@@ -996,8 +971,8 @@ function SaveLocationRow({
|
|
|
996
971
|
picking,
|
|
997
972
|
onPick
|
|
998
973
|
}) {
|
|
999
|
-
const [btnHovered, setBtnHovered] =
|
|
1000
|
-
return /* @__PURE__ */
|
|
974
|
+
const [btnHovered, setBtnHovered] = useState2(false);
|
|
975
|
+
return /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: /* @__PURE__ */ jsxs(
|
|
1001
976
|
"div",
|
|
1002
977
|
{
|
|
1003
978
|
style: {
|
|
@@ -1008,8 +983,8 @@ function SaveLocationRow({
|
|
|
1008
983
|
fontSize: 13
|
|
1009
984
|
},
|
|
1010
985
|
children: [
|
|
1011
|
-
/* @__PURE__ */
|
|
1012
|
-
/* @__PURE__ */
|
|
986
|
+
/* @__PURE__ */ jsx(FolderOpen, { size: 15, strokeWidth: 1.8, style: { flexShrink: 0 } }),
|
|
987
|
+
/* @__PURE__ */ jsx(
|
|
1013
988
|
"span",
|
|
1014
989
|
{
|
|
1015
990
|
style: {
|
|
@@ -1023,7 +998,7 @@ function SaveLocationRow({
|
|
|
1023
998
|
children: dir
|
|
1024
999
|
}
|
|
1025
1000
|
),
|
|
1026
|
-
/* @__PURE__ */
|
|
1001
|
+
/* @__PURE__ */ jsx(
|
|
1027
1002
|
"button",
|
|
1028
1003
|
{
|
|
1029
1004
|
onClick: onPick,
|
|
@@ -1052,10 +1027,11 @@ function SaveLocationRow({
|
|
|
1052
1027
|
function ToggleRow({
|
|
1053
1028
|
icon,
|
|
1054
1029
|
label,
|
|
1030
|
+
hint,
|
|
1055
1031
|
enabled,
|
|
1056
1032
|
onChange
|
|
1057
1033
|
}) {
|
|
1058
|
-
return /* @__PURE__ */
|
|
1034
|
+
return /* @__PURE__ */ jsxs(
|
|
1059
1035
|
"label",
|
|
1060
1036
|
{
|
|
1061
1037
|
style: {
|
|
@@ -1066,24 +1042,37 @@ function ToggleRow({
|
|
|
1066
1042
|
cursor: "pointer"
|
|
1067
1043
|
},
|
|
1068
1044
|
children: [
|
|
1069
|
-
/* @__PURE__ */
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1045
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 2 }, children: [
|
|
1046
|
+
/* @__PURE__ */ jsxs(
|
|
1047
|
+
"span",
|
|
1048
|
+
{
|
|
1049
|
+
style: {
|
|
1050
|
+
display: "flex",
|
|
1051
|
+
alignItems: "center",
|
|
1052
|
+
gap: 8,
|
|
1053
|
+
color: "rgba(255, 255, 255, 0.88)",
|
|
1054
|
+
fontSize: 13,
|
|
1055
|
+
whiteSpace: "nowrap"
|
|
1056
|
+
},
|
|
1057
|
+
children: [
|
|
1058
|
+
icon,
|
|
1059
|
+
label
|
|
1060
|
+
]
|
|
1061
|
+
}
|
|
1062
|
+
),
|
|
1063
|
+
hint && /* @__PURE__ */ jsx(
|
|
1064
|
+
"span",
|
|
1065
|
+
{
|
|
1066
|
+
style: {
|
|
1067
|
+
fontSize: 10,
|
|
1068
|
+
color: "rgba(255, 255, 255, 0.36)",
|
|
1069
|
+
paddingLeft: 23
|
|
1070
|
+
},
|
|
1071
|
+
children: hint
|
|
1072
|
+
}
|
|
1073
|
+
)
|
|
1074
|
+
] }),
|
|
1075
|
+
/* @__PURE__ */ jsx(
|
|
1087
1076
|
"button",
|
|
1088
1077
|
{
|
|
1089
1078
|
type: "button",
|
|
@@ -1100,7 +1089,7 @@ function ToggleRow({
|
|
|
1100
1089
|
flexShrink: 0,
|
|
1101
1090
|
transition: "background 0.12s ease"
|
|
1102
1091
|
},
|
|
1103
|
-
children: /* @__PURE__ */
|
|
1092
|
+
children: /* @__PURE__ */ jsx(
|
|
1104
1093
|
"span",
|
|
1105
1094
|
{
|
|
1106
1095
|
style: {
|
|
@@ -1125,14 +1114,14 @@ function NumInput({
|
|
|
1125
1114
|
value,
|
|
1126
1115
|
onChange
|
|
1127
1116
|
}) {
|
|
1128
|
-
const [editing, setEditing] =
|
|
1129
|
-
const [text, setText] =
|
|
1130
|
-
|
|
1117
|
+
const [editing, setEditing] = useState2(false);
|
|
1118
|
+
const [text, setText] = useState2(String(value));
|
|
1119
|
+
useEffect(() => {
|
|
1131
1120
|
if (!editing) {
|
|
1132
1121
|
setText(String(value));
|
|
1133
1122
|
}
|
|
1134
1123
|
}, [editing, value]);
|
|
1135
|
-
return /* @__PURE__ */
|
|
1124
|
+
return /* @__PURE__ */ jsx(
|
|
1136
1125
|
"input",
|
|
1137
1126
|
{
|
|
1138
1127
|
type: "text",
|
|
@@ -1170,9 +1159,9 @@ function HexInput({
|
|
|
1170
1159
|
value,
|
|
1171
1160
|
onChange
|
|
1172
1161
|
}) {
|
|
1173
|
-
const [editing, setEditing] =
|
|
1174
|
-
const [text, setText] =
|
|
1175
|
-
|
|
1162
|
+
const [editing, setEditing] = useState2(false);
|
|
1163
|
+
const [text, setText] = useState2(value);
|
|
1164
|
+
useEffect(() => {
|
|
1176
1165
|
if (!editing) {
|
|
1177
1166
|
setText(value);
|
|
1178
1167
|
}
|
|
@@ -1183,7 +1172,7 @@ function HexInput({
|
|
|
1183
1172
|
onChange(hex);
|
|
1184
1173
|
}
|
|
1185
1174
|
};
|
|
1186
|
-
return /* @__PURE__ */
|
|
1175
|
+
return /* @__PURE__ */ jsx(
|
|
1187
1176
|
"input",
|
|
1188
1177
|
{
|
|
1189
1178
|
type: "text",
|
|
@@ -1218,7 +1207,7 @@ function HexInput({
|
|
|
1218
1207
|
);
|
|
1219
1208
|
}
|
|
1220
1209
|
function StaticText({ children }) {
|
|
1221
|
-
return /* @__PURE__ */
|
|
1210
|
+
return /* @__PURE__ */ jsx(
|
|
1222
1211
|
"span",
|
|
1223
1212
|
{
|
|
1224
1213
|
style: {
|
|
@@ -1237,7 +1226,7 @@ function DropItem({
|
|
|
1237
1226
|
active,
|
|
1238
1227
|
accent
|
|
1239
1228
|
}) {
|
|
1240
|
-
return /* @__PURE__ */
|
|
1229
|
+
return /* @__PURE__ */ jsx(
|
|
1241
1230
|
"button",
|
|
1242
1231
|
{
|
|
1243
1232
|
onClick,
|
|
@@ -1258,7 +1247,7 @@ function DropItem({
|
|
|
1258
1247
|
);
|
|
1259
1248
|
}
|
|
1260
1249
|
function Separator({ vertical = true }) {
|
|
1261
|
-
return /* @__PURE__ */
|
|
1250
|
+
return /* @__PURE__ */ jsx(
|
|
1262
1251
|
"div",
|
|
1263
1252
|
{
|
|
1264
1253
|
style: {
|
|
@@ -1273,20 +1262,25 @@ function Separator({ vertical = true }) {
|
|
|
1273
1262
|
}
|
|
1274
1263
|
function HistoryButton({
|
|
1275
1264
|
open,
|
|
1276
|
-
onClick
|
|
1265
|
+
onClick,
|
|
1266
|
+
panelSide,
|
|
1267
|
+
tooltipSide
|
|
1277
1268
|
}) {
|
|
1278
|
-
const [
|
|
1279
|
-
const [
|
|
1280
|
-
const [
|
|
1281
|
-
const [
|
|
1282
|
-
const [
|
|
1283
|
-
const [
|
|
1284
|
-
const [
|
|
1285
|
-
const [
|
|
1286
|
-
const [
|
|
1287
|
-
const [
|
|
1288
|
-
const [
|
|
1289
|
-
|
|
1269
|
+
const [toast, setToast] = useState2(null);
|
|
1270
|
+
const [pushing, setPushing] = useState2(false);
|
|
1271
|
+
const [repos, setRepos] = useState2([]);
|
|
1272
|
+
const [branches, setBranches] = useState2([]);
|
|
1273
|
+
const [screenshots, setScreenshots] = useState2([]);
|
|
1274
|
+
const [selectedRepo, setSelectedRepo] = useState2(null);
|
|
1275
|
+
const [selectedBranch, setSelectedBranch] = useState2(null);
|
|
1276
|
+
const [loading, setLoading] = useState2(false);
|
|
1277
|
+
const [repoDropOpen, setRepoDropOpen] = useState2(false);
|
|
1278
|
+
const [branchDropOpen, setBranchDropOpen] = useState2(false);
|
|
1279
|
+
const [lightboxSrc, setLightboxSrc] = useState2(null);
|
|
1280
|
+
const [editingFile, setEditingFile] = useState2(null);
|
|
1281
|
+
const [editValue, setEditValue] = useState2("");
|
|
1282
|
+
const [hoveredThumb, setHoveredThumb] = useState2(null);
|
|
1283
|
+
useEffect(() => {
|
|
1290
1284
|
if (!open) {
|
|
1291
1285
|
setRepoDropOpen(false);
|
|
1292
1286
|
setBranchDropOpen(false);
|
|
@@ -1305,28 +1299,69 @@ function HistoryButton({
|
|
|
1305
1299
|
}).catch(() => {
|
|
1306
1300
|
}).finally(() => setLoading(false));
|
|
1307
1301
|
}, [open, selectedRepo, selectedBranch]);
|
|
1308
|
-
const showToast =
|
|
1302
|
+
const showToast = useCallback2((message, type) => {
|
|
1309
1303
|
setToast({ message, type });
|
|
1310
1304
|
setTimeout(() => setToast(null), 3e3);
|
|
1311
1305
|
}, []);
|
|
1312
1306
|
const handleOpenFolder = async () => {
|
|
1313
1307
|
try {
|
|
1314
|
-
const
|
|
1308
|
+
const body = selectedRepo && selectedBranch ? JSON.stringify({ repo: selectedRepo, branch: selectedBranch }) : void 0;
|
|
1309
|
+
const res = await fetch("/__afterbefore/open", {
|
|
1310
|
+
method: "POST",
|
|
1311
|
+
headers: body ? { "Content-Type": "application/json" } : void 0,
|
|
1312
|
+
body
|
|
1313
|
+
});
|
|
1315
1314
|
if (!res.ok) throw new Error();
|
|
1316
1315
|
showToast("Opened folder", "success");
|
|
1317
1316
|
} catch {
|
|
1318
1317
|
showToast("Could not open folder", "error");
|
|
1319
1318
|
}
|
|
1320
1319
|
};
|
|
1321
|
-
const
|
|
1320
|
+
const handleRename = async (oldName, newName) => {
|
|
1321
|
+
if (!newName.trim() || newName.trim() === oldName.replace(/\.png$/, "")) {
|
|
1322
|
+
setEditingFile(null);
|
|
1323
|
+
return;
|
|
1324
|
+
}
|
|
1325
|
+
try {
|
|
1326
|
+
const res = await fetch("/__afterbefore/history/rename", {
|
|
1327
|
+
method: "POST",
|
|
1328
|
+
headers: { "Content-Type": "application/json" },
|
|
1329
|
+
body: JSON.stringify({
|
|
1330
|
+
repo: selectedRepo,
|
|
1331
|
+
branch: selectedBranch,
|
|
1332
|
+
oldName,
|
|
1333
|
+
newName: newName.trim()
|
|
1334
|
+
})
|
|
1335
|
+
});
|
|
1336
|
+
if (!res.ok) throw new Error();
|
|
1337
|
+
const data = await res.json();
|
|
1338
|
+
setScreenshots(
|
|
1339
|
+
(prev) => prev.map(
|
|
1340
|
+
(s) => s.filename === oldName ? { ...s, filename: data.filename, timestamp: data.filename.replace(/\.png$/, "") } : s
|
|
1341
|
+
)
|
|
1342
|
+
);
|
|
1343
|
+
showToast("Renamed", "success");
|
|
1344
|
+
} catch {
|
|
1345
|
+
showToast("Rename failed", "error");
|
|
1346
|
+
}
|
|
1347
|
+
setEditingFile(null);
|
|
1348
|
+
};
|
|
1349
|
+
const handleDelete = async (filename) => {
|
|
1322
1350
|
try {
|
|
1323
|
-
const res = await fetch("/__afterbefore/
|
|
1351
|
+
const res = await fetch("/__afterbefore/history/delete", {
|
|
1352
|
+
method: "POST",
|
|
1353
|
+
headers: { "Content-Type": "application/json" },
|
|
1354
|
+
body: JSON.stringify({
|
|
1355
|
+
repo: selectedRepo,
|
|
1356
|
+
branch: selectedBranch,
|
|
1357
|
+
file: filename
|
|
1358
|
+
})
|
|
1359
|
+
});
|
|
1324
1360
|
if (!res.ok) throw new Error();
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
showToast("Copied!", "success");
|
|
1361
|
+
setScreenshots((prev) => prev.filter((s) => s.filename !== filename));
|
|
1362
|
+
showToast("Deleted", "success");
|
|
1328
1363
|
} catch {
|
|
1329
|
-
showToast("
|
|
1364
|
+
showToast("Delete failed", "error");
|
|
1330
1365
|
}
|
|
1331
1366
|
};
|
|
1332
1367
|
const handlePush = async () => {
|
|
@@ -1347,73 +1382,25 @@ function HistoryButton({
|
|
|
1347
1382
|
setPushing(false);
|
|
1348
1383
|
}
|
|
1349
1384
|
};
|
|
1350
|
-
|
|
1351
|
-
|
|
1385
|
+
const panelStyle = panelSide === "left" ? { right: "calc(100% + 10px)", top: 0 } : { left: "calc(100% + 10px)", top: 0 };
|
|
1386
|
+
return /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
|
|
1387
|
+
/* @__PURE__ */ jsx(IconButton, { active: open, tooltipSide, tooltip: !open ? "Screenshots" : void 0, onClick, children: /* @__PURE__ */ jsx(Clock, { size: 16, strokeWidth: 1.7 }) }),
|
|
1388
|
+
open && /* @__PURE__ */ jsxs(
|
|
1352
1389
|
"div",
|
|
1353
1390
|
{
|
|
1354
1391
|
style: {
|
|
1355
1392
|
position: "absolute",
|
|
1356
|
-
|
|
1357
|
-
bottom: "calc(100% + 10px)",
|
|
1358
|
-
transform: "translateX(-50%)",
|
|
1359
|
-
background: "rgba(32, 32, 36, 0.96)",
|
|
1360
|
-
backdropFilter: "blur(20px)",
|
|
1361
|
-
WebkitBackdropFilter: "blur(20px)",
|
|
1362
|
-
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
1363
|
-
borderRadius: 8,
|
|
1364
|
-
padding: "5px 10px",
|
|
1365
|
-
color: "rgba(255, 255, 255, 0.88)",
|
|
1366
|
-
fontSize: 12,
|
|
1367
|
-
whiteSpace: "nowrap",
|
|
1368
|
-
boxShadow: "0 8px 28px rgba(0, 0, 0, 0.28)",
|
|
1369
|
-
pointerEvents: "none"
|
|
1370
|
-
},
|
|
1371
|
-
children: "Screenshots"
|
|
1372
|
-
}
|
|
1373
|
-
),
|
|
1374
|
-
/* @__PURE__ */ jsx3(
|
|
1375
|
-
"button",
|
|
1376
|
-
{
|
|
1377
|
-
onClick,
|
|
1378
|
-
onMouseEnter: () => setHovered(true),
|
|
1379
|
-
onMouseLeave: () => setHovered(false),
|
|
1380
|
-
style: {
|
|
1381
|
-
width: 32,
|
|
1382
|
-
height: 32,
|
|
1383
|
-
borderRadius: "50%",
|
|
1384
|
-
border: "none",
|
|
1385
|
-
background: open || hovered ? "rgba(255, 255, 255, 0.12)" : "transparent",
|
|
1386
|
-
display: "flex",
|
|
1387
|
-
alignItems: "center",
|
|
1388
|
-
justifyContent: "center",
|
|
1389
|
-
cursor: "pointer",
|
|
1390
|
-
padding: 0,
|
|
1391
|
-
color: open || hovered ? "rgba(255, 255, 255, 0.96)" : "rgba(255, 255, 255, 0.52)",
|
|
1392
|
-
transition: "background 0.12s ease, color 0.12s ease"
|
|
1393
|
-
},
|
|
1394
|
-
children: /* @__PURE__ */ jsx3(Clock, { size: 16, strokeWidth: 1.7 })
|
|
1395
|
-
}
|
|
1396
|
-
),
|
|
1397
|
-
open && /* @__PURE__ */ jsxs2(
|
|
1398
|
-
"div",
|
|
1399
|
-
{
|
|
1400
|
-
style: {
|
|
1401
|
-
position: "absolute",
|
|
1402
|
-
left: "50%",
|
|
1403
|
-
bottom: "calc(100% + 12px)",
|
|
1404
|
-
transform: "translateX(-50%)",
|
|
1393
|
+
...panelStyle,
|
|
1405
1394
|
minWidth: 300,
|
|
1406
1395
|
maxWidth: 360,
|
|
1407
1396
|
padding: "10px 12px",
|
|
1408
1397
|
borderRadius: 12,
|
|
1409
|
-
background: "
|
|
1398
|
+
background: "rgb(32, 32, 36)",
|
|
1410
1399
|
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
1411
|
-
boxShadow: "0 14px 36px rgba(0, 0, 0, 0.32)"
|
|
1412
|
-
backdropFilter: "blur(20px)",
|
|
1413
|
-
WebkitBackdropFilter: "blur(20px)"
|
|
1400
|
+
boxShadow: "0 14px 36px rgba(0, 0, 0, 0.32)"
|
|
1414
1401
|
},
|
|
1415
1402
|
children: [
|
|
1416
|
-
/* @__PURE__ */
|
|
1403
|
+
/* @__PURE__ */ jsx(
|
|
1417
1404
|
"div",
|
|
1418
1405
|
{
|
|
1419
1406
|
style: {
|
|
@@ -1426,8 +1413,8 @@ function HistoryButton({
|
|
|
1426
1413
|
children: "Screenshots"
|
|
1427
1414
|
}
|
|
1428
1415
|
),
|
|
1429
|
-
/* @__PURE__ */
|
|
1430
|
-
/* @__PURE__ */
|
|
1416
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 6, marginBottom: 10 }, children: [
|
|
1417
|
+
/* @__PURE__ */ jsx(
|
|
1431
1418
|
FilterDropdown,
|
|
1432
1419
|
{
|
|
1433
1420
|
label: "Project",
|
|
@@ -1445,7 +1432,7 @@ function HistoryButton({
|
|
|
1445
1432
|
}
|
|
1446
1433
|
}
|
|
1447
1434
|
),
|
|
1448
|
-
/* @__PURE__ */
|
|
1435
|
+
/* @__PURE__ */ jsx(
|
|
1449
1436
|
FilterDropdown,
|
|
1450
1437
|
{
|
|
1451
1438
|
label: "Branch",
|
|
@@ -1463,7 +1450,7 @@ function HistoryButton({
|
|
|
1463
1450
|
}
|
|
1464
1451
|
)
|
|
1465
1452
|
] }),
|
|
1466
|
-
loading ? /* @__PURE__ */
|
|
1453
|
+
loading ? /* @__PURE__ */ jsx(
|
|
1467
1454
|
"div",
|
|
1468
1455
|
{
|
|
1469
1456
|
style: {
|
|
@@ -1474,7 +1461,7 @@ function HistoryButton({
|
|
|
1474
1461
|
},
|
|
1475
1462
|
children: "Loading..."
|
|
1476
1463
|
}
|
|
1477
|
-
) : screenshots.length === 0 ? /* @__PURE__ */
|
|
1464
|
+
) : screenshots.length === 0 ? /* @__PURE__ */ jsx(
|
|
1478
1465
|
"div",
|
|
1479
1466
|
{
|
|
1480
1467
|
style: {
|
|
@@ -1485,8 +1472,8 @@ function HistoryButton({
|
|
|
1485
1472
|
},
|
|
1486
1473
|
children: "No screenshots yet"
|
|
1487
1474
|
}
|
|
1488
|
-
) : /* @__PURE__ */
|
|
1489
|
-
/* @__PURE__ */
|
|
1475
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1476
|
+
/* @__PURE__ */ jsx(
|
|
1490
1477
|
"div",
|
|
1491
1478
|
{
|
|
1492
1479
|
style: {
|
|
@@ -1496,48 +1483,150 @@ function HistoryButton({
|
|
|
1496
1483
|
flexDirection: "column",
|
|
1497
1484
|
gap: 8
|
|
1498
1485
|
},
|
|
1499
|
-
children: screenshots.map((shot) =>
|
|
1500
|
-
"
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1486
|
+
children: screenshots.map((shot) => {
|
|
1487
|
+
const imgUrl = `/__afterbefore/history/image?repo=${encodeURIComponent(selectedRepo || "")}&branch=${encodeURIComponent(selectedBranch || "")}&file=${encodeURIComponent(shot.filename)}`;
|
|
1488
|
+
const isEditing = editingFile === shot.filename;
|
|
1489
|
+
return /* @__PURE__ */ jsxs(
|
|
1490
|
+
"div",
|
|
1491
|
+
{
|
|
1492
|
+
style: {
|
|
1493
|
+
display: "flex",
|
|
1494
|
+
gap: 10,
|
|
1495
|
+
alignItems: "center"
|
|
1496
|
+
},
|
|
1497
|
+
children: [
|
|
1498
|
+
/* @__PURE__ */ jsxs(
|
|
1499
|
+
"div",
|
|
1500
|
+
{
|
|
1501
|
+
style: {
|
|
1502
|
+
position: "relative",
|
|
1503
|
+
width: 56,
|
|
1504
|
+
height: 36,
|
|
1505
|
+
flexShrink: 0,
|
|
1506
|
+
borderRadius: 4,
|
|
1507
|
+
overflow: "hidden",
|
|
1508
|
+
cursor: "pointer"
|
|
1509
|
+
},
|
|
1510
|
+
onMouseEnter: () => setHoveredThumb(shot.filename),
|
|
1511
|
+
onMouseLeave: () => setHoveredThumb(null),
|
|
1512
|
+
onClick: () => setLightboxSrc(imgUrl),
|
|
1513
|
+
children: [
|
|
1514
|
+
/* @__PURE__ */ jsx(
|
|
1515
|
+
"img",
|
|
1516
|
+
{
|
|
1517
|
+
src: imgUrl,
|
|
1518
|
+
alt: "",
|
|
1519
|
+
style: {
|
|
1520
|
+
width: 56,
|
|
1521
|
+
height: 36,
|
|
1522
|
+
objectFit: "cover",
|
|
1523
|
+
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
1524
|
+
borderRadius: 4,
|
|
1525
|
+
background: "rgba(255, 255, 255, 0.05)",
|
|
1526
|
+
display: "block"
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
),
|
|
1530
|
+
/* @__PURE__ */ jsx(
|
|
1531
|
+
"div",
|
|
1532
|
+
{
|
|
1533
|
+
style: {
|
|
1534
|
+
position: "absolute",
|
|
1535
|
+
inset: 0,
|
|
1536
|
+
background: "rgba(0, 0, 0, 0.55)",
|
|
1537
|
+
display: "flex",
|
|
1538
|
+
alignItems: "center",
|
|
1539
|
+
justifyContent: "center",
|
|
1540
|
+
borderRadius: 4,
|
|
1541
|
+
opacity: hoveredThumb === shot.filename ? 1 : 0,
|
|
1542
|
+
transition: "opacity 0.15s ease"
|
|
1543
|
+
},
|
|
1544
|
+
children: /* @__PURE__ */ jsx(Eye, { size: 16, strokeWidth: 1.8, color: "rgba(255, 255, 255, 0.9)" })
|
|
1545
|
+
}
|
|
1546
|
+
)
|
|
1547
|
+
]
|
|
1521
1548
|
}
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1549
|
+
),
|
|
1550
|
+
/* @__PURE__ */ jsx("div", { style: { flex: 1, minWidth: 0 }, children: isEditing ? /* @__PURE__ */ jsx(
|
|
1551
|
+
"input",
|
|
1552
|
+
{
|
|
1553
|
+
autoFocus: true,
|
|
1554
|
+
value: editValue,
|
|
1555
|
+
onChange: (e) => setEditValue(e.target.value),
|
|
1556
|
+
onKeyDown: (e) => {
|
|
1557
|
+
if (e.key === "Enter") handleRename(shot.filename, editValue);
|
|
1558
|
+
if (e.key === "Escape") setEditingFile(null);
|
|
1559
|
+
},
|
|
1560
|
+
onBlur: () => handleRename(shot.filename, editValue),
|
|
1561
|
+
style: {
|
|
1562
|
+
width: "100%",
|
|
1563
|
+
fontSize: 12,
|
|
1564
|
+
color: "rgba(255, 255, 255, 0.88)",
|
|
1565
|
+
background: "rgba(255, 255, 255, 0.1)",
|
|
1566
|
+
border: "1px solid rgba(255, 255, 255, 0.2)",
|
|
1567
|
+
borderRadius: 4,
|
|
1568
|
+
padding: "2px 6px",
|
|
1569
|
+
outline: "none",
|
|
1570
|
+
fontFamily: "inherit"
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
) : /* @__PURE__ */ jsx(
|
|
1574
|
+
"div",
|
|
1575
|
+
{
|
|
1576
|
+
onClick: () => {
|
|
1577
|
+
setEditingFile(shot.filename);
|
|
1578
|
+
setEditValue(shot.filename.replace(/\.png$/, ""));
|
|
1579
|
+
},
|
|
1580
|
+
style: {
|
|
1581
|
+
fontSize: 12,
|
|
1582
|
+
color: "rgba(255, 255, 255, 0.88)",
|
|
1583
|
+
cursor: "pointer",
|
|
1584
|
+
overflow: "hidden",
|
|
1585
|
+
textOverflow: "ellipsis",
|
|
1586
|
+
whiteSpace: "nowrap"
|
|
1587
|
+
},
|
|
1588
|
+
title: "Click to rename",
|
|
1589
|
+
children: formatTimestamp(shot.filename)
|
|
1590
|
+
}
|
|
1591
|
+
) }),
|
|
1592
|
+
/* @__PURE__ */ jsx(
|
|
1593
|
+
"button",
|
|
1594
|
+
{
|
|
1595
|
+
onClick: () => handleDelete(shot.filename),
|
|
1596
|
+
title: "Delete screenshot",
|
|
1597
|
+
style: {
|
|
1598
|
+
flexShrink: 0,
|
|
1599
|
+
width: 24,
|
|
1600
|
+
height: 24,
|
|
1601
|
+
borderRadius: 4,
|
|
1602
|
+
border: "none",
|
|
1603
|
+
background: "transparent",
|
|
1604
|
+
color: "rgba(255, 255, 255, 0.35)",
|
|
1605
|
+
cursor: "pointer",
|
|
1606
|
+
display: "flex",
|
|
1607
|
+
alignItems: "center",
|
|
1608
|
+
justifyContent: "center",
|
|
1609
|
+
padding: 0
|
|
1610
|
+
},
|
|
1611
|
+
onMouseEnter: (e) => {
|
|
1612
|
+
e.currentTarget.style.color = "rgba(239, 68, 68, 0.9)";
|
|
1613
|
+
e.currentTarget.style.background = "rgba(239, 68, 68, 0.1)";
|
|
1614
|
+
},
|
|
1615
|
+
onMouseLeave: (e) => {
|
|
1616
|
+
e.currentTarget.style.color = "rgba(255, 255, 255, 0.35)";
|
|
1617
|
+
e.currentTarget.style.background = "transparent";
|
|
1618
|
+
},
|
|
1619
|
+
children: /* @__PURE__ */ jsx(Trash2, { size: 13, strokeWidth: 1.8 })
|
|
1620
|
+
}
|
|
1621
|
+
)
|
|
1622
|
+
]
|
|
1623
|
+
},
|
|
1624
|
+
shot.filename
|
|
1625
|
+
);
|
|
1626
|
+
})
|
|
1538
1627
|
}
|
|
1539
1628
|
),
|
|
1540
|
-
/* @__PURE__ */
|
|
1629
|
+
/* @__PURE__ */ jsx(
|
|
1541
1630
|
"div",
|
|
1542
1631
|
{
|
|
1543
1632
|
style: {
|
|
@@ -1547,22 +1636,18 @@ function HistoryButton({
|
|
|
1547
1636
|
}
|
|
1548
1637
|
}
|
|
1549
1638
|
),
|
|
1550
|
-
/* @__PURE__ */
|
|
1551
|
-
/* @__PURE__ */
|
|
1552
|
-
/* @__PURE__ */
|
|
1639
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 2 }, children: [
|
|
1640
|
+
/* @__PURE__ */ jsxs(ActionButton, { onClick: handleOpenFolder, children: [
|
|
1641
|
+
/* @__PURE__ */ jsx(FolderOpen, { size: 13, strokeWidth: 1.8 }),
|
|
1553
1642
|
"Open Folder"
|
|
1554
1643
|
] }),
|
|
1555
|
-
/* @__PURE__ */
|
|
1556
|
-
/* @__PURE__ */
|
|
1557
|
-
"Copy Markdown"
|
|
1558
|
-
] }),
|
|
1559
|
-
/* @__PURE__ */ jsxs2(ActionButton, { onClick: handlePush, disabled: pushing, children: [
|
|
1560
|
-
/* @__PURE__ */ jsx3(ArrowUp, { size: 13, strokeWidth: 1.8 }),
|
|
1644
|
+
/* @__PURE__ */ jsxs(ActionButton, { onClick: handlePush, disabled: pushing, children: [
|
|
1645
|
+
/* @__PURE__ */ jsx(ArrowUp, { size: 13, strokeWidth: 1.8 }),
|
|
1561
1646
|
pushing ? "Pushing..." : "Push to PR"
|
|
1562
1647
|
] })
|
|
1563
1648
|
] })
|
|
1564
1649
|
] }),
|
|
1565
|
-
toast && /* @__PURE__ */
|
|
1650
|
+
toast && /* @__PURE__ */ jsx(
|
|
1566
1651
|
"div",
|
|
1567
1652
|
{
|
|
1568
1653
|
style: {
|
|
@@ -1585,6 +1670,66 @@ function HistoryButton({
|
|
|
1585
1670
|
)
|
|
1586
1671
|
]
|
|
1587
1672
|
}
|
|
1673
|
+
),
|
|
1674
|
+
lightboxSrc && /* @__PURE__ */ jsxs(
|
|
1675
|
+
"div",
|
|
1676
|
+
{
|
|
1677
|
+
onClick: () => setLightboxSrc(null),
|
|
1678
|
+
onKeyDown: (e) => {
|
|
1679
|
+
if (e.key === "Escape") setLightboxSrc(null);
|
|
1680
|
+
},
|
|
1681
|
+
style: {
|
|
1682
|
+
position: "fixed",
|
|
1683
|
+
inset: 0,
|
|
1684
|
+
bottom: 100,
|
|
1685
|
+
zIndex: 2147483646,
|
|
1686
|
+
background: "rgba(0, 0, 0, 0.85)",
|
|
1687
|
+
display: "flex",
|
|
1688
|
+
alignItems: "center",
|
|
1689
|
+
justifyContent: "center",
|
|
1690
|
+
cursor: "zoom-out"
|
|
1691
|
+
},
|
|
1692
|
+
children: [
|
|
1693
|
+
/* @__PURE__ */ jsx(
|
|
1694
|
+
"img",
|
|
1695
|
+
{
|
|
1696
|
+
src: lightboxSrc,
|
|
1697
|
+
alt: "",
|
|
1698
|
+
onClick: (e) => e.stopPropagation(),
|
|
1699
|
+
style: {
|
|
1700
|
+
maxWidth: "90vw",
|
|
1701
|
+
maxHeight: "calc(100% - 32px)",
|
|
1702
|
+
borderRadius: 8,
|
|
1703
|
+
boxShadow: "0 20px 60px rgba(0, 0, 0, 0.5)",
|
|
1704
|
+
cursor: "default"
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
),
|
|
1708
|
+
/* @__PURE__ */ jsx(
|
|
1709
|
+
"button",
|
|
1710
|
+
{
|
|
1711
|
+
onClick: () => setLightboxSrc(null),
|
|
1712
|
+
style: {
|
|
1713
|
+
position: "absolute",
|
|
1714
|
+
top: 16,
|
|
1715
|
+
right: 16,
|
|
1716
|
+
width: 32,
|
|
1717
|
+
height: 32,
|
|
1718
|
+
borderRadius: "50%",
|
|
1719
|
+
border: "none",
|
|
1720
|
+
background: "rgba(255, 255, 255, 0.15)",
|
|
1721
|
+
color: "white",
|
|
1722
|
+
cursor: "pointer",
|
|
1723
|
+
display: "flex",
|
|
1724
|
+
alignItems: "center",
|
|
1725
|
+
justifyContent: "center",
|
|
1726
|
+
padding: 0
|
|
1727
|
+
},
|
|
1728
|
+
children: /* @__PURE__ */ jsx(X, { size: 18, strokeWidth: 2 })
|
|
1729
|
+
}
|
|
1730
|
+
)
|
|
1731
|
+
]
|
|
1732
|
+
}
|
|
1588
1733
|
)
|
|
1589
1734
|
] });
|
|
1590
1735
|
}
|
|
@@ -1596,8 +1741,8 @@ function FilterDropdown({
|
|
|
1596
1741
|
onToggle,
|
|
1597
1742
|
onSelect
|
|
1598
1743
|
}) {
|
|
1599
|
-
return /* @__PURE__ */
|
|
1600
|
-
/* @__PURE__ */
|
|
1744
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
1745
|
+
/* @__PURE__ */ jsx(
|
|
1601
1746
|
"div",
|
|
1602
1747
|
{
|
|
1603
1748
|
style: {
|
|
@@ -1609,8 +1754,8 @@ function FilterDropdown({
|
|
|
1609
1754
|
children: label
|
|
1610
1755
|
}
|
|
1611
1756
|
),
|
|
1612
|
-
/* @__PURE__ */
|
|
1613
|
-
/* @__PURE__ */
|
|
1757
|
+
/* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
|
|
1758
|
+
/* @__PURE__ */ jsxs(
|
|
1614
1759
|
"button",
|
|
1615
1760
|
{
|
|
1616
1761
|
onClick: onToggle,
|
|
@@ -1631,7 +1776,7 @@ function FilterDropdown({
|
|
|
1631
1776
|
fontFamily: "inherit"
|
|
1632
1777
|
},
|
|
1633
1778
|
children: [
|
|
1634
|
-
/* @__PURE__ */
|
|
1779
|
+
/* @__PURE__ */ jsx(
|
|
1635
1780
|
"span",
|
|
1636
1781
|
{
|
|
1637
1782
|
style: {
|
|
@@ -1642,11 +1787,11 @@ function FilterDropdown({
|
|
|
1642
1787
|
children: value || "\u2014"
|
|
1643
1788
|
}
|
|
1644
1789
|
),
|
|
1645
|
-
/* @__PURE__ */
|
|
1790
|
+
/* @__PURE__ */ jsx(ChevronDown, { size: 12, strokeWidth: 2 })
|
|
1646
1791
|
]
|
|
1647
1792
|
}
|
|
1648
1793
|
),
|
|
1649
|
-
isOpen && options.length > 0 && /* @__PURE__ */
|
|
1794
|
+
isOpen && options.length > 0 && /* @__PURE__ */ jsx(
|
|
1650
1795
|
"div",
|
|
1651
1796
|
{
|
|
1652
1797
|
style: {
|
|
@@ -1656,16 +1801,14 @@ function FilterDropdown({
|
|
|
1656
1801
|
right: 0,
|
|
1657
1802
|
maxHeight: 160,
|
|
1658
1803
|
overflowY: "auto",
|
|
1659
|
-
background: "
|
|
1804
|
+
background: "rgb(32, 32, 36)",
|
|
1660
1805
|
border: "1px solid rgba(255, 255, 255, 0.1)",
|
|
1661
1806
|
borderRadius: 8,
|
|
1662
1807
|
padding: "4px 0",
|
|
1663
1808
|
boxShadow: "0 10px 30px rgba(0, 0, 0, 0.3)",
|
|
1664
|
-
backdropFilter: "blur(20px)",
|
|
1665
|
-
WebkitBackdropFilter: "blur(20px)",
|
|
1666
1809
|
zIndex: 1
|
|
1667
1810
|
},
|
|
1668
|
-
children: options.map((opt) => /* @__PURE__ */
|
|
1811
|
+
children: options.map((opt) => /* @__PURE__ */ jsx(
|
|
1669
1812
|
DropItem,
|
|
1670
1813
|
{
|
|
1671
1814
|
active: opt === value,
|
|
@@ -1684,8 +1827,8 @@ function ActionButton({
|
|
|
1684
1827
|
onClick,
|
|
1685
1828
|
disabled
|
|
1686
1829
|
}) {
|
|
1687
|
-
const [hovered, setHovered] =
|
|
1688
|
-
return /* @__PURE__ */
|
|
1830
|
+
const [hovered, setHovered] = useState2(false);
|
|
1831
|
+
return /* @__PURE__ */ jsx(
|
|
1689
1832
|
"button",
|
|
1690
1833
|
{
|
|
1691
1834
|
onClick,
|
|
@@ -1727,23 +1870,28 @@ function formatTimestamp(filename) {
|
|
|
1727
1870
|
}
|
|
1728
1871
|
|
|
1729
1872
|
// src/overlay/ui/inspector.tsx
|
|
1730
|
-
import { useEffect as
|
|
1731
|
-
import {
|
|
1873
|
+
import { useEffect as useEffect2, useRef as useRef2, useCallback as useCallback3, useState as useState3 } from "react";
|
|
1874
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
1732
1875
|
function Inspector({ onSelect, onCancel }) {
|
|
1733
|
-
const [highlight, setHighlight] =
|
|
1734
|
-
const hoveredEl =
|
|
1735
|
-
const styleEl =
|
|
1736
|
-
|
|
1876
|
+
const [highlight, setHighlight] = useState3(null);
|
|
1877
|
+
const hoveredEl = useRef2(null);
|
|
1878
|
+
const styleEl = useRef2(null);
|
|
1879
|
+
useEffect2(() => {
|
|
1737
1880
|
const style = document.createElement("style");
|
|
1738
1881
|
style.setAttribute("data-afterbefore", "true");
|
|
1739
|
-
style.textContent =
|
|
1882
|
+
style.textContent = [
|
|
1883
|
+
"* { cursor: crosshair !important; }",
|
|
1884
|
+
"[data-afterbefore], [data-afterbefore] * { cursor: auto !important; }",
|
|
1885
|
+
"[data-afterbefore] button, [data-afterbefore] label, [data-afterbefore] a { cursor: pointer !important; }",
|
|
1886
|
+
"[data-afterbefore] input, [data-afterbefore] textarea { cursor: text !important; }"
|
|
1887
|
+
].join("\n");
|
|
1740
1888
|
document.head.appendChild(style);
|
|
1741
1889
|
styleEl.current = style;
|
|
1742
1890
|
return () => {
|
|
1743
1891
|
style.remove();
|
|
1744
1892
|
};
|
|
1745
1893
|
}, []);
|
|
1746
|
-
const isOverlayElement =
|
|
1894
|
+
const isOverlayElement = useCallback3((el) => {
|
|
1747
1895
|
let node = el;
|
|
1748
1896
|
while (node) {
|
|
1749
1897
|
if (node instanceof HTMLElement && node.dataset.afterbefore) return true;
|
|
@@ -1751,7 +1899,7 @@ function Inspector({ onSelect, onCancel }) {
|
|
|
1751
1899
|
}
|
|
1752
1900
|
return false;
|
|
1753
1901
|
}, []);
|
|
1754
|
-
const handleMouseMove =
|
|
1902
|
+
const handleMouseMove = useCallback3(
|
|
1755
1903
|
(e) => {
|
|
1756
1904
|
const el = document.elementFromPoint(e.clientX, e.clientY);
|
|
1757
1905
|
if (!el || !(el instanceof HTMLElement) || isOverlayElement(el)) {
|
|
@@ -1765,13 +1913,12 @@ function Inspector({ onSelect, onCancel }) {
|
|
|
1765
1913
|
x: rect.x,
|
|
1766
1914
|
y: rect.y,
|
|
1767
1915
|
width: rect.width,
|
|
1768
|
-
height: rect.height
|
|
1769
|
-
tag: el.tagName.toLowerCase() + (el.className && typeof el.className === "string" ? `.${el.className.split(" ")[0]}` : "")
|
|
1916
|
+
height: rect.height
|
|
1770
1917
|
});
|
|
1771
1918
|
},
|
|
1772
1919
|
[isOverlayElement]
|
|
1773
1920
|
);
|
|
1774
|
-
const handleClick =
|
|
1921
|
+
const handleClick = useCallback3(
|
|
1775
1922
|
(e) => {
|
|
1776
1923
|
if (isOverlayElement(e.target)) return;
|
|
1777
1924
|
e.preventDefault();
|
|
@@ -1783,7 +1930,7 @@ function Inspector({ onSelect, onCancel }) {
|
|
|
1783
1930
|
},
|
|
1784
1931
|
[onSelect, isOverlayElement]
|
|
1785
1932
|
);
|
|
1786
|
-
const handleKeyDown =
|
|
1933
|
+
const handleKeyDown = useCallback3(
|
|
1787
1934
|
(e) => {
|
|
1788
1935
|
if (e.key === "Escape") {
|
|
1789
1936
|
onCancel();
|
|
@@ -1791,7 +1938,7 @@ function Inspector({ onSelect, onCancel }) {
|
|
|
1791
1938
|
},
|
|
1792
1939
|
[onCancel]
|
|
1793
1940
|
);
|
|
1794
|
-
|
|
1941
|
+
useEffect2(() => {
|
|
1795
1942
|
document.addEventListener("mousemove", handleMouseMove, true);
|
|
1796
1943
|
document.addEventListener("click", handleClick, true);
|
|
1797
1944
|
document.addEventListener("keydown", handleKeyDown);
|
|
@@ -1801,48 +1948,27 @@ function Inspector({ onSelect, onCancel }) {
|
|
|
1801
1948
|
document.removeEventListener("keydown", handleKeyDown);
|
|
1802
1949
|
};
|
|
1803
1950
|
}, [handleMouseMove, handleClick, handleKeyDown]);
|
|
1804
|
-
return /* @__PURE__ */
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
{
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
}
|
|
1819
|
-
}
|
|
1820
|
-
),
|
|
1821
|
-
/* @__PURE__ */ jsx4(
|
|
1822
|
-
"div",
|
|
1823
|
-
{
|
|
1824
|
-
style: {
|
|
1825
|
-
position: "fixed",
|
|
1826
|
-
left: highlight.x,
|
|
1827
|
-
top: Math.max(0, highlight.y - 24),
|
|
1828
|
-
background: "rgba(59, 130, 246, 0.9)",
|
|
1829
|
-
color: "#fff",
|
|
1830
|
-
fontSize: 11,
|
|
1831
|
-
fontFamily: "system-ui, -apple-system, monospace",
|
|
1832
|
-
padding: "2px 6px",
|
|
1833
|
-
borderRadius: 3,
|
|
1834
|
-
pointerEvents: "none",
|
|
1835
|
-
whiteSpace: "nowrap",
|
|
1836
|
-
lineHeight: "18px"
|
|
1837
|
-
},
|
|
1838
|
-
children: highlight.tag
|
|
1951
|
+
return /* @__PURE__ */ jsx2("div", { "data-afterbefore": "true", style: { position: "fixed", inset: 0, zIndex: 2147483646, pointerEvents: "none" }, children: highlight && /* @__PURE__ */ jsx2(
|
|
1952
|
+
"div",
|
|
1953
|
+
{
|
|
1954
|
+
style: {
|
|
1955
|
+
position: "fixed",
|
|
1956
|
+
left: highlight.x,
|
|
1957
|
+
top: highlight.y,
|
|
1958
|
+
width: highlight.width,
|
|
1959
|
+
height: highlight.height,
|
|
1960
|
+
background: "transparent",
|
|
1961
|
+
border: "1px solid #fff",
|
|
1962
|
+
borderRadius: 2,
|
|
1963
|
+
boxShadow: "0 0 0 9999px rgba(0, 0, 0, 0.5)",
|
|
1964
|
+
pointerEvents: "none"
|
|
1839
1965
|
}
|
|
1840
|
-
|
|
1841
|
-
|
|
1966
|
+
}
|
|
1967
|
+
) });
|
|
1842
1968
|
}
|
|
1843
1969
|
|
|
1844
1970
|
// src/overlay/index.tsx
|
|
1845
|
-
import { jsx as
|
|
1971
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1846
1972
|
async function saveCapture(mode, dataUrl) {
|
|
1847
1973
|
try {
|
|
1848
1974
|
const res = await fetch("/__afterbefore/save", {
|
|
@@ -1860,13 +1986,12 @@ async function saveCapture(mode, dataUrl) {
|
|
|
1860
1986
|
}
|
|
1861
1987
|
function AfterBefore() {
|
|
1862
1988
|
const { state, captureComplete, reset } = useOverlayState();
|
|
1863
|
-
const [toolbarActive, setToolbarActive] =
|
|
1864
|
-
const [inspectorActive, setInspectorActive] =
|
|
1865
|
-
const [loading, setLoading] =
|
|
1866
|
-
const [selectedMode, setSelectedMode] =
|
|
1867
|
-
const [frameSettings, setFrameSettings] =
|
|
1868
|
-
|
|
1869
|
-
useEffect4(() => {
|
|
1989
|
+
const [toolbarActive, setToolbarActive] = useState4(false);
|
|
1990
|
+
const [inspectorActive, setInspectorActive] = useState4(false);
|
|
1991
|
+
const [loading, setLoading] = useState4(false);
|
|
1992
|
+
const [selectedMode, setSelectedMode] = useState4("component");
|
|
1993
|
+
const [frameSettings, setFrameSettings] = useState4(DEFAULT_FRAME_SETTINGS);
|
|
1994
|
+
useEffect3(() => {
|
|
1870
1995
|
try {
|
|
1871
1996
|
const stored = localStorage.getItem("ab-frame-settings");
|
|
1872
1997
|
if (stored) {
|
|
@@ -1881,7 +2006,7 @@ function AfterBefore() {
|
|
|
1881
2006
|
setFrameSettings(DEFAULT_FRAME_SETTINGS);
|
|
1882
2007
|
}
|
|
1883
2008
|
}, []);
|
|
1884
|
-
|
|
2009
|
+
useEffect3(() => {
|
|
1885
2010
|
if (state.phase === "ready") {
|
|
1886
2011
|
const timer = setTimeout(() => {
|
|
1887
2012
|
reset();
|
|
@@ -1889,13 +2014,7 @@ function AfterBefore() {
|
|
|
1889
2014
|
return () => clearTimeout(timer);
|
|
1890
2015
|
}
|
|
1891
2016
|
}, [state.phase, reset]);
|
|
1892
|
-
const
|
|
1893
|
-
(pos) => {
|
|
1894
|
-
iconPos.current = pos;
|
|
1895
|
-
},
|
|
1896
|
-
[]
|
|
1897
|
-
);
|
|
1898
|
-
const handleIconClick = useCallback5(() => {
|
|
2017
|
+
const handleToggle = useCallback4(() => {
|
|
1899
2018
|
if (loading) return;
|
|
1900
2019
|
if (state.phase === "ready") {
|
|
1901
2020
|
reset();
|
|
@@ -1913,7 +2032,7 @@ function AfterBefore() {
|
|
|
1913
2032
|
}
|
|
1914
2033
|
}
|
|
1915
2034
|
}, [state.phase, loading, toolbarActive, inspectorActive, selectedMode, reset]);
|
|
1916
|
-
const performCapture =
|
|
2035
|
+
const performCapture = useCallback4(
|
|
1917
2036
|
async (mode, element) => {
|
|
1918
2037
|
setLoading(true);
|
|
1919
2038
|
try {
|
|
@@ -1932,7 +2051,7 @@ function AfterBefore() {
|
|
|
1932
2051
|
},
|
|
1933
2052
|
[captureComplete, frameSettings]
|
|
1934
2053
|
);
|
|
1935
|
-
const handleToolbarCapture =
|
|
2054
|
+
const handleToolbarCapture = useCallback4(
|
|
1936
2055
|
(mode) => {
|
|
1937
2056
|
if (mode === "viewport") {
|
|
1938
2057
|
setToolbarActive(false);
|
|
@@ -1946,10 +2065,11 @@ function AfterBefore() {
|
|
|
1946
2065
|
},
|
|
1947
2066
|
[performCapture]
|
|
1948
2067
|
);
|
|
1949
|
-
const handleToolbarCancel =
|
|
2068
|
+
const handleToolbarCancel = useCallback4(() => {
|
|
1950
2069
|
setToolbarActive(false);
|
|
2070
|
+
setInspectorActive(false);
|
|
1951
2071
|
}, []);
|
|
1952
|
-
const handleComponentSelect =
|
|
2072
|
+
const handleComponentSelect = useCallback4(
|
|
1953
2073
|
(element) => {
|
|
1954
2074
|
setInspectorActive(false);
|
|
1955
2075
|
setToolbarActive(false);
|
|
@@ -1957,41 +2077,29 @@ function AfterBefore() {
|
|
|
1957
2077
|
},
|
|
1958
2078
|
[performCapture]
|
|
1959
2079
|
);
|
|
1960
|
-
const handleComponentCancel =
|
|
2080
|
+
const handleComponentCancel = useCallback4(() => {
|
|
1961
2081
|
setInspectorActive(false);
|
|
1962
2082
|
setToolbarActive(true);
|
|
1963
2083
|
}, []);
|
|
1964
|
-
const handleFrameSettingsChange =
|
|
2084
|
+
const handleFrameSettingsChange = useCallback4((next) => {
|
|
1965
2085
|
setFrameSettings(next);
|
|
1966
2086
|
try {
|
|
1967
2087
|
localStorage.setItem("ab-frame-settings", JSON.stringify(next));
|
|
1968
2088
|
} catch {
|
|
1969
2089
|
}
|
|
1970
2090
|
}, []);
|
|
1971
|
-
const handleModeChange =
|
|
2091
|
+
const handleModeChange = useCallback4((mode) => {
|
|
1972
2092
|
setSelectedMode(mode);
|
|
1973
2093
|
setInspectorActive(mode === "component");
|
|
1974
2094
|
}, []);
|
|
1975
|
-
return /* @__PURE__ */
|
|
1976
|
-
/* @__PURE__ */
|
|
1977
|
-
|
|
2095
|
+
return /* @__PURE__ */ jsxs2("div", { "data-afterbefore": "true", children: [
|
|
2096
|
+
/* @__PURE__ */ jsx3(
|
|
2097
|
+
Toolbar,
|
|
1978
2098
|
{
|
|
2099
|
+
expanded: toolbarActive,
|
|
2100
|
+
onToggle: handleToggle,
|
|
1979
2101
|
phase: state.phase,
|
|
1980
|
-
onClick: handleIconClick,
|
|
1981
2102
|
loading,
|
|
1982
|
-
onPositionChange: handlePositionChange
|
|
1983
|
-
}
|
|
1984
|
-
),
|
|
1985
|
-
toolbarActive && !inspectorActive && !loading && /* @__PURE__ */ jsx5(
|
|
1986
|
-
CapturePreview,
|
|
1987
|
-
{
|
|
1988
|
-
mode: selectedMode,
|
|
1989
|
-
onClick: () => handleToolbarCapture(selectedMode)
|
|
1990
|
-
}
|
|
1991
|
-
),
|
|
1992
|
-
toolbarActive && /* @__PURE__ */ jsx5(
|
|
1993
|
-
Toolbar,
|
|
1994
|
-
{
|
|
1995
2103
|
selectedMode,
|
|
1996
2104
|
onModeChange: handleModeChange,
|
|
1997
2105
|
onCapture: handleToolbarCapture,
|
|
@@ -2000,7 +2108,7 @@ function AfterBefore() {
|
|
|
2000
2108
|
onFrameSettingsChange: handleFrameSettingsChange
|
|
2001
2109
|
}
|
|
2002
2110
|
),
|
|
2003
|
-
inspectorActive && /* @__PURE__ */
|
|
2111
|
+
inspectorActive && /* @__PURE__ */ jsx3(Inspector, { onSelect: handleComponentSelect, onCancel: handleComponentCancel })
|
|
2004
2112
|
] });
|
|
2005
2113
|
}
|
|
2006
2114
|
export {
|