@satanwagen/reviewkit 0.1.2 → 0.1.3
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/CHANGELOG.md +105 -0
- package/README.md +134 -63
- package/dist/activate.cjs +150 -0
- package/dist/activate.cjs.map +1 -0
- package/dist/activate.d.cts +59 -0
- package/dist/activate.d.ts +59 -0
- package/dist/activate.js +21 -0
- package/dist/activate.js.map +1 -0
- package/dist/{chunk-4YNLMSCK.js → chunk-DG6O5XIC.js} +36 -10
- package/dist/chunk-DG6O5XIC.js.map +1 -0
- package/dist/chunk-ETAGGIDN.js +119 -0
- package/dist/chunk-ETAGGIDN.js.map +1 -0
- package/dist/{chunk-YWBFAV57.js → chunk-NSXRFM75.js} +853 -1544
- package/dist/chunk-NSXRFM75.js.map +1 -0
- package/dist/chunk-Q7U43PXE.js +36 -0
- package/dist/chunk-Q7U43PXE.js.map +1 -0
- package/dist/client/index.cjs +4530 -4237
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.js +49 -3
- package/dist/client/index.js.map +1 -1
- package/dist/effects-EWKHKUDP.js +851 -0
- package/dist/effects-EWKHKUDP.js.map +1 -0
- package/dist/index-BUSmAweg.d.ts +77 -0
- package/dist/index-Dl2Fl0qr.d.cts +77 -0
- package/dist/index.cjs +4544 -4256
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +35 -3
- package/dist/index.js.map +1 -1
- package/dist/lazy.cjs +8988 -0
- package/dist/lazy.cjs.map +1 -0
- package/dist/lazy.d.cts +7 -0
- package/dist/lazy.d.ts +7 -0
- package/dist/lazy.js +8 -0
- package/dist/lazy.js.map +1 -0
- package/dist/next.cjs +8989 -0
- package/dist/next.cjs.map +1 -0
- package/dist/next.d.cts +4 -0
- package/dist/next.d.ts +4 -0
- package/dist/next.js +9 -0
- package/dist/next.js.map +1 -0
- package/dist/schema.cjs +53 -16
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.cts +20 -5
- package/dist/schema.d.ts +20 -5
- package/dist/schema.js +30 -2
- package/dist/schema.js.map +1 -1
- package/package.json +21 -8
- package/cli/emblema-sync.mjs +0 -675
- package/dist/chunk-4YNLMSCK.js.map +0 -1
- package/dist/chunk-YWBFAV57.js.map +0 -1
- package/dist/index-BbucFgZi.d.ts +0 -49
- package/dist/index-CBlJrKkm.d.cts +0 -49
|
@@ -1,7 +1,30 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import {
|
|
2
|
+
ITEM_STATUSES,
|
|
3
|
+
SCHEMA_VERSION,
|
|
4
|
+
fetchSyncKey,
|
|
5
|
+
fetchSyncState,
|
|
6
|
+
generateSyncKey,
|
|
7
|
+
isCommentItem,
|
|
8
|
+
isCopyItem,
|
|
9
|
+
isDeleteItem,
|
|
10
|
+
isImageItem,
|
|
11
|
+
isKnownItemType,
|
|
12
|
+
isMoveItem,
|
|
13
|
+
isStyleItem,
|
|
14
|
+
parseSession,
|
|
15
|
+
parseSessionJson,
|
|
16
|
+
pingEmblema,
|
|
17
|
+
revokeSyncKey,
|
|
18
|
+
sendToEmblema
|
|
19
|
+
} from "./chunk-DG6O5XIC.js";
|
|
20
|
+
import {
|
|
21
|
+
clearSticky,
|
|
22
|
+
isLocalHost,
|
|
23
|
+
isStickyEnabled,
|
|
24
|
+
reviewParam,
|
|
25
|
+
setSticky,
|
|
26
|
+
shouldActivate
|
|
27
|
+
} from "./chunk-ETAGGIDN.js";
|
|
5
28
|
|
|
6
29
|
// src/client/target.ts
|
|
7
30
|
var HOST_ATTR = "data-review-kit-host";
|
|
@@ -316,19 +339,14 @@ function importSessionFile(file) {
|
|
|
316
339
|
});
|
|
317
340
|
}
|
|
318
341
|
|
|
342
|
+
// src/client/ReviewKit.tsx
|
|
343
|
+
import { useEffect as useEffect17, useState as useState13 } from "react";
|
|
344
|
+
import { createPortal } from "react-dom";
|
|
345
|
+
|
|
319
346
|
// src/client/env.ts
|
|
320
|
-
var STICKY_KEY = "review-kit:sticky";
|
|
321
347
|
var LEGACY_SESSION_KEY = "review-kit:active";
|
|
322
348
|
var LEGACY_LOCAL_FLAG = "reviewkit";
|
|
323
|
-
var STICKY_TTL_MS = 4 * 60 * 60 * 1e3;
|
|
324
349
|
var DEACTIVATE_EVENT = "review-kit:deactivate";
|
|
325
|
-
function isDevBuild() {
|
|
326
|
-
try {
|
|
327
|
-
return process.env.NODE_ENV === "development";
|
|
328
|
-
} catch {
|
|
329
|
-
return false;
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
350
|
function safeRemove(storage, key) {
|
|
333
351
|
try {
|
|
334
352
|
storage().removeItem(key);
|
|
@@ -339,40 +357,8 @@ function clearLegacyKeys() {
|
|
|
339
357
|
safeRemove(() => window.sessionStorage, LEGACY_SESSION_KEY);
|
|
340
358
|
safeRemove(() => window.localStorage, LEGACY_LOCAL_FLAG);
|
|
341
359
|
}
|
|
342
|
-
function readSticky() {
|
|
343
|
-
try {
|
|
344
|
-
const raw = window.sessionStorage.getItem(STICKY_KEY);
|
|
345
|
-
if (!raw) return null;
|
|
346
|
-
const parsed = JSON.parse(raw);
|
|
347
|
-
if (typeof parsed === "object" && parsed !== null && typeof parsed.token === "string" && typeof parsed.until === "number") {
|
|
348
|
-
return parsed;
|
|
349
|
-
}
|
|
350
|
-
} catch {
|
|
351
|
-
}
|
|
352
|
-
return null;
|
|
353
|
-
}
|
|
354
|
-
function isStickyEnabled(token) {
|
|
355
|
-
const sticky = readSticky();
|
|
356
|
-
if (!sticky) return false;
|
|
357
|
-
if (sticky.until < Date.now() || sticky.token !== (token ?? "")) {
|
|
358
|
-
safeRemove(() => window.sessionStorage, STICKY_KEY);
|
|
359
|
-
return false;
|
|
360
|
-
}
|
|
361
|
-
return true;
|
|
362
|
-
}
|
|
363
|
-
function setSticky(token, on) {
|
|
364
|
-
try {
|
|
365
|
-
if (on) {
|
|
366
|
-
const value = { token: token ?? "", until: Date.now() + STICKY_TTL_MS };
|
|
367
|
-
window.sessionStorage.setItem(STICKY_KEY, JSON.stringify(value));
|
|
368
|
-
} else {
|
|
369
|
-
window.sessionStorage.removeItem(STICKY_KEY);
|
|
370
|
-
}
|
|
371
|
-
} catch {
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
360
|
function deactivateReview() {
|
|
375
|
-
|
|
361
|
+
clearSticky();
|
|
376
362
|
clearLegacyKeys();
|
|
377
363
|
try {
|
|
378
364
|
const url = new URL(window.location.href);
|
|
@@ -387,67 +373,24 @@ function deactivateReview() {
|
|
|
387
373
|
} catch {
|
|
388
374
|
}
|
|
389
375
|
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
let host = "";
|
|
393
|
-
try {
|
|
394
|
-
host = window.location.hostname.toLowerCase();
|
|
395
|
-
} catch {
|
|
396
|
-
return false;
|
|
397
|
-
}
|
|
398
|
-
return allowedHosts.some((pattern) => {
|
|
399
|
-
const regex = new RegExp(
|
|
400
|
-
"^" + pattern.toLowerCase().split("*").map((part) => part.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join(".*") + "$"
|
|
401
|
-
);
|
|
402
|
-
return regex.test(host);
|
|
403
|
-
});
|
|
404
|
-
}
|
|
405
|
-
function resolveActivation(token) {
|
|
376
|
+
var warnedNoAllowlist = false;
|
|
377
|
+
function resolveActivation(options) {
|
|
406
378
|
if (typeof window === "undefined") return false;
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
if (tokenConfigured) {
|
|
420
|
-
if (param !== null && param !== "") {
|
|
421
|
-
if (param === token) {
|
|
422
|
-
setSticky(token, true);
|
|
423
|
-
return true;
|
|
424
|
-
}
|
|
425
|
-
console.warn("[review-kit] `?review` token does not match the configured token; staying inactive.");
|
|
426
|
-
return false;
|
|
427
|
-
}
|
|
428
|
-
if (isStickyEnabled(token)) {
|
|
429
|
-
setSticky(token, true);
|
|
430
|
-
return true;
|
|
379
|
+
clearLegacyKeys();
|
|
380
|
+
const active = shouldActivate(options);
|
|
381
|
+
if (!active) return false;
|
|
382
|
+
const token = options.token;
|
|
383
|
+
const param = reviewParam();
|
|
384
|
+
if (token !== void 0 && token !== "" && (param === token || isStickyEnabled(token))) {
|
|
385
|
+
setSticky(token, true);
|
|
386
|
+
if (param === token && !options.allowedHosts?.length && !isLocalHost() && !warnedNoAllowlist) {
|
|
387
|
+
warnedNoAllowlist = true;
|
|
388
|
+
console.warn(
|
|
389
|
+
"[review-kit] Review mode activated by URL token on a public hostname with no `allowedHosts`. For production pass `allowedHosts` next to `token` so the layer cannot be opened on hosts you did not intend."
|
|
390
|
+
);
|
|
431
391
|
}
|
|
432
|
-
clearLegacyKeys();
|
|
433
|
-
return false;
|
|
434
392
|
}
|
|
435
|
-
|
|
436
|
-
console.warn(
|
|
437
|
-
"[review-kit] Activated via `?review` with no token configured. Pass a `token` prop to <ReviewKit /> to restrict who can open review mode."
|
|
438
|
-
);
|
|
439
|
-
setSticky(void 0, true);
|
|
440
|
-
return true;
|
|
441
|
-
}
|
|
442
|
-
if (isStickyEnabled(void 0)) {
|
|
443
|
-
setSticky(void 0, true);
|
|
444
|
-
return true;
|
|
445
|
-
}
|
|
446
|
-
try {
|
|
447
|
-
if (window.localStorage.getItem(LEGACY_LOCAL_FLAG) !== null) return true;
|
|
448
|
-
} catch {
|
|
449
|
-
}
|
|
450
|
-
return isDevBuild();
|
|
393
|
+
return true;
|
|
451
394
|
}
|
|
452
395
|
var FOCUS_KEY = "review-kit:focus";
|
|
453
396
|
function rememberFocusItem(id) {
|
|
@@ -1295,6 +1238,7 @@ input, textarea, select {
|
|
|
1295
1238
|
.rk-epush-ok .rk-sync-dot { background: var(--rk-success); }
|
|
1296
1239
|
.rk-epush-sending .rk-sync-dot { background: var(--rk-warn); }
|
|
1297
1240
|
.rk-epush-offline .rk-sync-dot { background: var(--rk-fg-faint); }
|
|
1241
|
+
.rk-epush-rejected .rk-sync-dot { background: var(--rk-danger, #d33); }
|
|
1298
1242
|
|
|
1299
1243
|
/* ---------------------------------------------------------------- */
|
|
1300
1244
|
/* Floating editor cards */
|
|
@@ -2280,6 +2224,9 @@ input, textarea, select {
|
|
|
2280
2224
|
`;
|
|
2281
2225
|
}
|
|
2282
2226
|
|
|
2227
|
+
// src/client/store.tsx
|
|
2228
|
+
import { createContext, useContext, useMemo, useReducer } from "react";
|
|
2229
|
+
|
|
2283
2230
|
// src/client/id.ts
|
|
2284
2231
|
function rkId() {
|
|
2285
2232
|
const time = Date.now().toString(36);
|
|
@@ -2295,6 +2242,9 @@ function rkId() {
|
|
|
2295
2242
|
}
|
|
2296
2243
|
return `rk-${time}-${rand}`;
|
|
2297
2244
|
}
|
|
2245
|
+
|
|
2246
|
+
// src/client/store.tsx
|
|
2247
|
+
import { jsx } from "react/jsx-runtime";
|
|
2298
2248
|
function itemMatchesFilter(item, filter) {
|
|
2299
2249
|
if (!filter) return true;
|
|
2300
2250
|
if (filter.types.length > 0 && !filter.types.includes(item.type)) return false;
|
|
@@ -2617,7 +2567,7 @@ function StoreProvider({ config, children }) {
|
|
|
2617
2567
|
const configValue = useMemo(
|
|
2618
2568
|
() => config,
|
|
2619
2569
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- config object identity is per-render; depend on its fields
|
|
2620
|
-
[config.token, config.syncToken, config.syncUrl, config.defaultAuthor, config.position, config.storageKey, config.onSessionChange, config.emblema]
|
|
2570
|
+
[config.enabled, config.token, config.devAutoOn, config.syncToken, config.syncUrl, config.defaultAuthor, config.fxAssetsUrl, config.position, config.storageKey, config.onSessionChange, config.emblema]
|
|
2621
2571
|
);
|
|
2622
2572
|
return /* @__PURE__ */ jsx(ConfigContext.Provider, { value: configValue, children: /* @__PURE__ */ jsx(StateContext.Provider, { value: state, children: /* @__PURE__ */ jsx(DispatchContext.Provider, { value: dispatch, children }) }) });
|
|
2623
2573
|
}
|
|
@@ -2645,6 +2595,9 @@ function toast(dispatch, message, tone = "info") {
|
|
|
2645
2595
|
dispatch({ type: "PUSH_TOAST", toast: { id: rkId(), message, tone } });
|
|
2646
2596
|
}
|
|
2647
2597
|
|
|
2598
|
+
// src/client/App.tsx
|
|
2599
|
+
import { useEffect as useEffect16, useRef as useRef16 } from "react";
|
|
2600
|
+
|
|
2648
2601
|
// src/client/persist.ts
|
|
2649
2602
|
var DB_NAME = "review-kit";
|
|
2650
2603
|
var STORE = "sessions";
|
|
@@ -2771,6 +2724,9 @@ async function revealTarget(target) {
|
|
|
2771
2724
|
const el = resolveTarget(target)?.element ?? null;
|
|
2772
2725
|
return el && isElementVisible(el) ? "revealed" : "failed";
|
|
2773
2726
|
}
|
|
2727
|
+
|
|
2728
|
+
// src/client/preview.ts
|
|
2729
|
+
import { useEffect, useRef } from "react";
|
|
2774
2730
|
var EDITED_ATTR = "data-rk-edited";
|
|
2775
2731
|
var STYLE_ID = "rk-preview-style";
|
|
2776
2732
|
var RESCHEDULE_MS = 180;
|
|
@@ -2989,836 +2945,91 @@ function useAppliedPreview(state, dispatch) {
|
|
|
2989
2945
|
}, []);
|
|
2990
2946
|
}
|
|
2991
2947
|
|
|
2992
|
-
// src/client/
|
|
2993
|
-
var
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
particle.textContent = spec.glyphs[i % spec.glyphs.length];
|
|
3023
|
-
const delay = i / count * duration * 0.4;
|
|
3024
|
-
const life = duration * (0.45 + 0.35 * (i * 7 % 10) / 10);
|
|
3025
|
-
particle.style.fontSize = `${14 + i * 13 % 18}px`;
|
|
3026
|
-
if (spec.kind === "rain") {
|
|
3027
|
-
const x = i * 61 % 100 / 100 * vw;
|
|
3028
|
-
const sway = i * 31 % 60 - 30 | 0;
|
|
3029
|
-
particle.style.setProperty("--fx-x0", `${x}px`);
|
|
3030
|
-
particle.style.setProperty("--fx-x1", `${x + sway}px`);
|
|
3031
|
-
particle.style.setProperty("--fx-y0", `-40px`);
|
|
3032
|
-
particle.style.setProperty("--fx-y1", `${vh + 40}px`);
|
|
3033
|
-
} else {
|
|
3034
|
-
const angle = i / count * Math.PI * 2;
|
|
3035
|
-
const radius = 120 + i * 47 % 240;
|
|
3036
|
-
particle.style.setProperty("--fx-x0", `${vw / 2}px`);
|
|
3037
|
-
particle.style.setProperty("--fx-y0", `${vh / 2}px`);
|
|
3038
|
-
particle.style.setProperty("--fx-x1", `${vw / 2 + Math.cos(angle) * radius}px`);
|
|
3039
|
-
particle.style.setProperty("--fx-y1", `${vh / 2 + Math.sin(angle) * radius + vh * 0.4}px`);
|
|
3040
|
-
}
|
|
3041
|
-
particle.style.animation = `rk-fx-fall ${reduced ? life * 0.8 : life}ms linear ${delay}ms both`;
|
|
3042
|
-
layer.appendChild(particle);
|
|
3043
|
-
}
|
|
3044
|
-
}
|
|
3045
|
-
function runShake() {
|
|
3046
|
-
const prev = document.body.style.animation;
|
|
3047
|
-
let styleTag = document.getElementById("rk-fx-shake-style");
|
|
3048
|
-
if (!styleTag) {
|
|
3049
|
-
styleTag = document.createElement("style");
|
|
3050
|
-
styleTag.id = "rk-fx-shake-style";
|
|
3051
|
-
styleTag.textContent = "@keyframes rk-fx-shake { 0%,100% { transform: translate(0,0); } 25% { transform: translate(-5px,3px); } 50% { transform: translate(4px,-4px); } 75% { transform: translate(-3px,-2px); } }";
|
|
3052
|
-
document.head.appendChild(styleTag);
|
|
3053
|
-
}
|
|
3054
|
-
document.body.style.animation = "rk-fx-shake 260ms ease-in-out 6";
|
|
3055
|
-
let done = false;
|
|
3056
|
-
const restore2 = () => {
|
|
3057
|
-
if (done) return;
|
|
3058
|
-
done = true;
|
|
3059
|
-
document.body.style.animation = prev;
|
|
3060
|
-
if (document.body.getAttribute("style") === "") document.body.removeAttribute("style");
|
|
3061
|
-
};
|
|
3062
|
-
window.setTimeout(restore2, 1700);
|
|
3063
|
-
return restore2;
|
|
3064
|
-
}
|
|
3065
|
-
function startOndro({ layer, reduced }) {
|
|
3066
|
-
const cleanups = [];
|
|
3067
|
-
const timers = [];
|
|
3068
|
-
const intervals = [];
|
|
3069
|
-
const later = (fn, ms) => timers.push(window.setTimeout(fn, ms));
|
|
3070
|
-
const every = (fn, ms) => intervals.push(window.setInterval(fn, ms));
|
|
3071
|
-
cleanups.push(() => {
|
|
3072
|
-
timers.forEach((t) => window.clearTimeout(t));
|
|
3073
|
-
intervals.forEach((t) => window.clearInterval(t));
|
|
3074
|
-
});
|
|
3075
|
-
const addStyle = (css) => {
|
|
3076
|
-
const style = document.createElement("style");
|
|
3077
|
-
style.setAttribute("data-rk-fx", "ondro");
|
|
3078
|
-
style.textContent = css;
|
|
3079
|
-
document.head.appendChild(style);
|
|
3080
|
-
cleanups.push(() => style.remove());
|
|
3081
|
-
return style;
|
|
3082
|
-
};
|
|
3083
|
-
const wave = (spec) => {
|
|
3084
|
-
const sub = document.createElement("div");
|
|
3085
|
-
sub.className = "rk-fx-layer";
|
|
3086
|
-
layer.appendChild(sub);
|
|
3087
|
-
spawnParticles(sub, spec, reduced, spec.durationMs);
|
|
3088
|
-
const t = window.setTimeout(() => sub.remove(), spec.durationMs + 1600);
|
|
3089
|
-
timers.push(t);
|
|
3090
|
-
cleanups.push(() => sub.remove());
|
|
3091
|
-
};
|
|
3092
|
-
if (reduced) {
|
|
3093
|
-
addStyle(`@keyframes rk-ondro { 0% { filter: none; } 50% { filter: hue-rotate(40deg) saturate(1.15); } 100% { filter: none; } }
|
|
3094
|
-
${CHAOS_SEL} { animation: rk-ondro 8s ease-in-out infinite; }`);
|
|
3095
|
-
wave({ kind: "rain", glyphs: ["\u{1F92A}", "\u{1F4A5}", "\u{1F300}"], count: 8, durationMs: 8e3 });
|
|
3096
|
-
every(() => wave({ kind: "rain", glyphs: ["\u{1F92A}", "\u{1F300}"], count: 6, durationMs: 8e3 }), 15e3);
|
|
3097
|
-
} else {
|
|
3098
|
-
const scrollX = window.scrollX;
|
|
3099
|
-
const scrollY = window.scrollY;
|
|
3100
|
-
const htmlOverflow = document.documentElement.style.overflow;
|
|
3101
|
-
document.documentElement.style.overflow = "hidden";
|
|
3102
|
-
cleanups.push(() => {
|
|
3103
|
-
document.documentElement.style.overflow = htmlOverflow;
|
|
3104
|
-
if (document.documentElement.getAttribute("style") === "") document.documentElement.removeAttribute("style");
|
|
3105
|
-
window.scrollTo(scrollX, scrollY);
|
|
3106
|
-
});
|
|
3107
|
-
const originY = scrollY + window.innerHeight / 2;
|
|
3108
|
-
addStyle(`${CHAOS_SEL} { transform-origin: 50vw ${originY}px; }`);
|
|
3109
|
-
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
3110
|
-
svg.setAttribute("data-rk-fx", "ondro");
|
|
3111
|
-
svg.setAttribute("width", "0");
|
|
3112
|
-
svg.setAttribute("height", "0");
|
|
3113
|
-
svg.style.position = "absolute";
|
|
3114
|
-
svg.innerHTML = `<defs>
|
|
3115
|
-
<filter id="rk-ondro-warp" x="-10%" y="-10%" width="120%" height="120%">
|
|
3116
|
-
<feTurbulence type="turbulence" baseFrequency="0.004 0.017" numOctaves="2" result="n" seed="7">
|
|
3117
|
-
<animate attributeName="baseFrequency" dur="5.2s" values="0.004 0.017;0.013 0.005;0.004 0.017" repeatCount="indefinite"/>
|
|
3118
|
-
</feTurbulence>
|
|
3119
|
-
<feDisplacementMap in="SourceGraphic" in2="n" scale="14" xChannelSelector="R" yChannelSelector="G">
|
|
3120
|
-
<animate attributeName="scale" dur="4.4s" values="6;26;6" repeatCount="indefinite"/>
|
|
3121
|
-
</feDisplacementMap>
|
|
3122
|
-
</filter>
|
|
3123
|
-
<filter id="rk-ondro-ca" x="-5%" y="-5%" width="110%" height="110%">
|
|
3124
|
-
<feColorMatrix in="SourceGraphic" type="matrix" values="1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0" result="r"/>
|
|
3125
|
-
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0" result="g"/>
|
|
3126
|
-
<feColorMatrix in="SourceGraphic" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0" result="b"/>
|
|
3127
|
-
<feOffset in="r" dx="4" dy="0" result="ro"><animate attributeName="dx" dur="2.9s" values="1;6;1" repeatCount="indefinite"/></feOffset>
|
|
3128
|
-
<feOffset in="b" dx="-4" dy="1" result="bo"><animate attributeName="dx" dur="3.3s" values="-1;-6;-1" repeatCount="indefinite"/></feOffset>
|
|
3129
|
-
<feBlend in="ro" in2="g" mode="screen" result="rg"/>
|
|
3130
|
-
<feBlend in="rg" in2="bo" mode="screen"/>
|
|
3131
|
-
</filter>
|
|
3132
|
-
</defs>`;
|
|
3133
|
-
document.body.appendChild(svg);
|
|
3134
|
-
cleanups.push(() => svg.remove());
|
|
3135
|
-
addStyle(`@keyframes rk-ondro1 {
|
|
3136
|
-
0% { filter: none; transform: scale(1.22); }
|
|
3137
|
-
25% { filter: hue-rotate(120deg) saturate(1.9) blur(1.6px); transform: scale(1.238) rotate(1.4deg) translateX(6px); }
|
|
3138
|
-
50% { filter: hue-rotate(230deg) saturate(0.6) contrast(1.12) blur(0.6px); transform: scale(1.202) rotate(-1.2deg) translateY(5px); }
|
|
3139
|
-
75% { filter: hue-rotate(310deg) saturate(2.1) blur(2.6px); transform: scale(1.22) skewX(1.1deg) translateX(-7px); }
|
|
3140
|
-
100% { filter: hue-rotate(360deg); transform: scale(1.22); }
|
|
3141
|
-
}
|
|
3142
|
-
${CHAOS_SEL} { animation: rk-ondro1 2.6s ease-in-out infinite; }`);
|
|
3143
|
-
later(() => {
|
|
3144
|
-
addStyle(`@keyframes rk-ondro2 {
|
|
3145
|
-
0% { filter: url(#rk-ondro-warp) hue-rotate(0deg) saturate(1.3); transform: scale(1.22); }
|
|
3146
|
-
20% { filter: url(#rk-ondro-ca) hue-rotate(100deg) saturate(2.3) blur(3.4px); transform: scale(1.256) rotate(2.4deg) translate(12px, -6px); }
|
|
3147
|
-
45% { filter: url(#rk-ondro-warp) hue-rotate(190deg) saturate(0.45) contrast(1.2) blur(1.4px); transform: scale(1.19) rotate(-2.2deg) translate(-13px, 8px) skewY(1.2deg); }
|
|
3148
|
-
70% { filter: url(#rk-ondro-ca) hue-rotate(280deg) saturate(2.4) blur(4.6px); transform: scale(1.244) skewX(-1.8deg) translateY(-10px); }
|
|
3149
|
-
100% { filter: url(#rk-ondro-warp) hue-rotate(360deg) saturate(1.3); transform: scale(1.22); }
|
|
3150
|
-
}
|
|
3151
|
-
${CHAOS_SEL} { animation: rk-ondro2 2.2s ease-in-out infinite; }
|
|
3152
|
-
@keyframes rk-ondro-shake { 0%,100% { transform: translate(0,0); } 20% { transform: translate(-6px,4px); } 40% { transform: translate(5px,-5px); } 60% { transform: translate(-4px,-3px); } 80% { transform: translate(6px,3px); } }
|
|
3153
|
-
@keyframes rk-ondro-text {
|
|
3154
|
-
0%,100% { letter-spacing: normal; word-spacing: normal; text-shadow: none; }
|
|
3155
|
-
30% { letter-spacing: 0.12em; word-spacing: 0.3em; text-shadow: 4px 0 rgba(255,0,90,0.6), -4px 1px rgba(0,190,255,0.6); }
|
|
3156
|
-
60% { letter-spacing: -0.05em; word-spacing: -0.1em; text-shadow: -6px 0 rgba(255,0,90,0.55), 6px 2px rgba(0,190,255,0.55), 0 3px rgba(120,255,0,0.4); }
|
|
3157
|
-
80% { letter-spacing: 0.2em; text-shadow: 2px -2px rgba(255,0,90,0.65), -2px 2px rgba(0,190,255,0.65); }
|
|
3158
|
-
}
|
|
3159
|
-
h1, h2, h3, h4, p, a, li, button, span { animation: rk-ondro-text 3.1s ease-in-out infinite; }`);
|
|
3160
|
-
startTextDecay(cleanups, every);
|
|
3161
|
-
spawnGlitchBands(layer, cleanups);
|
|
3162
|
-
wave({ kind: "burst", glyphs: ["\u{1F4A5}", "\u{1F9E8}", "\u{1F525}", "\u{1F300}"], count: 34, durationMs: 5e3 });
|
|
3163
|
-
}, 6e3);
|
|
3164
|
-
later(() => {
|
|
3165
|
-
addStyle(`@keyframes rk-ondro3 {
|
|
3166
|
-
0% { filter: url(#rk-ondro-warp) hue-rotate(0deg) saturate(1.6) invert(0); transform: scale(1.22); }
|
|
3167
|
-
18% { filter: url(#rk-ondro-ca) hue-rotate(140deg) saturate(2.5) blur(6px) invert(0.35); transform: scale(1.27) rotate(3.2deg) translate(20px, -12px); }
|
|
3168
|
-
38% { filter: url(#rk-ondro-warp) hue-rotate(220deg) saturate(0.4) blur(2px) invert(0.75); transform: scale(1.18) rotate(-3deg) translate(-22px, 12px) skewY(2deg); }
|
|
3169
|
-
58% { filter: url(#rk-ondro-ca) hue-rotate(300deg) saturate(2.2) blur(7px) invert(0.3); transform: scale(1.25) skewX(2.4deg) translateY(-16px); }
|
|
3170
|
-
80% { filter: url(#rk-ondro-warp) hue-rotate(340deg) saturate(1.8) blur(3px) invert(0.05); transform: scale(1.23) rotate(1.6deg) translate(14px, 6px); }
|
|
3171
|
-
100% { filter: url(#rk-ondro-warp) hue-rotate(360deg) saturate(1.6) invert(0); transform: scale(1.22); }
|
|
3172
|
-
}
|
|
3173
|
-
${CHAOS_SEL} { animation: rk-ondro3 4s ease-in-out infinite; }
|
|
3174
|
-
@keyframes rk-ondro-shake3 { 0%,100% { transform: translate(0,0) rotate(0); } 25% { transform: translate(-9px,6px) rotate(-0.4deg); } 50% { transform: translate(8px,-8px) rotate(0.5deg); } 75% { transform: translate(-7px,-5px) rotate(-0.3deg); } }
|
|
3175
|
-
body { animation: rk-ondro-shake3 620ms ease-in-out infinite; }`);
|
|
3176
|
-
wave({ kind: "rain", glyphs: ["\u{1F92F}", "\u{1F480}", "\u{1F9E0}", "\u26A1\uFE0F", "\u{1FAE0}", "\u{1F529}"], count: 60, durationMs: 7e3 });
|
|
3177
|
-
}, 13e3);
|
|
3178
|
-
wave({ kind: "rain", glyphs: ["\u{1F92A}", "\u{1F4A5}", "\u{1F300}", "\u{1F9E0}", "\u26A1\uFE0F"], count: 40, durationMs: 12e3 });
|
|
3179
|
-
every(() => wave({ kind: "rain", glyphs: ["\u{1F92A}", "\u{1F4A5}", "\u{1F300}", "\u{1F9E0}", "\u26A1\uFE0F", "\u{1F355}", "\u{1F4C0}"], count: 30, durationMs: 9e3 }), 9500);
|
|
3180
|
-
every(() => spawnFallingLetters(layer), 12e3);
|
|
3181
|
-
later(() => spawnFallingLetters(layer), 7e3);
|
|
3182
|
-
}
|
|
3183
|
-
const audio = new Audio(`${FX_SOUND_BASE}/rick.mp3`);
|
|
3184
|
-
audio.volume = 0.8;
|
|
3185
|
-
audio.loop = true;
|
|
3186
|
-
cleanups.push(() => {
|
|
3187
|
-
audio.pause();
|
|
3188
|
-
audio.src = "";
|
|
3189
|
-
});
|
|
3190
|
-
audio.play().catch(() => {
|
|
3191
|
-
const chip = document.createElement("button");
|
|
3192
|
-
chip.className = "rk-fx-sound";
|
|
3193
|
-
chip.type = "button";
|
|
3194
|
-
chip.textContent = "\u{1F50A} klikni pre zvuk";
|
|
3195
|
-
chip.addEventListener("click", () => {
|
|
3196
|
-
audio.play().catch(() => void 0);
|
|
3197
|
-
chip.remove();
|
|
3198
|
-
});
|
|
3199
|
-
layer.appendChild(chip);
|
|
3200
|
-
cleanups.push(() => chip.remove());
|
|
3201
|
-
});
|
|
3202
|
-
installKillWord(cleanups);
|
|
3203
|
-
return () => {
|
|
3204
|
-
for (const fn of cleanups) fn();
|
|
3205
|
-
};
|
|
2948
|
+
// src/client/effectCatalog.ts
|
|
2949
|
+
var EFFECT_NAMES = [
|
|
2950
|
+
"ondro",
|
|
2951
|
+
"lava",
|
|
2952
|
+
"sklo",
|
|
2953
|
+
"vir",
|
|
2954
|
+
"crt",
|
|
2955
|
+
"hovno",
|
|
2956
|
+
"konfety",
|
|
2957
|
+
"srdiecka",
|
|
2958
|
+
"sneh",
|
|
2959
|
+
"zemetrasenie",
|
|
2960
|
+
"69",
|
|
2961
|
+
"kokot",
|
|
2962
|
+
"vrtule",
|
|
2963
|
+
"muchy",
|
|
2964
|
+
"pes",
|
|
2965
|
+
"pivo",
|
|
2966
|
+
"nikotin",
|
|
2967
|
+
"matrix",
|
|
2968
|
+
"disko",
|
|
2969
|
+
"zrkadlo",
|
|
2970
|
+
"pohreb",
|
|
2971
|
+
"laser",
|
|
2972
|
+
"kura",
|
|
2973
|
+
"spam"
|
|
2974
|
+
];
|
|
2975
|
+
var NAME_SET = new Set(EFFECT_NAMES);
|
|
2976
|
+
function isEffectCommand(name) {
|
|
2977
|
+
return name === "stop" || NAME_SET.has(name);
|
|
3206
2978
|
}
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
}
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
}
|
|
3227
|
-
function bigEffect(build) {
|
|
3228
|
-
return function start({ layer, reduced }) {
|
|
3229
|
-
const cleanups = [];
|
|
3230
|
-
const timers = [];
|
|
3231
|
-
const intervals = [];
|
|
3232
|
-
const later = (fn, ms) => timers.push(window.setTimeout(fn, ms));
|
|
3233
|
-
const every = (fn, ms) => intervals.push(window.setInterval(fn, ms));
|
|
3234
|
-
cleanups.push(() => {
|
|
3235
|
-
timers.forEach((t) => window.clearTimeout(t));
|
|
3236
|
-
intervals.forEach((t) => window.clearInterval(t));
|
|
3237
|
-
});
|
|
3238
|
-
const addStyle = (css) => {
|
|
3239
|
-
const style = document.createElement("style");
|
|
3240
|
-
style.setAttribute("data-rk-fx", "");
|
|
3241
|
-
style.textContent = css;
|
|
3242
|
-
document.head.appendChild(style);
|
|
3243
|
-
cleanups.push(() => style.remove());
|
|
3244
|
-
};
|
|
3245
|
-
const wave = (spec) => {
|
|
3246
|
-
const sub = document.createElement("div");
|
|
3247
|
-
sub.className = "rk-fx-layer";
|
|
3248
|
-
layer.appendChild(sub);
|
|
3249
|
-
spawnParticles(sub, spec, reduced, spec.durationMs);
|
|
3250
|
-
timers.push(window.setTimeout(() => sub.remove(), spec.durationMs + 1600));
|
|
3251
|
-
cleanups.push(() => sub.remove());
|
|
3252
|
-
};
|
|
3253
|
-
if (!reduced) {
|
|
3254
|
-
const scrollX = window.scrollX;
|
|
3255
|
-
const scrollY = window.scrollY;
|
|
3256
|
-
const htmlOverflow = document.documentElement.style.overflow;
|
|
3257
|
-
document.documentElement.style.overflow = "hidden";
|
|
3258
|
-
cleanups.push(() => {
|
|
3259
|
-
document.documentElement.style.overflow = htmlOverflow;
|
|
3260
|
-
if (document.documentElement.getAttribute("style") === "") document.documentElement.removeAttribute("style");
|
|
3261
|
-
window.scrollTo(scrollX, scrollY);
|
|
3262
|
-
});
|
|
3263
|
-
const originY = scrollY + window.innerHeight / 2;
|
|
3264
|
-
addStyle(`${CHAOS_SEL} { transform-origin: 50vw ${originY}px; }`);
|
|
3265
|
-
}
|
|
3266
|
-
build({
|
|
3267
|
-
layer,
|
|
3268
|
-
reduced,
|
|
3269
|
-
addStyle,
|
|
3270
|
-
later,
|
|
3271
|
-
every,
|
|
3272
|
-
wave,
|
|
3273
|
-
decayText: () => startTextDecay(cleanups, every),
|
|
3274
|
-
cleanups
|
|
2979
|
+
|
|
2980
|
+
// src/client/effectsLazy.ts
|
|
2981
|
+
var loaded = null;
|
|
2982
|
+
var loading = null;
|
|
2983
|
+
var broadcaster = null;
|
|
2984
|
+
var assetsUrl = null;
|
|
2985
|
+
var queued = 0;
|
|
2986
|
+
function load() {
|
|
2987
|
+
if (loaded) return Promise.resolve(loaded);
|
|
2988
|
+
if (!loading) {
|
|
2989
|
+
loading = import("./effects-EWKHKUDP.js").then((mod) => {
|
|
2990
|
+
loaded = mod;
|
|
2991
|
+
mod.setEffectBroadcaster(broadcaster);
|
|
2992
|
+
mod.setFxAssetsUrl(assetsUrl);
|
|
2993
|
+
return mod;
|
|
2994
|
+
}).catch((error) => {
|
|
2995
|
+
loading = null;
|
|
2996
|
+
queued = 0;
|
|
2997
|
+
throw error;
|
|
3275
2998
|
});
|
|
3276
|
-
installKillWord(cleanups);
|
|
3277
|
-
return () => {
|
|
3278
|
-
for (const fn of cleanups) fn();
|
|
3279
|
-
};
|
|
3280
|
-
};
|
|
3281
|
-
}
|
|
3282
|
-
function startTextDecay(cleanups, every) {
|
|
3283
|
-
const GLYPHS = "\u2593\u2592\u2591#@%&$?!\xD7\xD8\u2206\xA7";
|
|
3284
|
-
const originals = /* @__PURE__ */ new Map();
|
|
3285
|
-
const nodes = [];
|
|
3286
|
-
const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);
|
|
3287
|
-
let node;
|
|
3288
|
-
while ((node = walker.nextNode()) && nodes.length < 120) {
|
|
3289
|
-
const text = node;
|
|
3290
|
-
const value = text.nodeValue ?? "";
|
|
3291
|
-
if (value.trim().length < 4) continue;
|
|
3292
|
-
const parent = text.parentElement;
|
|
3293
|
-
if (!parent || parent.closest("[data-review-kit-host], script, style, [data-rk-edited]")) continue;
|
|
3294
|
-
nodes.push(text);
|
|
3295
2999
|
}
|
|
3296
|
-
|
|
3297
|
-
for (let i = 0; i < 22; i++) {
|
|
3298
|
-
const text = nodes[Math.random() * nodes.length | 0];
|
|
3299
|
-
if (!text || !text.isConnected) continue;
|
|
3300
|
-
if (!originals.has(text)) originals.set(text, text.nodeValue ?? "");
|
|
3301
|
-
const original = originals.get(text) ?? "";
|
|
3302
|
-
if (Math.random() < 0.3) {
|
|
3303
|
-
text.nodeValue = original;
|
|
3304
|
-
continue;
|
|
3305
|
-
}
|
|
3306
|
-
const chars = [...original];
|
|
3307
|
-
const swaps = 1 + (Math.random() * 3 | 0);
|
|
3308
|
-
for (let k = 0; k < swaps; k++) {
|
|
3309
|
-
const idx = Math.random() * chars.length | 0;
|
|
3310
|
-
if (chars[idx] !== " ") chars[idx] = GLYPHS[Math.random() * GLYPHS.length | 0];
|
|
3311
|
-
}
|
|
3312
|
-
text.nodeValue = chars.join("");
|
|
3313
|
-
}
|
|
3314
|
-
}, 260);
|
|
3315
|
-
cleanups.push(() => {
|
|
3316
|
-
for (const [text, value] of originals) {
|
|
3317
|
-
if (text.isConnected && text.nodeValue !== value) text.nodeValue = value;
|
|
3318
|
-
}
|
|
3319
|
-
originals.clear();
|
|
3320
|
-
});
|
|
3000
|
+
return loading;
|
|
3321
3001
|
}
|
|
3322
|
-
function
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
const r = el.getBoundingClientRect();
|
|
3328
|
-
return r.width > 0 && r.top < window.innerHeight && r.bottom > 0 && !el.closest("[data-review-kit-host]");
|
|
3329
|
-
});
|
|
3330
|
-
let spawned = 0;
|
|
3331
|
-
for (const heading of headings.slice(0, 3)) {
|
|
3332
|
-
const textNode = [...heading.childNodes].find((n) => n.nodeType === 3 && (n.nodeValue ?? "").trim().length > 3);
|
|
3333
|
-
const source = textNode ?? heading.firstChild;
|
|
3334
|
-
if (!source || source.nodeType !== 3) continue;
|
|
3335
|
-
const value = source.nodeValue ?? "";
|
|
3336
|
-
const range = document.createRange();
|
|
3337
|
-
for (let i = 0; i < value.length && spawned < 26; i++) {
|
|
3338
|
-
if (value[i] === " " || Math.random() < 0.55) continue;
|
|
3339
|
-
range.setStart(source, i);
|
|
3340
|
-
range.setEnd(source, i + 1);
|
|
3341
|
-
const rect = range.getBoundingClientRect();
|
|
3342
|
-
if (rect.width === 0) continue;
|
|
3343
|
-
const span = document.createElement("span");
|
|
3344
|
-
span.className = "rk-fx-letter";
|
|
3345
|
-
span.textContent = value[i];
|
|
3346
|
-
span.style.left = `${rect.left}px`;
|
|
3347
|
-
span.style.top = `${rect.top}px`;
|
|
3348
|
-
span.style.fontSize = `${rect.height}px`;
|
|
3349
|
-
span.style.animationDelay = `${Math.random() * 900 | 0}ms`;
|
|
3350
|
-
span.style.setProperty("--fx-drift", `${(Math.random() * 120 | 0) - 60}px`);
|
|
3351
|
-
sub.appendChild(span);
|
|
3352
|
-
spawned++;
|
|
3353
|
-
}
|
|
3354
|
-
}
|
|
3355
|
-
window.setTimeout(() => sub.remove(), 4600);
|
|
3356
|
-
}
|
|
3357
|
-
function spawnGlitchBands(layer, cleanups) {
|
|
3358
|
-
for (let i = 0; i < 3; i++) {
|
|
3359
|
-
const band = document.createElement("div");
|
|
3360
|
-
band.className = "rk-fx-band";
|
|
3361
|
-
band.style.height = `${34 + i * 16}px`;
|
|
3362
|
-
band.style.animationDuration = `${2.8 + i * 0.7}s`;
|
|
3363
|
-
band.style.animationDelay = `${i * 0.9}s`;
|
|
3364
|
-
layer.appendChild(band);
|
|
3365
|
-
cleanups.push(() => band.remove());
|
|
3366
|
-
}
|
|
3367
|
-
}
|
|
3368
|
-
var startLava = bigEffect(({ layer, reduced, addStyle, later, every, wave, decayText, cleanups }) => {
|
|
3369
|
-
if (reduced) {
|
|
3370
|
-
addStyle(`@keyframes rk-lava-soft { 0%,100% { filter: none; } 50% { filter: sepia(0.35) hue-rotate(-20deg) saturate(1.3); } }
|
|
3371
|
-
${CHAOS_SEL} { animation: rk-lava-soft 9s ease-in-out infinite; }`);
|
|
3372
|
-
wave({ kind: "rain", glyphs: ["\u{1FAE0}", "\u{1F525}"], count: 8, durationMs: 9e3 });
|
|
3373
|
-
every(() => wave({ kind: "rain", glyphs: ["\u{1FAE0}", "\u{1F4A7}"], count: 6, durationMs: 9e3 }), 14e3);
|
|
3374
|
-
return;
|
|
3375
|
-
}
|
|
3376
|
-
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
3377
|
-
svg.setAttribute("data-rk-fx", "");
|
|
3378
|
-
svg.setAttribute("width", "0");
|
|
3379
|
-
svg.setAttribute("height", "0");
|
|
3380
|
-
svg.style.position = "absolute";
|
|
3381
|
-
svg.innerHTML = `<defs><filter id="rk-lava-warp" x="-10%" y="-10%" width="120%" height="130%">
|
|
3382
|
-
<feTurbulence type="fractalNoise" baseFrequency="0.008 0.003" numOctaves="2" result="n" seed="4">
|
|
3383
|
-
<animate attributeName="baseFrequency" dur="7s" values="0.008 0.003;0.014 0.006;0.008 0.003" repeatCount="indefinite"/>
|
|
3384
|
-
</feTurbulence>
|
|
3385
|
-
<feDisplacementMap in="SourceGraphic" in2="n" scale="10" xChannelSelector="R" yChannelSelector="G">
|
|
3386
|
-
<animate attributeName="scale" dur="6s" values="4;24;4" repeatCount="indefinite"/>
|
|
3387
|
-
</feDisplacementMap>
|
|
3388
|
-
</filter></defs>`;
|
|
3389
|
-
document.body.appendChild(svg);
|
|
3390
|
-
cleanups.push(() => svg.remove());
|
|
3391
|
-
addStyle(`@keyframes rk-lava1 {
|
|
3392
|
-
0% { filter: none; transform: scale(1.22); }
|
|
3393
|
-
35% { filter: sepia(0.4) hue-rotate(-24deg) saturate(1.8) blur(0.8px); transform: scale(1.235) skewY(0.5deg) translateY(6px); }
|
|
3394
|
-
70% { filter: sepia(0.6) hue-rotate(-38deg) saturate(2.2) contrast(1.1) blur(1.6px); transform: scale(1.22) scaleY(1.03) translateY(14px) skewX(-0.6deg); }
|
|
3395
|
-
100% { filter: none; transform: scale(1.22); }
|
|
3396
|
-
}
|
|
3397
|
-
${CHAOS_SEL} { animation: rk-lava1 7s ease-in-out infinite; }`);
|
|
3398
|
-
later(() => {
|
|
3399
|
-
addStyle(`@keyframes rk-lava2 {
|
|
3400
|
-
0% { filter: url(#rk-lava-warp) sepia(0.5) hue-rotate(-30deg) saturate(2); transform: scale(1.22) translateY(10px); }
|
|
3401
|
-
40% { filter: url(#rk-lava-warp) sepia(0.8) hue-rotate(-48deg) saturate(2.8) contrast(1.18) blur(2.4px); transform: scale(1.2) scaleY(1.1) translateY(46px) skewX(1deg); }
|
|
3402
|
-
70% { filter: url(#rk-lava-warp) sepia(0.7) hue-rotate(-40deg) saturate(2.4) blur(1.2px); transform: scale(1.23) scaleY(1.06) translateY(28px) skewY(-0.8deg); }
|
|
3403
|
-
100% { filter: url(#rk-lava-warp) sepia(0.5) hue-rotate(-30deg) saturate(2); transform: scale(1.22) translateY(10px); }
|
|
3404
|
-
}
|
|
3405
|
-
${CHAOS_SEL} { animation: rk-lava2 6.5s ease-in-out infinite; }
|
|
3406
|
-
@keyframes rk-lava-text { 0%,100% { letter-spacing: normal; } 50% { letter-spacing: 0.1em; word-spacing: 0.25em; text-shadow: 0 6px 6px rgba(255,80,0,0.5); } }
|
|
3407
|
-
h1, h2, h3, p, a, li, button { animation: rk-lava-text 5s ease-in-out infinite; }`);
|
|
3408
|
-
decayText();
|
|
3409
|
-
}, 1e4);
|
|
3410
|
-
const drips = document.createElement("div");
|
|
3411
|
-
drips.className = "rk-fx-layer";
|
|
3412
|
-
layer.appendChild(drips);
|
|
3413
|
-
cleanups.push(() => drips.remove());
|
|
3414
|
-
every(() => {
|
|
3415
|
-
const d = document.createElement("div");
|
|
3416
|
-
d.className = "rk-fx-drip";
|
|
3417
|
-
d.style.left = `${(Math.random() * 96 + 2).toFixed(1)}vw`;
|
|
3418
|
-
d.style.animationDuration = `${(3.5 + Math.random() * 3).toFixed(2)}s`;
|
|
3419
|
-
d.style.background = `linear-gradient(180deg, transparent, hsl(${Math.random() * 30 + 8 | 0}, 95%, 55%))`;
|
|
3420
|
-
drips.appendChild(d);
|
|
3421
|
-
window.setTimeout(() => d.remove(), 7e3);
|
|
3422
|
-
}, 700);
|
|
3423
|
-
wave({ kind: "rain", glyphs: ["\u{1F525}", "\u{1FAE0}", "\u{1F321}\uFE0F", "\u{1F4A7}"], count: 30, durationMs: 1e4 });
|
|
3424
|
-
every(() => wave({ kind: "rain", glyphs: ["\u{1F525}", "\u{1FAE0}", "\u{1F4A7}"], count: 22, durationMs: 9e3 }), 9500);
|
|
3425
|
-
});
|
|
3426
|
-
var startSklo = bigEffect(({ layer, reduced, addStyle, every, wave, decayText, cleanups }) => {
|
|
3427
|
-
if (reduced) {
|
|
3428
|
-
addStyle(`@keyframes rk-sklo-soft { 0%,100% { filter: none; } 50% { filter: saturate(0.7) brightness(1.06); } }
|
|
3429
|
-
${CHAOS_SEL} { animation: rk-sklo-soft 8s ease-in-out infinite; }`);
|
|
3430
|
-
wave({ kind: "burst", glyphs: ["\u2727", "\u2756", "\u{1F4A0}"], count: 10, durationMs: 8e3 });
|
|
3431
|
-
return;
|
|
3432
|
-
}
|
|
3433
|
-
addStyle(`@keyframes rk-sklo-base {
|
|
3434
|
-
0%,10% { transform: scale(1.12); filter: none; }
|
|
3435
|
-
16% { transform: scale(1.125) rotate(0.4deg); filter: brightness(1.12) contrast(1.06); }
|
|
3436
|
-
50% { transform: scale(1.1) rotate(-0.5deg); filter: saturate(0.65) brightness(1.05) blur(0.5px); }
|
|
3437
|
-
72% { transform: scale(1.12); filter: none; }
|
|
3438
|
-
100% { transform: scale(1.12); filter: none; }
|
|
3439
|
-
}
|
|
3440
|
-
${CHAOS_SEL} { animation: rk-sklo-base 11s ease-in-out infinite; }
|
|
3441
|
-
@keyframes rk-sklo-fly {
|
|
3442
|
-
0%, 12% { transform: translate(0, 0) rotate(0); opacity: 1; }
|
|
3443
|
-
30% { transform: translate(var(--rk-gx), var(--rk-gy)) rotate(var(--rk-gr)); opacity: 0.92; }
|
|
3444
|
-
52% { transform: translate(calc(var(--rk-gx) * 1.18), calc(var(--rk-gy) * 1.18)) rotate(calc(var(--rk-gr) * 1.25)); opacity: 0.85; }
|
|
3445
|
-
74% { transform: translate(0, 0) rotate(0); opacity: 1; }
|
|
3446
|
-
100% { transform: translate(0, 0) rotate(0); opacity: 1; }
|
|
3447
|
-
}
|
|
3448
|
-
[data-rk-shard] { animation: rk-sklo-fly 11s cubic-bezier(0.55, 0, 0.3, 1) infinite; }`);
|
|
3449
|
-
const shards = [...document.querySelectorAll("h1, h2, h3, h4, p, li, img, button, a")].filter((el) => {
|
|
3450
|
-
if (el.closest("[data-review-kit-host]")) return false;
|
|
3451
|
-
const r = el.getBoundingClientRect();
|
|
3452
|
-
return r.width > 8 && r.height > 8 && r.bottom > -200 && r.top < window.innerHeight + 200;
|
|
3453
|
-
}).slice(0, 90);
|
|
3454
|
-
const rules = [];
|
|
3455
|
-
shards.forEach((el, i) => {
|
|
3456
|
-
const angle = i * 137.5 * Math.PI / 180;
|
|
3457
|
-
const dist = 18 + i * 29 % 46;
|
|
3458
|
-
rules.push(
|
|
3459
|
-
`[data-rk-shard="${i}"] { --rk-gx: ${(Math.cos(angle) * dist).toFixed(1)}vw; --rk-gy: ${(Math.sin(angle) * dist).toFixed(1)}vh; --rk-gr: ${i * 97 % 640 - 320}deg; }`
|
|
3460
|
-
);
|
|
3461
|
-
el.setAttribute("data-rk-shard", String(i));
|
|
3462
|
-
});
|
|
3463
|
-
addStyle(rules.join("\n"));
|
|
3464
|
-
cleanups.push(() => {
|
|
3465
|
-
for (const el of shards) el.removeAttribute("data-rk-shard");
|
|
3466
|
-
});
|
|
3467
|
-
const cracks = document.createElement("div");
|
|
3468
|
-
cracks.className = "rk-fx-cracks";
|
|
3469
|
-
cracks.innerHTML = Array.from({ length: 9 }, (_, i) => {
|
|
3470
|
-
const angle = i * 40 + i % 3 * 7;
|
|
3471
|
-
return `<span style="transform: rotate(${angle}deg); animation-delay: ${(i * 0.05).toFixed(2)}s"></span>`;
|
|
3472
|
-
}).join("");
|
|
3473
|
-
layer.appendChild(cracks);
|
|
3474
|
-
cleanups.push(() => cracks.remove());
|
|
3475
|
-
decayText();
|
|
3476
|
-
every(() => wave({ kind: "burst", glyphs: ["\u2727", "\u2756", "\u{1F4A0}", "\u{1F9CA}"], count: 26, durationMs: 5e3 }), 11e3);
|
|
3477
|
-
wave({ kind: "burst", glyphs: ["\u2727", "\u2756", "\u{1F4A0}"], count: 26, durationMs: 5e3 });
|
|
3478
|
-
});
|
|
3479
|
-
var startVir = bigEffect(({ layer, reduced, addStyle, later, wave, decayText, cleanups }) => {
|
|
3480
|
-
if (reduced) {
|
|
3481
|
-
addStyle(`@keyframes rk-vir-soft { 0%,100% { filter: none; } 50% { filter: hue-rotate(50deg); } }
|
|
3482
|
-
${CHAOS_SEL} { animation: rk-vir-soft 9s ease-in-out infinite; }`);
|
|
3483
|
-
wave({ kind: "burst", glyphs: ["\u{1F300}"], count: 8, durationMs: 8e3 });
|
|
3484
|
-
return;
|
|
3485
|
-
}
|
|
3486
|
-
addStyle(`@keyframes rk-vir1 {
|
|
3487
|
-
0% { transform: scale(1.25) rotate(0deg); filter: none; }
|
|
3488
|
-
30% { transform: scale(1.31) rotate(4deg); filter: hue-rotate(50deg) saturate(1.3) blur(0.5px); }
|
|
3489
|
-
60% { transform: scale(1.28) rotate(-3.4deg); filter: hue-rotate(140deg) saturate(0.8) blur(1px); }
|
|
3490
|
-
100% { transform: scale(1.25) rotate(0deg); filter: none; }
|
|
3491
|
-
}
|
|
3492
|
-
${CHAOS_SEL} { animation: rk-vir1 6.5s ease-in-out infinite; }`);
|
|
3493
|
-
later(() => {
|
|
3494
|
-
addStyle(`@keyframes rk-vir2 {
|
|
3495
|
-
0% { transform: scale(1.25) rotate(0deg); filter: hue-rotate(0deg) saturate(1.4); }
|
|
3496
|
-
25% { transform: scale(1.42) rotate(9deg); filter: hue-rotate(90deg) saturate(1.9) blur(1.6px); }
|
|
3497
|
-
50% { transform: scale(1.55) rotate(-7deg); filter: hue-rotate(200deg) saturate(0.6) contrast(1.15) blur(2.6px); }
|
|
3498
|
-
75% { transform: scale(1.38) rotate(10deg); filter: hue-rotate(300deg) saturate(1.8) blur(1.2px); }
|
|
3499
|
-
100% { transform: scale(1.25) rotate(0deg); filter: hue-rotate(360deg) saturate(1.4); }
|
|
3500
|
-
}
|
|
3501
|
-
${CHAOS_SEL} { animation: rk-vir2 5.5s ease-in-out infinite; }
|
|
3502
|
-
@keyframes rk-vir-text { 0%,100% { letter-spacing: normal; } 50% { letter-spacing: 0.16em; text-shadow: 3px 0 rgba(0,180,255,0.5), -3px 0 rgba(255,60,160,0.5); } }
|
|
3503
|
-
h1, h2, h3, p, a, li, button { animation: rk-vir-text 4.5s ease-in-out infinite; }`);
|
|
3504
|
-
decayText();
|
|
3505
|
-
}, 12e3);
|
|
3506
|
-
const GLYPHS = ["\u{1F300}", "\u2728", "\u{1F343}", "\u{1F4C4}", "\u2604\uFE0F"];
|
|
3507
|
-
const bits = [];
|
|
3508
|
-
const cx = () => window.innerWidth / 2;
|
|
3509
|
-
const cy = () => window.innerHeight / 2;
|
|
3510
|
-
const maxR = () => Math.hypot(window.innerWidth, window.innerHeight) / 2 + 60;
|
|
3511
|
-
for (let i = 0; i < 36; i++) {
|
|
3512
|
-
const el = document.createElement("span");
|
|
3513
|
-
el.className = "rk-fx-particle";
|
|
3514
|
-
el.textContent = GLYPHS[i % GLYPHS.length];
|
|
3515
|
-
el.style.fontSize = `${13 + i * 11 % 16}px`;
|
|
3516
|
-
layer.appendChild(el);
|
|
3517
|
-
bits.push({ el, r: maxR() * ((i + 1) / 36), a: i * 0.7, v: 0.6 + i % 5 * 0.16 });
|
|
3518
|
-
}
|
|
3519
|
-
let raf = 0;
|
|
3520
|
-
const tick = () => {
|
|
3521
|
-
raf = requestAnimationFrame(tick);
|
|
3522
|
-
for (const bit of bits) {
|
|
3523
|
-
bit.a += 0.014 * bit.v * (1 + 140 / Math.max(bit.r, 40));
|
|
3524
|
-
bit.r -= 0.55 * bit.v;
|
|
3525
|
-
if (bit.r < 16) bit.r = maxR();
|
|
3526
|
-
bit.el.style.transform = `translate3d(${cx() + Math.cos(bit.a) * bit.r}px, ${cy() + Math.sin(bit.a) * bit.r}px, 0) rotate(${bit.a}rad)`;
|
|
3527
|
-
bit.el.style.opacity = `${Math.min(1, bit.r / 120)}`;
|
|
3528
|
-
}
|
|
3529
|
-
};
|
|
3530
|
-
raf = requestAnimationFrame(tick);
|
|
3531
|
-
cleanups.push(() => {
|
|
3532
|
-
cancelAnimationFrame(raf);
|
|
3533
|
-
bits.forEach((bit) => bit.el.remove());
|
|
3534
|
-
});
|
|
3535
|
-
});
|
|
3536
|
-
var startCrt = bigEffect(({ layer, reduced, addStyle, every, wave, decayText, cleanups }) => {
|
|
3537
|
-
if (reduced) {
|
|
3538
|
-
addStyle(`${CHAOS_SEL} { filter: sepia(0.7) hue-rotate(55deg) saturate(1.6) contrast(1.05); transition: filter 2s ease; }`);
|
|
3539
|
-
return;
|
|
3002
|
+
function cancelWhenReady() {
|
|
3003
|
+
if (loaded) return loaded.cancelEffects();
|
|
3004
|
+
if (loading && queued > 0) {
|
|
3005
|
+
loading.then((mod) => mod.cancelEffects()).catch(() => void 0);
|
|
3006
|
+
return true;
|
|
3540
3007
|
}
|
|
3541
|
-
|
|
3542
|
-
svg.setAttribute("data-rk-fx", "");
|
|
3543
|
-
svg.setAttribute("width", "0");
|
|
3544
|
-
svg.setAttribute("height", "0");
|
|
3545
|
-
svg.style.position = "absolute";
|
|
3546
|
-
svg.innerHTML = `<defs><filter id="rk-crt-tear" x="-10%" y="-10%" width="120%" height="120%">
|
|
3547
|
-
<feTurbulence type="turbulence" baseFrequency="0.002 0.09" numOctaves="1" result="n" seed="11">
|
|
3548
|
-
<animate attributeName="seed" dur="3s" values="11;37;11" repeatCount="indefinite"/>
|
|
3549
|
-
</feTurbulence>
|
|
3550
|
-
<feDisplacementMap in="SourceGraphic" in2="n" scale="0" xChannelSelector="R" yChannelSelector="G">
|
|
3551
|
-
<animate attributeName="scale" dur="8s" values="0;0;26;4;0;0" keyTimes="0;0.55;0.62;0.7;0.78;1" repeatCount="indefinite"/>
|
|
3552
|
-
</feDisplacementMap>
|
|
3553
|
-
</filter></defs>`;
|
|
3554
|
-
document.body.appendChild(svg);
|
|
3555
|
-
cleanups.push(() => svg.remove());
|
|
3556
|
-
addStyle(`@keyframes rk-crt-hold {
|
|
3557
|
-
0%, 60% { transform: scale(1.16) translate(0, 0); }
|
|
3558
|
-
64% { transform: scale(1.16) translate(-3px, 14px) skewX(-0.8deg); }
|
|
3559
|
-
68% { transform: scale(1.16) translate(2px, -8px); }
|
|
3560
|
-
74%, 100% { transform: scale(1.16) translate(0, 0); }
|
|
3561
|
-
}
|
|
3562
|
-
${CHAOS_SEL} {
|
|
3563
|
-
filter: url(#rk-crt-tear) sepia(1) hue-rotate(55deg) saturate(2.6) contrast(1.22) brightness(0.92);
|
|
3564
|
-
animation: rk-crt-hold 8s linear infinite;
|
|
3565
|
-
}
|
|
3566
|
-
@keyframes rk-crt-text { 0%,100% { text-shadow: 1px 0 rgba(0,255,120,0.5); } 50% { text-shadow: -2px 0 rgba(0,255,120,0.7), 2px 0 rgba(0,120,60,0.5); letter-spacing: 0.06em; } }
|
|
3567
|
-
h1, h2, h3, p, a, li, button { animation: rk-crt-text 5s ease-in-out infinite; }`);
|
|
3568
|
-
const overlay = document.createElement("div");
|
|
3569
|
-
overlay.className = "rk-fx-crt";
|
|
3570
|
-
overlay.innerHTML = '<div class="rk-fx-crt-scan"></div><div class="rk-fx-crt-roll"></div><div class="rk-fx-crt-vignette"></div><div class="rk-fx-crt-osd">KAN\xC1L 69 \xB7 SLAB\xDD SIGN\xC1L</div>';
|
|
3571
|
-
layer.appendChild(overlay);
|
|
3572
|
-
cleanups.push(() => overlay.remove());
|
|
3573
|
-
decayText();
|
|
3574
|
-
every(() => wave({ kind: "rain", glyphs: ["\u{1F4FA}", "\u{1F4E1}", "\u{1D34D}"], count: 10, durationMs: 7e3 }), 16e3);
|
|
3575
|
-
});
|
|
3576
|
-
function startBanner({ layer, reduced }) {
|
|
3577
|
-
const banner = document.createElement("div");
|
|
3578
|
-
banner.className = "rk-fx-banner";
|
|
3579
|
-
banner.textContent = "\u{1F6A8} KOKOT ALERT \u{1F6A8} KOKOT ALERT \u{1F6A8} KOKOT ALERT \u{1F6A8}";
|
|
3580
|
-
if (reduced) banner.classList.add("rk-fx-banner-still");
|
|
3581
|
-
layer.appendChild(banner);
|
|
3582
|
-
return () => banner.remove();
|
|
3583
|
-
}
|
|
3584
|
-
function startVrtule({ reduced }) {
|
|
3585
|
-
const style = document.createElement("style");
|
|
3586
|
-
style.setAttribute("data-rk-fx", "vrtule");
|
|
3587
|
-
style.textContent = reduced ? `@keyframes rk-vrtula { 0%,100% { transform: rotate(0); } 50% { transform: rotate(3deg); } }
|
|
3588
|
-
img { animation: rk-vrtula 4s ease-in-out infinite; }` : `@keyframes rk-vrtula { from { transform: rotate(0) scale(1); } 50% { transform: rotate(180deg) scale(0.9); } to { transform: rotate(360deg) scale(1); } }
|
|
3589
|
-
img { animation: rk-vrtula 3.6s ease-in-out infinite; }`;
|
|
3590
|
-
document.head.appendChild(style);
|
|
3591
|
-
return () => style.remove();
|
|
3592
|
-
}
|
|
3593
|
-
function makeChase(options) {
|
|
3594
|
-
return function startChase({ layer, reduced }) {
|
|
3595
|
-
const critters = [];
|
|
3596
|
-
const count = reduced ? Math.min(4, options.count) : options.count;
|
|
3597
|
-
for (let i = 0; i < count; i++) {
|
|
3598
|
-
const el = document.createElement("span");
|
|
3599
|
-
el.className = "rk-fx-particle";
|
|
3600
|
-
el.textContent = options.glyphs[i % options.glyphs.length];
|
|
3601
|
-
el.style.fontSize = `${options.sizePx(i)}px`;
|
|
3602
|
-
layer.appendChild(el);
|
|
3603
|
-
critters.push({ el, x: window.innerWidth / 2, y: window.innerHeight / 2, seed: i * 137 });
|
|
3604
|
-
}
|
|
3605
|
-
const wobble = options.wobbleT ?? 400;
|
|
3606
|
-
let raf = 0;
|
|
3607
|
-
const tick = (t) => {
|
|
3608
|
-
raf = requestAnimationFrame(tick);
|
|
3609
|
-
const root = layer.getRootNode();
|
|
3610
|
-
const chips = [...root.querySelectorAll(".rk-peer-cursor")].filter((c) => c.style.opacity !== "0").map((c) => {
|
|
3611
|
-
const m = /translate3d\(([-\d.]+)px, ([-\d.]+)px/.exec(c.style.transform);
|
|
3612
|
-
return m ? { x: parseFloat(m[1]), y: parseFloat(m[2]) } : null;
|
|
3613
|
-
}).filter((p) => p !== null);
|
|
3614
|
-
chips.push({ x: lastPointerFallback.x, y: lastPointerFallback.y });
|
|
3615
|
-
for (const critter of critters) {
|
|
3616
|
-
const target = chips[critter.seed % chips.length];
|
|
3617
|
-
const orbit = reduced ? 14 : options.orbit(critter.seed);
|
|
3618
|
-
const wx = target.x + Math.cos(t / wobble + critter.seed) * orbit;
|
|
3619
|
-
const wy = target.y + Math.sin(t / (wobble * 0.82) + critter.seed) * orbit;
|
|
3620
|
-
const prevX = critter.x;
|
|
3621
|
-
critter.x += (wx - critter.x) * options.lag;
|
|
3622
|
-
critter.y += (wy - critter.y) * options.lag;
|
|
3623
|
-
const face = options.flip && critter.x < prevX ? " scaleX(-1)" : "";
|
|
3624
|
-
critter.el.style.transform = `translate3d(${critter.x}px, ${critter.y}px, 0)${face}`;
|
|
3625
|
-
}
|
|
3626
|
-
};
|
|
3627
|
-
raf = requestAnimationFrame(tick);
|
|
3628
|
-
const onMove = (event) => {
|
|
3629
|
-
lastPointerFallback.x = event.clientX;
|
|
3630
|
-
lastPointerFallback.y = event.clientY;
|
|
3631
|
-
};
|
|
3632
|
-
document.addEventListener("pointermove", onMove, { passive: true });
|
|
3633
|
-
return () => {
|
|
3634
|
-
cancelAnimationFrame(raf);
|
|
3635
|
-
document.removeEventListener("pointermove", onMove);
|
|
3636
|
-
for (const critter of critters) critter.el.remove();
|
|
3637
|
-
};
|
|
3638
|
-
};
|
|
3008
|
+
return false;
|
|
3639
3009
|
}
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
style.setAttribute("data-rk-fx", "");
|
|
3644
|
-
style.textContent = css;
|
|
3645
|
-
document.head.appendChild(style);
|
|
3646
|
-
return () => style.remove();
|
|
3647
|
-
}
|
|
3648
|
-
var PAGE_SEL = "body > :not([data-review-kit-host]):not(script):not(style)";
|
|
3649
|
-
function startDisko({ layer, reduced }) {
|
|
3650
|
-
const remove = styleEffect(
|
|
3651
|
-
reduced ? `@keyframes rk-disko { 0%,100% { filter: none; } 50% { filter: hue-rotate(60deg) saturate(1.2); } }
|
|
3652
|
-
${PAGE_SEL} { animation: rk-disko 8s ease-in-out infinite; }` : `@keyframes rk-disko { from { filter: hue-rotate(0deg) saturate(1.35); } to { filter: hue-rotate(360deg) saturate(1.35); } }
|
|
3653
|
-
${PAGE_SEL} { animation: rk-disko 4s linear infinite; }`
|
|
3654
|
-
);
|
|
3655
|
-
spawnParticles(layer, { kind: "rain", glyphs: ["\u2728", "\u{1FAA9}", "\u{1F483}", "\u{1F57A}"], count: 26}, reduced, 15e3);
|
|
3656
|
-
return remove;
|
|
3010
|
+
function setEffectBroadcaster(fn) {
|
|
3011
|
+
broadcaster = fn;
|
|
3012
|
+
loaded?.setEffectBroadcaster(fn);
|
|
3657
3013
|
}
|
|
3658
|
-
function
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
}
|
|
3662
|
-
return styleEffect(`@keyframes rk-zrkadlo {
|
|
3663
|
-
0%, 100% { transform: perspective(1400px) rotateY(0); }
|
|
3664
|
-
35%, 65% { transform: perspective(1400px) rotateY(180deg); }
|
|
3665
|
-
}
|
|
3666
|
-
${PAGE_SEL} { animation: rk-zrkadlo 12s ease-in-out both; transform-origin: 50% 50%; }`);
|
|
3667
|
-
}
|
|
3668
|
-
function startPohreb({ layer, reduced }) {
|
|
3669
|
-
const remove = styleEffect(`@keyframes rk-pohreb { from { filter: none; } to { filter: grayscale(1) brightness(0.82) sepia(0.15); } }
|
|
3670
|
-
${PAGE_SEL} { animation: rk-pohreb 5s ease-out both; }`);
|
|
3671
|
-
spawnParticles(layer, { kind: "rain", glyphs: ["\u{1F940}", "\u26B0\uFE0F", "\u{1F56F}\uFE0F", "\u{1F5A4}"], count: reduced ? 8 : 22}, reduced, 14e3);
|
|
3672
|
-
return remove;
|
|
3673
|
-
}
|
|
3674
|
-
function startLaser({ layer, reduced }) {
|
|
3675
|
-
const beams = [];
|
|
3676
|
-
const count = reduced ? 2 : 5;
|
|
3677
|
-
const hues = [330, 190, 120, 45, 265];
|
|
3678
|
-
for (let i = 0; i < count; i++) {
|
|
3679
|
-
const beam = document.createElement("div");
|
|
3680
|
-
beam.className = "rk-fx-laser";
|
|
3681
|
-
beam.style.background = `linear-gradient(90deg, transparent, hsla(${hues[i % hues.length]}, 100%, 60%, 0.55), transparent)`;
|
|
3682
|
-
beam.style.left = `${i % 2 * 100}%`;
|
|
3683
|
-
beam.style.animationDuration = `${3.4 + i * 0.6}s`;
|
|
3684
|
-
beam.style.animationDelay = `${i * 0.45}s`;
|
|
3685
|
-
if (i % 2) beam.style.animationDirection = "reverse";
|
|
3686
|
-
layer.appendChild(beam);
|
|
3687
|
-
beams.push(beam);
|
|
3688
|
-
}
|
|
3689
|
-
return () => beams.forEach((b) => b.remove());
|
|
3690
|
-
}
|
|
3691
|
-
function startKura({ layer, reduced }) {
|
|
3692
|
-
const hen = document.createElement("span");
|
|
3693
|
-
hen.className = "rk-fx-kura";
|
|
3694
|
-
hen.textContent = "\u{1F414}";
|
|
3695
|
-
layer.appendChild(hen);
|
|
3696
|
-
const props = [hen];
|
|
3697
|
-
const timers = [];
|
|
3698
|
-
const walkMs = reduced ? 16e3 : 11e3;
|
|
3699
|
-
hen.style.animationDuration = `${walkMs}ms`;
|
|
3700
|
-
if (!reduced) {
|
|
3701
|
-
for (let i = 1; i <= 5; i++) {
|
|
3702
|
-
timers.push(
|
|
3703
|
-
window.setTimeout(() => {
|
|
3704
|
-
const egg = document.createElement("span");
|
|
3705
|
-
egg.className = "rk-fx-egg";
|
|
3706
|
-
egg.textContent = "\u{1F95A}";
|
|
3707
|
-
egg.style.left = `${i / 6 * 100}%`;
|
|
3708
|
-
layer.appendChild(egg);
|
|
3709
|
-
props.push(egg);
|
|
3710
|
-
timers.push(
|
|
3711
|
-
window.setTimeout(() => {
|
|
3712
|
-
egg.textContent = "\u{1F423}";
|
|
3713
|
-
}, 2600 + i * 400)
|
|
3714
|
-
);
|
|
3715
|
-
}, walkMs * i / 6)
|
|
3716
|
-
);
|
|
3717
|
-
}
|
|
3718
|
-
}
|
|
3719
|
-
return () => {
|
|
3720
|
-
timers.forEach((t) => window.clearTimeout(t));
|
|
3721
|
-
props.forEach((p) => p.remove());
|
|
3722
|
-
};
|
|
3014
|
+
function setEffectAssetsUrl(url) {
|
|
3015
|
+
assetsUrl = url ?? null;
|
|
3016
|
+
loaded?.setFxAssetsUrl(assetsUrl);
|
|
3723
3017
|
}
|
|
3724
|
-
function
|
|
3725
|
-
|
|
3726
|
-
"\u26A0\uFE0F Kritick\xE1 chyba: str\xE1nka je pr\xEDli\u0161 pekn\xE1",
|
|
3727
|
-
"\u{1F525} 69 \u013Eud\xED pr\xE1ve pozer\xE1 tento button",
|
|
3728
|
-
"\u{1F4BE} Uklad\xE1m tvoje hriechy\u2026",
|
|
3729
|
-
"\u{1F4C8} Konverzia st\xFApla o 420 %",
|
|
3730
|
-
"\u{1F9E0} AI navrhuje: prerob to cel\xE9",
|
|
3731
|
-
"\u{1F36A} T\xE1to str\xE1nka \u017Eerie kol\xE1\u010Diky",
|
|
3732
|
-
"\u{1F4DE} Vol\xE1 ti klient. Zdvihni.",
|
|
3733
|
-
"\u{1F4B8} Fakt\xFAra po splatnosti (odjak\u017Eiva)",
|
|
3734
|
-
"\u{1F6F8} Zisten\xE1 mimozemsk\xE1 aktivita v p\xE4ti\u010Dke",
|
|
3735
|
-
"\u2705 Ni\u010D sa nepodarilo \xFAspe\u0161ne"
|
|
3736
|
-
];
|
|
3737
|
-
const toasts = [];
|
|
3738
|
-
const timers = [];
|
|
3739
|
-
const total = reduced ? 4 : MESSAGES.length;
|
|
3740
|
-
for (let i = 0; i < total; i++) {
|
|
3741
|
-
timers.push(
|
|
3742
|
-
window.setTimeout(() => {
|
|
3743
|
-
const toast2 = document.createElement("div");
|
|
3744
|
-
toast2.className = "rk-fx-toast";
|
|
3745
|
-
toast2.textContent = MESSAGES[i % MESSAGES.length];
|
|
3746
|
-
toast2.style.top = `${14 + i % 5 * 58}px`;
|
|
3747
|
-
layer.appendChild(toast2);
|
|
3748
|
-
toasts.push(toast2);
|
|
3749
|
-
timers.push(window.setTimeout(() => toast2.remove(), 5200));
|
|
3750
|
-
}, i * (reduced ? 1800 : 950))
|
|
3751
|
-
);
|
|
3752
|
-
}
|
|
3753
|
-
return () => {
|
|
3754
|
-
timers.forEach((t) => window.clearTimeout(t));
|
|
3755
|
-
toasts.forEach((t) => t.remove());
|
|
3756
|
-
};
|
|
3018
|
+
function cancelEffects() {
|
|
3019
|
+
return cancelWhenReady();
|
|
3757
3020
|
}
|
|
3758
|
-
var EFFECTS = {
|
|
3759
|
-
ondro: { kind: "custom", durationMs: ONDRO_MS, start: startOndro },
|
|
3760
|
-
lava: { kind: "custom", durationMs: BIG_MS, start: startLava },
|
|
3761
|
-
sklo: { kind: "custom", durationMs: BIG_MS, start: startSklo },
|
|
3762
|
-
vir: { kind: "custom", durationMs: BIG_MS, start: startVir },
|
|
3763
|
-
crt: { kind: "custom", durationMs: BIG_MS, start: startCrt },
|
|
3764
|
-
hovno: { kind: "rain", glyphs: ["\u{1F4A9}"], count: 44, durationMs: 4200 },
|
|
3765
|
-
konfety: { kind: "burst", glyphs: ["\u{1F389}", "\u{1F38A}", "\u2728"], count: 56, durationMs: 3600 },
|
|
3766
|
-
srdiecka: { kind: "rain", glyphs: ["\u2764\uFE0F", "\u{1F49A}", "\u{1F49B}"], count: 40, durationMs: 4200 },
|
|
3767
|
-
sneh: { kind: "rain", glyphs: ["\u2744\uFE0F", "\u{1F328}\uFE0F"], count: 48, durationMs: 5200 },
|
|
3768
|
-
zemetrasenie: { kind: "rain", glyphs: ["\u{1FAA8}", "\u{1F9F1}"], count: 18, durationMs: 2400, shake: true },
|
|
3769
|
-
"69": { kind: "burst", glyphs: ["\u{1F346}", "\u{1F351}", "\u{1F4A6}"], count: 69, durationMs: NICE_MS },
|
|
3770
|
-
kokot: { kind: "custom", durationMs: 14500, start: startBanner },
|
|
3771
|
-
vrtule: { kind: "custom", durationMs: NICE_MS, start: startVrtule },
|
|
3772
|
-
muchy: {
|
|
3773
|
-
kind: "custom",
|
|
3774
|
-
durationMs: NICE_MS,
|
|
3775
|
-
start: makeChase({ glyphs: ["\u{1FAB0}"], count: 14, sizePx: (i) => 12 + i % 3 * 4, orbit: (s) => 26 + s % 20, lag: 0.12, wobbleT: 400 })
|
|
3776
|
-
},
|
|
3777
|
-
pes: {
|
|
3778
|
-
kind: "custom",
|
|
3779
|
-
durationMs: 12e3,
|
|
3780
|
-
start: makeChase({ glyphs: ["\u{1F415}", "\u{1F429}", "\u{1F9AE}"], count: 3, sizePx: (i) => 26 + i % 2 * 6, orbit: (s) => 46 + s % 30, lag: 0.055, wobbleT: 900, flip: true })
|
|
3781
|
-
},
|
|
3782
|
-
pivo: { kind: "rain", glyphs: ["\u{1F37A}", "\u{1F37B}", "\u{1F37E}"], count: 42, durationMs: 8e3 },
|
|
3783
|
-
nikotin: { kind: "rain", glyphs: ["\u{1F6AC}", "\u{1F4A8}", "\u{1F62E}\u200D\u{1F4A8}"], count: 20, durationMs: 13e3 },
|
|
3784
|
-
matrix: { kind: "rain", glyphs: [..."\u30A2\u30AB\u30B5\u30BF\u30CA0169\uFF8A\uFF8F\uFF94\uFF97\uFF66"], count: 64, durationMs: 12e3, className: "rk-fx-matrix" },
|
|
3785
|
-
disko: { kind: "custom", durationMs: 15e3, start: startDisko },
|
|
3786
|
-
zrkadlo: { kind: "custom", durationMs: 12e3, start: startZrkadlo },
|
|
3787
|
-
pohreb: { kind: "custom", durationMs: 14e3, start: startPohreb },
|
|
3788
|
-
laser: { kind: "custom", durationMs: 12e3, start: startLaser },
|
|
3789
|
-
kura: { kind: "custom", durationMs: 11500, start: startKura },
|
|
3790
|
-
spam: { kind: "custom", durationMs: 11e3, start: startSpam }
|
|
3791
|
-
};
|
|
3792
3021
|
function runEffect(name, layerHost) {
|
|
3022
|
+
if (!isEffectCommand(name)) return false;
|
|
3793
3023
|
if (name === "stop") {
|
|
3794
|
-
|
|
3024
|
+
cancelWhenReady();
|
|
3795
3025
|
return true;
|
|
3796
3026
|
}
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
layerHost.appendChild(layer);
|
|
3804
|
-
let customCleanup = null;
|
|
3805
|
-
let shakeCleanup = null;
|
|
3806
|
-
if (spec.kind === "custom") {
|
|
3807
|
-
customCleanup = spec.start({ layer, reduced });
|
|
3808
|
-
} else {
|
|
3809
|
-
spawnParticles(layer, spec, reduced, duration);
|
|
3810
|
-
if (spec.shake && !reduced) shakeCleanup = runShake();
|
|
3811
|
-
}
|
|
3812
|
-
let timer = 0;
|
|
3813
|
-
const cancel = () => {
|
|
3814
|
-
window.clearTimeout(timer);
|
|
3815
|
-
customCleanup?.();
|
|
3816
|
-
shakeCleanup?.();
|
|
3817
|
-
layer.remove();
|
|
3818
|
-
active.delete(cancel);
|
|
3819
|
-
};
|
|
3820
|
-
timer = window.setTimeout(cancel, duration + 1200);
|
|
3821
|
-
active.add(cancel);
|
|
3027
|
+
queued += 1;
|
|
3028
|
+
void load().then((mod) => {
|
|
3029
|
+
queued = Math.max(0, queued - 1);
|
|
3030
|
+
mod.runEffect(name, layerHost);
|
|
3031
|
+
}).catch(() => {
|
|
3032
|
+
});
|
|
3822
3033
|
return true;
|
|
3823
3034
|
}
|
|
3824
3035
|
|
|
@@ -4118,21 +3329,24 @@ var SHORTCUTS = [
|
|
|
4118
3329
|
}
|
|
4119
3330
|
}
|
|
4120
3331
|
];
|
|
3332
|
+
|
|
3333
|
+
// src/client/emblemaPush.ts
|
|
3334
|
+
import { useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
4121
3335
|
var AUTO_PUSH_DEBOUNCE_MS = 500;
|
|
4122
3336
|
function useEmblemaAutoPush(state, dispatch, config) {
|
|
4123
3337
|
const emblema = config.emblema;
|
|
4124
|
-
const sessionRef =
|
|
3338
|
+
const sessionRef = useRef2(state.session);
|
|
4125
3339
|
sessionRef.current = state.session;
|
|
4126
|
-
const lastSent =
|
|
4127
|
-
const inFlight =
|
|
4128
|
-
const alive =
|
|
4129
|
-
|
|
3340
|
+
const lastSent = useRef2(/* @__PURE__ */ new Map());
|
|
3341
|
+
const inFlight = useRef2(false);
|
|
3342
|
+
const alive = useRef2(true);
|
|
3343
|
+
useEffect2(() => {
|
|
4130
3344
|
alive.current = true;
|
|
4131
3345
|
return () => {
|
|
4132
3346
|
alive.current = false;
|
|
4133
3347
|
};
|
|
4134
3348
|
}, []);
|
|
4135
|
-
const flushRef =
|
|
3349
|
+
const flushRef = useRef2(() => {
|
|
4136
3350
|
});
|
|
4137
3351
|
flushRef.current = () => {
|
|
4138
3352
|
if (!alive.current || !emblema) return;
|
|
@@ -4154,12 +3368,12 @@ function useEmblemaAutoPush(state, dispatch, config) {
|
|
|
4154
3368
|
for (const item of changed) lastSent.current.set(item.id, item);
|
|
4155
3369
|
if (alive.current) dispatch({ type: "EMBLEMA_PUSH_STATUS", status: "ok" });
|
|
4156
3370
|
} else if (alive.current) {
|
|
4157
|
-
dispatch({ type: "EMBLEMA_PUSH_STATUS", status: "offline" });
|
|
3371
|
+
dispatch({ type: "EMBLEMA_PUSH_STATUS", status: result.reason === "rejected" ? "rejected" : "offline" });
|
|
4158
3372
|
}
|
|
4159
3373
|
});
|
|
4160
3374
|
};
|
|
4161
3375
|
const items = state.session?.items;
|
|
4162
|
-
|
|
3376
|
+
useEffect2(() => {
|
|
4163
3377
|
if (!emblema || !items) return;
|
|
4164
3378
|
for (const id of [...lastSent.current.keys()]) {
|
|
4165
3379
|
if (!items.some((item) => item.id === id)) lastSent.current.delete(id);
|
|
@@ -4173,6 +3387,9 @@ function useEmblemaAutoPush(state, dispatch, config) {
|
|
|
4173
3387
|
}, [items, emblema]);
|
|
4174
3388
|
}
|
|
4175
3389
|
|
|
3390
|
+
// src/client/sync.ts
|
|
3391
|
+
import { useEffect as useEffect3, useMemo as useMemo2, useRef as useRef3 } from "react";
|
|
3392
|
+
|
|
4176
3393
|
// realtime/client/rkSync.ts
|
|
4177
3394
|
var RK_SYNC_PROTOCOL_VERSION = 1;
|
|
4178
3395
|
var BACKOFF_BASE_MS = 1e3;
|
|
@@ -4303,8 +3520,8 @@ function createRkSync(options) {
|
|
|
4303
3520
|
log(`welcome: ${items.length} items, ${peers.length} peers, ${deleted.length} tombstones, flushing ${queue.length}`);
|
|
4304
3521
|
safely(() => handlers.onSnapshot?.(items, peers, deleted));
|
|
4305
3522
|
while (queue.length > 0) {
|
|
4306
|
-
const
|
|
4307
|
-
if (!rawSend(
|
|
3523
|
+
const queued2 = queue[0];
|
|
3524
|
+
if (!rawSend(queued2)) break;
|
|
4308
3525
|
queue.shift();
|
|
4309
3526
|
}
|
|
4310
3527
|
break;
|
|
@@ -4356,8 +3573,8 @@ function createRkSync(options) {
|
|
|
4356
3573
|
if (typeof msg.peerId === "string") {
|
|
4357
3574
|
const peerId = msg.peerId;
|
|
4358
3575
|
const itemId = typeof msg.itemId === "string" ? msg.itemId : null;
|
|
4359
|
-
const
|
|
4360
|
-
safely(() => handlers.onPeerTyping?.(peerId, itemId,
|
|
3576
|
+
const active = msg.active === true;
|
|
3577
|
+
safely(() => handlers.onPeerTyping?.(peerId, itemId, active));
|
|
4361
3578
|
}
|
|
4362
3579
|
break;
|
|
4363
3580
|
case "item:add": {
|
|
@@ -4388,6 +3605,8 @@ function createRkSync(options) {
|
|
|
4388
3605
|
safely(() => handlers.onItemDelete?.(id, authorId));
|
|
4389
3606
|
}
|
|
4390
3607
|
break;
|
|
3608
|
+
default:
|
|
3609
|
+
break;
|
|
4391
3610
|
}
|
|
4392
3611
|
};
|
|
4393
3612
|
const connect = () => {
|
|
@@ -4471,8 +3690,8 @@ function createRkSync(options) {
|
|
|
4471
3690
|
sendSelecting(selector) {
|
|
4472
3691
|
sendEphemeral({ t: "selecting", selector });
|
|
4473
3692
|
},
|
|
4474
|
-
sendTyping(itemId,
|
|
4475
|
-
sendEphemeral({ t: "typing", itemId, active
|
|
3693
|
+
sendTyping(itemId, active) {
|
|
3694
|
+
sendEphemeral({ t: "typing", itemId, active });
|
|
4476
3695
|
},
|
|
4477
3696
|
sendEffect(name) {
|
|
4478
3697
|
sendEphemeral({ t: "fx", name });
|
|
@@ -4517,7 +3736,6 @@ function currentAuthor(name) {
|
|
|
4517
3736
|
}
|
|
4518
3737
|
|
|
4519
3738
|
// src/client/sync.ts
|
|
4520
|
-
var DEFAULT_SYNC_URL = "wss://agropolio.fucking.style/rk-sync";
|
|
4521
3739
|
function toPeerState(peer) {
|
|
4522
3740
|
return {
|
|
4523
3741
|
id: peer.id,
|
|
@@ -4541,21 +3759,21 @@ function sanitizeRemoteItem(raw) {
|
|
|
4541
3759
|
return { ...raw, target };
|
|
4542
3760
|
}
|
|
4543
3761
|
function useRealtimeSync(state, rawDispatch, config, reducer2) {
|
|
4544
|
-
const syncRef =
|
|
4545
|
-
const stateRef =
|
|
3762
|
+
const syncRef = useRef3(null);
|
|
3763
|
+
const stateRef = useRef3(state);
|
|
4546
3764
|
stateRef.current = state;
|
|
4547
|
-
const myIdRef =
|
|
4548
|
-
const enabled = typeof config.syncToken === "string" && config.syncToken !== "";
|
|
3765
|
+
const myIdRef = useRef3("");
|
|
3766
|
+
const enabled = typeof config.syncToken === "string" && config.syncToken !== "" && typeof config.syncUrl === "string" && config.syncUrl !== "";
|
|
4549
3767
|
const author = state.session?.author ?? "";
|
|
4550
3768
|
const hasSession = state.session !== null;
|
|
4551
|
-
|
|
3769
|
+
useEffect3(() => {
|
|
4552
3770
|
if (!enabled || !hasSession) return;
|
|
4553
3771
|
const id = reviewerId();
|
|
4554
3772
|
myIdRef.current = id;
|
|
4555
3773
|
const dispatch = rawDispatch;
|
|
4556
3774
|
const sync = createRkSync({
|
|
4557
3775
|
token: config.syncToken,
|
|
4558
|
-
url: config.syncUrl
|
|
3776
|
+
url: config.syncUrl,
|
|
4559
3777
|
user: { id, name: author || "Reviewer", color: colorForReviewer(id) },
|
|
4560
3778
|
handlers: {
|
|
4561
3779
|
onStatus: (status) => dispatch({ type: "SYNC_STATUS", status }),
|
|
@@ -4580,7 +3798,7 @@ function useRealtimeSync(state, rawDispatch, config, reducer2) {
|
|
|
4580
3798
|
runEffect(name, layerRoot);
|
|
4581
3799
|
},
|
|
4582
3800
|
onPeerSelecting: (peerId, selector) => dispatch({ type: "PEER_SELECTING", peerId, selector }),
|
|
4583
|
-
onPeerTyping: (peerId, itemId,
|
|
3801
|
+
onPeerTyping: (peerId, itemId, active) => dispatch({ type: "PEER_TYPING", peerId, itemId, active }),
|
|
4584
3802
|
onItemAdd: (item, authorId) => {
|
|
4585
3803
|
const safeItem = sanitizeRemoteItem(item);
|
|
4586
3804
|
if (!safeItem) return;
|
|
@@ -4619,7 +3837,7 @@ function useRealtimeSync(state, rawDispatch, config, reducer2) {
|
|
|
4619
3837
|
dispatch({ type: "PEERS_SET", peers: [] });
|
|
4620
3838
|
};
|
|
4621
3839
|
}, [enabled, hasSession, config.syncToken, config.syncUrl, author, rawDispatch]);
|
|
4622
|
-
const wrapped =
|
|
3840
|
+
const wrapped = useMemo2(() => {
|
|
4623
3841
|
return (action) => {
|
|
4624
3842
|
const prev = stateRef.current;
|
|
4625
3843
|
rawDispatch(action);
|
|
@@ -4641,7 +3859,7 @@ function useRealtimeSync(state, rawDispatch, config, reducer2) {
|
|
|
4641
3859
|
}
|
|
4642
3860
|
};
|
|
4643
3861
|
}, [rawDispatch, reducer2]);
|
|
4644
|
-
|
|
3862
|
+
useEffect3(() => {
|
|
4645
3863
|
if (!enabled) return;
|
|
4646
3864
|
let lastEl = null;
|
|
4647
3865
|
let lastSel = null;
|
|
@@ -4670,18 +3888,21 @@ function useRealtimeSync(state, rawDispatch, config, reducer2) {
|
|
|
4670
3888
|
return () => document.removeEventListener("pointermove", onPointerMove);
|
|
4671
3889
|
}, [enabled]);
|
|
4672
3890
|
const selectingSelector = state.editor?.target.selector ?? state.selection?.target.selector ?? null;
|
|
4673
|
-
|
|
3891
|
+
useEffect3(() => {
|
|
4674
3892
|
if (!enabled) return;
|
|
4675
3893
|
syncRef.current?.sendSelecting(selectingSelector);
|
|
4676
3894
|
}, [enabled, selectingSelector]);
|
|
4677
3895
|
const editorOpen = state.editor !== null;
|
|
4678
|
-
|
|
3896
|
+
useEffect3(() => {
|
|
4679
3897
|
if (!enabled) return;
|
|
4680
3898
|
syncRef.current?.sendTyping(null, editorOpen);
|
|
4681
3899
|
}, [enabled, editorOpen]);
|
|
4682
3900
|
return enabled ? wrapped : rawDispatch;
|
|
4683
3901
|
}
|
|
4684
3902
|
|
|
3903
|
+
// src/client/components/Badge.tsx
|
|
3904
|
+
import { useLayoutEffect, useRef as useRef4, useState } from "react";
|
|
3905
|
+
|
|
4685
3906
|
// src/client/dragPosition.ts
|
|
4686
3907
|
var MARGIN = 8;
|
|
4687
3908
|
var SNAP = 14;
|
|
@@ -4723,6 +3944,9 @@ function snapClampPos(x, y, width, height) {
|
|
|
4723
3944
|
if (y > vh - height - 16 - SNAP) y = vh - height - 16;
|
|
4724
3945
|
return clampPos(x, y, width, height);
|
|
4725
3946
|
}
|
|
3947
|
+
|
|
3948
|
+
// src/client/components/Badge.tsx
|
|
3949
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
4726
3950
|
var POS_KEY = "review-kit:badge-pos";
|
|
4727
3951
|
var DRAG_THRESHOLD = 6;
|
|
4728
3952
|
function defaultPos(corner, width, height) {
|
|
@@ -4745,16 +3969,16 @@ function Badge() {
|
|
|
4745
3969
|
const { session, mode, panelOpen } = useStore();
|
|
4746
3970
|
const dispatch = useDispatch();
|
|
4747
3971
|
const config = useConfig();
|
|
4748
|
-
const ref =
|
|
4749
|
-
const clickTimer =
|
|
4750
|
-
const lastClickAt =
|
|
3972
|
+
const ref = useRef4(null);
|
|
3973
|
+
const clickTimer = useRef4(null);
|
|
3974
|
+
const lastClickAt = useRef4(0);
|
|
4751
3975
|
const [pos, setPos] = useState(() => readStoredPos(POS_KEY));
|
|
4752
3976
|
const [dragging, setDragging] = useState(false);
|
|
4753
|
-
const drag =
|
|
3977
|
+
const drag = useRef4(null);
|
|
4754
3978
|
const openCount = session?.items.filter((item) => item.status === "open").length ?? 0;
|
|
4755
3979
|
const applyPos = (next, persist) => {
|
|
4756
3980
|
setPos(next);
|
|
4757
|
-
storePos(POS_KEY, next);
|
|
3981
|
+
if (persist) storePos(POS_KEY, next);
|
|
4758
3982
|
const el = ref.current;
|
|
4759
3983
|
if (el) {
|
|
4760
3984
|
const effective = next ?? defaultPos(config.position ?? "bottom-right", el.offsetWidth, el.offsetHeight);
|
|
@@ -4828,7 +4052,7 @@ function Badge() {
|
|
|
4828
4052
|
if (clickTimer.current !== null) window.clearTimeout(clickTimer.current);
|
|
4829
4053
|
clickTimer.current = null;
|
|
4830
4054
|
lastClickAt.current = 0;
|
|
4831
|
-
applyPos(null);
|
|
4055
|
+
applyPos(null, true);
|
|
4832
4056
|
return;
|
|
4833
4057
|
}
|
|
4834
4058
|
lastClickAt.current = now;
|
|
@@ -4846,7 +4070,7 @@ function Badge() {
|
|
|
4846
4070
|
node.offsetHeight
|
|
4847
4071
|
);
|
|
4848
4072
|
node.style.translate = `${snapped.x}px ${snapped.y}px`;
|
|
4849
|
-
applyPos(snapped);
|
|
4073
|
+
applyPos(snapped, true);
|
|
4850
4074
|
};
|
|
4851
4075
|
window.addEventListener("pointermove", onMove, { passive: false });
|
|
4852
4076
|
window.addEventListener("pointerup", onUp);
|
|
@@ -4865,15 +4089,18 @@ function Badge() {
|
|
|
4865
4089
|
"aria-expanded": panelOpen,
|
|
4866
4090
|
onPointerDown,
|
|
4867
4091
|
children: [
|
|
4868
|
-
/* @__PURE__ */
|
|
4092
|
+
/* @__PURE__ */ jsx2("span", { className: "rk-badge-dot" }),
|
|
4869
4093
|
"Review",
|
|
4870
|
-
openCount > 0 && /* @__PURE__ */
|
|
4094
|
+
openCount > 0 && /* @__PURE__ */ jsx2("span", { className: "rk-badge-count", children: openCount })
|
|
4871
4095
|
]
|
|
4872
4096
|
}
|
|
4873
4097
|
);
|
|
4874
4098
|
}
|
|
4099
|
+
|
|
4100
|
+
// src/client/components/icons.tsx
|
|
4101
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
4875
4102
|
function Base({ size = 16, children, ...rest }) {
|
|
4876
|
-
return /* @__PURE__ */
|
|
4103
|
+
return /* @__PURE__ */ jsx3(
|
|
4877
4104
|
"svg",
|
|
4878
4105
|
{
|
|
4879
4106
|
width: size,
|
|
@@ -4892,170 +4119,177 @@ function Base({ size = 16, children, ...rest }) {
|
|
|
4892
4119
|
);
|
|
4893
4120
|
}
|
|
4894
4121
|
function IconText(props) {
|
|
4895
|
-
return /* @__PURE__ */
|
|
4896
|
-
/* @__PURE__ */
|
|
4897
|
-
/* @__PURE__ */
|
|
4898
|
-
/* @__PURE__ */
|
|
4122
|
+
return /* @__PURE__ */ jsxs2(Base, { ...props, children: [
|
|
4123
|
+
/* @__PURE__ */ jsx3("path", { d: "M3.5 4.5V3h9v1.5" }),
|
|
4124
|
+
/* @__PURE__ */ jsx3("path", { d: "M8 3v10" }),
|
|
4125
|
+
/* @__PURE__ */ jsx3("path", { d: "M6 13h4" })
|
|
4899
4126
|
] });
|
|
4900
4127
|
}
|
|
4901
4128
|
function IconImage(props) {
|
|
4902
|
-
return /* @__PURE__ */
|
|
4903
|
-
/* @__PURE__ */
|
|
4904
|
-
/* @__PURE__ */
|
|
4905
|
-
/* @__PURE__ */
|
|
4129
|
+
return /* @__PURE__ */ jsxs2(Base, { ...props, children: [
|
|
4130
|
+
/* @__PURE__ */ jsx3("rect", { x: "2.25", y: "3.25", width: "11.5", height: "9.5", rx: "1.5" }),
|
|
4131
|
+
/* @__PURE__ */ jsx3("circle", { cx: "5.75", cy: "6.5", r: "1", fill: "currentColor", stroke: "none" }),
|
|
4132
|
+
/* @__PURE__ */ jsx3("path", { d: "M2.5 11l3.2-3.2a1 1 0 0 1 1.4 0L10 10.7l1.4-1.4a1 1 0 0 1 1.4 0l.95.95" })
|
|
4906
4133
|
] });
|
|
4907
4134
|
}
|
|
4908
4135
|
function IconComment(props) {
|
|
4909
|
-
return /* @__PURE__ */
|
|
4136
|
+
return /* @__PURE__ */ jsx3(Base, { ...props, children: /* @__PURE__ */ jsx3("path", { d: "M13.5 7.6c0 2.7-2.46 4.6-5.5 4.6-.6 0-1.18-.07-1.72-.2L3.5 13.5l.55-2.2C3.06 10.45 2.5 9.1 2.5 7.6 2.5 4.9 4.96 3 8 3s5.5 1.9 5.5 4.6Z" }) });
|
|
4910
4137
|
}
|
|
4911
4138
|
function IconTrash(props) {
|
|
4912
|
-
return /* @__PURE__ */
|
|
4913
|
-
/* @__PURE__ */
|
|
4914
|
-
/* @__PURE__ */
|
|
4915
|
-
/* @__PURE__ */
|
|
4916
|
-
/* @__PURE__ */
|
|
4139
|
+
return /* @__PURE__ */ jsxs2(Base, { ...props, children: [
|
|
4140
|
+
/* @__PURE__ */ jsx3("path", { d: "M2.75 4.25h10.5" }),
|
|
4141
|
+
/* @__PURE__ */ jsx3("path", { d: "M5.5 4.25V3.4c0-.63.51-1.15 1.15-1.15h2.7c.64 0 1.15.52 1.15 1.15v.85" }),
|
|
4142
|
+
/* @__PURE__ */ jsx3("path", { d: "M4.25 4.5l.55 8.05c.04.62.56 1.1 1.18 1.1h4.04c.62 0 1.14-.48 1.18-1.1l.55-8.05" }),
|
|
4143
|
+
/* @__PURE__ */ jsx3("path", { d: "M6.6 7v3.8M9.4 7v3.8" })
|
|
4917
4144
|
] });
|
|
4918
4145
|
}
|
|
4919
4146
|
function IconMove(props) {
|
|
4920
|
-
return /* @__PURE__ */
|
|
4921
|
-
/* @__PURE__ */
|
|
4922
|
-
/* @__PURE__ */
|
|
4923
|
-
/* @__PURE__ */
|
|
4147
|
+
return /* @__PURE__ */ jsxs2(Base, { ...props, children: [
|
|
4148
|
+
/* @__PURE__ */ jsx3("path", { d: "M8 2.5v11" }),
|
|
4149
|
+
/* @__PURE__ */ jsx3("path", { d: "M5.25 5.25 8 2.5l2.75 2.75" }),
|
|
4150
|
+
/* @__PURE__ */ jsx3("path", { d: "M5.25 10.75 8 13.5l2.75-2.75" })
|
|
4924
4151
|
] });
|
|
4925
4152
|
}
|
|
4926
4153
|
function IconStyle(props) {
|
|
4927
|
-
return /* @__PURE__ */
|
|
4928
|
-
/* @__PURE__ */
|
|
4929
|
-
/* @__PURE__ */
|
|
4154
|
+
return /* @__PURE__ */ jsxs2(Base, { ...props, children: [
|
|
4155
|
+
/* @__PURE__ */ jsx3("path", { d: "M11.2 2.6a1.6 1.6 0 0 1 2.26 2.26L7.1 11.2l-3.1.85.84-3.1 6.36-6.35Z" }),
|
|
4156
|
+
/* @__PURE__ */ jsx3("path", { d: "M9.6 4.2l2.2 2.2" })
|
|
4930
4157
|
] });
|
|
4931
4158
|
}
|
|
4932
4159
|
function IconClose(props) {
|
|
4933
|
-
return /* @__PURE__ */
|
|
4160
|
+
return /* @__PURE__ */ jsx3(Base, { ...props, children: /* @__PURE__ */ jsx3("path", { d: "M4 4l8 8M12 4l-8 8" }) });
|
|
4934
4161
|
}
|
|
4935
4162
|
function IconSearch(props) {
|
|
4936
|
-
return /* @__PURE__ */
|
|
4937
|
-
/* @__PURE__ */
|
|
4938
|
-
/* @__PURE__ */
|
|
4163
|
+
return /* @__PURE__ */ jsxs2(Base, { ...props, children: [
|
|
4164
|
+
/* @__PURE__ */ jsx3("circle", { cx: "7", cy: "7", r: "4.25" }),
|
|
4165
|
+
/* @__PURE__ */ jsx3("path", { d: "M10.3 10.3 13.5 13.5" })
|
|
4939
4166
|
] });
|
|
4940
4167
|
}
|
|
4941
4168
|
function IconDownload(props) {
|
|
4942
|
-
return /* @__PURE__ */
|
|
4943
|
-
/* @__PURE__ */
|
|
4944
|
-
/* @__PURE__ */
|
|
4945
|
-
/* @__PURE__ */
|
|
4169
|
+
return /* @__PURE__ */ jsxs2(Base, { ...props, children: [
|
|
4170
|
+
/* @__PURE__ */ jsx3("path", { d: "M8 2.5v7.5" }),
|
|
4171
|
+
/* @__PURE__ */ jsx3("path", { d: "M5.25 7.5 8 10.25 10.75 7.5" }),
|
|
4172
|
+
/* @__PURE__ */ jsx3("path", { d: "M3 11.5v1a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1v-1" })
|
|
4946
4173
|
] });
|
|
4947
4174
|
}
|
|
4948
4175
|
function IconUpload(props) {
|
|
4949
|
-
return /* @__PURE__ */
|
|
4950
|
-
/* @__PURE__ */
|
|
4951
|
-
/* @__PURE__ */
|
|
4952
|
-
/* @__PURE__ */
|
|
4176
|
+
return /* @__PURE__ */ jsxs2(Base, { ...props, children: [
|
|
4177
|
+
/* @__PURE__ */ jsx3("path", { d: "M8 10V2.75" }),
|
|
4178
|
+
/* @__PURE__ */ jsx3("path", { d: "M5.25 5.25 8 2.5l2.75 2.75" }),
|
|
4179
|
+
/* @__PURE__ */ jsx3("path", { d: "M3 11.5v1a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1v-1" })
|
|
4953
4180
|
] });
|
|
4954
4181
|
}
|
|
4955
4182
|
function IconCopyClipboard(props) {
|
|
4956
|
-
return /* @__PURE__ */
|
|
4957
|
-
/* @__PURE__ */
|
|
4958
|
-
/* @__PURE__ */
|
|
4183
|
+
return /* @__PURE__ */ jsxs2(Base, { ...props, children: [
|
|
4184
|
+
/* @__PURE__ */ jsx3("rect", { x: "5.5", y: "5.5", width: "8", height: "8", rx: "1.5" }),
|
|
4185
|
+
/* @__PURE__ */ jsx3("path", { d: "M10.5 5.5v-2a1 1 0 0 0-1-1h-6a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2" })
|
|
4959
4186
|
] });
|
|
4960
4187
|
}
|
|
4961
4188
|
function IconUndo(props) {
|
|
4962
|
-
return /* @__PURE__ */
|
|
4963
|
-
/* @__PURE__ */
|
|
4964
|
-
/* @__PURE__ */
|
|
4189
|
+
return /* @__PURE__ */ jsxs2(Base, { ...props, children: [
|
|
4190
|
+
/* @__PURE__ */ jsx3("path", { d: "M3 6.5h6.5a3.5 3.5 0 0 1 0 7H6" }),
|
|
4191
|
+
/* @__PURE__ */ jsx3("path", { d: "M5.5 4 3 6.5 5.5 9" })
|
|
4965
4192
|
] });
|
|
4966
4193
|
}
|
|
4967
4194
|
function IconCheck(props) {
|
|
4968
|
-
return /* @__PURE__ */
|
|
4195
|
+
return /* @__PURE__ */ jsx3(Base, { ...props, children: /* @__PURE__ */ jsx3("path", { d: "M3 8.5 6.5 12 13 4.5" }) });
|
|
4969
4196
|
}
|
|
4970
4197
|
function IconWarning(props) {
|
|
4971
|
-
return /* @__PURE__ */
|
|
4972
|
-
/* @__PURE__ */
|
|
4973
|
-
/* @__PURE__ */
|
|
4974
|
-
/* @__PURE__ */
|
|
4198
|
+
return /* @__PURE__ */ jsxs2(Base, { ...props, children: [
|
|
4199
|
+
/* @__PURE__ */ jsx3("path", { d: "M8 2.75 14.5 13.5h-13L8 2.75Z" }),
|
|
4200
|
+
/* @__PURE__ */ jsx3("path", { d: "M8 7v3" }),
|
|
4201
|
+
/* @__PURE__ */ jsx3("circle", { cx: "8", cy: "11.9", r: "0.55", fill: "currentColor", stroke: "none" })
|
|
4975
4202
|
] });
|
|
4976
4203
|
}
|
|
4977
4204
|
function IconTarget(props) {
|
|
4978
|
-
return /* @__PURE__ */
|
|
4979
|
-
/* @__PURE__ */
|
|
4980
|
-
/* @__PURE__ */
|
|
4981
|
-
/* @__PURE__ */
|
|
4205
|
+
return /* @__PURE__ */ jsxs2(Base, { ...props, children: [
|
|
4206
|
+
/* @__PURE__ */ jsx3("circle", { cx: "8", cy: "8", r: "5.5" }),
|
|
4207
|
+
/* @__PURE__ */ jsx3("circle", { cx: "8", cy: "8", r: "1", fill: "currentColor", stroke: "none" }),
|
|
4208
|
+
/* @__PURE__ */ jsx3("path", { d: "M8 1.5v2M8 12.5v2M1.5 8h2M12.5 8h2" })
|
|
4982
4209
|
] });
|
|
4983
4210
|
}
|
|
4984
4211
|
function IconKeyboard(props) {
|
|
4985
|
-
return /* @__PURE__ */
|
|
4986
|
-
/* @__PURE__ */
|
|
4987
|
-
/* @__PURE__ */
|
|
4212
|
+
return /* @__PURE__ */ jsxs2(Base, { ...props, children: [
|
|
4213
|
+
/* @__PURE__ */ jsx3("rect", { x: "2", y: "4.5", width: "12", height: "7.5", rx: "1.5" }),
|
|
4214
|
+
/* @__PURE__ */ jsx3("path", { d: "M4.5 7h.01M7 7h.01M9.5 7h.01M12 7h.01M5 9.5h6" })
|
|
4988
4215
|
] });
|
|
4989
4216
|
}
|
|
4990
4217
|
function IconGear(props) {
|
|
4991
|
-
return /* @__PURE__ */
|
|
4992
|
-
/* @__PURE__ */
|
|
4993
|
-
/* @__PURE__ */
|
|
4218
|
+
return /* @__PURE__ */ jsxs2(Base, { ...props, children: [
|
|
4219
|
+
/* @__PURE__ */ jsx3("circle", { cx: "8", cy: "8", r: "2.1" }),
|
|
4220
|
+
/* @__PURE__ */ jsx3("path", { d: "M8 1.8v2M8 12.2v2M1.8 8h2M12.2 8h2M3.6 3.6l1.4 1.4M11 11l1.4 1.4M12.4 3.6 11 5M5 11l-1.4 1.4" })
|
|
4994
4221
|
] });
|
|
4995
4222
|
}
|
|
4996
4223
|
function IconFilter(props) {
|
|
4997
|
-
return /* @__PURE__ */
|
|
4224
|
+
return /* @__PURE__ */ jsx3(Base, { ...props, children: /* @__PURE__ */ jsx3("path", { d: "M2.5 4h11M4.5 8h7M6.5 12h3" }) });
|
|
4998
4225
|
}
|
|
4999
4226
|
function IconLink(props) {
|
|
5000
|
-
return /* @__PURE__ */
|
|
5001
|
-
/* @__PURE__ */
|
|
5002
|
-
/* @__PURE__ */
|
|
5003
|
-
/* @__PURE__ */
|
|
4227
|
+
return /* @__PURE__ */ jsxs2(Base, { ...props, children: [
|
|
4228
|
+
/* @__PURE__ */ jsx3("path", { d: "M6.5 9.5 9.5 6.5" }),
|
|
4229
|
+
/* @__PURE__ */ jsx3("path", { d: "M7.25 4.9 8.4 3.75a2.4 2.4 0 0 1 3.4 0 2.4 2.4 0 0 1 0 3.4L10.65 8.3" }),
|
|
4230
|
+
/* @__PURE__ */ jsx3("path", { d: "M8.75 11.1 7.6 12.25a2.4 2.4 0 0 1-3.4 0 2.4 2.4 0 0 1 0-3.4L5.35 7.7" })
|
|
5004
4231
|
] });
|
|
5005
4232
|
}
|
|
5006
4233
|
function IconUnlink(props) {
|
|
5007
|
-
return /* @__PURE__ */
|
|
5008
|
-
/* @__PURE__ */
|
|
5009
|
-
/* @__PURE__ */
|
|
4234
|
+
return /* @__PURE__ */ jsxs2(Base, { ...props, children: [
|
|
4235
|
+
/* @__PURE__ */ jsx3("path", { d: "M6.5 4.5v-2M9.5 13.5v-2M4.5 6.5h-2M13.5 9.5h-2" }),
|
|
4236
|
+
/* @__PURE__ */ jsx3("path", { d: "M6 10 3.5 12.5M10 6l2.5-2.5" })
|
|
5010
4237
|
] });
|
|
5011
4238
|
}
|
|
5012
4239
|
function iconForType(type, size = 14) {
|
|
5013
4240
|
switch (type) {
|
|
5014
4241
|
case "copy":
|
|
5015
|
-
return /* @__PURE__ */
|
|
4242
|
+
return /* @__PURE__ */ jsx3(IconText, { size });
|
|
5016
4243
|
case "image":
|
|
5017
|
-
return /* @__PURE__ */
|
|
4244
|
+
return /* @__PURE__ */ jsx3(IconImage, { size });
|
|
5018
4245
|
case "comment":
|
|
5019
|
-
return /* @__PURE__ */
|
|
4246
|
+
return /* @__PURE__ */ jsx3(IconComment, { size });
|
|
5020
4247
|
case "delete":
|
|
5021
|
-
return /* @__PURE__ */
|
|
4248
|
+
return /* @__PURE__ */ jsx3(IconTrash, { size });
|
|
5022
4249
|
case "move":
|
|
5023
|
-
return /* @__PURE__ */
|
|
4250
|
+
return /* @__PURE__ */ jsx3(IconMove, { size });
|
|
5024
4251
|
case "style":
|
|
5025
|
-
return /* @__PURE__ */
|
|
4252
|
+
return /* @__PURE__ */ jsx3(IconStyle, { size });
|
|
5026
4253
|
default:
|
|
5027
|
-
return /* @__PURE__ */
|
|
4254
|
+
return /* @__PURE__ */ jsx3(IconTarget, { size });
|
|
5028
4255
|
}
|
|
5029
4256
|
}
|
|
4257
|
+
|
|
4258
|
+
// src/client/components/CheatSheet.tsx
|
|
4259
|
+
import { Fragment, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
5030
4260
|
var GROUPS = ["Tools", "View", "Items", "Session"];
|
|
5031
4261
|
function CheatSheet() {
|
|
5032
4262
|
const { cheatsheetOpen } = useStore();
|
|
5033
4263
|
const dispatch = useDispatch();
|
|
5034
4264
|
if (!cheatsheetOpen) return null;
|
|
5035
4265
|
const close = () => dispatch({ type: "SET_CHEATSHEET", open: false });
|
|
5036
|
-
return /* @__PURE__ */
|
|
5037
|
-
/* @__PURE__ */
|
|
5038
|
-
/* @__PURE__ */
|
|
5039
|
-
/* @__PURE__ */
|
|
5040
|
-
/* @__PURE__ */
|
|
5041
|
-
/* @__PURE__ */
|
|
5042
|
-
/* @__PURE__ */
|
|
5043
|
-
/* @__PURE__ */
|
|
4266
|
+
return /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
4267
|
+
/* @__PURE__ */ jsx4("div", { className: "rk-backdrop", onClick: close }),
|
|
4268
|
+
/* @__PURE__ */ jsxs3("div", { className: "rk-modal rk-cheatsheet", role: "dialog", "aria-modal": "true", "aria-label": "Keyboard shortcuts", children: [
|
|
4269
|
+
/* @__PURE__ */ jsxs3("div", { className: "rk-cheat-head", children: [
|
|
4270
|
+
/* @__PURE__ */ jsx4("span", { className: "rk-cheat-head-icon", children: /* @__PURE__ */ jsx4(IconKeyboard, { size: 15 }) }),
|
|
4271
|
+
/* @__PURE__ */ jsx4("span", { className: "rk-cheat-title", children: "Keyboard shortcuts" }),
|
|
4272
|
+
/* @__PURE__ */ jsx4("span", { style: { flex: 1 } }),
|
|
4273
|
+
/* @__PURE__ */ jsx4("button", { type: "button", className: "rk-icon-btn", "aria-label": "Close", onClick: close, autoFocus: true, children: /* @__PURE__ */ jsx4(IconClose, { size: 13 }) })
|
|
5044
4274
|
] }),
|
|
5045
|
-
/* @__PURE__ */
|
|
5046
|
-
/* @__PURE__ */
|
|
5047
|
-
SHORTCUTS.filter((def) => def.group === group).map((def) => /* @__PURE__ */
|
|
5048
|
-
/* @__PURE__ */
|
|
5049
|
-
/* @__PURE__ */
|
|
5050
|
-
/* @__PURE__ */
|
|
4275
|
+
/* @__PURE__ */ jsx4("div", { className: "rk-cheat-grid", children: GROUPS.map((group) => /* @__PURE__ */ jsxs3("section", { className: "rk-cheat-group", children: [
|
|
4276
|
+
/* @__PURE__ */ jsx4("h3", { className: "rk-cheat-group-title", children: group }),
|
|
4277
|
+
SHORTCUTS.filter((def) => def.group === group).map((def) => /* @__PURE__ */ jsxs3("div", { className: "rk-shortcut-row", children: [
|
|
4278
|
+
/* @__PURE__ */ jsxs3("span", { className: "rk-shortcut-text", children: [
|
|
4279
|
+
/* @__PURE__ */ jsx4("span", { className: "rk-shortcut-title", children: def.title }),
|
|
4280
|
+
/* @__PURE__ */ jsx4("span", { className: "rk-shortcut-desc", children: def.description })
|
|
5051
4281
|
] }),
|
|
5052
|
-
/* @__PURE__ */
|
|
4282
|
+
/* @__PURE__ */ jsx4("span", { className: "rk-keys", children: displayKeys(def, IS_MAC).map((key) => /* @__PURE__ */ jsx4("span", { className: "rk-kbd", children: key }, key)) })
|
|
5053
4283
|
] }, def.id))
|
|
5054
4284
|
] }, group)) }),
|
|
5055
|
-
/* @__PURE__ */
|
|
4285
|
+
/* @__PURE__ */ jsx4("div", { className: "rk-egg", children: "Psst \u2014 the \u201C/\u201D box knows a few tricks it won\u2019t tell you about." })
|
|
5056
4286
|
] })
|
|
5057
4287
|
] });
|
|
5058
4288
|
}
|
|
4289
|
+
|
|
4290
|
+
// src/client/components/EmblemaConnect.tsx
|
|
4291
|
+
import { useEffect as useEffect4, useState as useState2 } from "react";
|
|
4292
|
+
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
5059
4293
|
function shortKey(key) {
|
|
5060
4294
|
return `${key.slice(0, 4)}\u2026${key.slice(-4)}`;
|
|
5061
4295
|
}
|
|
@@ -5070,14 +4304,14 @@ function ago(iso) {
|
|
|
5070
4304
|
function EmblemaConnect() {
|
|
5071
4305
|
const { emblemaConnectOpen } = useStore();
|
|
5072
4306
|
const dispatch = useDispatch();
|
|
5073
|
-
const [state, setState] =
|
|
5074
|
-
const [key, setKey] =
|
|
5075
|
-
const [busy, setBusy] =
|
|
4307
|
+
const [state, setState] = useState2("loading");
|
|
4308
|
+
const [key, setKey] = useState2(null);
|
|
4309
|
+
const [busy, setBusy] = useState2(false);
|
|
5076
4310
|
const refresh = () => {
|
|
5077
4311
|
setState("loading");
|
|
5078
4312
|
void fetchSyncState().then(setState);
|
|
5079
4313
|
};
|
|
5080
|
-
|
|
4314
|
+
useEffect4(() => {
|
|
5081
4315
|
if (emblemaConnectOpen) {
|
|
5082
4316
|
setKey(null);
|
|
5083
4317
|
refresh();
|
|
@@ -5106,48 +4340,48 @@ function EmblemaConnect() {
|
|
|
5106
4340
|
refresh();
|
|
5107
4341
|
}).finally(() => setBusy(false));
|
|
5108
4342
|
};
|
|
5109
|
-
return /* @__PURE__ */
|
|
5110
|
-
/* @__PURE__ */
|
|
5111
|
-
/* @__PURE__ */
|
|
5112
|
-
/* @__PURE__ */
|
|
4343
|
+
return /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
4344
|
+
/* @__PURE__ */ jsx5("div", { className: "rk-backdrop", onClick: close }),
|
|
4345
|
+
/* @__PURE__ */ jsx5("div", { className: "rk-modal", role: "dialog", "aria-modal": "true", "aria-label": "Connect to Emblema", children: /* @__PURE__ */ jsxs4("div", { className: "rk-modal-body", children: [
|
|
4346
|
+
/* @__PURE__ */ jsxs4("div", { className: "rk-modal-title", style: { display: "flex", alignItems: "center", gap: 8 }, children: [
|
|
5113
4347
|
"Connect to Emblema",
|
|
5114
|
-
/* @__PURE__ */
|
|
5115
|
-
/* @__PURE__ */
|
|
4348
|
+
/* @__PURE__ */ jsx5("span", { style: { flex: 1 } }),
|
|
4349
|
+
/* @__PURE__ */ jsx5("button", { type: "button", className: "rk-icon-btn", "aria-label": "Close", onClick: close, autoFocus: true, children: /* @__PURE__ */ jsx5(IconClose, { size: 13 }) })
|
|
5116
4350
|
] }),
|
|
5117
|
-
state === "loading" && /* @__PURE__ */
|
|
5118
|
-
state === null && /* @__PURE__ */
|
|
4351
|
+
state === "loading" && /* @__PURE__ */ jsx5("div", { className: "rk-modal-text", children: "Looking for the local sync agent\u2026" }),
|
|
4352
|
+
state === null && /* @__PURE__ */ jsxs4("div", { className: "rk-modal-text", children: [
|
|
5119
4353
|
"The local sync agent isn't running. In the project repo run:",
|
|
5120
|
-
/* @__PURE__ */
|
|
5121
|
-
"npx reviewkit-
|
|
4354
|
+
/* @__PURE__ */ jsxs4("code", { className: "rk-connect-cmd", children: [
|
|
4355
|
+
"npx @satanwagen/reviewkit-cli init --origin ",
|
|
5122
4356
|
window.location.origin
|
|
5123
4357
|
] }),
|
|
5124
|
-
/* @__PURE__ */
|
|
4358
|
+
/* @__PURE__ */ jsx5("code", { className: "rk-connect-cmd", children: "npx @satanwagen/reviewkit-cli serve" }),
|
|
5125
4359
|
"then reopen this dialog."
|
|
5126
4360
|
] }),
|
|
5127
|
-
state !== null && state !== "loading" && /* @__PURE__ */
|
|
5128
|
-
/* @__PURE__ */
|
|
4361
|
+
state !== null && state !== "loading" && /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
4362
|
+
/* @__PURE__ */ jsxs4("div", { className: "rk-modal-text", children: [
|
|
5129
4363
|
"Project ",
|
|
5130
|
-
/* @__PURE__ */
|
|
4364
|
+
/* @__PURE__ */ jsx5("strong", { children: state.name }),
|
|
5131
4365
|
" ",
|
|
5132
|
-
/* @__PURE__ */
|
|
4366
|
+
/* @__PURE__ */ jsxs4("span", { className: "rk-connect-id", children: [
|
|
5133
4367
|
"(",
|
|
5134
4368
|
state.id,
|
|
5135
4369
|
")"
|
|
5136
4370
|
] }),
|
|
5137
|
-
/* @__PURE__ */
|
|
4371
|
+
/* @__PURE__ */ jsx5("br", {}),
|
|
5138
4372
|
"Status:",
|
|
5139
4373
|
" ",
|
|
5140
|
-
state.revoked ? /* @__PURE__ */
|
|
5141
|
-
/* @__PURE__ */
|
|
4374
|
+
state.revoked ? /* @__PURE__ */ jsx5("span", { className: "rk-connect-bad", children: "revoked \u2014 generate a new key to reconnect" }) : /* @__PURE__ */ jsx5(Fragment2, { children: "paired key active" }),
|
|
4375
|
+
/* @__PURE__ */ jsx5("br", {}),
|
|
5142
4376
|
"Last confirmed by Emblema: ",
|
|
5143
|
-
/* @__PURE__ */
|
|
4377
|
+
/* @__PURE__ */ jsx5("strong", { children: ago(state.lastAck) }),
|
|
5144
4378
|
" \xB7 ",
|
|
5145
4379
|
state.findings,
|
|
5146
4380
|
" finding",
|
|
5147
4381
|
state.findings === 1 ? "" : "s",
|
|
5148
4382
|
" tracked"
|
|
5149
4383
|
] }),
|
|
5150
|
-
key && /* @__PURE__ */
|
|
4384
|
+
key && /* @__PURE__ */ jsx5(
|
|
5151
4385
|
"code",
|
|
5152
4386
|
{
|
|
5153
4387
|
className: "rk-connect-key",
|
|
@@ -5155,8 +4389,8 @@ function EmblemaConnect() {
|
|
|
5155
4389
|
children: shortKey(key)
|
|
5156
4390
|
}
|
|
5157
4391
|
),
|
|
5158
|
-
/* @__PURE__ */
|
|
5159
|
-
/* @__PURE__ */
|
|
4392
|
+
/* @__PURE__ */ jsxs4("div", { className: "rk-connect-actions", children: [
|
|
4393
|
+
/* @__PURE__ */ jsx5(
|
|
5160
4394
|
"button",
|
|
5161
4395
|
{
|
|
5162
4396
|
type: "button",
|
|
@@ -5167,7 +4401,7 @@ function EmblemaConnect() {
|
|
|
5167
4401
|
children: state.revoked ? "Generate new key" : "New key (rotate)"
|
|
5168
4402
|
}
|
|
5169
4403
|
),
|
|
5170
|
-
/* @__PURE__ */
|
|
4404
|
+
/* @__PURE__ */ jsx5(
|
|
5171
4405
|
"button",
|
|
5172
4406
|
{
|
|
5173
4407
|
type: "button",
|
|
@@ -5184,8 +4418,8 @@ function EmblemaConnect() {
|
|
|
5184
4418
|
children: "Copy key"
|
|
5185
4419
|
}
|
|
5186
4420
|
),
|
|
5187
|
-
/* @__PURE__ */
|
|
5188
|
-
/* @__PURE__ */
|
|
4421
|
+
/* @__PURE__ */ jsx5("span", { style: { flex: 1 } }),
|
|
4422
|
+
/* @__PURE__ */ jsx5(
|
|
5189
4423
|
"button",
|
|
5190
4424
|
{
|
|
5191
4425
|
type: "button",
|
|
@@ -5207,12 +4441,16 @@ function EmblemaConnect() {
|
|
|
5207
4441
|
] }) })
|
|
5208
4442
|
] });
|
|
5209
4443
|
}
|
|
4444
|
+
|
|
4445
|
+
// src/client/components/CoachMark.tsx
|
|
4446
|
+
import { useState as useState3 } from "react";
|
|
4447
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
5210
4448
|
var COACH_KEY = "review-kit:coach-dismissed";
|
|
5211
4449
|
function CoachMark() {
|
|
5212
4450
|
const { coachOpen, session } = useStore();
|
|
5213
4451
|
const dispatch = useDispatch();
|
|
5214
4452
|
const config = useConfig();
|
|
5215
|
-
const [name, setName] =
|
|
4453
|
+
const [name, setName] = useState3(session?.author ?? config.defaultAuthor ?? "");
|
|
5216
4454
|
if (!coachOpen) return null;
|
|
5217
4455
|
const done = (startPicking) => {
|
|
5218
4456
|
if (name.trim() !== "") dispatch({ type: "SET_AUTHOR", author: name.trim() });
|
|
@@ -5223,39 +4461,39 @@ function CoachMark() {
|
|
|
5223
4461
|
}
|
|
5224
4462
|
if (startPicking) dispatch({ type: "SET_MODE", mode: "pick" });
|
|
5225
4463
|
};
|
|
5226
|
-
return /* @__PURE__ */
|
|
5227
|
-
/* @__PURE__ */
|
|
5228
|
-
/* @__PURE__ */
|
|
5229
|
-
/* @__PURE__ */
|
|
5230
|
-
/* @__PURE__ */
|
|
4464
|
+
return /* @__PURE__ */ jsxs5("div", { className: "rk-coach", role: "dialog", "aria-label": "Welcome to review mode", children: [
|
|
4465
|
+
/* @__PURE__ */ jsx6("div", { className: "rk-coach-accent" }),
|
|
4466
|
+
/* @__PURE__ */ jsxs5("div", { className: "rk-coach-body", children: [
|
|
4467
|
+
/* @__PURE__ */ jsxs5("div", { className: "rk-modal-title", style: { display: "flex", alignItems: "center", gap: 8 }, children: [
|
|
4468
|
+
/* @__PURE__ */ jsx6(IconTarget, { size: 16 }),
|
|
5231
4469
|
" Review mode"
|
|
5232
4470
|
] }),
|
|
5233
|
-
/* @__PURE__ */
|
|
5234
|
-
/* @__PURE__ */
|
|
5235
|
-
/* @__PURE__ */
|
|
5236
|
-
/* @__PURE__ */
|
|
4471
|
+
/* @__PURE__ */ jsx6("div", { className: "rk-modal-text", children: "Click anything on the page to suggest a change \u2014 rewrite the copy, swap an image, or leave a note. The live site stays untouched; everything you add is collected for the team." }),
|
|
4472
|
+
/* @__PURE__ */ jsxs5("div", { className: "rk-coach-keys", "aria-label": "Key shortcuts", children: [
|
|
4473
|
+
/* @__PURE__ */ jsxs5("span", { children: [
|
|
4474
|
+
/* @__PURE__ */ jsx6("span", { className: "rk-kbd", children: "T" }),
|
|
5237
4475
|
" rewrite"
|
|
5238
4476
|
] }),
|
|
5239
|
-
/* @__PURE__ */
|
|
5240
|
-
/* @__PURE__ */
|
|
4477
|
+
/* @__PURE__ */ jsxs5("span", { children: [
|
|
4478
|
+
/* @__PURE__ */ jsx6("span", { className: "rk-kbd", children: "C" }),
|
|
5241
4479
|
" comment"
|
|
5242
4480
|
] }),
|
|
5243
|
-
/* @__PURE__ */
|
|
5244
|
-
/* @__PURE__ */
|
|
4481
|
+
/* @__PURE__ */ jsxs5("span", { children: [
|
|
4482
|
+
/* @__PURE__ */ jsx6("span", { className: "rk-kbd", children: "I" }),
|
|
5245
4483
|
" image"
|
|
5246
4484
|
] }),
|
|
5247
|
-
/* @__PURE__ */
|
|
5248
|
-
/* @__PURE__ */
|
|
4485
|
+
/* @__PURE__ */ jsxs5("span", { children: [
|
|
4486
|
+
/* @__PURE__ */ jsx6("span", { className: "rk-kbd", children: "V" }),
|
|
5249
4487
|
" select"
|
|
5250
4488
|
] }),
|
|
5251
|
-
/* @__PURE__ */
|
|
5252
|
-
/* @__PURE__ */
|
|
4489
|
+
/* @__PURE__ */ jsxs5("span", { children: [
|
|
4490
|
+
/* @__PURE__ */ jsx6("span", { className: "rk-kbd", children: "?" }),
|
|
5253
4491
|
" all shortcuts"
|
|
5254
4492
|
] })
|
|
5255
4493
|
] }),
|
|
5256
|
-
/* @__PURE__ */
|
|
5257
|
-
/* @__PURE__ */
|
|
5258
|
-
/* @__PURE__ */
|
|
4494
|
+
/* @__PURE__ */ jsxs5("div", { children: [
|
|
4495
|
+
/* @__PURE__ */ jsx6("label", { className: "rk-label", htmlFor: "rk-author", children: "Your name" }),
|
|
4496
|
+
/* @__PURE__ */ jsx6(
|
|
5259
4497
|
"input",
|
|
5260
4498
|
{
|
|
5261
4499
|
id: "rk-author",
|
|
@@ -5269,32 +4507,36 @@ function CoachMark() {
|
|
|
5269
4507
|
}
|
|
5270
4508
|
)
|
|
5271
4509
|
] }),
|
|
5272
|
-
/* @__PURE__ */
|
|
5273
|
-
/* @__PURE__ */
|
|
5274
|
-
/* @__PURE__ */
|
|
4510
|
+
/* @__PURE__ */ jsxs5("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 4 }, children: [
|
|
4511
|
+
/* @__PURE__ */ jsx6("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => done(false), children: "Not now" }),
|
|
4512
|
+
/* @__PURE__ */ jsx6("button", { type: "button", className: "rk-btn rk-btn-primary", onClick: () => done(true), children: "Start reviewing" })
|
|
5275
4513
|
] })
|
|
5276
4514
|
] })
|
|
5277
4515
|
] });
|
|
5278
4516
|
}
|
|
4517
|
+
|
|
4518
|
+
// src/client/components/Confirm.tsx
|
|
4519
|
+
import { useEffect as useEffect5, useRef as useRef5 } from "react";
|
|
4520
|
+
import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
5279
4521
|
function ConfirmHost() {
|
|
5280
4522
|
const { confirm } = useStore();
|
|
5281
4523
|
const dispatch = useDispatch();
|
|
5282
|
-
const cancelRef =
|
|
5283
|
-
|
|
4524
|
+
const cancelRef = useRef5(null);
|
|
4525
|
+
useEffect5(() => {
|
|
5284
4526
|
if (confirm) cancelRef.current?.focus();
|
|
5285
4527
|
}, [confirm]);
|
|
5286
4528
|
if (!confirm) return null;
|
|
5287
4529
|
const close = () => dispatch({ type: "SET_CONFIRM", confirm: null });
|
|
5288
|
-
return /* @__PURE__ */
|
|
5289
|
-
/* @__PURE__ */
|
|
5290
|
-
/* @__PURE__ */
|
|
5291
|
-
/* @__PURE__ */
|
|
5292
|
-
/* @__PURE__ */
|
|
5293
|
-
/* @__PURE__ */
|
|
4530
|
+
return /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
4531
|
+
/* @__PURE__ */ jsx7("div", { className: "rk-backdrop", onClick: close }),
|
|
4532
|
+
/* @__PURE__ */ jsxs6("div", { className: "rk-modal", role: "alertdialog", "aria-modal": "true", "aria-label": confirm.title, children: [
|
|
4533
|
+
/* @__PURE__ */ jsxs6("div", { className: "rk-modal-body", children: [
|
|
4534
|
+
/* @__PURE__ */ jsx7("div", { className: "rk-modal-title", children: confirm.title }),
|
|
4535
|
+
/* @__PURE__ */ jsx7("div", { className: "rk-modal-text", children: confirm.message })
|
|
5294
4536
|
] }),
|
|
5295
|
-
/* @__PURE__ */
|
|
5296
|
-
/* @__PURE__ */
|
|
5297
|
-
/* @__PURE__ */
|
|
4537
|
+
/* @__PURE__ */ jsxs6("div", { className: "rk-modal-actions", children: [
|
|
4538
|
+
/* @__PURE__ */ jsx7("button", { ref: cancelRef, type: "button", className: "rk-btn rk-btn-ghost", onClick: close, children: "Cancel" }),
|
|
4539
|
+
/* @__PURE__ */ jsx7(
|
|
5298
4540
|
"button",
|
|
5299
4541
|
{
|
|
5300
4542
|
type: "button",
|
|
@@ -5312,6 +4554,12 @@ function ConfirmHost() {
|
|
|
5312
4554
|
] });
|
|
5313
4555
|
}
|
|
5314
4556
|
|
|
4557
|
+
// src/client/components/ImageEditor.tsx
|
|
4558
|
+
import { useEffect as useEffect6, useRef as useRef7, useState as useState5 } from "react";
|
|
4559
|
+
|
|
4560
|
+
// src/client/useAnchored.ts
|
|
4561
|
+
import { useLayoutEffect as useLayoutEffect2, useRef as useRef6, useState as useState4 } from "react";
|
|
4562
|
+
|
|
5315
4563
|
// src/client/position.ts
|
|
5316
4564
|
function place(anchor, size, side, offset) {
|
|
5317
4565
|
switch (side) {
|
|
@@ -5355,9 +4603,9 @@ function computePosition(anchor, size, options = {}) {
|
|
|
5355
4603
|
|
|
5356
4604
|
// src/client/useAnchored.ts
|
|
5357
4605
|
function useAnchored(anchorEl, side = "bottom", offset = 8) {
|
|
5358
|
-
const ref =
|
|
5359
|
-
const [pos, setPos] =
|
|
5360
|
-
|
|
4606
|
+
const ref = useRef6(null);
|
|
4607
|
+
const [pos, setPos] = useState4(null);
|
|
4608
|
+
useLayoutEffect2(() => {
|
|
5361
4609
|
if (!anchorEl) {
|
|
5362
4610
|
setPos(null);
|
|
5363
4611
|
return;
|
|
@@ -5386,6 +4634,9 @@ function anchoredStyle(pos) {
|
|
|
5386
4634
|
if (!pos) return { visibility: "hidden", transform: "translate3d(-9999px, -9999px, 0)" };
|
|
5387
4635
|
return { transform: `translate3d(${pos.x}px, ${pos.y}px, 0)`, top: 0, left: 0 };
|
|
5388
4636
|
}
|
|
4637
|
+
|
|
4638
|
+
// src/client/components/ImageEditor.tsx
|
|
4639
|
+
import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
5389
4640
|
var MAX_BYTES = 2 * 1024 * 1024;
|
|
5390
4641
|
var FETCH_TIMEOUT_MS = 12e3;
|
|
5391
4642
|
var PROBE_TIMEOUT_MS = 8e3;
|
|
@@ -5443,15 +4694,15 @@ function urlFromDataTransfer(dt) {
|
|
|
5443
4694
|
function ImageEditor({ editor }) {
|
|
5444
4695
|
const dispatch = useDispatch();
|
|
5445
4696
|
const { route, session } = useStore();
|
|
5446
|
-
const [replacement, setReplacement] =
|
|
5447
|
-
const [urlValue, setUrlValue] =
|
|
5448
|
-
const [
|
|
5449
|
-
const [description, setDescription] =
|
|
5450
|
-
const [priority, setPriority] =
|
|
5451
|
-
const [over, setOver] =
|
|
5452
|
-
const fileInput =
|
|
5453
|
-
const abortRef =
|
|
5454
|
-
const debounceRef =
|
|
4697
|
+
const [replacement, setReplacement] = useState5(null);
|
|
4698
|
+
const [urlValue, setUrlValue] = useState5("");
|
|
4699
|
+
const [loading2, setLoading] = useState5(false);
|
|
4700
|
+
const [description, setDescription] = useState5("");
|
|
4701
|
+
const [priority, setPriority] = useState5("nice");
|
|
4702
|
+
const [over, setOver] = useState5(false);
|
|
4703
|
+
const fileInput = useRef7(null);
|
|
4704
|
+
const abortRef = useRef7(null);
|
|
4705
|
+
const debounceRef = useRef7(null);
|
|
5455
4706
|
const { ref, pos } = useAnchored(editor.element, "bottom", 12);
|
|
5456
4707
|
const image = findImage(editor.element);
|
|
5457
4708
|
const beforeSrc = image?.currentSrc || image?.src || "";
|
|
@@ -5515,7 +4766,7 @@ function ImageEditor({ editor }) {
|
|
|
5515
4766
|
}
|
|
5516
4767
|
}
|
|
5517
4768
|
};
|
|
5518
|
-
|
|
4769
|
+
useEffect6(() => {
|
|
5519
4770
|
if (debounceRef.current !== null) window.clearTimeout(debounceRef.current);
|
|
5520
4771
|
if (urlValue.trim() === "" || replacement !== null) return;
|
|
5521
4772
|
debounceRef.current = window.setTimeout(() => {
|
|
@@ -5525,8 +4776,8 @@ function ImageEditor({ editor }) {
|
|
|
5525
4776
|
if (debounceRef.current !== null) window.clearTimeout(debounceRef.current);
|
|
5526
4777
|
};
|
|
5527
4778
|
}, [urlValue, replacement]);
|
|
5528
|
-
|
|
5529
|
-
|
|
4779
|
+
useEffect6(() => () => abortRef.current?.abort(), []);
|
|
4780
|
+
useEffect6(() => {
|
|
5530
4781
|
const onPaste = (event) => {
|
|
5531
4782
|
const data = event.clipboardData;
|
|
5532
4783
|
if (!data) return;
|
|
@@ -5604,23 +4855,23 @@ function ImageEditor({ editor }) {
|
|
|
5604
4855
|
toast(dispatch, "Image proposal saved", "success");
|
|
5605
4856
|
};
|
|
5606
4857
|
const previewSrc = replacement?.kind === "data" ? replacement.dataUrl : replacement?.url;
|
|
5607
|
-
return /* @__PURE__ */
|
|
5608
|
-
/* @__PURE__ */
|
|
5609
|
-
/* @__PURE__ */
|
|
4858
|
+
return /* @__PURE__ */ jsxs7("div", { ref, className: "rk-card", style: anchoredStyle(pos), role: "dialog", "aria-label": "Replace image", children: [
|
|
4859
|
+
/* @__PURE__ */ jsxs7("div", { className: "rk-card-head", children: [
|
|
4860
|
+
/* @__PURE__ */ jsx8(IconImage, { size: 14 }),
|
|
5610
4861
|
"Replace image"
|
|
5611
4862
|
] }),
|
|
5612
|
-
/* @__PURE__ */
|
|
5613
|
-
replacement && previewSrc ? /* @__PURE__ */
|
|
5614
|
-
/* @__PURE__ */
|
|
5615
|
-
/* @__PURE__ */
|
|
5616
|
-
/* @__PURE__ */
|
|
4863
|
+
/* @__PURE__ */ jsxs7("div", { className: "rk-card-body", children: [
|
|
4864
|
+
replacement && previewSrc ? /* @__PURE__ */ jsx8("div", { className: "rk-thumbs", children: /* @__PURE__ */ jsxs7("div", { className: "rk-thumb-pair", title: "Hover to compare with the current image", children: [
|
|
4865
|
+
/* @__PURE__ */ jsxs7("figure", { className: "rk-thumb", children: [
|
|
4866
|
+
/* @__PURE__ */ jsx8("img", { src: beforeSrc, alt: "Current" }),
|
|
4867
|
+
/* @__PURE__ */ jsx8("figcaption", { children: "Before" })
|
|
5617
4868
|
] }),
|
|
5618
|
-
/* @__PURE__ */
|
|
5619
|
-
/* @__PURE__ */
|
|
5620
|
-
/* @__PURE__ */
|
|
4869
|
+
/* @__PURE__ */ jsxs7("figure", { className: "rk-thumb", children: [
|
|
4870
|
+
/* @__PURE__ */ jsx8("img", { src: previewSrc, alt: "Proposed replacement" }),
|
|
4871
|
+
/* @__PURE__ */ jsx8("figcaption", { children: replacement.kind === "url" ? "After \xB7 linked" : "After" })
|
|
5621
4872
|
] })
|
|
5622
|
-
] }) }) : /* @__PURE__ */
|
|
5623
|
-
/* @__PURE__ */
|
|
4873
|
+
] }) }) : /* @__PURE__ */ jsxs7(Fragment4, { children: [
|
|
4874
|
+
/* @__PURE__ */ jsxs7(
|
|
5624
4875
|
"button",
|
|
5625
4876
|
{
|
|
5626
4877
|
type: "button",
|
|
@@ -5633,18 +4884,18 @@ function ImageEditor({ editor }) {
|
|
|
5633
4884
|
onDragLeave: () => setOver(false),
|
|
5634
4885
|
onDrop,
|
|
5635
4886
|
children: [
|
|
5636
|
-
/* @__PURE__ */
|
|
5637
|
-
/* @__PURE__ */
|
|
4887
|
+
/* @__PURE__ */ jsx8(IconUpload, { size: 18 }),
|
|
4888
|
+
/* @__PURE__ */ jsxs7("span", { children: [
|
|
5638
4889
|
"Drop an image \u2014 from your disk or another tab \u2014",
|
|
5639
|
-
/* @__PURE__ */
|
|
4890
|
+
/* @__PURE__ */ jsx8("br", {}),
|
|
5640
4891
|
"or click to browse (max 2 MB)"
|
|
5641
4892
|
] })
|
|
5642
4893
|
]
|
|
5643
4894
|
}
|
|
5644
4895
|
),
|
|
5645
|
-
/* @__PURE__ */
|
|
5646
|
-
|
|
5647
|
-
/* @__PURE__ */
|
|
4896
|
+
/* @__PURE__ */ jsxs7("div", { className: "rk-url", children: [
|
|
4897
|
+
loading2 ? /* @__PURE__ */ jsx8("span", { className: "rk-spinner", "aria-label": "Loading image" }) : /* @__PURE__ */ jsx8(IconLink, { size: 13 }),
|
|
4898
|
+
/* @__PURE__ */ jsx8(
|
|
5648
4899
|
"input",
|
|
5649
4900
|
{
|
|
5650
4901
|
className: "rk-input",
|
|
@@ -5659,9 +4910,9 @@ function ImageEditor({ editor }) {
|
|
|
5659
4910
|
)
|
|
5660
4911
|
] })
|
|
5661
4912
|
] }),
|
|
5662
|
-
replacement && /* @__PURE__ */
|
|
5663
|
-
/* @__PURE__ */
|
|
5664
|
-
/* @__PURE__ */
|
|
4913
|
+
replacement && /* @__PURE__ */ jsx8("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: clearReplacement, children: "Remove replacement" }),
|
|
4914
|
+
/* @__PURE__ */ jsx8("input", { ref: fileInput, type: "file", accept: "image/*", hidden: true, onChange: onPick }),
|
|
4915
|
+
/* @__PURE__ */ jsx8(
|
|
5665
4916
|
"textarea",
|
|
5666
4917
|
{
|
|
5667
4918
|
className: "rk-textarea",
|
|
@@ -5671,39 +4922,43 @@ function ImageEditor({ editor }) {
|
|
|
5671
4922
|
rows: 2
|
|
5672
4923
|
}
|
|
5673
4924
|
),
|
|
5674
|
-
/* @__PURE__ */
|
|
5675
|
-
/* @__PURE__ */
|
|
5676
|
-
/* @__PURE__ */
|
|
4925
|
+
/* @__PURE__ */ jsxs7("div", { className: "rk-seg", role: "group", "aria-label": "Priority", children: [
|
|
4926
|
+
/* @__PURE__ */ jsx8("button", { type: "button", "aria-pressed": priority === "must", onClick: () => setPriority("must"), children: "Must" }),
|
|
4927
|
+
/* @__PURE__ */ jsx8("button", { type: "button", "aria-pressed": priority === "nice", onClick: () => setPriority("nice"), children: "Nice to have" })
|
|
5677
4928
|
] })
|
|
5678
4929
|
] }),
|
|
5679
|
-
/* @__PURE__ */
|
|
5680
|
-
/* @__PURE__ */
|
|
5681
|
-
/* @__PURE__ */
|
|
4930
|
+
/* @__PURE__ */ jsxs7("div", { className: "rk-card-foot", children: [
|
|
4931
|
+
/* @__PURE__ */ jsxs7("span", { className: "rk-hint", children: [
|
|
4932
|
+
/* @__PURE__ */ jsx8("span", { className: "rk-kbd", children: "esc" }),
|
|
5682
4933
|
" cancel"
|
|
5683
4934
|
] }),
|
|
5684
|
-
/* @__PURE__ */
|
|
5685
|
-
/* @__PURE__ */
|
|
5686
|
-
/* @__PURE__ */
|
|
4935
|
+
/* @__PURE__ */ jsxs7("div", { className: "rk-actions", children: [
|
|
4936
|
+
/* @__PURE__ */ jsx8("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => dispatch({ type: "CLOSE_EDITOR" }), children: "Cancel" }),
|
|
4937
|
+
/* @__PURE__ */ jsx8("button", { type: "button", className: "rk-btn rk-btn-primary", onClick: save, children: "Save" })
|
|
5687
4938
|
] })
|
|
5688
4939
|
] })
|
|
5689
4940
|
] });
|
|
5690
4941
|
}
|
|
4942
|
+
|
|
4943
|
+
// src/client/components/InlineEditor.tsx
|
|
4944
|
+
import { useEffect as useEffect7, useRef as useRef8, useState as useState6 } from "react";
|
|
4945
|
+
import { Fragment as Fragment5, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
5691
4946
|
function InlineEditor({ editor }) {
|
|
5692
4947
|
const dispatch = useDispatch();
|
|
5693
4948
|
const { route, session } = useStore();
|
|
5694
|
-
const [after, setAfter] =
|
|
5695
|
-
const [priority, setPriority] =
|
|
5696
|
-
const [note, setNote] =
|
|
5697
|
-
const original =
|
|
5698
|
-
const baseline =
|
|
5699
|
-
const [sizeDelta, setSizeDelta] =
|
|
5700
|
-
const [widthDelta, setWidthDelta] =
|
|
5701
|
-
const [clipped, setClipped] =
|
|
5702
|
-
const ringRef =
|
|
5703
|
-
const afterRef =
|
|
4949
|
+
const [after, setAfter] = useState6(() => editor.element.innerText);
|
|
4950
|
+
const [priority, setPriority] = useState6("nice");
|
|
4951
|
+
const [note, setNote] = useState6("");
|
|
4952
|
+
const original = useRef8(null);
|
|
4953
|
+
const baseline = useRef8(null);
|
|
4954
|
+
const [sizeDelta, setSizeDelta] = useState6(0);
|
|
4955
|
+
const [widthDelta, setWidthDelta] = useState6(0);
|
|
4956
|
+
const [clipped, setClipped] = useState6(false);
|
|
4957
|
+
const ringRef = useRef8(null);
|
|
4958
|
+
const afterRef = useRef8(null);
|
|
5704
4959
|
const { ref, pos } = useAnchored(editor.element, "bottom", 12);
|
|
5705
4960
|
const element = editor.element;
|
|
5706
|
-
|
|
4961
|
+
useEffect7(() => {
|
|
5707
4962
|
const el = element;
|
|
5708
4963
|
original.current = { html: el.innerHTML, text: el.innerText, styleAttr: el.getAttribute("style") };
|
|
5709
4964
|
const rect = el.getBoundingClientRect();
|
|
@@ -5733,8 +4988,8 @@ function InlineEditor({ editor }) {
|
|
|
5733
4988
|
}
|
|
5734
4989
|
};
|
|
5735
4990
|
}, [element]);
|
|
5736
|
-
const focusedOnce =
|
|
5737
|
-
|
|
4991
|
+
const focusedOnce = useRef8(false);
|
|
4992
|
+
useEffect7(() => {
|
|
5738
4993
|
const field = afterRef.current;
|
|
5739
4994
|
if (pos === null || focusedOnce.current || !field) return;
|
|
5740
4995
|
focusedOnce.current = true;
|
|
@@ -5742,7 +4997,7 @@ function InlineEditor({ editor }) {
|
|
|
5742
4997
|
const end = field.value.length;
|
|
5743
4998
|
field.setSelectionRange(end, end);
|
|
5744
4999
|
}, [pos]);
|
|
5745
|
-
|
|
5000
|
+
useEffect7(() => {
|
|
5746
5001
|
const field = afterRef.current;
|
|
5747
5002
|
if (!field) return;
|
|
5748
5003
|
field.style.height = "auto";
|
|
@@ -5752,7 +5007,7 @@ function InlineEditor({ editor }) {
|
|
|
5752
5007
|
setAfter(value);
|
|
5753
5008
|
if (element.innerText !== value) setElementText(element, value);
|
|
5754
5009
|
};
|
|
5755
|
-
|
|
5010
|
+
useEffect7(() => {
|
|
5756
5011
|
let raf = 0;
|
|
5757
5012
|
let lastDelta = 0;
|
|
5758
5013
|
let lastWidth = 0;
|
|
@@ -5822,7 +5077,7 @@ function InlineEditor({ editor }) {
|
|
|
5822
5077
|
cancel();
|
|
5823
5078
|
}
|
|
5824
5079
|
};
|
|
5825
|
-
|
|
5080
|
+
useEffect7(() => {
|
|
5826
5081
|
const el = element;
|
|
5827
5082
|
const onKeyDown = (event) => {
|
|
5828
5083
|
if (event.key === "Enter" && !event.shiftKey) {
|
|
@@ -5840,19 +5095,19 @@ function InlineEditor({ editor }) {
|
|
|
5840
5095
|
});
|
|
5841
5096
|
const before = original.current?.text ?? "";
|
|
5842
5097
|
const delta = after.length - before.length;
|
|
5843
|
-
return /* @__PURE__ */
|
|
5844
|
-
/* @__PURE__ */
|
|
5845
|
-
/* @__PURE__ */
|
|
5846
|
-
/* @__PURE__ */
|
|
5847
|
-
/* @__PURE__ */
|
|
5098
|
+
return /* @__PURE__ */ jsxs8(Fragment5, { children: [
|
|
5099
|
+
/* @__PURE__ */ jsx9("div", { ref: ringRef, className: "rk-edit-ring" }),
|
|
5100
|
+
/* @__PURE__ */ jsxs8("div", { ref, className: "rk-card", style: anchoredStyle(pos), role: "dialog", "aria-label": "Rewrite text", children: [
|
|
5101
|
+
/* @__PURE__ */ jsxs8("div", { className: "rk-card-head", children: [
|
|
5102
|
+
/* @__PURE__ */ jsx9(IconText, { size: 14 }),
|
|
5848
5103
|
"Rewrite text",
|
|
5849
|
-
/* @__PURE__ */
|
|
5850
|
-
/* @__PURE__ */
|
|
5104
|
+
/* @__PURE__ */ jsx9("span", { className: "rk-spacer" }),
|
|
5105
|
+
/* @__PURE__ */ jsxs8("span", { className: "rk-delta", "aria-live": "polite", children: [
|
|
5851
5106
|
before.length,
|
|
5852
5107
|
" \u2192 ",
|
|
5853
5108
|
after.length,
|
|
5854
5109
|
" ",
|
|
5855
|
-
delta !== 0 && /* @__PURE__ */
|
|
5110
|
+
delta !== 0 && /* @__PURE__ */ jsxs8("span", { className: delta > 0 ? "rk-plus" : "rk-minus", children: [
|
|
5856
5111
|
"(",
|
|
5857
5112
|
delta > 0 ? "+" : "",
|
|
5858
5113
|
delta,
|
|
@@ -5860,15 +5115,15 @@ function InlineEditor({ editor }) {
|
|
|
5860
5115
|
] })
|
|
5861
5116
|
] })
|
|
5862
5117
|
] }),
|
|
5863
|
-
/* @__PURE__ */
|
|
5864
|
-
/* @__PURE__ */
|
|
5865
|
-
/* @__PURE__ */
|
|
5866
|
-
/* @__PURE__ */
|
|
5867
|
-
/* @__PURE__ */
|
|
5118
|
+
/* @__PURE__ */ jsxs8("div", { className: "rk-card-body", children: [
|
|
5119
|
+
/* @__PURE__ */ jsxs8("div", { className: "rk-diff", "aria-label": "Before and after", children: [
|
|
5120
|
+
/* @__PURE__ */ jsxs8("div", { className: "rk-diff-row rk-diff-before", children: [
|
|
5121
|
+
/* @__PURE__ */ jsx9("span", { className: "rk-diff-tag", children: "Before" }),
|
|
5122
|
+
/* @__PURE__ */ jsx9("span", { className: "rk-diff-text", children: before })
|
|
5868
5123
|
] }),
|
|
5869
|
-
/* @__PURE__ */
|
|
5870
|
-
/* @__PURE__ */
|
|
5871
|
-
/* @__PURE__ */
|
|
5124
|
+
/* @__PURE__ */ jsxs8("div", { className: "rk-diff-row rk-diff-after", children: [
|
|
5125
|
+
/* @__PURE__ */ jsx9("span", { className: "rk-diff-tag", children: "After" }),
|
|
5126
|
+
/* @__PURE__ */ jsx9(
|
|
5872
5127
|
"textarea",
|
|
5873
5128
|
{
|
|
5874
5129
|
ref: afterRef,
|
|
@@ -5882,11 +5137,11 @@ function InlineEditor({ editor }) {
|
|
|
5882
5137
|
)
|
|
5883
5138
|
] })
|
|
5884
5139
|
] }),
|
|
5885
|
-
(Math.abs(sizeDelta) > 2 || Math.abs(widthDelta) > 4 || clipped) && /* @__PURE__ */
|
|
5140
|
+
(Math.abs(sizeDelta) > 2 || Math.abs(widthDelta) > 4 || clipped) && /* @__PURE__ */ jsxs8("div", { className: "rk-size-note", role: "status", children: [
|
|
5886
5141
|
Math.abs(sizeDelta) > 2 && (() => {
|
|
5887
5142
|
const lines = baseline.current ? Math.round(Math.abs(sizeDelta) / baseline.current.lineHeight) : 0;
|
|
5888
5143
|
const lineNote = lines >= 1 ? ` (~${lines} line${lines === 1 ? "" : "s"})` : "";
|
|
5889
|
-
return /* @__PURE__ */
|
|
5144
|
+
return /* @__PURE__ */ jsxs8("span", { children: [
|
|
5890
5145
|
"Block ",
|
|
5891
5146
|
sizeDelta > 0 ? "grew" : "shrank",
|
|
5892
5147
|
" by ",
|
|
@@ -5896,16 +5151,16 @@ function InlineEditor({ editor }) {
|
|
|
5896
5151
|
" \u2014 as it would with this text live."
|
|
5897
5152
|
] });
|
|
5898
5153
|
})(),
|
|
5899
|
-
Math.abs(sizeDelta) <= 2 && Math.abs(widthDelta) > 4 && /* @__PURE__ */
|
|
5154
|
+
Math.abs(sizeDelta) <= 2 && Math.abs(widthDelta) > 4 && /* @__PURE__ */ jsxs8("span", { children: [
|
|
5900
5155
|
"Block got ",
|
|
5901
5156
|
widthDelta > 0 ? "wider" : "narrower",
|
|
5902
5157
|
" by ",
|
|
5903
5158
|
Math.abs(widthDelta),
|
|
5904
5159
|
" px \u2014 as it would with this text live."
|
|
5905
5160
|
] }),
|
|
5906
|
-
clipped && /* @__PURE__ */
|
|
5161
|
+
clipped && /* @__PURE__ */ jsx9("span", { className: "rk-clip-note", children: "Text exceeds the visible crop here and will be cut off." })
|
|
5907
5162
|
] }),
|
|
5908
|
-
/* @__PURE__ */
|
|
5163
|
+
/* @__PURE__ */ jsx9(
|
|
5909
5164
|
"input",
|
|
5910
5165
|
{
|
|
5911
5166
|
className: "rk-input",
|
|
@@ -5914,29 +5169,33 @@ function InlineEditor({ editor }) {
|
|
|
5914
5169
|
onChange: (event) => setNote(event.target.value)
|
|
5915
5170
|
}
|
|
5916
5171
|
),
|
|
5917
|
-
/* @__PURE__ */
|
|
5918
|
-
/* @__PURE__ */
|
|
5919
|
-
/* @__PURE__ */
|
|
5172
|
+
/* @__PURE__ */ jsxs8("div", { className: "rk-seg", role: "group", "aria-label": "Priority", children: [
|
|
5173
|
+
/* @__PURE__ */ jsx9("button", { type: "button", "aria-pressed": priority === "must", onClick: () => setPriority("must"), children: "Must" }),
|
|
5174
|
+
/* @__PURE__ */ jsx9("button", { type: "button", "aria-pressed": priority === "nice", onClick: () => setPriority("nice"), children: "Nice to have" })
|
|
5920
5175
|
] })
|
|
5921
5176
|
] }),
|
|
5922
|
-
/* @__PURE__ */
|
|
5923
|
-
/* @__PURE__ */
|
|
5924
|
-
/* @__PURE__ */
|
|
5177
|
+
/* @__PURE__ */ jsxs8("div", { className: "rk-card-foot", children: [
|
|
5178
|
+
/* @__PURE__ */ jsxs8("span", { className: "rk-hint", children: [
|
|
5179
|
+
/* @__PURE__ */ jsx9("span", { className: "rk-kbd", children: "\u21B5" }),
|
|
5925
5180
|
" save \xB7 ",
|
|
5926
|
-
/* @__PURE__ */
|
|
5181
|
+
/* @__PURE__ */ jsx9("span", { className: "rk-kbd", children: "\u21E7\u21B5" }),
|
|
5927
5182
|
" newline \xB7",
|
|
5928
5183
|
" ",
|
|
5929
|
-
/* @__PURE__ */
|
|
5184
|
+
/* @__PURE__ */ jsx9("span", { className: "rk-kbd", children: "esc" }),
|
|
5930
5185
|
" cancel"
|
|
5931
5186
|
] }),
|
|
5932
|
-
/* @__PURE__ */
|
|
5933
|
-
/* @__PURE__ */
|
|
5934
|
-
/* @__PURE__ */
|
|
5187
|
+
/* @__PURE__ */ jsxs8("div", { className: "rk-actions", children: [
|
|
5188
|
+
/* @__PURE__ */ jsx9("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: cancel, children: "Cancel" }),
|
|
5189
|
+
/* @__PURE__ */ jsx9("button", { type: "button", className: "rk-btn rk-btn-primary", onClick: commit, children: "Save" })
|
|
5935
5190
|
] })
|
|
5936
5191
|
] })
|
|
5937
5192
|
] })
|
|
5938
5193
|
] });
|
|
5939
5194
|
}
|
|
5195
|
+
|
|
5196
|
+
// src/client/components/NoteComposer.tsx
|
|
5197
|
+
import { useEffect as useEffect8, useRef as useRef9, useState as useState7 } from "react";
|
|
5198
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
5940
5199
|
var TITLES = {
|
|
5941
5200
|
comment: "Comment",
|
|
5942
5201
|
delete: "Mark for deletion",
|
|
@@ -5952,14 +5211,14 @@ var PLACEHOLDERS = {
|
|
|
5952
5211
|
function NoteComposer({ editor }) {
|
|
5953
5212
|
const dispatch = useDispatch();
|
|
5954
5213
|
const { route, session } = useStore();
|
|
5955
|
-
const [text, setText] =
|
|
5956
|
-
const [direction, setDirection] =
|
|
5957
|
-
const [priority, setPriority] =
|
|
5958
|
-
const textareaRef =
|
|
5214
|
+
const [text, setText] = useState7("");
|
|
5215
|
+
const [direction, setDirection] = useState7(void 0);
|
|
5216
|
+
const [priority, setPriority] = useState7("nice");
|
|
5217
|
+
const textareaRef = useRef9(null);
|
|
5959
5218
|
const { ref, pos } = useAnchored(editor.element, "bottom", 12);
|
|
5960
5219
|
const { kind } = editor;
|
|
5961
|
-
const focusedOnce =
|
|
5962
|
-
|
|
5220
|
+
const focusedOnce = useRef9(false);
|
|
5221
|
+
useEffect8(() => {
|
|
5963
5222
|
const field = textareaRef.current;
|
|
5964
5223
|
if (pos === null || focusedOnce.current || !field) return;
|
|
5965
5224
|
focusedOnce.current = true;
|
|
@@ -6018,13 +5277,13 @@ function NoteComposer({ editor }) {
|
|
|
6018
5277
|
save();
|
|
6019
5278
|
}
|
|
6020
5279
|
};
|
|
6021
|
-
return /* @__PURE__ */
|
|
6022
|
-
/* @__PURE__ */
|
|
5280
|
+
return /* @__PURE__ */ jsxs9("div", { ref, className: "rk-card", style: anchoredStyle(pos), role: "dialog", "aria-label": TITLES[kind], children: [
|
|
5281
|
+
/* @__PURE__ */ jsxs9("div", { className: "rk-card-head", children: [
|
|
6023
5282
|
iconForType(kind),
|
|
6024
5283
|
TITLES[kind]
|
|
6025
5284
|
] }),
|
|
6026
|
-
/* @__PURE__ */
|
|
6027
|
-
kind === "move" && /* @__PURE__ */
|
|
5285
|
+
/* @__PURE__ */ jsxs9("div", { className: "rk-card-body", children: [
|
|
5286
|
+
kind === "move" && /* @__PURE__ */ jsx10("div", { className: "rk-seg", role: "group", "aria-label": "Direction", children: ["up", "down", "first", "last"].map((option) => /* @__PURE__ */ jsx10(
|
|
6028
5287
|
"button",
|
|
6029
5288
|
{
|
|
6030
5289
|
type: "button",
|
|
@@ -6034,7 +5293,7 @@ function NoteComposer({ editor }) {
|
|
|
6034
5293
|
},
|
|
6035
5294
|
option
|
|
6036
5295
|
)) }),
|
|
6037
|
-
/* @__PURE__ */
|
|
5296
|
+
/* @__PURE__ */ jsx10(
|
|
6038
5297
|
"textarea",
|
|
6039
5298
|
{
|
|
6040
5299
|
ref: textareaRef,
|
|
@@ -6046,25 +5305,29 @@ function NoteComposer({ editor }) {
|
|
|
6046
5305
|
rows: 3
|
|
6047
5306
|
}
|
|
6048
5307
|
),
|
|
6049
|
-
/* @__PURE__ */
|
|
6050
|
-
/* @__PURE__ */
|
|
6051
|
-
/* @__PURE__ */
|
|
5308
|
+
/* @__PURE__ */ jsxs9("div", { className: "rk-seg", role: "group", "aria-label": "Priority", children: [
|
|
5309
|
+
/* @__PURE__ */ jsx10("button", { type: "button", "aria-pressed": priority === "must", onClick: () => setPriority("must"), children: "Must" }),
|
|
5310
|
+
/* @__PURE__ */ jsx10("button", { type: "button", "aria-pressed": priority === "nice", onClick: () => setPriority("nice"), children: "Nice to have" })
|
|
6052
5311
|
] })
|
|
6053
5312
|
] }),
|
|
6054
|
-
/* @__PURE__ */
|
|
6055
|
-
/* @__PURE__ */
|
|
6056
|
-
/* @__PURE__ */
|
|
5313
|
+
/* @__PURE__ */ jsxs9("div", { className: "rk-card-foot", children: [
|
|
5314
|
+
/* @__PURE__ */ jsxs9("span", { className: "rk-hint", children: [
|
|
5315
|
+
/* @__PURE__ */ jsx10("span", { className: "rk-kbd", children: "\u2318\u21B5" }),
|
|
6057
5316
|
" save \xB7 ",
|
|
6058
|
-
/* @__PURE__ */
|
|
5317
|
+
/* @__PURE__ */ jsx10("span", { className: "rk-kbd", children: "esc" }),
|
|
6059
5318
|
" cancel"
|
|
6060
5319
|
] }),
|
|
6061
|
-
/* @__PURE__ */
|
|
6062
|
-
/* @__PURE__ */
|
|
6063
|
-
/* @__PURE__ */
|
|
5320
|
+
/* @__PURE__ */ jsxs9("div", { className: "rk-actions", children: [
|
|
5321
|
+
/* @__PURE__ */ jsx10("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => dispatch({ type: "CLOSE_EDITOR" }), children: "Cancel" }),
|
|
5322
|
+
/* @__PURE__ */ jsx10("button", { type: "button", className: "rk-btn rk-btn-primary", onClick: save, children: "Save" })
|
|
6064
5323
|
] })
|
|
6065
5324
|
] })
|
|
6066
5325
|
] });
|
|
6067
5326
|
}
|
|
5327
|
+
|
|
5328
|
+
// src/client/components/Panel.tsx
|
|
5329
|
+
import { useEffect as useEffect9, useMemo as useMemo3, useRef as useRef10, useState as useState8 } from "react";
|
|
5330
|
+
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
6068
5331
|
function changeSummary(item) {
|
|
6069
5332
|
if (isCopyItem(item)) return `\u201C${item.payload.after}\u201D`;
|
|
6070
5333
|
if (isImageItem(item)) {
|
|
@@ -6146,24 +5409,24 @@ function formatBytes(bytes) {
|
|
|
6146
5409
|
function CopyDiff({ before, after }) {
|
|
6147
5410
|
const parts = diffParts(before, after);
|
|
6148
5411
|
const delta = after.length - before.length;
|
|
6149
|
-
return /* @__PURE__ */
|
|
6150
|
-
/* @__PURE__ */
|
|
6151
|
-
/* @__PURE__ */
|
|
6152
|
-
/* @__PURE__ */
|
|
5412
|
+
return /* @__PURE__ */ jsxs10("div", { className: "rk-diffview", children: [
|
|
5413
|
+
/* @__PURE__ */ jsxs10("div", { className: "rk-diff-row rk-diff-before", children: [
|
|
5414
|
+
/* @__PURE__ */ jsx11("span", { className: "rk-diff-tag", children: "Before" }),
|
|
5415
|
+
/* @__PURE__ */ jsxs10("span", { className: "rk-diff-text", children: [
|
|
6153
5416
|
parts.prefix,
|
|
6154
|
-
parts.delMid && /* @__PURE__ */
|
|
5417
|
+
parts.delMid && /* @__PURE__ */ jsx11("mark", { className: "rk-del", children: parts.delMid }),
|
|
6155
5418
|
parts.suffix
|
|
6156
5419
|
] })
|
|
6157
5420
|
] }),
|
|
6158
|
-
/* @__PURE__ */
|
|
6159
|
-
/* @__PURE__ */
|
|
6160
|
-
/* @__PURE__ */
|
|
5421
|
+
/* @__PURE__ */ jsxs10("div", { className: "rk-diff-row rk-diff-after", children: [
|
|
5422
|
+
/* @__PURE__ */ jsx11("span", { className: "rk-diff-tag", children: "After" }),
|
|
5423
|
+
/* @__PURE__ */ jsxs10("span", { className: "rk-diff-text", children: [
|
|
6161
5424
|
parts.prefix,
|
|
6162
|
-
parts.insMid && /* @__PURE__ */
|
|
5425
|
+
parts.insMid && /* @__PURE__ */ jsx11("mark", { className: "rk-ins", children: parts.insMid }),
|
|
6163
5426
|
parts.suffix
|
|
6164
5427
|
] })
|
|
6165
5428
|
] }),
|
|
6166
|
-
/* @__PURE__ */
|
|
5429
|
+
/* @__PURE__ */ jsxs10("div", { className: "rk-diff-len", children: [
|
|
6167
5430
|
before.length,
|
|
6168
5431
|
" \u2192 ",
|
|
6169
5432
|
after.length,
|
|
@@ -6174,8 +5437,8 @@ function CopyDiff({ before, after }) {
|
|
|
6174
5437
|
}
|
|
6175
5438
|
function ImageDetail({ beforeSrc, afterSrc, afterDataUrl }) {
|
|
6176
5439
|
const replacement = afterDataUrl ?? afterSrc;
|
|
6177
|
-
const [dims, setDims] =
|
|
6178
|
-
|
|
5440
|
+
const [dims, setDims] = useState8("");
|
|
5441
|
+
useEffect9(() => {
|
|
6179
5442
|
if (!replacement) return;
|
|
6180
5443
|
const img = new Image();
|
|
6181
5444
|
img.onload = () => setDims(`${img.naturalWidth}\xD7${img.naturalHeight}px`);
|
|
@@ -6200,32 +5463,32 @@ function ImageDetail({ beforeSrc, afterSrc, afterDataUrl }) {
|
|
|
6200
5463
|
window.open(replacement, "_blank", "noopener");
|
|
6201
5464
|
}
|
|
6202
5465
|
};
|
|
6203
|
-
return /* @__PURE__ */
|
|
6204
|
-
/* @__PURE__ */
|
|
6205
|
-
/* @__PURE__ */
|
|
6206
|
-
beforeSrc ? /* @__PURE__ */
|
|
6207
|
-
/* @__PURE__ */
|
|
5466
|
+
return /* @__PURE__ */ jsxs10("div", { className: "rk-imgdetail", children: [
|
|
5467
|
+
/* @__PURE__ */ jsxs10("div", { className: "rk-thumbs", children: [
|
|
5468
|
+
/* @__PURE__ */ jsxs10("figure", { className: "rk-thumb", children: [
|
|
5469
|
+
beforeSrc ? /* @__PURE__ */ jsx11("img", { src: beforeSrc, alt: "Current" }) : /* @__PURE__ */ jsx11("div", { className: "rk-thumb-missing", children: "no image" }),
|
|
5470
|
+
/* @__PURE__ */ jsx11("figcaption", { children: "Before" })
|
|
6208
5471
|
] }),
|
|
6209
|
-
/* @__PURE__ */
|
|
6210
|
-
/* @__PURE__ */
|
|
6211
|
-
/* @__PURE__ */
|
|
5472
|
+
/* @__PURE__ */ jsxs10("figure", { className: "rk-thumb", children: [
|
|
5473
|
+
/* @__PURE__ */ jsx11("img", { src: replacement, alt: "Proposed replacement" }),
|
|
5474
|
+
/* @__PURE__ */ jsxs10("figcaption", { children: [
|
|
6212
5475
|
"After",
|
|
6213
5476
|
embedded ? "" : " \xB7 linked"
|
|
6214
5477
|
] })
|
|
6215
5478
|
] })
|
|
6216
5479
|
] }),
|
|
6217
|
-
/* @__PURE__ */
|
|
5480
|
+
/* @__PURE__ */ jsxs10("div", { className: "rk-imgdetail-meta", children: [
|
|
6218
5481
|
embedded ? "Embedded image" : "Linked image",
|
|
6219
5482
|
dims ? ` \xB7 ${dims}` : "",
|
|
6220
5483
|
bytes !== null ? ` \xB7 ${formatBytes(bytes)}` : ""
|
|
6221
5484
|
] }),
|
|
6222
|
-
!embedded && afterSrc && /* @__PURE__ */
|
|
6223
|
-
/* @__PURE__ */
|
|
6224
|
-
/* @__PURE__ */
|
|
6225
|
-
/* @__PURE__ */
|
|
5485
|
+
!embedded && afterSrc && /* @__PURE__ */ jsx11("a", { className: "rk-imgdetail-url", href: afterSrc, target: "_blank", rel: "noopener noreferrer", title: afterSrc, children: afterSrc }),
|
|
5486
|
+
/* @__PURE__ */ jsxs10("div", { className: "rk-imgdetail-actions", children: [
|
|
5487
|
+
/* @__PURE__ */ jsxs10("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => void download(), children: [
|
|
5488
|
+
/* @__PURE__ */ jsx11(IconDownload, { size: 12 }),
|
|
6226
5489
|
" Download"
|
|
6227
5490
|
] }),
|
|
6228
|
-
/* @__PURE__ */
|
|
5491
|
+
/* @__PURE__ */ jsx11("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => window.open(replacement, "_blank", "noopener"), children: "Open" })
|
|
6229
5492
|
] })
|
|
6230
5493
|
] });
|
|
6231
5494
|
}
|
|
@@ -6233,22 +5496,22 @@ function Panel() {
|
|
|
6233
5496
|
const { session, panelOpen, activeItemId, badgeCorner, undoStack, preview, unapplied, syncStatus, emblemaPush, peers } = useStore();
|
|
6234
5497
|
const dispatch = useDispatch();
|
|
6235
5498
|
const config = useConfig();
|
|
6236
|
-
const [sticky, setStickyState] =
|
|
6237
|
-
const [query, setQuery] =
|
|
6238
|
-
const [typeFilter, setTypeFilter] =
|
|
6239
|
-
const [prioFilter, setPrioFilter] =
|
|
6240
|
-
const [statusFilter, setStatusFilter] =
|
|
6241
|
-
const [filterOpen, setFilterOpen] =
|
|
6242
|
-
const [settingsOpen, setSettingsOpen] =
|
|
6243
|
-
const [emblemaAlive, setEmblemaAlive] =
|
|
6244
|
-
const [emblemaSending, setEmblemaSending] =
|
|
6245
|
-
const [emblemaSync, setEmblemaSync] =
|
|
6246
|
-
const panelRef =
|
|
6247
|
-
const searchRef =
|
|
6248
|
-
const importRef =
|
|
6249
|
-
const sheetDrag =
|
|
6250
|
-
const items =
|
|
6251
|
-
const { orphanIds, hiddenIds } =
|
|
5499
|
+
const [sticky, setStickyState] = useState8(() => isStickyEnabled(config.token));
|
|
5500
|
+
const [query, setQuery] = useState8("");
|
|
5501
|
+
const [typeFilter, setTypeFilter] = useState8(/* @__PURE__ */ new Set());
|
|
5502
|
+
const [prioFilter, setPrioFilter] = useState8(/* @__PURE__ */ new Set());
|
|
5503
|
+
const [statusFilter, setStatusFilter] = useState8(/* @__PURE__ */ new Set());
|
|
5504
|
+
const [filterOpen, setFilterOpen] = useState8(false);
|
|
5505
|
+
const [settingsOpen, setSettingsOpen] = useState8(false);
|
|
5506
|
+
const [emblemaAlive, setEmblemaAlive] = useState8(null);
|
|
5507
|
+
const [emblemaSending, setEmblemaSending] = useState8(false);
|
|
5508
|
+
const [emblemaSync, setEmblemaSync] = useState8("unknown");
|
|
5509
|
+
const panelRef = useRef10(null);
|
|
5510
|
+
const searchRef = useRef10(null);
|
|
5511
|
+
const importRef = useRef10(null);
|
|
5512
|
+
const sheetDrag = useRef10(null);
|
|
5513
|
+
const items = useMemo3(() => session?.items ?? [], [session]);
|
|
5514
|
+
const { orphanIds, hiddenIds } = useMemo3(() => {
|
|
6252
5515
|
const orphans = /* @__PURE__ */ new Set();
|
|
6253
5516
|
const hiddens = /* @__PURE__ */ new Set();
|
|
6254
5517
|
for (const item of items) {
|
|
@@ -6259,15 +5522,15 @@ function Panel() {
|
|
|
6259
5522
|
}
|
|
6260
5523
|
return { orphanIds: orphans, hiddenIds: hiddens };
|
|
6261
5524
|
}, [items, panelOpen]);
|
|
6262
|
-
const activeFilter =
|
|
5525
|
+
const activeFilter = useMemo3(
|
|
6263
5526
|
() => typeFilter.size + prioFilter.size + statusFilter.size > 0 ? { types: [...typeFilter], priorities: [...prioFilter], statuses: [...statusFilter] } : null,
|
|
6264
5527
|
[typeFilter, prioFilter, statusFilter]
|
|
6265
5528
|
);
|
|
6266
|
-
|
|
5529
|
+
useEffect9(() => {
|
|
6267
5530
|
dispatch({ type: "SET_FILTER", filter: activeFilter });
|
|
6268
5531
|
return () => dispatch({ type: "SET_FILTER", filter: null });
|
|
6269
5532
|
}, [activeFilter, dispatch]);
|
|
6270
|
-
const filtered =
|
|
5533
|
+
const filtered = useMemo3(() => {
|
|
6271
5534
|
const q = query.trim().toLowerCase();
|
|
6272
5535
|
return items.map((item, index) => ({ item, number: index + 1 })).filter(({ item }) => {
|
|
6273
5536
|
if (!itemMatchesFilter(item, activeFilter)) return false;
|
|
@@ -6276,22 +5539,22 @@ function Panel() {
|
|
|
6276
5539
|
return haystack.includes(q);
|
|
6277
5540
|
});
|
|
6278
5541
|
}, [items, query, activeFilter]);
|
|
6279
|
-
const typeCounts =
|
|
5542
|
+
const typeCounts = useMemo3(() => {
|
|
6280
5543
|
const counts = /* @__PURE__ */ new Map();
|
|
6281
5544
|
for (const item of items) counts.set(item.type, (counts.get(item.type) ?? 0) + 1);
|
|
6282
5545
|
return counts;
|
|
6283
5546
|
}, [items]);
|
|
6284
|
-
const prioCounts =
|
|
5547
|
+
const prioCounts = useMemo3(() => {
|
|
6285
5548
|
const counts = /* @__PURE__ */ new Map();
|
|
6286
5549
|
for (const item of items) counts.set(item.priority, (counts.get(item.priority) ?? 0) + 1);
|
|
6287
5550
|
return counts;
|
|
6288
5551
|
}, [items]);
|
|
6289
|
-
const statusCounts =
|
|
5552
|
+
const statusCounts = useMemo3(() => {
|
|
6290
5553
|
const counts = /* @__PURE__ */ new Map();
|
|
6291
5554
|
for (const item of items) counts.set(item.status, (counts.get(item.status) ?? 0) + 1);
|
|
6292
5555
|
return counts;
|
|
6293
5556
|
}, [items]);
|
|
6294
|
-
const groups =
|
|
5557
|
+
const groups = useMemo3(() => {
|
|
6295
5558
|
const map = /* @__PURE__ */ new Map();
|
|
6296
5559
|
for (const entry of filtered) {
|
|
6297
5560
|
const list = map.get(entry.item.route) ?? [];
|
|
@@ -6300,7 +5563,7 @@ function Panel() {
|
|
|
6300
5563
|
}
|
|
6301
5564
|
return Array.from(map.entries());
|
|
6302
5565
|
}, [filtered]);
|
|
6303
|
-
|
|
5566
|
+
useEffect9(() => {
|
|
6304
5567
|
if (!filterOpen && !settingsOpen) return;
|
|
6305
5568
|
const onDown = (event) => {
|
|
6306
5569
|
const path = event.composedPath();
|
|
@@ -6311,7 +5574,7 @@ function Panel() {
|
|
|
6311
5574
|
document.addEventListener("pointerdown", onDown, true);
|
|
6312
5575
|
return () => document.removeEventListener("pointerdown", onDown, true);
|
|
6313
5576
|
}, [filterOpen, settingsOpen]);
|
|
6314
|
-
|
|
5577
|
+
useEffect9(() => {
|
|
6315
5578
|
if (!settingsOpen) return;
|
|
6316
5579
|
let alive = true;
|
|
6317
5580
|
const probe = () => {
|
|
@@ -6335,7 +5598,7 @@ function Panel() {
|
|
|
6335
5598
|
live: "paired",
|
|
6336
5599
|
off: "not paired"
|
|
6337
5600
|
}[emblemaPairState];
|
|
6338
|
-
|
|
5601
|
+
useEffect9(() => {
|
|
6339
5602
|
if (!panelOpen || activeItemId === null) return;
|
|
6340
5603
|
const row = panelRef.current?.querySelector(`[data-item-id="${activeItemId}"]`);
|
|
6341
5604
|
row?.scrollIntoView({ block: "nearest" });
|
|
@@ -6366,11 +5629,11 @@ function Panel() {
|
|
|
6366
5629
|
if (focusable.length === 0) return;
|
|
6367
5630
|
const first = focusable[0];
|
|
6368
5631
|
const last = focusable[focusable.length - 1];
|
|
6369
|
-
const
|
|
6370
|
-
if (event.shiftKey &&
|
|
5632
|
+
const active = panel.getRootNode() instanceof ShadowRoot ? panel.getRootNode().activeElement : document.activeElement;
|
|
5633
|
+
if (event.shiftKey && active === first) {
|
|
6371
5634
|
event.preventDefault();
|
|
6372
5635
|
last.focus();
|
|
6373
|
-
} else if (!event.shiftKey &&
|
|
5636
|
+
} else if (!event.shiftKey && active === last) {
|
|
6374
5637
|
event.preventDefault();
|
|
6375
5638
|
first.focus();
|
|
6376
5639
|
}
|
|
@@ -6451,7 +5714,7 @@ function Panel() {
|
|
|
6451
5714
|
panel.style.transform = "";
|
|
6452
5715
|
if (dy > 110) dispatch({ type: "SET_PANEL", open: false });
|
|
6453
5716
|
};
|
|
6454
|
-
return /* @__PURE__ */
|
|
5717
|
+
return /* @__PURE__ */ jsxs10(
|
|
6455
5718
|
"div",
|
|
6456
5719
|
{
|
|
6457
5720
|
ref: panelRef,
|
|
@@ -6461,7 +5724,7 @@ function Panel() {
|
|
|
6461
5724
|
"aria-label": "Review feedback panel",
|
|
6462
5725
|
onKeyDown,
|
|
6463
5726
|
children: [
|
|
6464
|
-
/* @__PURE__ */
|
|
5727
|
+
/* @__PURE__ */ jsx11(
|
|
6465
5728
|
"div",
|
|
6466
5729
|
{
|
|
6467
5730
|
className: "rk-sheet-handle",
|
|
@@ -6472,34 +5735,34 @@ function Panel() {
|
|
|
6472
5735
|
onPointerCancel: onSheetHandleUp
|
|
6473
5736
|
}
|
|
6474
5737
|
),
|
|
6475
|
-
/* @__PURE__ */
|
|
6476
|
-
/* @__PURE__ */
|
|
6477
|
-
/* @__PURE__ */
|
|
6478
|
-
/* @__PURE__ */
|
|
5738
|
+
/* @__PURE__ */ jsxs10("div", { className: "rk-panel-head", children: [
|
|
5739
|
+
/* @__PURE__ */ jsxs10("div", { children: [
|
|
5740
|
+
/* @__PURE__ */ jsx11("div", { className: "rk-panel-title", children: "Feedback" }),
|
|
5741
|
+
/* @__PURE__ */ jsxs10("div", { className: "rk-panel-sub", children: [
|
|
6479
5742
|
items.length,
|
|
6480
5743
|
" item",
|
|
6481
5744
|
items.length === 1 ? "" : "s",
|
|
6482
5745
|
session.author ? ` \xB7 ${session.author}` : "",
|
|
6483
|
-
syncStatus !== "disabled" && /* @__PURE__ */
|
|
6484
|
-
/* @__PURE__ */
|
|
5746
|
+
syncStatus !== "disabled" && /* @__PURE__ */ jsxs10("span", { className: `rk-sync rk-sync-${syncStatus}`, children: [
|
|
5747
|
+
/* @__PURE__ */ jsx11("span", { className: "rk-sync-dot" }),
|
|
6485
5748
|
syncStatus === "online" ? `live${peers.length > 0 ? ` \xB7 ${peers.length} other${peers.length === 1 ? "" : "s"}` : ""}` : syncStatus === "connecting" ? "connecting\u2026" : "local only"
|
|
6486
5749
|
] }),
|
|
6487
|
-
config.emblema && emblemaPush !== "idle" && /* @__PURE__ */
|
|
5750
|
+
config.emblema && emblemaPush !== "idle" && /* @__PURE__ */ jsxs10(
|
|
6488
5751
|
"span",
|
|
6489
5752
|
{
|
|
6490
5753
|
className: `rk-sync rk-epush-${emblemaPush}`,
|
|
6491
5754
|
title: emblemaPush === "ok" ? "Review items stream to Emblema automatically" : emblemaPush === "sending" ? "Sending items to Emblema\u2026" : "Emblema isn't reachable \u2014 items resend on the next change, or use Resend all in the menu",
|
|
6492
5755
|
children: [
|
|
6493
|
-
/* @__PURE__ */
|
|
6494
|
-
emblemaPush === "ok" ? "emblema" : emblemaPush === "sending" ? "emblema\u2026" : "emblema offline"
|
|
5756
|
+
/* @__PURE__ */ jsx11("span", { className: "rk-sync-dot" }),
|
|
5757
|
+
emblemaPush === "ok" ? "emblema" : emblemaPush === "sending" ? "emblema\u2026" : emblemaPush === "rejected" ? "emblema rejected" : "emblema offline"
|
|
6495
5758
|
]
|
|
6496
5759
|
}
|
|
6497
5760
|
)
|
|
6498
5761
|
] })
|
|
6499
5762
|
] }),
|
|
6500
|
-
/* @__PURE__ */
|
|
6501
|
-
/* @__PURE__ */
|
|
6502
|
-
/* @__PURE__ */
|
|
5763
|
+
/* @__PURE__ */ jsx11("span", { className: "rk-spacer" }),
|
|
5764
|
+
/* @__PURE__ */ jsxs10("div", { className: "rk-menu-scope rk-menu-anchor", children: [
|
|
5765
|
+
/* @__PURE__ */ jsx11(
|
|
6503
5766
|
"button",
|
|
6504
5767
|
{
|
|
6505
5768
|
type: "button",
|
|
@@ -6515,11 +5778,11 @@ function Panel() {
|
|
|
6515
5778
|
void pingEmblema(config.emblema).then((port) => setEmblemaAlive(port !== null));
|
|
6516
5779
|
}
|
|
6517
5780
|
},
|
|
6518
|
-
children: /* @__PURE__ */
|
|
5781
|
+
children: /* @__PURE__ */ jsx11(IconGear, { size: 15 })
|
|
6519
5782
|
}
|
|
6520
5783
|
),
|
|
6521
|
-
settingsOpen && /* @__PURE__ */
|
|
6522
|
-
/* @__PURE__ */
|
|
5784
|
+
settingsOpen && /* @__PURE__ */ jsxs10("div", { className: "rk-menu", role: "menu", "aria-label": "Session settings", children: [
|
|
5785
|
+
config.token && /* @__PURE__ */ jsxs10(
|
|
6523
5786
|
"button",
|
|
6524
5787
|
{
|
|
6525
5788
|
type: "button",
|
|
@@ -6534,12 +5797,12 @@ function Panel() {
|
|
|
6534
5797
|
toast(dispatch, next ? "Review stays on in this tab" : "Review active only via the link", "info");
|
|
6535
5798
|
},
|
|
6536
5799
|
children: [
|
|
6537
|
-
/* @__PURE__ */
|
|
5800
|
+
/* @__PURE__ */ jsx11("span", { className: `rk-menu-check${sticky ? " rk-on" : ""}` }),
|
|
6538
5801
|
"Keep review on in this tab"
|
|
6539
5802
|
]
|
|
6540
5803
|
}
|
|
6541
5804
|
),
|
|
6542
|
-
config.emblema && /* @__PURE__ */
|
|
5805
|
+
config.emblema && /* @__PURE__ */ jsxs10(
|
|
6543
5806
|
"button",
|
|
6544
5807
|
{
|
|
6545
5808
|
type: "button",
|
|
@@ -6569,7 +5832,7 @@ function Panel() {
|
|
|
6569
5832
|
}).finally(() => setEmblemaSending(false));
|
|
6570
5833
|
},
|
|
6571
5834
|
children: [
|
|
6572
|
-
/* @__PURE__ */
|
|
5835
|
+
/* @__PURE__ */ jsx11(
|
|
6573
5836
|
"span",
|
|
6574
5837
|
{
|
|
6575
5838
|
className: "rk-emblema-dot",
|
|
@@ -6580,25 +5843,25 @@ function Panel() {
|
|
|
6580
5843
|
]
|
|
6581
5844
|
}
|
|
6582
5845
|
),
|
|
6583
|
-
/* @__PURE__ */
|
|
5846
|
+
/* @__PURE__ */ jsxs10(
|
|
6584
5847
|
"button",
|
|
6585
5848
|
{
|
|
6586
5849
|
type: "button",
|
|
6587
5850
|
role: "menuitem",
|
|
6588
5851
|
className: "rk-menu-item",
|
|
6589
|
-
title: emblemaPairState === "stale" ? "The local sync agent is not answering \u2014 run `npx reviewkit-
|
|
5852
|
+
title: emblemaPairState === "stale" ? "The local sync agent is not answering \u2014 run `npx @satanwagen/reviewkit-cli serve` in the project" : "Pair this project with the Emblema app via a sync key",
|
|
6590
5853
|
onClick: () => {
|
|
6591
5854
|
setSettingsOpen(false);
|
|
6592
5855
|
dispatch({ type: "SET_EMBLEMA_CONNECT", open: true });
|
|
6593
5856
|
},
|
|
6594
5857
|
children: [
|
|
6595
|
-
/* @__PURE__ */
|
|
5858
|
+
/* @__PURE__ */ jsx11("span", { className: "rk-emblema-dot", "data-state": emblemaPairState }),
|
|
6596
5859
|
"Connect to Emblema\u2026",
|
|
6597
|
-
/* @__PURE__ */
|
|
5860
|
+
/* @__PURE__ */ jsx11("span", { className: "rk-menu-count", children: emblemaPairLabel })
|
|
6598
5861
|
]
|
|
6599
5862
|
}
|
|
6600
5863
|
),
|
|
6601
|
-
/* @__PURE__ */
|
|
5864
|
+
/* @__PURE__ */ jsx11(
|
|
6602
5865
|
"button",
|
|
6603
5866
|
{
|
|
6604
5867
|
type: "button",
|
|
@@ -6611,31 +5874,31 @@ function Panel() {
|
|
|
6611
5874
|
)
|
|
6612
5875
|
] })
|
|
6613
5876
|
] }),
|
|
6614
|
-
/* @__PURE__ */
|
|
5877
|
+
/* @__PURE__ */ jsx11(
|
|
6615
5878
|
"button",
|
|
6616
5879
|
{
|
|
6617
5880
|
type: "button",
|
|
6618
5881
|
className: "rk-icon-btn",
|
|
6619
5882
|
"aria-label": "Keyboard shortcuts",
|
|
6620
5883
|
onClick: () => dispatch({ type: "SET_CHEATSHEET", open: true }),
|
|
6621
|
-
children: /* @__PURE__ */
|
|
5884
|
+
children: /* @__PURE__ */ jsx11(IconKeyboard, { size: 15 })
|
|
6622
5885
|
}
|
|
6623
5886
|
),
|
|
6624
|
-
/* @__PURE__ */
|
|
5887
|
+
/* @__PURE__ */ jsx11(
|
|
6625
5888
|
"button",
|
|
6626
5889
|
{
|
|
6627
5890
|
type: "button",
|
|
6628
5891
|
className: "rk-icon-btn",
|
|
6629
5892
|
"aria-label": "Close panel",
|
|
6630
5893
|
onClick: () => dispatch({ type: "SET_PANEL", open: false }),
|
|
6631
|
-
children: /* @__PURE__ */
|
|
5894
|
+
children: /* @__PURE__ */ jsx11(IconClose, { size: 14 })
|
|
6632
5895
|
}
|
|
6633
5896
|
)
|
|
6634
5897
|
] }),
|
|
6635
|
-
/* @__PURE__ */
|
|
6636
|
-
/* @__PURE__ */
|
|
6637
|
-
/* @__PURE__ */
|
|
6638
|
-
/* @__PURE__ */
|
|
5898
|
+
/* @__PURE__ */ jsxs10("div", { className: "rk-view-row", children: [
|
|
5899
|
+
/* @__PURE__ */ jsx11("div", { className: "rk-view-info", children: /* @__PURE__ */ jsx11("div", { className: "rk-view-title", children: "Page view" }) }),
|
|
5900
|
+
/* @__PURE__ */ jsxs10("div", { className: "rk-seg rk-view-toggle", role: "group", "aria-label": "Page view (P to toggle)", children: [
|
|
5901
|
+
/* @__PURE__ */ jsx11(
|
|
6639
5902
|
"button",
|
|
6640
5903
|
{
|
|
6641
5904
|
type: "button",
|
|
@@ -6645,7 +5908,7 @@ function Panel() {
|
|
|
6645
5908
|
children: "Original"
|
|
6646
5909
|
}
|
|
6647
5910
|
),
|
|
6648
|
-
/* @__PURE__ */
|
|
5911
|
+
/* @__PURE__ */ jsx11(
|
|
6649
5912
|
"button",
|
|
6650
5913
|
{
|
|
6651
5914
|
type: "button",
|
|
@@ -6657,8 +5920,8 @@ function Panel() {
|
|
|
6657
5920
|
)
|
|
6658
5921
|
] })
|
|
6659
5922
|
] }),
|
|
6660
|
-
/* @__PURE__ */
|
|
6661
|
-
/* @__PURE__ */
|
|
5923
|
+
/* @__PURE__ */ jsxs10("div", { className: "rk-panel-tools", children: [
|
|
5924
|
+
/* @__PURE__ */ jsxs10(
|
|
6662
5925
|
"button",
|
|
6663
5926
|
{
|
|
6664
5927
|
type: "button",
|
|
@@ -6669,15 +5932,15 @@ function Panel() {
|
|
|
6669
5932
|
dispatch({ type: "SET_MODE", mode: "pick" });
|
|
6670
5933
|
},
|
|
6671
5934
|
children: [
|
|
6672
|
-
/* @__PURE__ */
|
|
5935
|
+
/* @__PURE__ */ jsx11(IconTarget, { size: 14 }),
|
|
6673
5936
|
" Pick an element"
|
|
6674
5937
|
]
|
|
6675
5938
|
}
|
|
6676
5939
|
),
|
|
6677
|
-
/* @__PURE__ */
|
|
6678
|
-
/* @__PURE__ */
|
|
6679
|
-
/* @__PURE__ */
|
|
6680
|
-
/* @__PURE__ */
|
|
5940
|
+
/* @__PURE__ */ jsxs10("div", { className: "rk-search-row", children: [
|
|
5941
|
+
/* @__PURE__ */ jsxs10("div", { className: "rk-search", children: [
|
|
5942
|
+
/* @__PURE__ */ jsx11(IconSearch, { size: 13 }),
|
|
5943
|
+
/* @__PURE__ */ jsx11(
|
|
6681
5944
|
"input",
|
|
6682
5945
|
{
|
|
6683
5946
|
ref: searchRef,
|
|
@@ -6689,8 +5952,8 @@ function Panel() {
|
|
|
6689
5952
|
}
|
|
6690
5953
|
)
|
|
6691
5954
|
] }),
|
|
6692
|
-
/* @__PURE__ */
|
|
6693
|
-
/* @__PURE__ */
|
|
5955
|
+
/* @__PURE__ */ jsxs10("div", { className: "rk-menu-scope rk-menu-anchor", children: [
|
|
5956
|
+
/* @__PURE__ */ jsxs10(
|
|
6694
5957
|
"button",
|
|
6695
5958
|
{
|
|
6696
5959
|
type: "button",
|
|
@@ -6702,15 +5965,15 @@ function Panel() {
|
|
|
6702
5965
|
setSettingsOpen(false);
|
|
6703
5966
|
},
|
|
6704
5967
|
children: [
|
|
6705
|
-
/* @__PURE__ */
|
|
5968
|
+
/* @__PURE__ */ jsx11(IconFilter, { size: 13 }),
|
|
6706
5969
|
"Filter",
|
|
6707
|
-
typeFilter.size + prioFilter.size + statusFilter.size > 0 && /* @__PURE__ */
|
|
5970
|
+
typeFilter.size + prioFilter.size + statusFilter.size > 0 && /* @__PURE__ */ jsx11("span", { className: "rk-badge-count", children: typeFilter.size + prioFilter.size + statusFilter.size })
|
|
6708
5971
|
]
|
|
6709
5972
|
}
|
|
6710
5973
|
),
|
|
6711
|
-
filterOpen && /* @__PURE__ */
|
|
6712
|
-
/* @__PURE__ */
|
|
6713
|
-
TYPE_FILTERS.map((type) => /* @__PURE__ */
|
|
5974
|
+
filterOpen && /* @__PURE__ */ jsxs10("div", { className: "rk-menu", role: "menu", "aria-label": "Filter items", children: [
|
|
5975
|
+
/* @__PURE__ */ jsx11("div", { className: "rk-menu-title", children: "Type" }),
|
|
5976
|
+
TYPE_FILTERS.map((type) => /* @__PURE__ */ jsxs10(
|
|
6714
5977
|
"button",
|
|
6715
5978
|
{
|
|
6716
5979
|
type: "button",
|
|
@@ -6724,16 +5987,16 @@ function Panel() {
|
|
|
6724
5987
|
setTypeFilter(next);
|
|
6725
5988
|
},
|
|
6726
5989
|
children: [
|
|
6727
|
-
/* @__PURE__ */
|
|
5990
|
+
/* @__PURE__ */ jsx11("span", { className: `rk-menu-check${typeFilter.has(type) ? " rk-on" : ""}` }),
|
|
6728
5991
|
iconForType(type, 12),
|
|
6729
|
-
/* @__PURE__ */
|
|
6730
|
-
/* @__PURE__ */
|
|
5992
|
+
/* @__PURE__ */ jsx11("span", { className: "rk-menu-label", children: type }),
|
|
5993
|
+
/* @__PURE__ */ jsx11("span", { className: "rk-menu-count", children: typeCounts.get(type) ?? 0 })
|
|
6731
5994
|
]
|
|
6732
5995
|
},
|
|
6733
5996
|
type
|
|
6734
5997
|
)),
|
|
6735
|
-
/* @__PURE__ */
|
|
6736
|
-
PRIORITY_FILTERS.map((priority) => /* @__PURE__ */
|
|
5998
|
+
/* @__PURE__ */ jsx11("div", { className: "rk-menu-title", children: "Priority" }),
|
|
5999
|
+
PRIORITY_FILTERS.map((priority) => /* @__PURE__ */ jsxs10(
|
|
6737
6000
|
"button",
|
|
6738
6001
|
{
|
|
6739
6002
|
type: "button",
|
|
@@ -6747,15 +6010,15 @@ function Panel() {
|
|
|
6747
6010
|
setPrioFilter(next);
|
|
6748
6011
|
},
|
|
6749
6012
|
children: [
|
|
6750
|
-
/* @__PURE__ */
|
|
6751
|
-
/* @__PURE__ */
|
|
6752
|
-
/* @__PURE__ */
|
|
6013
|
+
/* @__PURE__ */ jsx11("span", { className: `rk-menu-check${prioFilter.has(priority) ? " rk-on" : ""}` }),
|
|
6014
|
+
/* @__PURE__ */ jsx11("span", { className: "rk-menu-label", children: PRIORITY_LABELS[priority] }),
|
|
6015
|
+
/* @__PURE__ */ jsx11("span", { className: "rk-menu-count", children: prioCounts.get(priority) ?? 0 })
|
|
6753
6016
|
]
|
|
6754
6017
|
},
|
|
6755
6018
|
priority
|
|
6756
6019
|
)),
|
|
6757
|
-
/* @__PURE__ */
|
|
6758
|
-
STATUSES.map((status) => /* @__PURE__ */
|
|
6020
|
+
/* @__PURE__ */ jsx11("div", { className: "rk-menu-title", children: "Status" }),
|
|
6021
|
+
STATUSES.map((status) => /* @__PURE__ */ jsxs10(
|
|
6759
6022
|
"button",
|
|
6760
6023
|
{
|
|
6761
6024
|
type: "button",
|
|
@@ -6769,15 +6032,15 @@ function Panel() {
|
|
|
6769
6032
|
setStatusFilter(next);
|
|
6770
6033
|
},
|
|
6771
6034
|
children: [
|
|
6772
|
-
/* @__PURE__ */
|
|
6773
|
-
/* @__PURE__ */
|
|
6774
|
-
/* @__PURE__ */
|
|
6775
|
-
/* @__PURE__ */
|
|
6035
|
+
/* @__PURE__ */ jsx11("span", { className: `rk-menu-check${statusFilter.has(status) ? " rk-on" : ""}` }),
|
|
6036
|
+
/* @__PURE__ */ jsx11("span", { className: `rk-status-dot rk-st-${status}` }),
|
|
6037
|
+
/* @__PURE__ */ jsx11("span", { className: "rk-menu-label", children: status }),
|
|
6038
|
+
/* @__PURE__ */ jsx11("span", { className: "rk-menu-count", children: statusCounts.get(status) ?? 0 })
|
|
6776
6039
|
]
|
|
6777
6040
|
},
|
|
6778
6041
|
status
|
|
6779
6042
|
)),
|
|
6780
|
-
/* @__PURE__ */
|
|
6043
|
+
/* @__PURE__ */ jsx11(
|
|
6781
6044
|
"button",
|
|
6782
6045
|
{
|
|
6783
6046
|
type: "button",
|
|
@@ -6797,28 +6060,28 @@ function Panel() {
|
|
|
6797
6060
|
] })
|
|
6798
6061
|
] })
|
|
6799
6062
|
] }),
|
|
6800
|
-
preview && unapplied > 0 && /* @__PURE__ */
|
|
6063
|
+
preview && unapplied > 0 && /* @__PURE__ */ jsxs10("div", { className: "rk-unplaced", role: "status", children: [
|
|
6801
6064
|
unapplied,
|
|
6802
6065
|
" saved change",
|
|
6803
6066
|
unapplied === 1 ? "" : "s",
|
|
6804
6067
|
" couldn\u2019t be placed on the current page \u2014 the page has changed since they were captured."
|
|
6805
6068
|
] }),
|
|
6806
|
-
/* @__PURE__ */
|
|
6807
|
-
/* @__PURE__ */
|
|
6808
|
-
/* @__PURE__ */
|
|
6809
|
-
/* @__PURE__ */
|
|
6810
|
-
] }) : groups.map(([route, entries]) => /* @__PURE__ */
|
|
6811
|
-
/* @__PURE__ */
|
|
6069
|
+
/* @__PURE__ */ jsx11("div", { className: "rk-panel-list", children: filtered.length === 0 ? /* @__PURE__ */ jsxs10("div", { className: "rk-empty", children: [
|
|
6070
|
+
/* @__PURE__ */ jsx11("div", { className: "rk-empty-art", children: /* @__PURE__ */ jsx11(IconTarget, { size: 22 }) }),
|
|
6071
|
+
/* @__PURE__ */ jsx11("div", { className: "rk-empty-title", children: items.length === 0 ? "Nothing here yet" : "No matches" }),
|
|
6072
|
+
/* @__PURE__ */ jsx11("div", { className: "rk-empty-text", children: items.length === 0 ? "Choose \u201CPick an element\u201D, then click anything on the page. Your suggestions collect here, ready to hand off." : "Try a different search, or clear the filters." })
|
|
6073
|
+
] }) : groups.map(([route, entries]) => /* @__PURE__ */ jsxs10("div", { children: [
|
|
6074
|
+
/* @__PURE__ */ jsx11("div", { className: "rk-group-title", children: route }),
|
|
6812
6075
|
entries.map(({ item, number }) => {
|
|
6813
|
-
const
|
|
6076
|
+
const active = item.id === activeItemId;
|
|
6814
6077
|
const orphan = orphanIds.has(item.id);
|
|
6815
6078
|
const hiddenEl = hiddenIds.has(item.id);
|
|
6816
|
-
return /* @__PURE__ */
|
|
6817
|
-
/* @__PURE__ */
|
|
6079
|
+
return /* @__PURE__ */ jsxs10("div", { children: [
|
|
6080
|
+
/* @__PURE__ */ jsxs10(
|
|
6818
6081
|
"div",
|
|
6819
6082
|
{
|
|
6820
6083
|
"data-item-id": item.id,
|
|
6821
|
-
className: `rk-item${
|
|
6084
|
+
className: `rk-item${active ? " rk-active" : ""}${orphan ? " rk-orphan" : ""}`,
|
|
6822
6085
|
role: "button",
|
|
6823
6086
|
tabIndex: 0,
|
|
6824
6087
|
onClick: () => jumpTo(item),
|
|
@@ -6829,18 +6092,18 @@ function Panel() {
|
|
|
6829
6092
|
}
|
|
6830
6093
|
},
|
|
6831
6094
|
children: [
|
|
6832
|
-
/* @__PURE__ */
|
|
6833
|
-
/* @__PURE__ */
|
|
6834
|
-
/* @__PURE__ */
|
|
6835
|
-
/* @__PURE__ */
|
|
6095
|
+
/* @__PURE__ */ jsx11("span", { className: "rk-item-num", children: number }),
|
|
6096
|
+
/* @__PURE__ */ jsx11("span", { className: "rk-item-icon", children: iconForType(item.type) }),
|
|
6097
|
+
/* @__PURE__ */ jsxs10("span", { className: "rk-item-body", children: [
|
|
6098
|
+
/* @__PURE__ */ jsxs10("span", { className: "rk-item-snippet", children: [
|
|
6836
6099
|
item.target.tagName,
|
|
6837
6100
|
" \xB7 ",
|
|
6838
6101
|
item.target.textSnippet || item.target.selector
|
|
6839
6102
|
] }),
|
|
6840
|
-
/* @__PURE__ */
|
|
6841
|
-
/* @__PURE__ */
|
|
6842
|
-
/* @__PURE__ */
|
|
6843
|
-
/* @__PURE__ */
|
|
6103
|
+
/* @__PURE__ */ jsx11("span", { className: "rk-item-change", children: changeSummary(item) }),
|
|
6104
|
+
/* @__PURE__ */ jsxs10("span", { className: "rk-item-meta", children: [
|
|
6105
|
+
/* @__PURE__ */ jsxs10("span", { className: "rk-author", title: new Date(item.createdAt).toLocaleString(), children: [
|
|
6106
|
+
/* @__PURE__ */ jsx11(
|
|
6844
6107
|
"span",
|
|
6845
6108
|
{
|
|
6846
6109
|
className: "rk-author-dot",
|
|
@@ -6848,15 +6111,15 @@ function Panel() {
|
|
|
6848
6111
|
}
|
|
6849
6112
|
),
|
|
6850
6113
|
item.author?.name ?? "Unknown",
|
|
6851
|
-
/* @__PURE__ */
|
|
6114
|
+
/* @__PURE__ */ jsxs10("span", { className: "rk-time", children: [
|
|
6852
6115
|
" \xB7 ",
|
|
6853
6116
|
timeAgo(item.createdAt)
|
|
6854
6117
|
] })
|
|
6855
6118
|
] }),
|
|
6856
|
-
item.priority === "must" && /* @__PURE__ */
|
|
6857
|
-
item.status !== "open" && /* @__PURE__ */
|
|
6858
|
-
orphan && /* @__PURE__ */
|
|
6859
|
-
hiddenEl && /* @__PURE__ */
|
|
6119
|
+
item.priority === "must" && /* @__PURE__ */ jsx11("span", { className: "rk-badge-mini rk-must", children: "must" }),
|
|
6120
|
+
item.status !== "open" && /* @__PURE__ */ jsx11("span", { className: `rk-badge-mini rk-${item.status}`, children: item.status }),
|
|
6121
|
+
orphan && /* @__PURE__ */ jsx11("span", { className: "rk-badge-mini rk-orphaned", children: "unanchored" }),
|
|
6122
|
+
hiddenEl && /* @__PURE__ */ jsx11(
|
|
6860
6123
|
"span",
|
|
6861
6124
|
{
|
|
6862
6125
|
className: "rk-badge-mini rk-hidden-el",
|
|
@@ -6864,14 +6127,14 @@ function Panel() {
|
|
|
6864
6127
|
children: "hidden"
|
|
6865
6128
|
}
|
|
6866
6129
|
),
|
|
6867
|
-
item.note && /* @__PURE__ */
|
|
6868
|
-
peers.filter((peer) => peer.typingActive && peer.typingItemId === item.id).map((peer) => /* @__PURE__ */
|
|
6130
|
+
item.note && /* @__PURE__ */ jsx11("span", { className: "rk-badge-mini", children: "note" }),
|
|
6131
|
+
peers.filter((peer) => peer.typingActive && peer.typingItemId === item.id).map((peer) => /* @__PURE__ */ jsxs10("span", { className: "rk-badge-mini", style: { color: peer.color }, children: [
|
|
6869
6132
|
peer.name || "peer",
|
|
6870
6133
|
" is writing\u2026"
|
|
6871
6134
|
] }, peer.id))
|
|
6872
6135
|
] })
|
|
6873
6136
|
] }),
|
|
6874
|
-
/* @__PURE__ */
|
|
6137
|
+
/* @__PURE__ */ jsx11("span", { className: "rk-item-actions", children: /* @__PURE__ */ jsx11(
|
|
6875
6138
|
"button",
|
|
6876
6139
|
{
|
|
6877
6140
|
type: "button",
|
|
@@ -6886,15 +6149,15 @@ function Panel() {
|
|
|
6886
6149
|
"info"
|
|
6887
6150
|
);
|
|
6888
6151
|
},
|
|
6889
|
-
children: /* @__PURE__ */
|
|
6152
|
+
children: /* @__PURE__ */ jsx11(IconTrash, { size: 13 })
|
|
6890
6153
|
}
|
|
6891
6154
|
) })
|
|
6892
6155
|
]
|
|
6893
6156
|
}
|
|
6894
6157
|
),
|
|
6895
|
-
|
|
6896
|
-
/* @__PURE__ */
|
|
6897
|
-
/* @__PURE__ */
|
|
6158
|
+
active && /* @__PURE__ */ jsxs10("div", { className: "rk-item-edit", children: [
|
|
6159
|
+
/* @__PURE__ */ jsxs10("div", { className: "rk-detail-byline", title: new Date(item.createdAt).toLocaleString(), children: [
|
|
6160
|
+
/* @__PURE__ */ jsx11(
|
|
6898
6161
|
"span",
|
|
6899
6162
|
{
|
|
6900
6163
|
className: "rk-author-dot",
|
|
@@ -6905,8 +6168,8 @@ function Panel() {
|
|
|
6905
6168
|
" \xB7 ",
|
|
6906
6169
|
timeAgo(item.createdAt)
|
|
6907
6170
|
] }),
|
|
6908
|
-
isCopyItem(item) && /* @__PURE__ */
|
|
6909
|
-
isImageItem(item) && /* @__PURE__ */
|
|
6171
|
+
isCopyItem(item) && /* @__PURE__ */ jsx11(CopyDiff, { before: item.payload.before, after: item.payload.after }),
|
|
6172
|
+
isImageItem(item) && /* @__PURE__ */ jsx11(
|
|
6910
6173
|
ImageDetail,
|
|
6911
6174
|
{
|
|
6912
6175
|
beforeSrc: item.payload.beforeSrc,
|
|
@@ -6914,7 +6177,7 @@ function Panel() {
|
|
|
6914
6177
|
afterDataUrl: item.payload.afterDataUrl
|
|
6915
6178
|
}
|
|
6916
6179
|
),
|
|
6917
|
-
isKnownItemType(item.type) && item.type !== "move" && /* @__PURE__ */
|
|
6180
|
+
isKnownItemType(item.type) && item.type !== "move" && /* @__PURE__ */ jsx11(
|
|
6918
6181
|
"textarea",
|
|
6919
6182
|
{
|
|
6920
6183
|
className: "rk-textarea",
|
|
@@ -6924,7 +6187,7 @@ function Panel() {
|
|
|
6924
6187
|
onChange: (event) => dispatch({ type: "UPDATE_ITEM", id: item.id, patch: withPayloadText(item, event.target.value) })
|
|
6925
6188
|
}
|
|
6926
6189
|
),
|
|
6927
|
-
/* @__PURE__ */
|
|
6190
|
+
/* @__PURE__ */ jsx11(
|
|
6928
6191
|
"input",
|
|
6929
6192
|
{
|
|
6930
6193
|
className: "rk-input",
|
|
@@ -6934,9 +6197,9 @@ function Panel() {
|
|
|
6934
6197
|
onChange: (event) => dispatch({ type: "UPDATE_ITEM", id: item.id, patch: { note: event.target.value } })
|
|
6935
6198
|
}
|
|
6936
6199
|
),
|
|
6937
|
-
/* @__PURE__ */
|
|
6938
|
-
/* @__PURE__ */
|
|
6939
|
-
/* @__PURE__ */
|
|
6200
|
+
/* @__PURE__ */ jsxs10("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
|
|
6201
|
+
/* @__PURE__ */ jsxs10("div", { className: "rk-seg", role: "group", "aria-label": "Priority", children: [
|
|
6202
|
+
/* @__PURE__ */ jsx11(
|
|
6940
6203
|
"button",
|
|
6941
6204
|
{
|
|
6942
6205
|
type: "button",
|
|
@@ -6945,7 +6208,7 @@ function Panel() {
|
|
|
6945
6208
|
children: "Must"
|
|
6946
6209
|
}
|
|
6947
6210
|
),
|
|
6948
|
-
/* @__PURE__ */
|
|
6211
|
+
/* @__PURE__ */ jsx11(
|
|
6949
6212
|
"button",
|
|
6950
6213
|
{
|
|
6951
6214
|
type: "button",
|
|
@@ -6955,7 +6218,7 @@ function Panel() {
|
|
|
6955
6218
|
}
|
|
6956
6219
|
)
|
|
6957
6220
|
] }),
|
|
6958
|
-
/* @__PURE__ */
|
|
6221
|
+
/* @__PURE__ */ jsx11("div", { className: "rk-seg", role: "group", "aria-label": "Status", children: STATUSES.map((status) => /* @__PURE__ */ jsx11(
|
|
6959
6222
|
"button",
|
|
6960
6223
|
{
|
|
6961
6224
|
type: "button",
|
|
@@ -6970,22 +6233,22 @@ function Panel() {
|
|
|
6970
6233
|
] }, item.id);
|
|
6971
6234
|
})
|
|
6972
6235
|
] }, route)) }),
|
|
6973
|
-
/* @__PURE__ */
|
|
6974
|
-
/* @__PURE__ */
|
|
6975
|
-
/* @__PURE__ */
|
|
6236
|
+
/* @__PURE__ */ jsxs10("div", { className: "rk-panel-foot", children: [
|
|
6237
|
+
/* @__PURE__ */ jsxs10("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: onExport, disabled: items.length === 0, children: [
|
|
6238
|
+
/* @__PURE__ */ jsx11(IconDownload, { size: 13 }),
|
|
6976
6239
|
" Export"
|
|
6977
6240
|
] }),
|
|
6978
|
-
/* @__PURE__ */
|
|
6979
|
-
/* @__PURE__ */
|
|
6241
|
+
/* @__PURE__ */ jsxs10("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => void onCopy(), disabled: items.length === 0, children: [
|
|
6242
|
+
/* @__PURE__ */ jsx11(IconCopyClipboard, { size: 13 }),
|
|
6980
6243
|
" Copy"
|
|
6981
6244
|
] }),
|
|
6982
|
-
/* @__PURE__ */
|
|
6983
|
-
/* @__PURE__ */
|
|
6245
|
+
/* @__PURE__ */ jsxs10("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => importRef.current?.click(), children: [
|
|
6246
|
+
/* @__PURE__ */ jsx11(IconUpload, { size: 13 }),
|
|
6984
6247
|
" Import"
|
|
6985
6248
|
] }),
|
|
6986
|
-
/* @__PURE__ */
|
|
6987
|
-
undoStack.length > 0 && /* @__PURE__ */
|
|
6988
|
-
/* @__PURE__ */
|
|
6249
|
+
/* @__PURE__ */ jsx11("span", { className: "rk-spacer" }),
|
|
6250
|
+
undoStack.length > 0 && /* @__PURE__ */ jsx11("button", { type: "button", className: "rk-icon-btn", "aria-label": "Undo last change (\u2318Z)", onClick: () => dispatch({ type: "UNDO" }), children: /* @__PURE__ */ jsx11(IconUndo, { size: 14 }) }),
|
|
6251
|
+
/* @__PURE__ */ jsx11(
|
|
6989
6252
|
"button",
|
|
6990
6253
|
{
|
|
6991
6254
|
type: "button",
|
|
@@ -6996,7 +6259,7 @@ function Panel() {
|
|
|
6996
6259
|
children: "Clear"
|
|
6997
6260
|
}
|
|
6998
6261
|
),
|
|
6999
|
-
/* @__PURE__ */
|
|
6262
|
+
/* @__PURE__ */ jsx11(
|
|
7000
6263
|
"button",
|
|
7001
6264
|
{
|
|
7002
6265
|
type: "button",
|
|
@@ -7006,7 +6269,7 @@ function Panel() {
|
|
|
7006
6269
|
children: "Exit review"
|
|
7007
6270
|
}
|
|
7008
6271
|
),
|
|
7009
|
-
/* @__PURE__ */
|
|
6272
|
+
/* @__PURE__ */ jsx11(
|
|
7010
6273
|
"input",
|
|
7011
6274
|
{
|
|
7012
6275
|
ref: importRef,
|
|
@@ -7025,6 +6288,10 @@ function Panel() {
|
|
|
7025
6288
|
}
|
|
7026
6289
|
);
|
|
7027
6290
|
}
|
|
6291
|
+
|
|
6292
|
+
// src/client/components/Presence.tsx
|
|
6293
|
+
import { useEffect as useEffect10, useRef as useRef11 } from "react";
|
|
6294
|
+
import { Fragment as Fragment6, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
7028
6295
|
function initials(name) {
|
|
7029
6296
|
const parts = name.trim().split(/\s+/).filter(Boolean);
|
|
7030
6297
|
if (parts.length === 0) return "\xB7";
|
|
@@ -7034,8 +6301,8 @@ function initials(name) {
|
|
|
7034
6301
|
function PresenceStrip() {
|
|
7035
6302
|
const { peers, syncStatus } = useStore();
|
|
7036
6303
|
if (syncStatus === "disabled" || peers.length === 0) return null;
|
|
7037
|
-
return /* @__PURE__ */
|
|
7038
|
-
peers.slice(0, 5).map((peer) => /* @__PURE__ */
|
|
6304
|
+
return /* @__PURE__ */ jsxs11("div", { className: "rk-presence", "aria-label": `${peers.length} reviewer${peers.length === 1 ? "" : "s"} online`, children: [
|
|
6305
|
+
peers.slice(0, 5).map((peer) => /* @__PURE__ */ jsx12(
|
|
7039
6306
|
"span",
|
|
7040
6307
|
{
|
|
7041
6308
|
className: "rk-avatar",
|
|
@@ -7045,7 +6312,7 @@ function PresenceStrip() {
|
|
|
7045
6312
|
},
|
|
7046
6313
|
peer.id
|
|
7047
6314
|
)),
|
|
7048
|
-
peers.length > 5 && /* @__PURE__ */
|
|
6315
|
+
peers.length > 5 && /* @__PURE__ */ jsxs11("span", { className: "rk-avatar rk-avatar-more", children: [
|
|
7049
6316
|
"+",
|
|
7050
6317
|
peers.length - 5
|
|
7051
6318
|
] })
|
|
@@ -7053,13 +6320,13 @@ function PresenceStrip() {
|
|
|
7053
6320
|
}
|
|
7054
6321
|
function PeerCursors() {
|
|
7055
6322
|
const { peers } = useStore();
|
|
7056
|
-
const ringRefs =
|
|
7057
|
-
const cursorRefs =
|
|
7058
|
-
const motion =
|
|
6323
|
+
const ringRefs = useRef11(/* @__PURE__ */ new Map());
|
|
6324
|
+
const cursorRefs = useRef11(/* @__PURE__ */ new Map());
|
|
6325
|
+
const motion = useRef11(
|
|
7059
6326
|
/* @__PURE__ */ new Map()
|
|
7060
6327
|
);
|
|
7061
|
-
const peersRef =
|
|
7062
|
-
const seen =
|
|
6328
|
+
const peersRef = useRef11(peers);
|
|
6329
|
+
const seen = useRef11(/* @__PURE__ */ new Map());
|
|
7063
6330
|
for (const peer of peers) {
|
|
7064
6331
|
const sig = peer.cursor ? `${peer.cursor.x},${peer.cursor.y},${peer.cursor.ox},${peer.cursor.oy}` : "";
|
|
7065
6332
|
if (seen.current.get(peer.id) !== sig) {
|
|
@@ -7069,7 +6336,7 @@ function PeerCursors() {
|
|
|
7069
6336
|
}
|
|
7070
6337
|
}
|
|
7071
6338
|
peersRef.current = peers;
|
|
7072
|
-
|
|
6339
|
+
useEffect10(() => {
|
|
7073
6340
|
const reduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
7074
6341
|
let raf = 0;
|
|
7075
6342
|
let last = performance.now();
|
|
@@ -7174,8 +6441,8 @@ function PeerCursors() {
|
|
|
7174
6441
|
return () => cancelAnimationFrame(raf);
|
|
7175
6442
|
}, []);
|
|
7176
6443
|
if (peers.length === 0) return null;
|
|
7177
|
-
return /* @__PURE__ */
|
|
7178
|
-
peers.map((peer) => /* @__PURE__ */
|
|
6444
|
+
return /* @__PURE__ */ jsxs11(Fragment6, { children: [
|
|
6445
|
+
peers.map((peer) => /* @__PURE__ */ jsx12(
|
|
7179
6446
|
"div",
|
|
7180
6447
|
{
|
|
7181
6448
|
ref: (el) => {
|
|
@@ -7187,7 +6454,7 @@ function PeerCursors() {
|
|
|
7187
6454
|
},
|
|
7188
6455
|
`ring-${peer.id}`
|
|
7189
6456
|
)),
|
|
7190
|
-
peers.map((peer, index) => /* @__PURE__ */
|
|
6457
|
+
peers.map((peer, index) => /* @__PURE__ */ jsxs11(
|
|
7191
6458
|
"div",
|
|
7192
6459
|
{
|
|
7193
6460
|
ref: (el) => {
|
|
@@ -7197,8 +6464,8 @@ function PeerCursors() {
|
|
|
7197
6464
|
className: "rk-peer-cursor",
|
|
7198
6465
|
style: { opacity: 0 },
|
|
7199
6466
|
children: [
|
|
7200
|
-
/* @__PURE__ */
|
|
7201
|
-
/* @__PURE__ */
|
|
6467
|
+
/* @__PURE__ */ jsx12("svg", { width: "14", height: "18", viewBox: "0 0 14 18", "aria-hidden": "true", children: /* @__PURE__ */ jsx12("path", { d: "M1 1l12 7.5-5.2 1.2L5 16z", fill: peer.color, stroke: "rgba(0,0,0,0.25)", strokeWidth: "1" }) }),
|
|
6468
|
+
/* @__PURE__ */ jsxs11(
|
|
7202
6469
|
"span",
|
|
7203
6470
|
{
|
|
7204
6471
|
className: "rk-peer-name",
|
|
@@ -7215,17 +6482,21 @@ function PeerCursors() {
|
|
|
7215
6482
|
))
|
|
7216
6483
|
] });
|
|
7217
6484
|
}
|
|
6485
|
+
|
|
6486
|
+
// src/client/components/QuickComment.tsx
|
|
6487
|
+
import { useEffect as useEffect11, useRef as useRef12, useState as useState9 } from "react";
|
|
6488
|
+
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
7218
6489
|
function QuickComment() {
|
|
7219
6490
|
const { quick } = useStore();
|
|
7220
6491
|
if (!quick) return null;
|
|
7221
|
-
return /* @__PURE__ */
|
|
6492
|
+
return /* @__PURE__ */ jsx13(QuickComposerCard, { quick }, quick.id);
|
|
7222
6493
|
}
|
|
7223
6494
|
function QuickComposerCard({ quick }) {
|
|
7224
6495
|
const { route, session } = useStore();
|
|
7225
6496
|
const dispatch = useDispatch();
|
|
7226
|
-
const [text, setText] =
|
|
7227
|
-
const fieldRef =
|
|
7228
|
-
|
|
6497
|
+
const [text, setText] = useState9("");
|
|
6498
|
+
const fieldRef = useRef12(null);
|
|
6499
|
+
useEffect11(() => {
|
|
7229
6500
|
const field = fieldRef.current;
|
|
7230
6501
|
if (!field) return;
|
|
7231
6502
|
field.focus();
|
|
@@ -7242,7 +6513,7 @@ function QuickComposerCard({ quick }) {
|
|
|
7242
6513
|
return;
|
|
7243
6514
|
}
|
|
7244
6515
|
const command = /^\/(\S+)$/.exec(trimmed);
|
|
7245
|
-
if (command &&
|
|
6516
|
+
if (command && isEffectCommand(command[1])) {
|
|
7246
6517
|
try {
|
|
7247
6518
|
runEffect(command[1], layerRoot);
|
|
7248
6519
|
sendEffectToRoom(command[1]);
|
|
@@ -7278,18 +6549,18 @@ function QuickComposerCard({ quick }) {
|
|
|
7278
6549
|
};
|
|
7279
6550
|
const x = Math.min(Math.max(quick.x, 8), window.innerWidth - 288);
|
|
7280
6551
|
const y = Math.min(Math.max(quick.y + 12, 8), window.innerHeight - 108);
|
|
7281
|
-
return /* @__PURE__ */
|
|
7282
|
-
/* @__PURE__ */
|
|
7283
|
-
/* @__PURE__ */
|
|
7284
|
-
/* @__PURE__ */
|
|
7285
|
-
/* @__PURE__ */
|
|
7286
|
-
/* @__PURE__ */
|
|
6552
|
+
return /* @__PURE__ */ jsxs12("div", { className: "rk-quick", style: { transform: `translate3d(${x}px, ${y}px, 0)` }, role: "dialog", "aria-label": "Quick comment", children: [
|
|
6553
|
+
/* @__PURE__ */ jsxs12("div", { className: "rk-quick-head", children: [
|
|
6554
|
+
/* @__PURE__ */ jsx13(IconComment, { size: 12 }),
|
|
6555
|
+
/* @__PURE__ */ jsx13("span", { children: "Comment here" }),
|
|
6556
|
+
/* @__PURE__ */ jsxs12("span", { className: "rk-hint", children: [
|
|
6557
|
+
/* @__PURE__ */ jsx13("span", { className: "rk-kbd", children: "\u21B5" }),
|
|
7287
6558
|
" save \xB7 ",
|
|
7288
|
-
/* @__PURE__ */
|
|
6559
|
+
/* @__PURE__ */ jsx13("span", { className: "rk-kbd", children: "esc" }),
|
|
7289
6560
|
" cancel"
|
|
7290
6561
|
] })
|
|
7291
6562
|
] }),
|
|
7292
|
-
/* @__PURE__ */
|
|
6563
|
+
/* @__PURE__ */ jsx13(
|
|
7293
6564
|
"textarea",
|
|
7294
6565
|
{
|
|
7295
6566
|
ref: fieldRef,
|
|
@@ -7303,6 +6574,10 @@ function QuickComposerCard({ quick }) {
|
|
|
7303
6574
|
)
|
|
7304
6575
|
] });
|
|
7305
6576
|
}
|
|
6577
|
+
|
|
6578
|
+
// src/client/components/PickLayer.tsx
|
|
6579
|
+
import { useEffect as useEffect12, useRef as useRef13, useState as useState10 } from "react";
|
|
6580
|
+
import { Fragment as Fragment7, jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
7306
6581
|
function applyRect(el, rect, pad2 = 3) {
|
|
7307
6582
|
if (!el) return;
|
|
7308
6583
|
if (!rect) {
|
|
@@ -7317,14 +6592,14 @@ function applyRect(el, rect, pad2 = 3) {
|
|
|
7317
6592
|
function PickLayer() {
|
|
7318
6593
|
const { mode, selection, tool } = useStore();
|
|
7319
6594
|
const dispatch = useDispatch();
|
|
7320
|
-
const [hovered, setHovered] =
|
|
7321
|
-
const outlineRef =
|
|
7322
|
-
const labelRef =
|
|
7323
|
-
const selectRef =
|
|
7324
|
-
const hoveredRef =
|
|
6595
|
+
const [hovered, setHovered] = useState10(null);
|
|
6596
|
+
const outlineRef = useRef13(null);
|
|
6597
|
+
const labelRef = useRef13(null);
|
|
6598
|
+
const selectRef = useRef13(null);
|
|
6599
|
+
const hoveredRef = useRef13(null);
|
|
7325
6600
|
hoveredRef.current = hovered;
|
|
7326
6601
|
const picking = mode === "pick";
|
|
7327
|
-
|
|
6602
|
+
useEffect12(() => {
|
|
7328
6603
|
if (!picking) {
|
|
7329
6604
|
setHovered(null);
|
|
7330
6605
|
return;
|
|
@@ -7368,7 +6643,7 @@ function PickLayer() {
|
|
|
7368
6643
|
document.removeEventListener("mousedown", swallow, true);
|
|
7369
6644
|
};
|
|
7370
6645
|
}, [picking, tool, dispatch]);
|
|
7371
|
-
|
|
6646
|
+
useEffect12(() => {
|
|
7372
6647
|
if (!picking) return;
|
|
7373
6648
|
const body = document.body;
|
|
7374
6649
|
const prev = body.style.cursor;
|
|
@@ -7378,7 +6653,7 @@ function PickLayer() {
|
|
|
7378
6653
|
if (body.getAttribute("style") === "") body.removeAttribute("style");
|
|
7379
6654
|
};
|
|
7380
6655
|
}, [picking, tool]);
|
|
7381
|
-
|
|
6656
|
+
useEffect12(() => {
|
|
7382
6657
|
let raf = 0;
|
|
7383
6658
|
const tick = () => {
|
|
7384
6659
|
const hoverEl = hoveredRef.current;
|
|
@@ -7404,17 +6679,21 @@ function PickLayer() {
|
|
|
7404
6679
|
raf = requestAnimationFrame(tick);
|
|
7405
6680
|
return () => cancelAnimationFrame(raf);
|
|
7406
6681
|
}, [picking, selection]);
|
|
7407
|
-
return /* @__PURE__ */
|
|
7408
|
-
picking && /* @__PURE__ */
|
|
7409
|
-
/* @__PURE__ */
|
|
7410
|
-
/* @__PURE__ */
|
|
7411
|
-
/* @__PURE__ */
|
|
7412
|
-
/* @__PURE__ */
|
|
7413
|
-
] }) : /* @__PURE__ */
|
|
6682
|
+
return /* @__PURE__ */ jsxs13(Fragment7, { children: [
|
|
6683
|
+
picking && /* @__PURE__ */ jsxs13(Fragment7, { children: [
|
|
6684
|
+
/* @__PURE__ */ jsx14("div", { ref: outlineRef, className: "rk-outline", style: { opacity: 0 } }),
|
|
6685
|
+
/* @__PURE__ */ jsx14("div", { ref: labelRef, className: "rk-outline-label", style: { opacity: 0 }, children: hovered ? /* @__PURE__ */ jsxs13(Fragment7, { children: [
|
|
6686
|
+
/* @__PURE__ */ jsx14("span", { className: "rk-tag", children: hovered.tagName.toLowerCase() }),
|
|
6687
|
+
/* @__PURE__ */ jsx14("span", { children: describeElement(hovered).replace(/^[a-z0-9]+ · /, "") })
|
|
6688
|
+
] }) : /* @__PURE__ */ jsx14("span", { children: "Pick an element" }) })
|
|
7414
6689
|
] }),
|
|
7415
|
-
selection && /* @__PURE__ */
|
|
6690
|
+
selection && /* @__PURE__ */ jsx14("div", { ref: selectRef, className: "rk-select-ring", style: { opacity: 0 } })
|
|
7416
6691
|
] });
|
|
7417
6692
|
}
|
|
6693
|
+
|
|
6694
|
+
// src/client/components/Pins.tsx
|
|
6695
|
+
import { useEffect as useEffect13, useMemo as useMemo4, useRef as useRef14, useState as useState11 } from "react";
|
|
6696
|
+
import { Fragment as Fragment8, jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
7418
6697
|
var STATUS_LABELS = {
|
|
7419
6698
|
open: "open",
|
|
7420
6699
|
accepted: "accepted",
|
|
@@ -7426,22 +6705,22 @@ var RERESOLVE_MS = 800;
|
|
|
7426
6705
|
function Pins() {
|
|
7427
6706
|
const { session, route, activeItemId, editor, mode, filter } = useStore();
|
|
7428
6707
|
const dispatch = useDispatch();
|
|
7429
|
-
const [clusters, setClusters] =
|
|
7430
|
-
const [orphanCount, setOrphanCount] =
|
|
7431
|
-
const wrapRefs =
|
|
7432
|
-
const visibleCache =
|
|
7433
|
-
const highlightRef =
|
|
7434
|
-
const hoveredItems =
|
|
7435
|
-
const elementCache =
|
|
7436
|
-
const lastResolve =
|
|
7437
|
-
const [newestId, setNewestId] =
|
|
7438
|
-
const prevCount =
|
|
7439
|
-
const items =
|
|
6708
|
+
const [clusters, setClusters] = useState11([]);
|
|
6709
|
+
const [orphanCount, setOrphanCount] = useState11(0);
|
|
6710
|
+
const wrapRefs = useRef14(/* @__PURE__ */ new Map());
|
|
6711
|
+
const visibleCache = useRef14(/* @__PURE__ */ new Map());
|
|
6712
|
+
const highlightRef = useRef14(null);
|
|
6713
|
+
const hoveredItems = useRef14(null);
|
|
6714
|
+
const elementCache = useRef14(/* @__PURE__ */ new Map());
|
|
6715
|
+
const lastResolve = useRef14(0);
|
|
6716
|
+
const [newestId, setNewestId] = useState11(null);
|
|
6717
|
+
const prevCount = useRef14(0);
|
|
6718
|
+
const items = useMemo4(() => {
|
|
7440
6719
|
const all = session?.items ?? [];
|
|
7441
6720
|
return all.map((item, index) => ({ item, number: index + 1 })).filter(({ item }) => item.route === route);
|
|
7442
6721
|
}, [session, route]);
|
|
7443
6722
|
const byId = new Map(items.map(({ item }) => [item.id, item]));
|
|
7444
|
-
|
|
6723
|
+
useEffect13(() => {
|
|
7445
6724
|
const count = session?.items.length ?? 0;
|
|
7446
6725
|
if (count > prevCount.current && session && count > 0) {
|
|
7447
6726
|
const id = session.items[count - 1].id;
|
|
@@ -7452,7 +6731,7 @@ function Pins() {
|
|
|
7452
6731
|
}
|
|
7453
6732
|
prevCount.current = count;
|
|
7454
6733
|
}, [session]);
|
|
7455
|
-
|
|
6734
|
+
useEffect13(() => {
|
|
7456
6735
|
let raf = 0;
|
|
7457
6736
|
let lastSignature = "";
|
|
7458
6737
|
const tick = (time) => {
|
|
@@ -7536,8 +6815,8 @@ function Pins() {
|
|
|
7536
6815
|
dispatch({ type: "SET_ACTIVE_ITEM", id });
|
|
7537
6816
|
dispatch({ type: "SET_PANEL", open: true });
|
|
7538
6817
|
};
|
|
7539
|
-
return /* @__PURE__ */
|
|
7540
|
-
/* @__PURE__ */
|
|
6818
|
+
return /* @__PURE__ */ jsxs14(Fragment8, { children: [
|
|
6819
|
+
/* @__PURE__ */ jsx15("div", { ref: highlightRef, className: "rk-hl-ring", style: { opacity: 0 } }),
|
|
7541
6820
|
clusters.map((cluster) => {
|
|
7542
6821
|
const isCluster = cluster.ids.length > 1;
|
|
7543
6822
|
const isActive = activeItemId !== null && cluster.ids.includes(activeItemId);
|
|
@@ -7547,7 +6826,7 @@ function Pins() {
|
|
|
7547
6826
|
const status = statuses.size === 1 ? members[0]?.status : void 0;
|
|
7548
6827
|
const dimmed = filter !== null && members.length > 0 && !members.some((item) => itemMatchesFilter(item, filter));
|
|
7549
6828
|
const statusHint = isCluster ? status ? ` \xB7 all ${STATUS_LABELS[status] ?? status}` : "" : ` \xB7 ${STATUS_LABELS[members[0]?.status ?? "open"] ?? members[0]?.status}`;
|
|
7550
|
-
return /* @__PURE__ */
|
|
6829
|
+
return /* @__PURE__ */ jsx15(
|
|
7551
6830
|
"div",
|
|
7552
6831
|
{
|
|
7553
6832
|
ref: (el) => {
|
|
@@ -7555,7 +6834,7 @@ function Pins() {
|
|
|
7555
6834
|
else wrapRefs.current.delete(cluster.key);
|
|
7556
6835
|
},
|
|
7557
6836
|
className: `rk-pin-wrap${picking ? " rk-pin-ghost" : ""}`,
|
|
7558
|
-
children: /* @__PURE__ */
|
|
6837
|
+
children: /* @__PURE__ */ jsx15(
|
|
7559
6838
|
"button",
|
|
7560
6839
|
{
|
|
7561
6840
|
type: "button",
|
|
@@ -7577,7 +6856,7 @@ function Pins() {
|
|
|
7577
6856
|
cluster.key
|
|
7578
6857
|
);
|
|
7579
6858
|
}),
|
|
7580
|
-
orphanCount > 0 && /* @__PURE__ */
|
|
6859
|
+
orphanCount > 0 && /* @__PURE__ */ jsxs14(
|
|
7581
6860
|
"button",
|
|
7582
6861
|
{
|
|
7583
6862
|
type: "button",
|
|
@@ -7585,7 +6864,7 @@ function Pins() {
|
|
|
7585
6864
|
style: { bottom: 16, left: "50%", transform: "translateX(-50%)" },
|
|
7586
6865
|
onClick: () => dispatch({ type: "SET_PANEL", open: true }),
|
|
7587
6866
|
children: [
|
|
7588
|
-
/* @__PURE__ */
|
|
6867
|
+
/* @__PURE__ */ jsx15(IconUnlink, { size: 13 }),
|
|
7589
6868
|
orphanCount,
|
|
7590
6869
|
" unanchored item",
|
|
7591
6870
|
orphanCount === 1 ? "" : "s"
|
|
@@ -7594,11 +6873,15 @@ function Pins() {
|
|
|
7594
6873
|
)
|
|
7595
6874
|
] });
|
|
7596
6875
|
}
|
|
6876
|
+
|
|
6877
|
+
// src/client/components/Toolbar.tsx
|
|
6878
|
+
import { useEffect as useEffect14, useLayoutEffect as useLayoutEffect3, useRef as useRef15, useState as useState12 } from "react";
|
|
6879
|
+
import { Fragment as Fragment9, jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
7597
6880
|
var TOOLS = [
|
|
7598
|
-
{ tool: "select", hintId: "tool-select", label: "Select", icon: (n) => /* @__PURE__ */
|
|
7599
|
-
{ tool: "copy", hintId: "tool-copy", label: "Rewrite text", icon: (n) => /* @__PURE__ */
|
|
7600
|
-
{ tool: "comment", hintId: "tool-comment", label: "Comment", icon: (n) => /* @__PURE__ */
|
|
7601
|
-
{ tool: "image", hintId: "tool-image", label: "Replace image", icon: (n) => /* @__PURE__ */
|
|
6881
|
+
{ tool: "select", hintId: "tool-select", label: "Select", icon: (n) => /* @__PURE__ */ jsx16(IconTarget, { size: n }) },
|
|
6882
|
+
{ tool: "copy", hintId: "tool-copy", label: "Rewrite text", icon: (n) => /* @__PURE__ */ jsx16(IconText, { size: n }) },
|
|
6883
|
+
{ tool: "comment", hintId: "tool-comment", label: "Comment", icon: (n) => /* @__PURE__ */ jsx16(IconComment, { size: n }) },
|
|
6884
|
+
{ tool: "image", hintId: "tool-image", label: "Replace image", icon: (n) => /* @__PURE__ */ jsx16(IconImage, { size: n }) }
|
|
7602
6885
|
];
|
|
7603
6886
|
var POS_KEY2 = "review-kit:toolbar-pos";
|
|
7604
6887
|
var DRAG_THRESHOLD2 = 6;
|
|
@@ -7606,30 +6889,30 @@ function Toolbar() {
|
|
|
7606
6889
|
const { selection, editor, peers, syncStatus, mode, tool } = useStore();
|
|
7607
6890
|
const hasPeers = syncStatus !== "disabled" && peers.length > 0;
|
|
7608
6891
|
const dispatch = useDispatch();
|
|
7609
|
-
const ref =
|
|
7610
|
-
const [pos, setPos] =
|
|
7611
|
-
const drag =
|
|
7612
|
-
const [dragging, setDragging] =
|
|
7613
|
-
const justDragged =
|
|
6892
|
+
const ref = useRef15(null);
|
|
6893
|
+
const [pos, setPos] = useState12(() => readStoredPos(POS_KEY2));
|
|
6894
|
+
const drag = useRef15(null);
|
|
6895
|
+
const [dragging, setDragging] = useState12(false);
|
|
6896
|
+
const justDragged = useRef15(false);
|
|
7614
6897
|
const visible = editor === null || selection !== null;
|
|
7615
6898
|
const applyPos = (next, persist) => {
|
|
7616
6899
|
if (next === null && ref.current) ref.current.style.bottom = "";
|
|
7617
6900
|
setPos(next);
|
|
7618
|
-
storePos(POS_KEY2, next);
|
|
6901
|
+
if (persist) storePos(POS_KEY2, next);
|
|
7619
6902
|
};
|
|
7620
|
-
|
|
6903
|
+
useLayoutEffect3(() => {
|
|
7621
6904
|
const el = ref.current;
|
|
7622
6905
|
if (!el || pos === null) return;
|
|
7623
6906
|
const clamped = clampPos(pos.x, pos.y, el.offsetWidth, el.offsetHeight);
|
|
7624
|
-
if (clamped.x !== pos.x || clamped.y !== pos.y) applyPos(clamped);
|
|
6907
|
+
if (clamped.x !== pos.x || clamped.y !== pos.y) applyPos(clamped, true);
|
|
7625
6908
|
}, [pos, selection, hasPeers, visible]);
|
|
7626
|
-
|
|
6909
|
+
useEffect14(() => {
|
|
7627
6910
|
const onResize = () => {
|
|
7628
6911
|
const el = ref.current;
|
|
7629
6912
|
const current = readStoredPos(POS_KEY2);
|
|
7630
6913
|
if (!el || !current) return;
|
|
7631
6914
|
const clamped = clampPos(current.x, current.y, el.offsetWidth, el.offsetHeight);
|
|
7632
|
-
if (clamped.x !== current.x || clamped.y !== current.y) applyPos(clamped);
|
|
6915
|
+
if (clamped.x !== current.x || clamped.y !== current.y) applyPos(clamped, true);
|
|
7633
6916
|
};
|
|
7634
6917
|
window.addEventListener("resize", onResize);
|
|
7635
6918
|
return () => window.removeEventListener("resize", onResize);
|
|
@@ -7694,7 +6977,7 @@ function Toolbar() {
|
|
|
7694
6977
|
node.style.left = "0px";
|
|
7695
6978
|
node.style.top = "0px";
|
|
7696
6979
|
node.style.translate = `${snapped.x}px ${snapped.y}px`;
|
|
7697
|
-
applyPos(snapped);
|
|
6980
|
+
applyPos(snapped, true);
|
|
7698
6981
|
};
|
|
7699
6982
|
window.addEventListener("pointermove", onMove, { passive: false });
|
|
7700
6983
|
window.addEventListener("pointerup", onUp);
|
|
@@ -7721,7 +7004,7 @@ function Toolbar() {
|
|
|
7721
7004
|
else if (event.key === "ArrowDown") dy = stepSize;
|
|
7722
7005
|
else return;
|
|
7723
7006
|
event.preventDefault();
|
|
7724
|
-
applyPos(clampPos(rect.left + dx, rect.top + dy, el.offsetWidth, el.offsetHeight));
|
|
7007
|
+
applyPos(clampPos(rect.left + dx, rect.top + dy, el.offsetWidth, el.offsetHeight), true);
|
|
7725
7008
|
};
|
|
7726
7009
|
const open = (kind) => {
|
|
7727
7010
|
if (!selection) return;
|
|
@@ -7736,7 +7019,7 @@ function Toolbar() {
|
|
|
7736
7019
|
mode === "pick" && selection === null ? "rk-ghost" : ""
|
|
7737
7020
|
].filter(Boolean).join(" ");
|
|
7738
7021
|
const style = pos !== null ? { left: 0, top: 0, translate: `${pos.x}px ${pos.y}px` } : void 0;
|
|
7739
|
-
return /* @__PURE__ */
|
|
7022
|
+
return /* @__PURE__ */ jsxs15(
|
|
7740
7023
|
"div",
|
|
7741
7024
|
{
|
|
7742
7025
|
ref,
|
|
@@ -7747,27 +7030,27 @@ function Toolbar() {
|
|
|
7747
7030
|
onPointerDown,
|
|
7748
7031
|
onClickCapture,
|
|
7749
7032
|
children: [
|
|
7750
|
-
/* @__PURE__ */
|
|
7033
|
+
/* @__PURE__ */ jsx16(
|
|
7751
7034
|
"button",
|
|
7752
7035
|
{
|
|
7753
7036
|
type: "button",
|
|
7754
7037
|
className: "rk-toolbar-grip",
|
|
7755
7038
|
"aria-label": "Move the toolbar \u2014 drag, or use arrow keys; double-click to reset its position",
|
|
7756
7039
|
onKeyDown: onGripKeyDown,
|
|
7757
|
-
onDoubleClick: () => applyPos(null),
|
|
7758
|
-
children: /* @__PURE__ */
|
|
7759
|
-
/* @__PURE__ */
|
|
7760
|
-
/* @__PURE__ */
|
|
7761
|
-
/* @__PURE__ */
|
|
7762
|
-
/* @__PURE__ */
|
|
7763
|
-
/* @__PURE__ */
|
|
7764
|
-
/* @__PURE__ */
|
|
7040
|
+
onDoubleClick: () => applyPos(null, true),
|
|
7041
|
+
children: /* @__PURE__ */ jsxs15("svg", { width: "8", height: "14", viewBox: "0 0 8 14", "aria-hidden": "true", fill: "currentColor", children: [
|
|
7042
|
+
/* @__PURE__ */ jsx16("circle", { cx: "2", cy: "2", r: "1.1" }),
|
|
7043
|
+
/* @__PURE__ */ jsx16("circle", { cx: "6", cy: "2", r: "1.1" }),
|
|
7044
|
+
/* @__PURE__ */ jsx16("circle", { cx: "2", cy: "7", r: "1.1" }),
|
|
7045
|
+
/* @__PURE__ */ jsx16("circle", { cx: "6", cy: "7", r: "1.1" }),
|
|
7046
|
+
/* @__PURE__ */ jsx16("circle", { cx: "2", cy: "12", r: "1.1" }),
|
|
7047
|
+
/* @__PURE__ */ jsx16("circle", { cx: "6", cy: "12", r: "1.1" })
|
|
7765
7048
|
] })
|
|
7766
7049
|
}
|
|
7767
7050
|
),
|
|
7768
|
-
/* @__PURE__ */
|
|
7769
|
-
hasPeers && /* @__PURE__ */
|
|
7770
|
-
/* @__PURE__ */
|
|
7051
|
+
/* @__PURE__ */ jsx16(PresenceStrip, {}),
|
|
7052
|
+
hasPeers && /* @__PURE__ */ jsx16("span", { className: "rk-toolbar-sep" }),
|
|
7053
|
+
/* @__PURE__ */ jsx16("div", { className: "rk-seg rk-tool-seg", role: "group", "aria-label": "Tools", children: TOOLS.map((entry) => /* @__PURE__ */ jsx16(
|
|
7771
7054
|
"button",
|
|
7772
7055
|
{
|
|
7773
7056
|
type: "button",
|
|
@@ -7779,9 +7062,9 @@ function Toolbar() {
|
|
|
7779
7062
|
},
|
|
7780
7063
|
entry.tool
|
|
7781
7064
|
)) }),
|
|
7782
|
-
selection && /* @__PURE__ */
|
|
7783
|
-
selection && /* @__PURE__ */
|
|
7784
|
-
/* @__PURE__ */
|
|
7065
|
+
selection && /* @__PURE__ */ jsx16("span", { className: "rk-toolbar-sep" }),
|
|
7066
|
+
selection && /* @__PURE__ */ jsxs15(Fragment9, { children: [
|
|
7067
|
+
/* @__PURE__ */ jsxs15(
|
|
7785
7068
|
"button",
|
|
7786
7069
|
{
|
|
7787
7070
|
type: "button",
|
|
@@ -7790,12 +7073,12 @@ function Toolbar() {
|
|
|
7790
7073
|
title: `Rewrite text${keyHint("tool-copy")}`,
|
|
7791
7074
|
onClick: () => open("copy"),
|
|
7792
7075
|
children: [
|
|
7793
|
-
/* @__PURE__ */
|
|
7076
|
+
/* @__PURE__ */ jsx16(IconText, { size: 14 }),
|
|
7794
7077
|
" Rewrite"
|
|
7795
7078
|
]
|
|
7796
7079
|
}
|
|
7797
7080
|
),
|
|
7798
|
-
hasImage && /* @__PURE__ */
|
|
7081
|
+
hasImage && /* @__PURE__ */ jsxs15(
|
|
7799
7082
|
"button",
|
|
7800
7083
|
{
|
|
7801
7084
|
type: "button",
|
|
@@ -7804,12 +7087,12 @@ function Toolbar() {
|
|
|
7804
7087
|
title: `Replace image${keyHint("tool-image")}`,
|
|
7805
7088
|
onClick: () => open("image"),
|
|
7806
7089
|
children: [
|
|
7807
|
-
/* @__PURE__ */
|
|
7090
|
+
/* @__PURE__ */ jsx16(IconImage, { size: 14 }),
|
|
7808
7091
|
" Image"
|
|
7809
7092
|
]
|
|
7810
7093
|
}
|
|
7811
7094
|
),
|
|
7812
|
-
/* @__PURE__ */
|
|
7095
|
+
/* @__PURE__ */ jsxs15(
|
|
7813
7096
|
"button",
|
|
7814
7097
|
{
|
|
7815
7098
|
type: "button",
|
|
@@ -7818,32 +7101,32 @@ function Toolbar() {
|
|
|
7818
7101
|
title: `Comment${keyHint("tool-comment")}`,
|
|
7819
7102
|
onClick: () => open("comment"),
|
|
7820
7103
|
children: [
|
|
7821
|
-
/* @__PURE__ */
|
|
7104
|
+
/* @__PURE__ */ jsx16(IconComment, { size: 14 }),
|
|
7822
7105
|
" Comment"
|
|
7823
7106
|
]
|
|
7824
7107
|
}
|
|
7825
7108
|
),
|
|
7826
|
-
/* @__PURE__ */
|
|
7827
|
-
/* @__PURE__ */
|
|
7109
|
+
/* @__PURE__ */ jsxs15("button", { type: "button", role: "menuitem", className: "rk-toolbar-btn", onClick: () => open("style"), children: [
|
|
7110
|
+
/* @__PURE__ */ jsx16(IconStyle, { size: 14 }),
|
|
7828
7111
|
" Style"
|
|
7829
7112
|
] }),
|
|
7830
|
-
/* @__PURE__ */
|
|
7831
|
-
/* @__PURE__ */
|
|
7113
|
+
/* @__PURE__ */ jsxs15("button", { type: "button", role: "menuitem", className: "rk-toolbar-btn", onClick: () => open("move"), children: [
|
|
7114
|
+
/* @__PURE__ */ jsx16(IconMove, { size: 14 }),
|
|
7832
7115
|
" Move"
|
|
7833
7116
|
] }),
|
|
7834
|
-
/* @__PURE__ */
|
|
7835
|
-
/* @__PURE__ */
|
|
7117
|
+
/* @__PURE__ */ jsxs15("button", { type: "button", role: "menuitem", className: "rk-toolbar-btn rk-danger", onClick: () => open("delete"), children: [
|
|
7118
|
+
/* @__PURE__ */ jsx16(IconTrash, { size: 14 }),
|
|
7836
7119
|
" Delete"
|
|
7837
7120
|
] }),
|
|
7838
|
-
/* @__PURE__ */
|
|
7839
|
-
/* @__PURE__ */
|
|
7121
|
+
/* @__PURE__ */ jsx16("span", { className: "rk-toolbar-sep" }),
|
|
7122
|
+
/* @__PURE__ */ jsx16(
|
|
7840
7123
|
"button",
|
|
7841
7124
|
{
|
|
7842
7125
|
type: "button",
|
|
7843
7126
|
className: "rk-icon-btn",
|
|
7844
7127
|
"aria-label": "Deselect",
|
|
7845
7128
|
onClick: () => dispatch({ type: "SELECT", selection: null }),
|
|
7846
|
-
children: /* @__PURE__ */
|
|
7129
|
+
children: /* @__PURE__ */ jsx16(IconClose, { size: 13 })
|
|
7847
7130
|
}
|
|
7848
7131
|
)
|
|
7849
7132
|
] })
|
|
@@ -7851,32 +7134,42 @@ function Toolbar() {
|
|
|
7851
7134
|
}
|
|
7852
7135
|
);
|
|
7853
7136
|
}
|
|
7137
|
+
|
|
7138
|
+
// src/client/components/Toast.tsx
|
|
7139
|
+
import { useEffect as useEffect15 } from "react";
|
|
7140
|
+
import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
7854
7141
|
function ToastRow({ toast: toast2 }) {
|
|
7855
7142
|
const dispatch = useDispatch();
|
|
7856
|
-
|
|
7143
|
+
useEffect15(() => {
|
|
7857
7144
|
const timer = window.setTimeout(() => dispatch({ type: "DISMISS_TOAST", id: toast2.id }), 3500);
|
|
7858
7145
|
return () => window.clearTimeout(timer);
|
|
7859
7146
|
}, [toast2.id, dispatch]);
|
|
7860
|
-
return /* @__PURE__ */
|
|
7861
|
-
toast2.tone === "success" ? /* @__PURE__ */
|
|
7147
|
+
return /* @__PURE__ */ jsxs16("div", { className: `rk-toast rk-${toast2.tone}`, role: "status", children: [
|
|
7148
|
+
toast2.tone === "success" ? /* @__PURE__ */ jsx17(IconCheck, { size: 13 }) : toast2.tone === "error" ? /* @__PURE__ */ jsx17(IconWarning, { size: 13 }) : /* @__PURE__ */ jsx17(IconComment, { size: 13 }),
|
|
7862
7149
|
toast2.message
|
|
7863
7150
|
] });
|
|
7864
7151
|
}
|
|
7865
7152
|
function ToastHost() {
|
|
7866
7153
|
const { toasts } = useStore();
|
|
7867
7154
|
if (toasts.length === 0) return null;
|
|
7868
|
-
return /* @__PURE__ */
|
|
7155
|
+
return /* @__PURE__ */ jsx17("div", { className: "rk-toasts", "aria-live": "polite", children: toasts.map((toast2) => /* @__PURE__ */ jsx17(ToastRow, { toast: toast2 }, toast2.id)) });
|
|
7869
7156
|
}
|
|
7157
|
+
|
|
7158
|
+
// src/client/App.tsx
|
|
7159
|
+
import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
7870
7160
|
function App() {
|
|
7871
7161
|
const state = useStore();
|
|
7872
7162
|
const rawDispatch = useDispatch();
|
|
7873
7163
|
const config = useConfig();
|
|
7874
7164
|
const dispatch = useRealtimeSync(state, rawDispatch, config, reducer);
|
|
7875
|
-
const saveTimer =
|
|
7165
|
+
const saveTimer = useRef16(null);
|
|
7876
7166
|
const storageKey = config.storageKey ?? defaultStorageKey();
|
|
7877
7167
|
useAppliedPreview(state, dispatch);
|
|
7878
7168
|
useEmblemaAutoPush(state, dispatch, config);
|
|
7879
|
-
|
|
7169
|
+
useEffect16(() => {
|
|
7170
|
+
setEffectAssetsUrl(config.fxAssetsUrl);
|
|
7171
|
+
}, [config.fxAssetsUrl]);
|
|
7172
|
+
useEffect16(() => {
|
|
7880
7173
|
let cancelled = false;
|
|
7881
7174
|
void loadSession(storageKey).then((stored) => {
|
|
7882
7175
|
if (cancelled) return;
|
|
@@ -7894,7 +7187,7 @@ function App() {
|
|
|
7894
7187
|
};
|
|
7895
7188
|
}, [storageKey, config.defaultAuthor, dispatch]);
|
|
7896
7189
|
const { session } = state;
|
|
7897
|
-
|
|
7190
|
+
useEffect16(() => {
|
|
7898
7191
|
if (!session) return;
|
|
7899
7192
|
if (saveTimer.current !== null) window.clearTimeout(saveTimer.current);
|
|
7900
7193
|
saveTimer.current = window.setTimeout(() => {
|
|
@@ -7905,9 +7198,9 @@ function App() {
|
|
|
7905
7198
|
if (saveTimer.current !== null) window.clearTimeout(saveTimer.current);
|
|
7906
7199
|
};
|
|
7907
7200
|
}, [session, storageKey, config]);
|
|
7908
|
-
|
|
7909
|
-
const focusHandled =
|
|
7910
|
-
|
|
7201
|
+
useEffect16(() => trackPointer(), []);
|
|
7202
|
+
const focusHandled = useRef16(false);
|
|
7203
|
+
useEffect16(() => {
|
|
7911
7204
|
if (!session || focusHandled.current) return;
|
|
7912
7205
|
focusHandled.current = true;
|
|
7913
7206
|
const id = takeFocusItem();
|
|
@@ -7932,7 +7225,7 @@ function App() {
|
|
|
7932
7225
|
cancelled = true;
|
|
7933
7226
|
};
|
|
7934
7227
|
}, [session, dispatch]);
|
|
7935
|
-
|
|
7228
|
+
useEffect16(() => {
|
|
7936
7229
|
let last = window.location.pathname;
|
|
7937
7230
|
const check = () => {
|
|
7938
7231
|
if (window.location.pathname !== last) {
|
|
@@ -7947,9 +7240,9 @@ function App() {
|
|
|
7947
7240
|
window.removeEventListener("popstate", check);
|
|
7948
7241
|
};
|
|
7949
7242
|
}, [dispatch]);
|
|
7950
|
-
const stateRef =
|
|
7243
|
+
const stateRef = useRef16(state);
|
|
7951
7244
|
stateRef.current = state;
|
|
7952
|
-
|
|
7245
|
+
useEffect16(() => {
|
|
7953
7246
|
const onKeyDown = (event) => {
|
|
7954
7247
|
const current = stateRef.current;
|
|
7955
7248
|
for (const def of SHORTCUTS) {
|
|
@@ -7964,7 +7257,7 @@ function App() {
|
|
|
7964
7257
|
document.addEventListener("keydown", onKeyDown);
|
|
7965
7258
|
return () => document.removeEventListener("keydown", onKeyDown);
|
|
7966
7259
|
}, [dispatch]);
|
|
7967
|
-
|
|
7260
|
+
useEffect16(() => {
|
|
7968
7261
|
if (!state.editor) return;
|
|
7969
7262
|
const editorEl = state.editor.element;
|
|
7970
7263
|
const onPointerDown = (event) => {
|
|
@@ -7977,29 +7270,32 @@ function App() {
|
|
|
7977
7270
|
}, [state.editor, dispatch]);
|
|
7978
7271
|
if (!session) return null;
|
|
7979
7272
|
if (state.hidden) {
|
|
7980
|
-
return /* @__PURE__ */
|
|
7273
|
+
return /* @__PURE__ */ jsx18(DispatchContext.Provider, { value: dispatch, children: null });
|
|
7981
7274
|
}
|
|
7982
|
-
return /* @__PURE__ */
|
|
7983
|
-
/* @__PURE__ */
|
|
7984
|
-
/* @__PURE__ */
|
|
7985
|
-
/* @__PURE__ */
|
|
7986
|
-
state.editor?.kind === "copy" && /* @__PURE__ */
|
|
7987
|
-
state.editor?.kind === "image" && /* @__PURE__ */
|
|
7988
|
-
state.editor && state.editor.kind !== "copy" && state.editor.kind !== "image" && /* @__PURE__ */
|
|
7989
|
-
/* @__PURE__ */
|
|
7990
|
-
/* @__PURE__ */
|
|
7991
|
-
/* @__PURE__ */
|
|
7992
|
-
/* @__PURE__ */
|
|
7993
|
-
/* @__PURE__ */
|
|
7994
|
-
/* @__PURE__ */
|
|
7995
|
-
/* @__PURE__ */
|
|
7996
|
-
/* @__PURE__ */
|
|
7997
|
-
/* @__PURE__ */
|
|
7275
|
+
return /* @__PURE__ */ jsxs17(DispatchContext.Provider, { value: dispatch, children: [
|
|
7276
|
+
/* @__PURE__ */ jsx18(PickLayer, {}),
|
|
7277
|
+
/* @__PURE__ */ jsx18(PeerCursors, {}),
|
|
7278
|
+
/* @__PURE__ */ jsx18(Toolbar, {}),
|
|
7279
|
+
state.editor?.kind === "copy" && /* @__PURE__ */ jsx18(InlineEditor, { editor: state.editor }),
|
|
7280
|
+
state.editor?.kind === "image" && /* @__PURE__ */ jsx18(ImageEditor, { editor: state.editor }),
|
|
7281
|
+
state.editor && state.editor.kind !== "copy" && state.editor.kind !== "image" && /* @__PURE__ */ jsx18(NoteComposer, { editor: state.editor }),
|
|
7282
|
+
/* @__PURE__ */ jsx18(Pins, {}),
|
|
7283
|
+
/* @__PURE__ */ jsx18(QuickComment, {}),
|
|
7284
|
+
/* @__PURE__ */ jsx18(Panel, {}),
|
|
7285
|
+
/* @__PURE__ */ jsx18(Badge, {}),
|
|
7286
|
+
/* @__PURE__ */ jsx18(CoachMark, {}),
|
|
7287
|
+
/* @__PURE__ */ jsx18(CheatSheet, {}),
|
|
7288
|
+
/* @__PURE__ */ jsx18(EmblemaConnect, {}),
|
|
7289
|
+
/* @__PURE__ */ jsx18(ConfirmHost, {}),
|
|
7290
|
+
/* @__PURE__ */ jsx18(ToastHost, {})
|
|
7998
7291
|
] });
|
|
7999
7292
|
}
|
|
7293
|
+
|
|
7294
|
+
// src/client/ReviewKit.tsx
|
|
7295
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
8000
7296
|
function ShadowHost({ config }) {
|
|
8001
|
-
const [mount, setMount] =
|
|
8002
|
-
|
|
7297
|
+
const [mount, setMount] = useState13(null);
|
|
7298
|
+
useEffect17(() => {
|
|
8003
7299
|
const host = document.createElement("div");
|
|
8004
7300
|
host.setAttribute(HOST_ATTR, "");
|
|
8005
7301
|
host.style.position = "fixed";
|
|
@@ -8035,23 +7331,36 @@ function ShadowHost({ config }) {
|
|
|
8035
7331
|
}, []);
|
|
8036
7332
|
if (!mount) return null;
|
|
8037
7333
|
return createPortal(
|
|
8038
|
-
/* @__PURE__ */
|
|
7334
|
+
/* @__PURE__ */ jsx19(StoreProvider, { config, children: /* @__PURE__ */ jsx19(App, {}) }),
|
|
8039
7335
|
mount
|
|
8040
7336
|
);
|
|
8041
7337
|
}
|
|
8042
7338
|
function ReviewKit(props) {
|
|
8043
|
-
const [
|
|
8044
|
-
|
|
8045
|
-
|
|
8046
|
-
|
|
7339
|
+
const [active, setActive] = useState13(false);
|
|
7340
|
+
const { enabled, token, allowedHosts, devAutoOn } = props;
|
|
7341
|
+
const hostsKey = allowedHosts?.join("\0") ?? "";
|
|
7342
|
+
useEffect17(() => {
|
|
7343
|
+
if (enabled === false) {
|
|
7344
|
+
setActive(false);
|
|
7345
|
+
return;
|
|
7346
|
+
}
|
|
7347
|
+
setActive(resolveActivation({ token, allowedHosts, devAutoOn, enabled }));
|
|
8047
7348
|
const onDeactivate = () => setActive(false);
|
|
8048
7349
|
window.addEventListener(DEACTIVATE_EVENT, onDeactivate);
|
|
8049
7350
|
return () => window.removeEventListener(DEACTIVATE_EVENT, onDeactivate);
|
|
8050
|
-
}, [
|
|
8051
|
-
if (!
|
|
8052
|
-
return /* @__PURE__ */
|
|
7351
|
+
}, [enabled, token, devAutoOn, hostsKey]);
|
|
7352
|
+
if (enabled === false || !active) return null;
|
|
7353
|
+
return /* @__PURE__ */ jsx19(ShadowHost, { config: props });
|
|
8053
7354
|
}
|
|
8054
7355
|
|
|
8055
|
-
export {
|
|
8056
|
-
|
|
8057
|
-
|
|
7356
|
+
export {
|
|
7357
|
+
captureTarget,
|
|
7358
|
+
resolveTarget,
|
|
7359
|
+
exportFilename,
|
|
7360
|
+
sessionToJson,
|
|
7361
|
+
downloadSession,
|
|
7362
|
+
copySessionToClipboard,
|
|
7363
|
+
importSessionFile,
|
|
7364
|
+
ReviewKit
|
|
7365
|
+
};
|
|
7366
|
+
//# sourceMappingURL=chunk-NSXRFM75.js.map
|