@satanwagen/reviewkit 0.1.3 → 0.1.5
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 +181 -1
- package/README.md +43 -18
- package/dist/{chunk-Q7U43PXE.js → chunk-L7JLBD7Q.js} +1 -1
- package/dist/{chunk-NSXRFM75.js → chunk-VNRVRNZX.js} +755 -450
- package/dist/chunk-VNRVRNZX.js.map +1 -0
- package/dist/client/index.cjs +803 -498
- 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 +1 -1
- package/dist/{index-Dl2Fl0qr.d.cts → index-CWGkg1-E.d.cts} +17 -8
- package/dist/{index-BUSmAweg.d.ts → index-DPsjkvaY.d.ts} +17 -8
- package/dist/index.cjs +803 -498
- 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 +1 -1
- package/dist/lazy.cjs +849 -521
- package/dist/lazy.cjs.map +1 -1
- package/dist/lazy.d.cts +1 -1
- package/dist/lazy.d.ts +1 -1
- package/dist/lazy.js +1 -1
- package/dist/next.cjs +849 -521
- package/dist/next.cjs.map +1 -1
- package/dist/next.d.cts +1 -1
- package/dist/next.d.ts +1 -1
- package/dist/next.js +1 -1
- package/package.json +4 -2
- package/dist/chunk-NSXRFM75.js.map +0 -1
- /package/dist/{chunk-Q7U43PXE.js.map → chunk-L7JLBD7Q.js.map} +0 -0
|
@@ -340,7 +340,7 @@ function importSessionFile(file) {
|
|
|
340
340
|
}
|
|
341
341
|
|
|
342
342
|
// src/client/ReviewKit.tsx
|
|
343
|
-
import { useEffect as
|
|
343
|
+
import { useEffect as useEffect18, useState as useState14 } from "react";
|
|
344
344
|
import { createPortal } from "react-dom";
|
|
345
345
|
|
|
346
346
|
// src/client/env.ts
|
|
@@ -1234,6 +1234,8 @@ input, textarea, select {
|
|
|
1234
1234
|
.rk-sync-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--rk-fg-faint); }
|
|
1235
1235
|
.rk-sync-online .rk-sync-dot { background: var(--rk-success); }
|
|
1236
1236
|
.rk-sync-connecting .rk-sync-dot { background: var(--rk-warn); }
|
|
1237
|
+
.rk-sync-reason-token-short .rk-sync-dot, .rk-sync-reason-bad-token .rk-sync-dot { background: var(--rk-danger); }
|
|
1238
|
+
.rk-sync[title] { cursor: help; }
|
|
1237
1239
|
/* Automatic Emblema push hint (same quiet language) */
|
|
1238
1240
|
.rk-epush-ok .rk-sync-dot { background: var(--rk-success); }
|
|
1239
1241
|
.rk-epush-sending .rk-sync-dot { background: var(--rk-warn); }
|
|
@@ -2306,7 +2308,8 @@ function reducer(state, action) {
|
|
|
2306
2308
|
panelOpen: false,
|
|
2307
2309
|
confirm: null,
|
|
2308
2310
|
cheatsheetOpen: false,
|
|
2309
|
-
emblemaConnectOpen: false
|
|
2311
|
+
emblemaConnectOpen: false,
|
|
2312
|
+
terminalConnectOpen: false
|
|
2310
2313
|
} : { ...state, hidden: false };
|
|
2311
2314
|
case "SELECT":
|
|
2312
2315
|
return { ...state, selection: action.selection };
|
|
@@ -2416,12 +2419,16 @@ function reducer(state, action) {
|
|
|
2416
2419
|
return { ...state, cheatsheetOpen: action.open };
|
|
2417
2420
|
case "SET_EMBLEMA_CONNECT":
|
|
2418
2421
|
return { ...state, emblemaConnectOpen: action.open };
|
|
2422
|
+
case "SET_TERMINAL_CONNECT":
|
|
2423
|
+
return { ...state, terminalConnectOpen: action.open };
|
|
2419
2424
|
case "SET_COACH":
|
|
2420
2425
|
return { ...state, coachOpen: action.open };
|
|
2421
2426
|
case "SET_CORNER":
|
|
2422
2427
|
return { ...state, badgeCorner: action.corner };
|
|
2423
|
-
case "SYNC_STATUS":
|
|
2424
|
-
|
|
2428
|
+
case "SYNC_STATUS": {
|
|
2429
|
+
const reason = action.reason === void 0 ? action.status === "online" ? null : state.syncReason : action.reason;
|
|
2430
|
+
return state.syncStatus === action.status && state.syncReason === reason ? state : { ...state, syncStatus: action.status, syncReason: reason };
|
|
2431
|
+
}
|
|
2425
2432
|
case "EMBLEMA_PUSH_STATUS":
|
|
2426
2433
|
return state.emblemaPush === action.status ? state : { ...state, emblemaPush: action.status };
|
|
2427
2434
|
/*
|
|
@@ -2550,9 +2557,11 @@ function initialState() {
|
|
|
2550
2557
|
confirm: null,
|
|
2551
2558
|
cheatsheetOpen: false,
|
|
2552
2559
|
emblemaConnectOpen: false,
|
|
2560
|
+
terminalConnectOpen: false,
|
|
2553
2561
|
coachOpen: false,
|
|
2554
2562
|
undoStack: [],
|
|
2555
2563
|
syncStatus: "disabled",
|
|
2564
|
+
syncReason: null,
|
|
2556
2565
|
emblemaPush: "idle",
|
|
2557
2566
|
peers: [],
|
|
2558
2567
|
quick: null,
|
|
@@ -2567,7 +2576,7 @@ function StoreProvider({ config, children }) {
|
|
|
2567
2576
|
const configValue = useMemo(
|
|
2568
2577
|
() => config,
|
|
2569
2578
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- config object identity is per-render; depend on its fields
|
|
2570
|
-
[config.enabled, config.token, config.devAutoOn, config.syncToken, config.syncUrl, config.defaultAuthor, config.fxAssetsUrl, config.position, config.storageKey, config.onSessionChange, config.emblema]
|
|
2579
|
+
[config.enabled, config.token, config.devAutoOn, config.sync, config.syncToken, config.syncUrl, config.defaultAuthor, config.fxAssetsUrl, config.position, config.storageKey, config.onSessionChange, config.emblema]
|
|
2571
2580
|
);
|
|
2572
2581
|
return /* @__PURE__ */ jsx(ConfigContext.Provider, { value: configValue, children: /* @__PURE__ */ jsx(StateContext.Provider, { value: state, children: /* @__PURE__ */ jsx(DispatchContext.Provider, { value: dispatch, children }) }) });
|
|
2573
2582
|
}
|
|
@@ -2596,7 +2605,7 @@ function toast(dispatch, message, tone = "info") {
|
|
|
2596
2605
|
}
|
|
2597
2606
|
|
|
2598
2607
|
// src/client/App.tsx
|
|
2599
|
-
import { useEffect as
|
|
2608
|
+
import { useEffect as useEffect17, useRef as useRef16 } from "react";
|
|
2600
2609
|
|
|
2601
2610
|
// src/client/persist.ts
|
|
2602
2611
|
var DB_NAME = "review-kit";
|
|
@@ -3532,9 +3541,13 @@ function createRkSync(options) {
|
|
|
3532
3541
|
pongTimer = null;
|
|
3533
3542
|
}
|
|
3534
3543
|
break;
|
|
3535
|
-
case "error":
|
|
3544
|
+
case "error": {
|
|
3536
3545
|
log("server error:", msg.code, msg.message);
|
|
3546
|
+
const code = typeof msg.code === "string" ? msg.code : "error";
|
|
3547
|
+
const message = typeof msg.message === "string" ? msg.message : "";
|
|
3548
|
+
safely(() => handlers.onError?.(code, message));
|
|
3537
3549
|
break;
|
|
3550
|
+
}
|
|
3538
3551
|
case "presence:join": {
|
|
3539
3552
|
const peer = msg.peer;
|
|
3540
3553
|
if (peer && typeof peer.id === "string") safely(() => handlers.onPeerJoin?.(peer));
|
|
@@ -3736,6 +3749,23 @@ function currentAuthor(name) {
|
|
|
3736
3749
|
}
|
|
3737
3750
|
|
|
3738
3751
|
// src/client/sync.ts
|
|
3752
|
+
var DEFAULT_SYNC_URL = "wss://2-59-219-26.sslip.io/rk-sync";
|
|
3753
|
+
function normalizeRoute(route) {
|
|
3754
|
+
let r = String(route ?? "/");
|
|
3755
|
+
if (!r.startsWith("/")) r = "/" + r;
|
|
3756
|
+
return r.length > 1 ? r.replace(/\/+$/, "") : r;
|
|
3757
|
+
}
|
|
3758
|
+
function resolveSyncUrl(config) {
|
|
3759
|
+
return typeof config.syncUrl === "string" && config.syncUrl !== "" ? config.syncUrl : DEFAULT_SYNC_URL;
|
|
3760
|
+
}
|
|
3761
|
+
var MIN_SYNC_TOKEN_LENGTH = 8;
|
|
3762
|
+
var warnedShortToken = false;
|
|
3763
|
+
function resolveSyncToken(config) {
|
|
3764
|
+
if (config.sync === false) return null;
|
|
3765
|
+
const explicit = typeof config.syncToken === "string" && config.syncToken !== "" ? config.syncToken : null;
|
|
3766
|
+
const fallback = typeof config.token === "string" && config.token !== "" ? config.token : null;
|
|
3767
|
+
return explicit ?? fallback;
|
|
3768
|
+
}
|
|
3739
3769
|
function toPeerState(peer) {
|
|
3740
3770
|
return {
|
|
3741
3771
|
id: peer.id,
|
|
@@ -3763,20 +3793,43 @@ function useRealtimeSync(state, rawDispatch, config, reducer2) {
|
|
|
3763
3793
|
const stateRef = useRef3(state);
|
|
3764
3794
|
stateRef.current = state;
|
|
3765
3795
|
const myIdRef = useRef3("");
|
|
3766
|
-
const
|
|
3796
|
+
const syncToken = resolveSyncToken(config);
|
|
3797
|
+
const syncUrl = resolveSyncUrl(config);
|
|
3798
|
+
const enabled = syncToken !== null;
|
|
3767
3799
|
const author = state.session?.author ?? "";
|
|
3768
3800
|
const hasSession = state.session !== null;
|
|
3769
3801
|
useEffect3(() => {
|
|
3770
3802
|
if (!enabled || !hasSession) return;
|
|
3803
|
+
const dispatchGuard = rawDispatch;
|
|
3804
|
+
if (syncToken.length < MIN_SYNC_TOKEN_LENGTH) {
|
|
3805
|
+
dispatchGuard({ type: "SYNC_STATUS", status: "offline", reason: "token-short" });
|
|
3806
|
+
if (!warnedShortToken) {
|
|
3807
|
+
warnedShortToken = true;
|
|
3808
|
+
console.warn(
|
|
3809
|
+
`[review-kit] live sync is off: the token has ${syncToken.length} characters, the sync server needs at least ${MIN_SYNC_TOKEN_LENGTH}. Use a longer \`token\` (or \`syncToken\`) \u2014 it is the secret of your private rooms.`
|
|
3810
|
+
);
|
|
3811
|
+
}
|
|
3812
|
+
return () => dispatchGuard({ type: "SYNC_STATUS", status: "disabled", reason: null });
|
|
3813
|
+
}
|
|
3771
3814
|
const id = reviewerId();
|
|
3772
3815
|
myIdRef.current = id;
|
|
3773
3816
|
const dispatch = rawDispatch;
|
|
3774
3817
|
const sync = createRkSync({
|
|
3775
|
-
token:
|
|
3776
|
-
url:
|
|
3818
|
+
token: syncToken,
|
|
3819
|
+
url: syncUrl,
|
|
3777
3820
|
user: { id, name: author || "Reviewer", color: colorForReviewer(id) },
|
|
3778
3821
|
handlers: {
|
|
3779
|
-
onStatus: (status) => dispatch({
|
|
3822
|
+
onStatus: (status) => dispatch({
|
|
3823
|
+
type: "SYNC_STATUS",
|
|
3824
|
+
status,
|
|
3825
|
+
// Offline with no server verdict = the socket never got through
|
|
3826
|
+
// (server down, CSP connect-src, network); a verdict keeps its reason.
|
|
3827
|
+
...status === "offline" ? { reason: stateRef.current.syncReason ?? "unreachable" } : {}
|
|
3828
|
+
}),
|
|
3829
|
+
onError: (code) => {
|
|
3830
|
+
if (code === "bad-token") dispatch({ type: "SYNC_STATUS", status: "offline", reason: "bad-token" });
|
|
3831
|
+
else if (code === "room-full") dispatch({ type: "SYNC_STATUS", status: "offline", reason: "room-full" });
|
|
3832
|
+
},
|
|
3780
3833
|
onSnapshot: (items, peers, deletedIds = []) => {
|
|
3781
3834
|
const safeItems = items.map(sanitizeRemoteItem).filter((item) => item !== null);
|
|
3782
3835
|
dispatch({ type: "SYNC_SNAPSHOT", items: safeItems });
|
|
@@ -3784,8 +3837,11 @@ function useRealtimeSync(state, rawDispatch, config, reducer2) {
|
|
|
3784
3837
|
for (const id2 of deletedIds) dispatch({ type: "REMOTE_DELETE", id: id2 });
|
|
3785
3838
|
dispatch({ type: "PEERS_SET", peers: peers.filter((peer) => peer.id !== id).map(toPeerState) });
|
|
3786
3839
|
const serverIds = new Set(items.map((item) => item.id));
|
|
3840
|
+
const here = normalizeRoute(window.location.pathname);
|
|
3787
3841
|
for (const item of stateRef.current.session?.items ?? []) {
|
|
3788
|
-
if (
|
|
3842
|
+
if (serverIds.has(item.id) || deleted.has(item.id)) continue;
|
|
3843
|
+
if (normalizeRoute(item.route) !== here) continue;
|
|
3844
|
+
sync.addItem(item);
|
|
3789
3845
|
}
|
|
3790
3846
|
},
|
|
3791
3847
|
onPeerJoin: (peer) => dispatch({
|
|
@@ -3833,10 +3889,10 @@ function useRealtimeSync(state, rawDispatch, config, reducer2) {
|
|
|
3833
3889
|
if (activeSyncRef === sync) activeSyncRef = null;
|
|
3834
3890
|
setEffectBroadcaster(null);
|
|
3835
3891
|
sync.stop();
|
|
3836
|
-
dispatch({ type: "SYNC_STATUS", status: "disabled" });
|
|
3892
|
+
dispatch({ type: "SYNC_STATUS", status: "disabled", reason: null });
|
|
3837
3893
|
dispatch({ type: "PEERS_SET", peers: [] });
|
|
3838
3894
|
};
|
|
3839
|
-
}, [enabled, hasSession,
|
|
3895
|
+
}, [enabled, hasSession, syncToken, syncUrl, author, rawDispatch]);
|
|
3840
3896
|
const wrapped = useMemo2(() => {
|
|
3841
3897
|
return (action) => {
|
|
3842
3898
|
const prev = stateRef.current;
|
|
@@ -4352,10 +4408,10 @@ function EmblemaConnect() {
|
|
|
4352
4408
|
state === null && /* @__PURE__ */ jsxs4("div", { className: "rk-modal-text", children: [
|
|
4353
4409
|
"The local sync agent isn't running. In the project repo run:",
|
|
4354
4410
|
/* @__PURE__ */ jsxs4("code", { className: "rk-connect-cmd", children: [
|
|
4355
|
-
"npx @satanwagen/reviewkit-cli init --origin ",
|
|
4411
|
+
"npx -p @satanwagen/reviewkit-cli reviewkit-emblema init --origin ",
|
|
4356
4412
|
window.location.origin
|
|
4357
4413
|
] }),
|
|
4358
|
-
/* @__PURE__ */ jsx5("code", { className: "rk-connect-cmd", children: "npx @satanwagen/reviewkit-cli serve" }),
|
|
4414
|
+
/* @__PURE__ */ jsx5("code", { className: "rk-connect-cmd", children: "npx -p @satanwagen/reviewkit-cli reviewkit-emblema serve" }),
|
|
4359
4415
|
"then reopen this dialog."
|
|
4360
4416
|
] }),
|
|
4361
4417
|
state !== null && state !== "loading" && /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
@@ -4442,15 +4498,229 @@ function EmblemaConnect() {
|
|
|
4442
4498
|
] });
|
|
4443
4499
|
}
|
|
4444
4500
|
|
|
4501
|
+
// src/client/components/TerminalConnect.tsx
|
|
4502
|
+
import { useEffect as useEffect5, useState as useState3 } from "react";
|
|
4503
|
+
|
|
4504
|
+
// src/integrations/terminal.ts
|
|
4505
|
+
var TERMINAL_PAIR_PORTS = [48780, 48781, 48782, 48783];
|
|
4506
|
+
async function fetchJson(url, init, timeoutMs) {
|
|
4507
|
+
const abort = new AbortController();
|
|
4508
|
+
const timer = window.setTimeout(() => abort.abort(), timeoutMs);
|
|
4509
|
+
try {
|
|
4510
|
+
return await fetch(url, { ...init, signal: abort.signal });
|
|
4511
|
+
} finally {
|
|
4512
|
+
window.clearTimeout(timer);
|
|
4513
|
+
}
|
|
4514
|
+
}
|
|
4515
|
+
async function probeTerminal() {
|
|
4516
|
+
for (const port of TERMINAL_PAIR_PORTS) {
|
|
4517
|
+
try {
|
|
4518
|
+
const res = await fetchJson(`http://127.0.0.1:${port}/pair`, { method: "GET" }, 900);
|
|
4519
|
+
if (!res.ok) continue;
|
|
4520
|
+
const body = await res.json();
|
|
4521
|
+
if (typeof body === "object" && body !== null && body.app === "reviewkit-cli") {
|
|
4522
|
+
const b = body;
|
|
4523
|
+
return {
|
|
4524
|
+
port,
|
|
4525
|
+
cwd: typeof b.cwd === "string" ? b.cwd : void 0,
|
|
4526
|
+
projects: Array.isArray(b.projects) ? b.projects.filter((p) => typeof p === "string") : []
|
|
4527
|
+
};
|
|
4528
|
+
}
|
|
4529
|
+
} catch {
|
|
4530
|
+
}
|
|
4531
|
+
}
|
|
4532
|
+
return null;
|
|
4533
|
+
}
|
|
4534
|
+
async function pairTerminal(port, key) {
|
|
4535
|
+
try {
|
|
4536
|
+
const res = await fetchJson(
|
|
4537
|
+
`http://127.0.0.1:${port}/pair`,
|
|
4538
|
+
{ method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ key }) },
|
|
4539
|
+
5e3
|
|
4540
|
+
);
|
|
4541
|
+
const body = await res.json().catch(() => null);
|
|
4542
|
+
if (res.ok && body?.ok) return { ok: true, name: body.name ?? "", repo: body.repo ?? null };
|
|
4543
|
+
return { ok: false, error: body?.error ?? `HTTP ${res.status}` };
|
|
4544
|
+
} catch {
|
|
4545
|
+
return { ok: false, error: "the terminal stopped answering" };
|
|
4546
|
+
}
|
|
4547
|
+
}
|
|
4548
|
+
|
|
4549
|
+
// src/client/terminalKey.ts
|
|
4550
|
+
var TERMINAL_KEY_PREFIX = "rkc_";
|
|
4551
|
+
var TERMINAL_KEY_VERSION = 1;
|
|
4552
|
+
function base64url(text) {
|
|
4553
|
+
const bytes = new TextEncoder().encode(text);
|
|
4554
|
+
let binary = "";
|
|
4555
|
+
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
4556
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
4557
|
+
}
|
|
4558
|
+
function encodeTerminalKey(fields) {
|
|
4559
|
+
const payload = { v: TERMINAL_KEY_VERSION, ...fields };
|
|
4560
|
+
return TERMINAL_KEY_PREFIX + base64url(JSON.stringify(payload));
|
|
4561
|
+
}
|
|
4562
|
+
function currentTerminalKey(syncUrl, syncToken) {
|
|
4563
|
+
const origin = window.location.origin;
|
|
4564
|
+
let route = "/";
|
|
4565
|
+
try {
|
|
4566
|
+
route = window.location.pathname || "/";
|
|
4567
|
+
} catch {
|
|
4568
|
+
}
|
|
4569
|
+
return encodeTerminalKey({ name: window.location.hostname, origin, syncUrl, syncToken, route });
|
|
4570
|
+
}
|
|
4571
|
+
|
|
4572
|
+
// src/client/components/TerminalConnect.tsx
|
|
4573
|
+
import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
4574
|
+
function shortKey2(key) {
|
|
4575
|
+
return `${key.slice(0, 8)}\u2026${key.slice(-6)}`;
|
|
4576
|
+
}
|
|
4577
|
+
function shortPath(path) {
|
|
4578
|
+
if (!path) return "";
|
|
4579
|
+
const parts = path.split("/").filter(Boolean);
|
|
4580
|
+
return parts.length > 2 ? `\u2026/${parts.slice(-2).join("/")}` : path;
|
|
4581
|
+
}
|
|
4582
|
+
function TerminalConnect() {
|
|
4583
|
+
const { terminalConnectOpen } = useStore();
|
|
4584
|
+
const config = useConfig();
|
|
4585
|
+
const dispatch = useDispatch();
|
|
4586
|
+
const [phase, setPhase] = useState3("probing");
|
|
4587
|
+
const [probe, setProbe] = useState3(null);
|
|
4588
|
+
const [paired, setPaired] = useState3(null);
|
|
4589
|
+
const [showManual, setShowManual] = useState3(false);
|
|
4590
|
+
const syncToken = resolveSyncToken(config);
|
|
4591
|
+
const key = terminalConnectOpen && syncToken ? currentTerminalKey(resolveSyncUrl(config), syncToken) : null;
|
|
4592
|
+
useEffect5(() => {
|
|
4593
|
+
if (!terminalConnectOpen) return;
|
|
4594
|
+
let cancelled = false;
|
|
4595
|
+
setPhase("probing");
|
|
4596
|
+
setProbe(null);
|
|
4597
|
+
setPaired(null);
|
|
4598
|
+
setShowManual(false);
|
|
4599
|
+
const look = () => void probeTerminal().then((found) => {
|
|
4600
|
+
if (cancelled) return;
|
|
4601
|
+
setProbe(found);
|
|
4602
|
+
setPhase((current) => current === "pairing" || current === "paired" ? current : found ? "found" : "missing");
|
|
4603
|
+
});
|
|
4604
|
+
look();
|
|
4605
|
+
const timer = window.setInterval(look, 2e3);
|
|
4606
|
+
return () => {
|
|
4607
|
+
cancelled = true;
|
|
4608
|
+
window.clearInterval(timer);
|
|
4609
|
+
};
|
|
4610
|
+
}, [terminalConnectOpen]);
|
|
4611
|
+
if (!terminalConnectOpen) return null;
|
|
4612
|
+
const close = () => dispatch({ type: "SET_TERMINAL_CONNECT", open: false });
|
|
4613
|
+
const copy = async (value, what) => {
|
|
4614
|
+
try {
|
|
4615
|
+
await navigator.clipboard.writeText(value);
|
|
4616
|
+
toast(dispatch, `${what} copied`, "success");
|
|
4617
|
+
} catch {
|
|
4618
|
+
toast(dispatch, "Copy failed \u2014 select the text manually", "error");
|
|
4619
|
+
}
|
|
4620
|
+
};
|
|
4621
|
+
const connect = () => {
|
|
4622
|
+
if (!probe || !key) return;
|
|
4623
|
+
setPhase("pairing");
|
|
4624
|
+
void pairTerminal(probe.port, key).then((result) => {
|
|
4625
|
+
if (result.ok) {
|
|
4626
|
+
setPaired({ name: result.name, repo: result.repo });
|
|
4627
|
+
setPhase("paired");
|
|
4628
|
+
toast(dispatch, `Terminal paired as \u201C${result.name}\u201D`, "success");
|
|
4629
|
+
} else {
|
|
4630
|
+
setPhase("found");
|
|
4631
|
+
toast(dispatch, `Pairing failed: ${result.error}`, "error");
|
|
4632
|
+
}
|
|
4633
|
+
});
|
|
4634
|
+
};
|
|
4635
|
+
const connectCmd = key ? `npx -y @satanwagen/reviewkit-cli connect ${key}` : "";
|
|
4636
|
+
return /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
4637
|
+
/* @__PURE__ */ jsx6("div", { className: "rk-backdrop", onClick: close }),
|
|
4638
|
+
/* @__PURE__ */ jsx6("div", { className: "rk-modal", role: "dialog", "aria-modal": "true", "aria-label": "Connect terminal or agent", children: /* @__PURE__ */ jsxs5("div", { className: "rk-modal-body", children: [
|
|
4639
|
+
/* @__PURE__ */ jsxs5("div", { className: "rk-modal-title", style: { display: "flex", alignItems: "center", gap: 8 }, children: [
|
|
4640
|
+
"Connect terminal / agent",
|
|
4641
|
+
/* @__PURE__ */ jsx6("span", { style: { flex: 1 } }),
|
|
4642
|
+
/* @__PURE__ */ jsx6("button", { type: "button", className: "rk-icon-btn", "aria-label": "Close", onClick: close, autoFocus: true, children: /* @__PURE__ */ jsx6(IconClose, { size: 13 }) })
|
|
4643
|
+
] }),
|
|
4644
|
+
!key && /* @__PURE__ */ jsxs5("div", { className: "rk-modal-text", children: [
|
|
4645
|
+
"Live sync is off on this page (",
|
|
4646
|
+
/* @__PURE__ */ jsx6("code", { children: "sync=false" }),
|
|
4647
|
+
" or no token), so there is no shared room a terminal could read."
|
|
4648
|
+
] }),
|
|
4649
|
+
key && phase === "paired" && paired && /* @__PURE__ */ jsxs5("div", { className: "rk-modal-text", children: [
|
|
4650
|
+
/* @__PURE__ */ jsx6("span", { className: "rk-emblema-dot", "data-state": "live" }),
|
|
4651
|
+
" Paired as ",
|
|
4652
|
+
/* @__PURE__ */ jsx6("strong", { children: paired.name }),
|
|
4653
|
+
paired.repo ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
4654
|
+
" in ",
|
|
4655
|
+
/* @__PURE__ */ jsx6("code", { children: shortPath(paired.repo) })
|
|
4656
|
+
] }) : null,
|
|
4657
|
+
". The terminal shows this page's comments live, and Claude Code / Cursor can read and resolve them through the ",
|
|
4658
|
+
/* @__PURE__ */ jsx6("code", { children: "reviewkit" }),
|
|
4659
|
+
" MCP tools."
|
|
4660
|
+
] }),
|
|
4661
|
+
key && phase !== "paired" && /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
4662
|
+
/* @__PURE__ */ jsxs5("div", { className: "rk-modal-text", children: [
|
|
4663
|
+
phase === "probing" && /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
4664
|
+
"Looking for a ",
|
|
4665
|
+
/* @__PURE__ */ jsx6("code", { children: "reviewkit" }),
|
|
4666
|
+
" terminal on this machine\u2026"
|
|
4667
|
+
] }),
|
|
4668
|
+
phase === "missing" && /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
4669
|
+
"No terminal is listening yet. In the site's repo run",
|
|
4670
|
+
/* @__PURE__ */ jsx6("code", { className: "rk-connect-cmd", children: "npx -y @satanwagen/reviewkit-cli setup" }),
|
|
4671
|
+
"and this dialog will pick it up by itself."
|
|
4672
|
+
] }),
|
|
4673
|
+
(phase === "found" || phase === "pairing") && probe && /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
4674
|
+
/* @__PURE__ */ jsx6("span", { className: "rk-emblema-dot", "data-state": "live" }),
|
|
4675
|
+
" Terminal found",
|
|
4676
|
+
probe.cwd ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
4677
|
+
" in ",
|
|
4678
|
+
/* @__PURE__ */ jsx6("code", { children: shortPath(probe.cwd) })
|
|
4679
|
+
] }) : null,
|
|
4680
|
+
".",
|
|
4681
|
+
probe.projects.length > 0 ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
4682
|
+
" Already paired: ",
|
|
4683
|
+
probe.projects.join(", "),
|
|
4684
|
+
"."
|
|
4685
|
+
] }) : null
|
|
4686
|
+
] })
|
|
4687
|
+
] }),
|
|
4688
|
+
/* @__PURE__ */ jsxs5("div", { className: "rk-connect-actions", children: [
|
|
4689
|
+
/* @__PURE__ */ jsx6(
|
|
4690
|
+
"button",
|
|
4691
|
+
{
|
|
4692
|
+
type: "button",
|
|
4693
|
+
className: "rk-btn rk-btn-primary",
|
|
4694
|
+
disabled: phase !== "found",
|
|
4695
|
+
onClick: connect,
|
|
4696
|
+
title: "Send this site's connection to the terminal \u2014 nothing to copy",
|
|
4697
|
+
children: phase === "pairing" ? "Connecting\u2026" : "Connect this terminal"
|
|
4698
|
+
}
|
|
4699
|
+
),
|
|
4700
|
+
/* @__PURE__ */ jsx6("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => setShowManual((v) => !v), children: showManual ? "Hide manual option" : "Another machine\u2026" })
|
|
4701
|
+
] }),
|
|
4702
|
+
showManual && /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
4703
|
+
/* @__PURE__ */ jsx6("div", { className: "rk-modal-text", style: { marginTop: 10 }, children: "On a machine without a listening terminal, run this once (the key carries the sync server and its token \u2014 treat it like a review link):" }),
|
|
4704
|
+
/* @__PURE__ */ jsxs5("code", { className: "rk-connect-cmd", title: connectCmd, children: [
|
|
4705
|
+
"npx -y @satanwagen/reviewkit-cli connect ",
|
|
4706
|
+
shortKey2(key)
|
|
4707
|
+
] }),
|
|
4708
|
+
/* @__PURE__ */ jsx6("div", { className: "rk-connect-actions", children: /* @__PURE__ */ jsx6("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => void copy(connectCmd, "Command"), children: "Copy command" }) })
|
|
4709
|
+
] })
|
|
4710
|
+
] })
|
|
4711
|
+
] }) })
|
|
4712
|
+
] });
|
|
4713
|
+
}
|
|
4714
|
+
|
|
4445
4715
|
// src/client/components/CoachMark.tsx
|
|
4446
|
-
import { useState as
|
|
4447
|
-
import { jsx as
|
|
4716
|
+
import { useState as useState4 } from "react";
|
|
4717
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
4448
4718
|
var COACH_KEY = "review-kit:coach-dismissed";
|
|
4449
4719
|
function CoachMark() {
|
|
4450
4720
|
const { coachOpen, session } = useStore();
|
|
4451
4721
|
const dispatch = useDispatch();
|
|
4452
4722
|
const config = useConfig();
|
|
4453
|
-
const [name, setName] =
|
|
4723
|
+
const [name, setName] = useState4(session?.author ?? config.defaultAuthor ?? "");
|
|
4454
4724
|
if (!coachOpen) return null;
|
|
4455
4725
|
const done = (startPicking) => {
|
|
4456
4726
|
if (name.trim() !== "") dispatch({ type: "SET_AUTHOR", author: name.trim() });
|
|
@@ -4461,39 +4731,39 @@ function CoachMark() {
|
|
|
4461
4731
|
}
|
|
4462
4732
|
if (startPicking) dispatch({ type: "SET_MODE", mode: "pick" });
|
|
4463
4733
|
};
|
|
4464
|
-
return /* @__PURE__ */
|
|
4465
|
-
/* @__PURE__ */
|
|
4466
|
-
/* @__PURE__ */
|
|
4467
|
-
/* @__PURE__ */
|
|
4468
|
-
/* @__PURE__ */
|
|
4734
|
+
return /* @__PURE__ */ jsxs6("div", { className: "rk-coach", role: "dialog", "aria-label": "Welcome to review mode", children: [
|
|
4735
|
+
/* @__PURE__ */ jsx7("div", { className: "rk-coach-accent" }),
|
|
4736
|
+
/* @__PURE__ */ jsxs6("div", { className: "rk-coach-body", children: [
|
|
4737
|
+
/* @__PURE__ */ jsxs6("div", { className: "rk-modal-title", style: { display: "flex", alignItems: "center", gap: 8 }, children: [
|
|
4738
|
+
/* @__PURE__ */ jsx7(IconTarget, { size: 16 }),
|
|
4469
4739
|
" Review mode"
|
|
4470
4740
|
] }),
|
|
4471
|
-
/* @__PURE__ */
|
|
4472
|
-
/* @__PURE__ */
|
|
4473
|
-
/* @__PURE__ */
|
|
4474
|
-
/* @__PURE__ */
|
|
4741
|
+
/* @__PURE__ */ jsx7("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." }),
|
|
4742
|
+
/* @__PURE__ */ jsxs6("div", { className: "rk-coach-keys", "aria-label": "Key shortcuts", children: [
|
|
4743
|
+
/* @__PURE__ */ jsxs6("span", { children: [
|
|
4744
|
+
/* @__PURE__ */ jsx7("span", { className: "rk-kbd", children: "T" }),
|
|
4475
4745
|
" rewrite"
|
|
4476
4746
|
] }),
|
|
4477
|
-
/* @__PURE__ */
|
|
4478
|
-
/* @__PURE__ */
|
|
4747
|
+
/* @__PURE__ */ jsxs6("span", { children: [
|
|
4748
|
+
/* @__PURE__ */ jsx7("span", { className: "rk-kbd", children: "C" }),
|
|
4479
4749
|
" comment"
|
|
4480
4750
|
] }),
|
|
4481
|
-
/* @__PURE__ */
|
|
4482
|
-
/* @__PURE__ */
|
|
4751
|
+
/* @__PURE__ */ jsxs6("span", { children: [
|
|
4752
|
+
/* @__PURE__ */ jsx7("span", { className: "rk-kbd", children: "I" }),
|
|
4483
4753
|
" image"
|
|
4484
4754
|
] }),
|
|
4485
|
-
/* @__PURE__ */
|
|
4486
|
-
/* @__PURE__ */
|
|
4755
|
+
/* @__PURE__ */ jsxs6("span", { children: [
|
|
4756
|
+
/* @__PURE__ */ jsx7("span", { className: "rk-kbd", children: "V" }),
|
|
4487
4757
|
" select"
|
|
4488
4758
|
] }),
|
|
4489
|
-
/* @__PURE__ */
|
|
4490
|
-
/* @__PURE__ */
|
|
4759
|
+
/* @__PURE__ */ jsxs6("span", { children: [
|
|
4760
|
+
/* @__PURE__ */ jsx7("span", { className: "rk-kbd", children: "?" }),
|
|
4491
4761
|
" all shortcuts"
|
|
4492
4762
|
] })
|
|
4493
4763
|
] }),
|
|
4494
|
-
/* @__PURE__ */
|
|
4495
|
-
/* @__PURE__ */
|
|
4496
|
-
/* @__PURE__ */
|
|
4764
|
+
/* @__PURE__ */ jsxs6("div", { children: [
|
|
4765
|
+
/* @__PURE__ */ jsx7("label", { className: "rk-label", htmlFor: "rk-author", children: "Your name" }),
|
|
4766
|
+
/* @__PURE__ */ jsx7(
|
|
4497
4767
|
"input",
|
|
4498
4768
|
{
|
|
4499
4769
|
id: "rk-author",
|
|
@@ -4507,36 +4777,36 @@ function CoachMark() {
|
|
|
4507
4777
|
}
|
|
4508
4778
|
)
|
|
4509
4779
|
] }),
|
|
4510
|
-
/* @__PURE__ */
|
|
4511
|
-
/* @__PURE__ */
|
|
4512
|
-
/* @__PURE__ */
|
|
4780
|
+
/* @__PURE__ */ jsxs6("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 4 }, children: [
|
|
4781
|
+
/* @__PURE__ */ jsx7("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => done(false), children: "Not now" }),
|
|
4782
|
+
/* @__PURE__ */ jsx7("button", { type: "button", className: "rk-btn rk-btn-primary", onClick: () => done(true), children: "Start reviewing" })
|
|
4513
4783
|
] })
|
|
4514
4784
|
] })
|
|
4515
4785
|
] });
|
|
4516
4786
|
}
|
|
4517
4787
|
|
|
4518
4788
|
// src/client/components/Confirm.tsx
|
|
4519
|
-
import { useEffect as
|
|
4520
|
-
import { Fragment as
|
|
4789
|
+
import { useEffect as useEffect6, useRef as useRef5 } from "react";
|
|
4790
|
+
import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
4521
4791
|
function ConfirmHost() {
|
|
4522
4792
|
const { confirm } = useStore();
|
|
4523
4793
|
const dispatch = useDispatch();
|
|
4524
4794
|
const cancelRef = useRef5(null);
|
|
4525
|
-
|
|
4795
|
+
useEffect6(() => {
|
|
4526
4796
|
if (confirm) cancelRef.current?.focus();
|
|
4527
4797
|
}, [confirm]);
|
|
4528
4798
|
if (!confirm) return null;
|
|
4529
4799
|
const close = () => dispatch({ type: "SET_CONFIRM", confirm: null });
|
|
4530
|
-
return /* @__PURE__ */
|
|
4531
|
-
/* @__PURE__ */
|
|
4532
|
-
/* @__PURE__ */
|
|
4533
|
-
/* @__PURE__ */
|
|
4534
|
-
/* @__PURE__ */
|
|
4535
|
-
/* @__PURE__ */
|
|
4800
|
+
return /* @__PURE__ */ jsxs7(Fragment4, { children: [
|
|
4801
|
+
/* @__PURE__ */ jsx8("div", { className: "rk-backdrop", onClick: close }),
|
|
4802
|
+
/* @__PURE__ */ jsxs7("div", { className: "rk-modal", role: "alertdialog", "aria-modal": "true", "aria-label": confirm.title, children: [
|
|
4803
|
+
/* @__PURE__ */ jsxs7("div", { className: "rk-modal-body", children: [
|
|
4804
|
+
/* @__PURE__ */ jsx8("div", { className: "rk-modal-title", children: confirm.title }),
|
|
4805
|
+
/* @__PURE__ */ jsx8("div", { className: "rk-modal-text", children: confirm.message })
|
|
4536
4806
|
] }),
|
|
4537
|
-
/* @__PURE__ */
|
|
4538
|
-
/* @__PURE__ */
|
|
4539
|
-
/* @__PURE__ */
|
|
4807
|
+
/* @__PURE__ */ jsxs7("div", { className: "rk-modal-actions", children: [
|
|
4808
|
+
/* @__PURE__ */ jsx8("button", { ref: cancelRef, type: "button", className: "rk-btn rk-btn-ghost", onClick: close, children: "Cancel" }),
|
|
4809
|
+
/* @__PURE__ */ jsx8(
|
|
4540
4810
|
"button",
|
|
4541
4811
|
{
|
|
4542
4812
|
type: "button",
|
|
@@ -4555,10 +4825,10 @@ function ConfirmHost() {
|
|
|
4555
4825
|
}
|
|
4556
4826
|
|
|
4557
4827
|
// src/client/components/ImageEditor.tsx
|
|
4558
|
-
import { useEffect as
|
|
4828
|
+
import { useEffect as useEffect7, useRef as useRef7, useState as useState6 } from "react";
|
|
4559
4829
|
|
|
4560
4830
|
// src/client/useAnchored.ts
|
|
4561
|
-
import { useLayoutEffect as useLayoutEffect2, useRef as useRef6, useState as
|
|
4831
|
+
import { useLayoutEffect as useLayoutEffect2, useRef as useRef6, useState as useState5 } from "react";
|
|
4562
4832
|
|
|
4563
4833
|
// src/client/position.ts
|
|
4564
4834
|
function place(anchor, size, side, offset) {
|
|
@@ -4604,7 +4874,7 @@ function computePosition(anchor, size, options = {}) {
|
|
|
4604
4874
|
// src/client/useAnchored.ts
|
|
4605
4875
|
function useAnchored(anchorEl, side = "bottom", offset = 8) {
|
|
4606
4876
|
const ref = useRef6(null);
|
|
4607
|
-
const [pos, setPos] =
|
|
4877
|
+
const [pos, setPos] = useState5(null);
|
|
4608
4878
|
useLayoutEffect2(() => {
|
|
4609
4879
|
if (!anchorEl) {
|
|
4610
4880
|
setPos(null);
|
|
@@ -4636,7 +4906,7 @@ function anchoredStyle(pos) {
|
|
|
4636
4906
|
}
|
|
4637
4907
|
|
|
4638
4908
|
// src/client/components/ImageEditor.tsx
|
|
4639
|
-
import { Fragment as
|
|
4909
|
+
import { Fragment as Fragment5, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
4640
4910
|
var MAX_BYTES = 2 * 1024 * 1024;
|
|
4641
4911
|
var FETCH_TIMEOUT_MS = 12e3;
|
|
4642
4912
|
var PROBE_TIMEOUT_MS = 8e3;
|
|
@@ -4694,12 +4964,12 @@ function urlFromDataTransfer(dt) {
|
|
|
4694
4964
|
function ImageEditor({ editor }) {
|
|
4695
4965
|
const dispatch = useDispatch();
|
|
4696
4966
|
const { route, session } = useStore();
|
|
4697
|
-
const [replacement, setReplacement] =
|
|
4698
|
-
const [urlValue, setUrlValue] =
|
|
4699
|
-
const [loading2, setLoading] =
|
|
4700
|
-
const [description, setDescription] =
|
|
4701
|
-
const [priority, setPriority] =
|
|
4702
|
-
const [over, setOver] =
|
|
4967
|
+
const [replacement, setReplacement] = useState6(null);
|
|
4968
|
+
const [urlValue, setUrlValue] = useState6("");
|
|
4969
|
+
const [loading2, setLoading] = useState6(false);
|
|
4970
|
+
const [description, setDescription] = useState6("");
|
|
4971
|
+
const [priority, setPriority] = useState6("nice");
|
|
4972
|
+
const [over, setOver] = useState6(false);
|
|
4703
4973
|
const fileInput = useRef7(null);
|
|
4704
4974
|
const abortRef = useRef7(null);
|
|
4705
4975
|
const debounceRef = useRef7(null);
|
|
@@ -4766,7 +5036,7 @@ function ImageEditor({ editor }) {
|
|
|
4766
5036
|
}
|
|
4767
5037
|
}
|
|
4768
5038
|
};
|
|
4769
|
-
|
|
5039
|
+
useEffect7(() => {
|
|
4770
5040
|
if (debounceRef.current !== null) window.clearTimeout(debounceRef.current);
|
|
4771
5041
|
if (urlValue.trim() === "" || replacement !== null) return;
|
|
4772
5042
|
debounceRef.current = window.setTimeout(() => {
|
|
@@ -4776,8 +5046,8 @@ function ImageEditor({ editor }) {
|
|
|
4776
5046
|
if (debounceRef.current !== null) window.clearTimeout(debounceRef.current);
|
|
4777
5047
|
};
|
|
4778
5048
|
}, [urlValue, replacement]);
|
|
4779
|
-
|
|
4780
|
-
|
|
5049
|
+
useEffect7(() => () => abortRef.current?.abort(), []);
|
|
5050
|
+
useEffect7(() => {
|
|
4781
5051
|
const onPaste = (event) => {
|
|
4782
5052
|
const data = event.clipboardData;
|
|
4783
5053
|
if (!data) return;
|
|
@@ -4855,23 +5125,23 @@ function ImageEditor({ editor }) {
|
|
|
4855
5125
|
toast(dispatch, "Image proposal saved", "success");
|
|
4856
5126
|
};
|
|
4857
5127
|
const previewSrc = replacement?.kind === "data" ? replacement.dataUrl : replacement?.url;
|
|
4858
|
-
return /* @__PURE__ */
|
|
4859
|
-
/* @__PURE__ */
|
|
4860
|
-
/* @__PURE__ */
|
|
5128
|
+
return /* @__PURE__ */ jsxs8("div", { ref, className: "rk-card", style: anchoredStyle(pos), role: "dialog", "aria-label": "Replace image", children: [
|
|
5129
|
+
/* @__PURE__ */ jsxs8("div", { className: "rk-card-head", children: [
|
|
5130
|
+
/* @__PURE__ */ jsx9(IconImage, { size: 14 }),
|
|
4861
5131
|
"Replace image"
|
|
4862
5132
|
] }),
|
|
4863
|
-
/* @__PURE__ */
|
|
4864
|
-
replacement && previewSrc ? /* @__PURE__ */
|
|
4865
|
-
/* @__PURE__ */
|
|
4866
|
-
/* @__PURE__ */
|
|
4867
|
-
/* @__PURE__ */
|
|
5133
|
+
/* @__PURE__ */ jsxs8("div", { className: "rk-card-body", children: [
|
|
5134
|
+
replacement && previewSrc ? /* @__PURE__ */ jsx9("div", { className: "rk-thumbs", children: /* @__PURE__ */ jsxs8("div", { className: "rk-thumb-pair", title: "Hover to compare with the current image", children: [
|
|
5135
|
+
/* @__PURE__ */ jsxs8("figure", { className: "rk-thumb", children: [
|
|
5136
|
+
/* @__PURE__ */ jsx9("img", { src: beforeSrc, alt: "Current" }),
|
|
5137
|
+
/* @__PURE__ */ jsx9("figcaption", { children: "Before" })
|
|
4868
5138
|
] }),
|
|
4869
|
-
/* @__PURE__ */
|
|
4870
|
-
/* @__PURE__ */
|
|
4871
|
-
/* @__PURE__ */
|
|
5139
|
+
/* @__PURE__ */ jsxs8("figure", { className: "rk-thumb", children: [
|
|
5140
|
+
/* @__PURE__ */ jsx9("img", { src: previewSrc, alt: "Proposed replacement" }),
|
|
5141
|
+
/* @__PURE__ */ jsx9("figcaption", { children: replacement.kind === "url" ? "After \xB7 linked" : "After" })
|
|
4872
5142
|
] })
|
|
4873
|
-
] }) }) : /* @__PURE__ */
|
|
4874
|
-
/* @__PURE__ */
|
|
5143
|
+
] }) }) : /* @__PURE__ */ jsxs8(Fragment5, { children: [
|
|
5144
|
+
/* @__PURE__ */ jsxs8(
|
|
4875
5145
|
"button",
|
|
4876
5146
|
{
|
|
4877
5147
|
type: "button",
|
|
@@ -4884,18 +5154,18 @@ function ImageEditor({ editor }) {
|
|
|
4884
5154
|
onDragLeave: () => setOver(false),
|
|
4885
5155
|
onDrop,
|
|
4886
5156
|
children: [
|
|
4887
|
-
/* @__PURE__ */
|
|
4888
|
-
/* @__PURE__ */
|
|
5157
|
+
/* @__PURE__ */ jsx9(IconUpload, { size: 18 }),
|
|
5158
|
+
/* @__PURE__ */ jsxs8("span", { children: [
|
|
4889
5159
|
"Drop an image \u2014 from your disk or another tab \u2014",
|
|
4890
|
-
/* @__PURE__ */
|
|
5160
|
+
/* @__PURE__ */ jsx9("br", {}),
|
|
4891
5161
|
"or click to browse (max 2 MB)"
|
|
4892
5162
|
] })
|
|
4893
5163
|
]
|
|
4894
5164
|
}
|
|
4895
5165
|
),
|
|
4896
|
-
/* @__PURE__ */
|
|
4897
|
-
loading2 ? /* @__PURE__ */
|
|
4898
|
-
/* @__PURE__ */
|
|
5166
|
+
/* @__PURE__ */ jsxs8("div", { className: "rk-url", children: [
|
|
5167
|
+
loading2 ? /* @__PURE__ */ jsx9("span", { className: "rk-spinner", "aria-label": "Loading image" }) : /* @__PURE__ */ jsx9(IconLink, { size: 13 }),
|
|
5168
|
+
/* @__PURE__ */ jsx9(
|
|
4899
5169
|
"input",
|
|
4900
5170
|
{
|
|
4901
5171
|
className: "rk-input",
|
|
@@ -4910,9 +5180,9 @@ function ImageEditor({ editor }) {
|
|
|
4910
5180
|
)
|
|
4911
5181
|
] })
|
|
4912
5182
|
] }),
|
|
4913
|
-
replacement && /* @__PURE__ */
|
|
4914
|
-
/* @__PURE__ */
|
|
4915
|
-
/* @__PURE__ */
|
|
5183
|
+
replacement && /* @__PURE__ */ jsx9("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: clearReplacement, children: "Remove replacement" }),
|
|
5184
|
+
/* @__PURE__ */ jsx9("input", { ref: fileInput, type: "file", accept: "image/*", hidden: true, onChange: onPick }),
|
|
5185
|
+
/* @__PURE__ */ jsx9(
|
|
4916
5186
|
"textarea",
|
|
4917
5187
|
{
|
|
4918
5188
|
className: "rk-textarea",
|
|
@@ -4922,43 +5192,43 @@ function ImageEditor({ editor }) {
|
|
|
4922
5192
|
rows: 2
|
|
4923
5193
|
}
|
|
4924
5194
|
),
|
|
4925
|
-
/* @__PURE__ */
|
|
4926
|
-
/* @__PURE__ */
|
|
4927
|
-
/* @__PURE__ */
|
|
5195
|
+
/* @__PURE__ */ jsxs8("div", { className: "rk-seg", role: "group", "aria-label": "Priority", children: [
|
|
5196
|
+
/* @__PURE__ */ jsx9("button", { type: "button", "aria-pressed": priority === "must", onClick: () => setPriority("must"), children: "Must" }),
|
|
5197
|
+
/* @__PURE__ */ jsx9("button", { type: "button", "aria-pressed": priority === "nice", onClick: () => setPriority("nice"), children: "Nice to have" })
|
|
4928
5198
|
] })
|
|
4929
5199
|
] }),
|
|
4930
|
-
/* @__PURE__ */
|
|
4931
|
-
/* @__PURE__ */
|
|
4932
|
-
/* @__PURE__ */
|
|
5200
|
+
/* @__PURE__ */ jsxs8("div", { className: "rk-card-foot", children: [
|
|
5201
|
+
/* @__PURE__ */ jsxs8("span", { className: "rk-hint", children: [
|
|
5202
|
+
/* @__PURE__ */ jsx9("span", { className: "rk-kbd", children: "esc" }),
|
|
4933
5203
|
" cancel"
|
|
4934
5204
|
] }),
|
|
4935
|
-
/* @__PURE__ */
|
|
4936
|
-
/* @__PURE__ */
|
|
4937
|
-
/* @__PURE__ */
|
|
5205
|
+
/* @__PURE__ */ jsxs8("div", { className: "rk-actions", children: [
|
|
5206
|
+
/* @__PURE__ */ jsx9("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => dispatch({ type: "CLOSE_EDITOR" }), children: "Cancel" }),
|
|
5207
|
+
/* @__PURE__ */ jsx9("button", { type: "button", className: "rk-btn rk-btn-primary", onClick: save, children: "Save" })
|
|
4938
5208
|
] })
|
|
4939
5209
|
] })
|
|
4940
5210
|
] });
|
|
4941
5211
|
}
|
|
4942
5212
|
|
|
4943
5213
|
// src/client/components/InlineEditor.tsx
|
|
4944
|
-
import { useEffect as
|
|
4945
|
-
import { Fragment as
|
|
5214
|
+
import { useEffect as useEffect8, useRef as useRef8, useState as useState7 } from "react";
|
|
5215
|
+
import { Fragment as Fragment6, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
4946
5216
|
function InlineEditor({ editor }) {
|
|
4947
5217
|
const dispatch = useDispatch();
|
|
4948
5218
|
const { route, session } = useStore();
|
|
4949
|
-
const [after, setAfter] =
|
|
4950
|
-
const [priority, setPriority] =
|
|
4951
|
-
const [note, setNote] =
|
|
5219
|
+
const [after, setAfter] = useState7(() => editor.element.innerText);
|
|
5220
|
+
const [priority, setPriority] = useState7("nice");
|
|
5221
|
+
const [note, setNote] = useState7("");
|
|
4952
5222
|
const original = useRef8(null);
|
|
4953
5223
|
const baseline = useRef8(null);
|
|
4954
|
-
const [sizeDelta, setSizeDelta] =
|
|
4955
|
-
const [widthDelta, setWidthDelta] =
|
|
4956
|
-
const [clipped, setClipped] =
|
|
5224
|
+
const [sizeDelta, setSizeDelta] = useState7(0);
|
|
5225
|
+
const [widthDelta, setWidthDelta] = useState7(0);
|
|
5226
|
+
const [clipped, setClipped] = useState7(false);
|
|
4957
5227
|
const ringRef = useRef8(null);
|
|
4958
5228
|
const afterRef = useRef8(null);
|
|
4959
5229
|
const { ref, pos } = useAnchored(editor.element, "bottom", 12);
|
|
4960
5230
|
const element = editor.element;
|
|
4961
|
-
|
|
5231
|
+
useEffect8(() => {
|
|
4962
5232
|
const el = element;
|
|
4963
5233
|
original.current = { html: el.innerHTML, text: el.innerText, styleAttr: el.getAttribute("style") };
|
|
4964
5234
|
const rect = el.getBoundingClientRect();
|
|
@@ -4989,7 +5259,7 @@ function InlineEditor({ editor }) {
|
|
|
4989
5259
|
};
|
|
4990
5260
|
}, [element]);
|
|
4991
5261
|
const focusedOnce = useRef8(false);
|
|
4992
|
-
|
|
5262
|
+
useEffect8(() => {
|
|
4993
5263
|
const field = afterRef.current;
|
|
4994
5264
|
if (pos === null || focusedOnce.current || !field) return;
|
|
4995
5265
|
focusedOnce.current = true;
|
|
@@ -4997,7 +5267,7 @@ function InlineEditor({ editor }) {
|
|
|
4997
5267
|
const end = field.value.length;
|
|
4998
5268
|
field.setSelectionRange(end, end);
|
|
4999
5269
|
}, [pos]);
|
|
5000
|
-
|
|
5270
|
+
useEffect8(() => {
|
|
5001
5271
|
const field = afterRef.current;
|
|
5002
5272
|
if (!field) return;
|
|
5003
5273
|
field.style.height = "auto";
|
|
@@ -5007,7 +5277,7 @@ function InlineEditor({ editor }) {
|
|
|
5007
5277
|
setAfter(value);
|
|
5008
5278
|
if (element.innerText !== value) setElementText(element, value);
|
|
5009
5279
|
};
|
|
5010
|
-
|
|
5280
|
+
useEffect8(() => {
|
|
5011
5281
|
let raf = 0;
|
|
5012
5282
|
let lastDelta = 0;
|
|
5013
5283
|
let lastWidth = 0;
|
|
@@ -5077,7 +5347,7 @@ function InlineEditor({ editor }) {
|
|
|
5077
5347
|
cancel();
|
|
5078
5348
|
}
|
|
5079
5349
|
};
|
|
5080
|
-
|
|
5350
|
+
useEffect8(() => {
|
|
5081
5351
|
const el = element;
|
|
5082
5352
|
const onKeyDown = (event) => {
|
|
5083
5353
|
if (event.key === "Enter" && !event.shiftKey) {
|
|
@@ -5095,19 +5365,19 @@ function InlineEditor({ editor }) {
|
|
|
5095
5365
|
});
|
|
5096
5366
|
const before = original.current?.text ?? "";
|
|
5097
5367
|
const delta = after.length - before.length;
|
|
5098
|
-
return /* @__PURE__ */
|
|
5099
|
-
/* @__PURE__ */
|
|
5100
|
-
/* @__PURE__ */
|
|
5101
|
-
/* @__PURE__ */
|
|
5102
|
-
/* @__PURE__ */
|
|
5368
|
+
return /* @__PURE__ */ jsxs9(Fragment6, { children: [
|
|
5369
|
+
/* @__PURE__ */ jsx10("div", { ref: ringRef, className: "rk-edit-ring" }),
|
|
5370
|
+
/* @__PURE__ */ jsxs9("div", { ref, className: "rk-card", style: anchoredStyle(pos), role: "dialog", "aria-label": "Rewrite text", children: [
|
|
5371
|
+
/* @__PURE__ */ jsxs9("div", { className: "rk-card-head", children: [
|
|
5372
|
+
/* @__PURE__ */ jsx10(IconText, { size: 14 }),
|
|
5103
5373
|
"Rewrite text",
|
|
5104
|
-
/* @__PURE__ */
|
|
5105
|
-
/* @__PURE__ */
|
|
5374
|
+
/* @__PURE__ */ jsx10("span", { className: "rk-spacer" }),
|
|
5375
|
+
/* @__PURE__ */ jsxs9("span", { className: "rk-delta", "aria-live": "polite", children: [
|
|
5106
5376
|
before.length,
|
|
5107
5377
|
" \u2192 ",
|
|
5108
5378
|
after.length,
|
|
5109
5379
|
" ",
|
|
5110
|
-
delta !== 0 && /* @__PURE__ */
|
|
5380
|
+
delta !== 0 && /* @__PURE__ */ jsxs9("span", { className: delta > 0 ? "rk-plus" : "rk-minus", children: [
|
|
5111
5381
|
"(",
|
|
5112
5382
|
delta > 0 ? "+" : "",
|
|
5113
5383
|
delta,
|
|
@@ -5115,15 +5385,15 @@ function InlineEditor({ editor }) {
|
|
|
5115
5385
|
] })
|
|
5116
5386
|
] })
|
|
5117
5387
|
] }),
|
|
5118
|
-
/* @__PURE__ */
|
|
5119
|
-
/* @__PURE__ */
|
|
5120
|
-
/* @__PURE__ */
|
|
5121
|
-
/* @__PURE__ */
|
|
5122
|
-
/* @__PURE__ */
|
|
5388
|
+
/* @__PURE__ */ jsxs9("div", { className: "rk-card-body", children: [
|
|
5389
|
+
/* @__PURE__ */ jsxs9("div", { className: "rk-diff", "aria-label": "Before and after", children: [
|
|
5390
|
+
/* @__PURE__ */ jsxs9("div", { className: "rk-diff-row rk-diff-before", children: [
|
|
5391
|
+
/* @__PURE__ */ jsx10("span", { className: "rk-diff-tag", children: "Before" }),
|
|
5392
|
+
/* @__PURE__ */ jsx10("span", { className: "rk-diff-text", children: before })
|
|
5123
5393
|
] }),
|
|
5124
|
-
/* @__PURE__ */
|
|
5125
|
-
/* @__PURE__ */
|
|
5126
|
-
/* @__PURE__ */
|
|
5394
|
+
/* @__PURE__ */ jsxs9("div", { className: "rk-diff-row rk-diff-after", children: [
|
|
5395
|
+
/* @__PURE__ */ jsx10("span", { className: "rk-diff-tag", children: "After" }),
|
|
5396
|
+
/* @__PURE__ */ jsx10(
|
|
5127
5397
|
"textarea",
|
|
5128
5398
|
{
|
|
5129
5399
|
ref: afterRef,
|
|
@@ -5137,11 +5407,11 @@ function InlineEditor({ editor }) {
|
|
|
5137
5407
|
)
|
|
5138
5408
|
] })
|
|
5139
5409
|
] }),
|
|
5140
|
-
(Math.abs(sizeDelta) > 2 || Math.abs(widthDelta) > 4 || clipped) && /* @__PURE__ */
|
|
5410
|
+
(Math.abs(sizeDelta) > 2 || Math.abs(widthDelta) > 4 || clipped) && /* @__PURE__ */ jsxs9("div", { className: "rk-size-note", role: "status", children: [
|
|
5141
5411
|
Math.abs(sizeDelta) > 2 && (() => {
|
|
5142
5412
|
const lines = baseline.current ? Math.round(Math.abs(sizeDelta) / baseline.current.lineHeight) : 0;
|
|
5143
5413
|
const lineNote = lines >= 1 ? ` (~${lines} line${lines === 1 ? "" : "s"})` : "";
|
|
5144
|
-
return /* @__PURE__ */
|
|
5414
|
+
return /* @__PURE__ */ jsxs9("span", { children: [
|
|
5145
5415
|
"Block ",
|
|
5146
5416
|
sizeDelta > 0 ? "grew" : "shrank",
|
|
5147
5417
|
" by ",
|
|
@@ -5151,16 +5421,16 @@ function InlineEditor({ editor }) {
|
|
|
5151
5421
|
" \u2014 as it would with this text live."
|
|
5152
5422
|
] });
|
|
5153
5423
|
})(),
|
|
5154
|
-
Math.abs(sizeDelta) <= 2 && Math.abs(widthDelta) > 4 && /* @__PURE__ */
|
|
5424
|
+
Math.abs(sizeDelta) <= 2 && Math.abs(widthDelta) > 4 && /* @__PURE__ */ jsxs9("span", { children: [
|
|
5155
5425
|
"Block got ",
|
|
5156
5426
|
widthDelta > 0 ? "wider" : "narrower",
|
|
5157
5427
|
" by ",
|
|
5158
5428
|
Math.abs(widthDelta),
|
|
5159
5429
|
" px \u2014 as it would with this text live."
|
|
5160
5430
|
] }),
|
|
5161
|
-
clipped && /* @__PURE__ */
|
|
5431
|
+
clipped && /* @__PURE__ */ jsx10("span", { className: "rk-clip-note", children: "Text exceeds the visible crop here and will be cut off." })
|
|
5162
5432
|
] }),
|
|
5163
|
-
/* @__PURE__ */
|
|
5433
|
+
/* @__PURE__ */ jsx10(
|
|
5164
5434
|
"input",
|
|
5165
5435
|
{
|
|
5166
5436
|
className: "rk-input",
|
|
@@ -5169,24 +5439,24 @@ function InlineEditor({ editor }) {
|
|
|
5169
5439
|
onChange: (event) => setNote(event.target.value)
|
|
5170
5440
|
}
|
|
5171
5441
|
),
|
|
5172
|
-
/* @__PURE__ */
|
|
5173
|
-
/* @__PURE__ */
|
|
5174
|
-
/* @__PURE__ */
|
|
5442
|
+
/* @__PURE__ */ jsxs9("div", { className: "rk-seg", role: "group", "aria-label": "Priority", children: [
|
|
5443
|
+
/* @__PURE__ */ jsx10("button", { type: "button", "aria-pressed": priority === "must", onClick: () => setPriority("must"), children: "Must" }),
|
|
5444
|
+
/* @__PURE__ */ jsx10("button", { type: "button", "aria-pressed": priority === "nice", onClick: () => setPriority("nice"), children: "Nice to have" })
|
|
5175
5445
|
] })
|
|
5176
5446
|
] }),
|
|
5177
|
-
/* @__PURE__ */
|
|
5178
|
-
/* @__PURE__ */
|
|
5179
|
-
/* @__PURE__ */
|
|
5447
|
+
/* @__PURE__ */ jsxs9("div", { className: "rk-card-foot", children: [
|
|
5448
|
+
/* @__PURE__ */ jsxs9("span", { className: "rk-hint", children: [
|
|
5449
|
+
/* @__PURE__ */ jsx10("span", { className: "rk-kbd", children: "\u21B5" }),
|
|
5180
5450
|
" save \xB7 ",
|
|
5181
|
-
/* @__PURE__ */
|
|
5451
|
+
/* @__PURE__ */ jsx10("span", { className: "rk-kbd", children: "\u21E7\u21B5" }),
|
|
5182
5452
|
" newline \xB7",
|
|
5183
5453
|
" ",
|
|
5184
|
-
/* @__PURE__ */
|
|
5454
|
+
/* @__PURE__ */ jsx10("span", { className: "rk-kbd", children: "esc" }),
|
|
5185
5455
|
" cancel"
|
|
5186
5456
|
] }),
|
|
5187
|
-
/* @__PURE__ */
|
|
5188
|
-
/* @__PURE__ */
|
|
5189
|
-
/* @__PURE__ */
|
|
5457
|
+
/* @__PURE__ */ jsxs9("div", { className: "rk-actions", children: [
|
|
5458
|
+
/* @__PURE__ */ jsx10("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: cancel, children: "Cancel" }),
|
|
5459
|
+
/* @__PURE__ */ jsx10("button", { type: "button", className: "rk-btn rk-btn-primary", onClick: commit, children: "Save" })
|
|
5190
5460
|
] })
|
|
5191
5461
|
] })
|
|
5192
5462
|
] })
|
|
@@ -5194,8 +5464,8 @@ function InlineEditor({ editor }) {
|
|
|
5194
5464
|
}
|
|
5195
5465
|
|
|
5196
5466
|
// src/client/components/NoteComposer.tsx
|
|
5197
|
-
import { useEffect as
|
|
5198
|
-
import { jsx as
|
|
5467
|
+
import { useEffect as useEffect9, useRef as useRef9, useState as useState8 } from "react";
|
|
5468
|
+
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
5199
5469
|
var TITLES = {
|
|
5200
5470
|
comment: "Comment",
|
|
5201
5471
|
delete: "Mark for deletion",
|
|
@@ -5211,14 +5481,14 @@ var PLACEHOLDERS = {
|
|
|
5211
5481
|
function NoteComposer({ editor }) {
|
|
5212
5482
|
const dispatch = useDispatch();
|
|
5213
5483
|
const { route, session } = useStore();
|
|
5214
|
-
const [text, setText] =
|
|
5215
|
-
const [direction, setDirection] =
|
|
5216
|
-
const [priority, setPriority] =
|
|
5484
|
+
const [text, setText] = useState8("");
|
|
5485
|
+
const [direction, setDirection] = useState8(void 0);
|
|
5486
|
+
const [priority, setPriority] = useState8("nice");
|
|
5217
5487
|
const textareaRef = useRef9(null);
|
|
5218
5488
|
const { ref, pos } = useAnchored(editor.element, "bottom", 12);
|
|
5219
5489
|
const { kind } = editor;
|
|
5220
5490
|
const focusedOnce = useRef9(false);
|
|
5221
|
-
|
|
5491
|
+
useEffect9(() => {
|
|
5222
5492
|
const field = textareaRef.current;
|
|
5223
5493
|
if (pos === null || focusedOnce.current || !field) return;
|
|
5224
5494
|
focusedOnce.current = true;
|
|
@@ -5277,13 +5547,13 @@ function NoteComposer({ editor }) {
|
|
|
5277
5547
|
save();
|
|
5278
5548
|
}
|
|
5279
5549
|
};
|
|
5280
|
-
return /* @__PURE__ */
|
|
5281
|
-
/* @__PURE__ */
|
|
5550
|
+
return /* @__PURE__ */ jsxs10("div", { ref, className: "rk-card", style: anchoredStyle(pos), role: "dialog", "aria-label": TITLES[kind], children: [
|
|
5551
|
+
/* @__PURE__ */ jsxs10("div", { className: "rk-card-head", children: [
|
|
5282
5552
|
iconForType(kind),
|
|
5283
5553
|
TITLES[kind]
|
|
5284
5554
|
] }),
|
|
5285
|
-
/* @__PURE__ */
|
|
5286
|
-
kind === "move" && /* @__PURE__ */
|
|
5555
|
+
/* @__PURE__ */ jsxs10("div", { className: "rk-card-body", children: [
|
|
5556
|
+
kind === "move" && /* @__PURE__ */ jsx11("div", { className: "rk-seg", role: "group", "aria-label": "Direction", children: ["up", "down", "first", "last"].map((option) => /* @__PURE__ */ jsx11(
|
|
5287
5557
|
"button",
|
|
5288
5558
|
{
|
|
5289
5559
|
type: "button",
|
|
@@ -5293,7 +5563,7 @@ function NoteComposer({ editor }) {
|
|
|
5293
5563
|
},
|
|
5294
5564
|
option
|
|
5295
5565
|
)) }),
|
|
5296
|
-
/* @__PURE__ */
|
|
5566
|
+
/* @__PURE__ */ jsx11(
|
|
5297
5567
|
"textarea",
|
|
5298
5568
|
{
|
|
5299
5569
|
ref: textareaRef,
|
|
@@ -5305,29 +5575,29 @@ function NoteComposer({ editor }) {
|
|
|
5305
5575
|
rows: 3
|
|
5306
5576
|
}
|
|
5307
5577
|
),
|
|
5308
|
-
/* @__PURE__ */
|
|
5309
|
-
/* @__PURE__ */
|
|
5310
|
-
/* @__PURE__ */
|
|
5578
|
+
/* @__PURE__ */ jsxs10("div", { className: "rk-seg", role: "group", "aria-label": "Priority", children: [
|
|
5579
|
+
/* @__PURE__ */ jsx11("button", { type: "button", "aria-pressed": priority === "must", onClick: () => setPriority("must"), children: "Must" }),
|
|
5580
|
+
/* @__PURE__ */ jsx11("button", { type: "button", "aria-pressed": priority === "nice", onClick: () => setPriority("nice"), children: "Nice to have" })
|
|
5311
5581
|
] })
|
|
5312
5582
|
] }),
|
|
5313
|
-
/* @__PURE__ */
|
|
5314
|
-
/* @__PURE__ */
|
|
5315
|
-
/* @__PURE__ */
|
|
5583
|
+
/* @__PURE__ */ jsxs10("div", { className: "rk-card-foot", children: [
|
|
5584
|
+
/* @__PURE__ */ jsxs10("span", { className: "rk-hint", children: [
|
|
5585
|
+
/* @__PURE__ */ jsx11("span", { className: "rk-kbd", children: "\u2318\u21B5" }),
|
|
5316
5586
|
" save \xB7 ",
|
|
5317
|
-
/* @__PURE__ */
|
|
5587
|
+
/* @__PURE__ */ jsx11("span", { className: "rk-kbd", children: "esc" }),
|
|
5318
5588
|
" cancel"
|
|
5319
5589
|
] }),
|
|
5320
|
-
/* @__PURE__ */
|
|
5321
|
-
/* @__PURE__ */
|
|
5322
|
-
/* @__PURE__ */
|
|
5590
|
+
/* @__PURE__ */ jsxs10("div", { className: "rk-actions", children: [
|
|
5591
|
+
/* @__PURE__ */ jsx11("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => dispatch({ type: "CLOSE_EDITOR" }), children: "Cancel" }),
|
|
5592
|
+
/* @__PURE__ */ jsx11("button", { type: "button", className: "rk-btn rk-btn-primary", onClick: save, children: "Save" })
|
|
5323
5593
|
] })
|
|
5324
5594
|
] })
|
|
5325
5595
|
] });
|
|
5326
5596
|
}
|
|
5327
5597
|
|
|
5328
5598
|
// src/client/components/Panel.tsx
|
|
5329
|
-
import { useEffect as
|
|
5330
|
-
import { jsx as
|
|
5599
|
+
import { useEffect as useEffect10, useMemo as useMemo3, useRef as useRef10, useState as useState9 } from "react";
|
|
5600
|
+
import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
5331
5601
|
function changeSummary(item) {
|
|
5332
5602
|
if (isCopyItem(item)) return `\u201C${item.payload.after}\u201D`;
|
|
5333
5603
|
if (isImageItem(item)) {
|
|
@@ -5409,24 +5679,24 @@ function formatBytes(bytes) {
|
|
|
5409
5679
|
function CopyDiff({ before, after }) {
|
|
5410
5680
|
const parts = diffParts(before, after);
|
|
5411
5681
|
const delta = after.length - before.length;
|
|
5412
|
-
return /* @__PURE__ */
|
|
5413
|
-
/* @__PURE__ */
|
|
5414
|
-
/* @__PURE__ */
|
|
5415
|
-
/* @__PURE__ */
|
|
5682
|
+
return /* @__PURE__ */ jsxs11("div", { className: "rk-diffview", children: [
|
|
5683
|
+
/* @__PURE__ */ jsxs11("div", { className: "rk-diff-row rk-diff-before", children: [
|
|
5684
|
+
/* @__PURE__ */ jsx12("span", { className: "rk-diff-tag", children: "Before" }),
|
|
5685
|
+
/* @__PURE__ */ jsxs11("span", { className: "rk-diff-text", children: [
|
|
5416
5686
|
parts.prefix,
|
|
5417
|
-
parts.delMid && /* @__PURE__ */
|
|
5687
|
+
parts.delMid && /* @__PURE__ */ jsx12("mark", { className: "rk-del", children: parts.delMid }),
|
|
5418
5688
|
parts.suffix
|
|
5419
5689
|
] })
|
|
5420
5690
|
] }),
|
|
5421
|
-
/* @__PURE__ */
|
|
5422
|
-
/* @__PURE__ */
|
|
5423
|
-
/* @__PURE__ */
|
|
5691
|
+
/* @__PURE__ */ jsxs11("div", { className: "rk-diff-row rk-diff-after", children: [
|
|
5692
|
+
/* @__PURE__ */ jsx12("span", { className: "rk-diff-tag", children: "After" }),
|
|
5693
|
+
/* @__PURE__ */ jsxs11("span", { className: "rk-diff-text", children: [
|
|
5424
5694
|
parts.prefix,
|
|
5425
|
-
parts.insMid && /* @__PURE__ */
|
|
5695
|
+
parts.insMid && /* @__PURE__ */ jsx12("mark", { className: "rk-ins", children: parts.insMid }),
|
|
5426
5696
|
parts.suffix
|
|
5427
5697
|
] })
|
|
5428
5698
|
] }),
|
|
5429
|
-
/* @__PURE__ */
|
|
5699
|
+
/* @__PURE__ */ jsxs11("div", { className: "rk-diff-len", children: [
|
|
5430
5700
|
before.length,
|
|
5431
5701
|
" \u2192 ",
|
|
5432
5702
|
after.length,
|
|
@@ -5437,8 +5707,8 @@ function CopyDiff({ before, after }) {
|
|
|
5437
5707
|
}
|
|
5438
5708
|
function ImageDetail({ beforeSrc, afterSrc, afterDataUrl }) {
|
|
5439
5709
|
const replacement = afterDataUrl ?? afterSrc;
|
|
5440
|
-
const [dims, setDims] =
|
|
5441
|
-
|
|
5710
|
+
const [dims, setDims] = useState9("");
|
|
5711
|
+
useEffect10(() => {
|
|
5442
5712
|
if (!replacement) return;
|
|
5443
5713
|
const img = new Image();
|
|
5444
5714
|
img.onload = () => setDims(`${img.naturalWidth}\xD7${img.naturalHeight}px`);
|
|
@@ -5463,49 +5733,61 @@ function ImageDetail({ beforeSrc, afterSrc, afterDataUrl }) {
|
|
|
5463
5733
|
window.open(replacement, "_blank", "noopener");
|
|
5464
5734
|
}
|
|
5465
5735
|
};
|
|
5466
|
-
return /* @__PURE__ */
|
|
5467
|
-
/* @__PURE__ */
|
|
5468
|
-
/* @__PURE__ */
|
|
5469
|
-
beforeSrc ? /* @__PURE__ */
|
|
5470
|
-
/* @__PURE__ */
|
|
5736
|
+
return /* @__PURE__ */ jsxs11("div", { className: "rk-imgdetail", children: [
|
|
5737
|
+
/* @__PURE__ */ jsxs11("div", { className: "rk-thumbs", children: [
|
|
5738
|
+
/* @__PURE__ */ jsxs11("figure", { className: "rk-thumb", children: [
|
|
5739
|
+
beforeSrc ? /* @__PURE__ */ jsx12("img", { src: beforeSrc, alt: "Current" }) : /* @__PURE__ */ jsx12("div", { className: "rk-thumb-missing", children: "no image" }),
|
|
5740
|
+
/* @__PURE__ */ jsx12("figcaption", { children: "Before" })
|
|
5471
5741
|
] }),
|
|
5472
|
-
/* @__PURE__ */
|
|
5473
|
-
/* @__PURE__ */
|
|
5474
|
-
/* @__PURE__ */
|
|
5742
|
+
/* @__PURE__ */ jsxs11("figure", { className: "rk-thumb", children: [
|
|
5743
|
+
/* @__PURE__ */ jsx12("img", { src: replacement, alt: "Proposed replacement" }),
|
|
5744
|
+
/* @__PURE__ */ jsxs11("figcaption", { children: [
|
|
5475
5745
|
"After",
|
|
5476
5746
|
embedded ? "" : " \xB7 linked"
|
|
5477
5747
|
] })
|
|
5478
5748
|
] })
|
|
5479
5749
|
] }),
|
|
5480
|
-
/* @__PURE__ */
|
|
5750
|
+
/* @__PURE__ */ jsxs11("div", { className: "rk-imgdetail-meta", children: [
|
|
5481
5751
|
embedded ? "Embedded image" : "Linked image",
|
|
5482
5752
|
dims ? ` \xB7 ${dims}` : "",
|
|
5483
5753
|
bytes !== null ? ` \xB7 ${formatBytes(bytes)}` : ""
|
|
5484
5754
|
] }),
|
|
5485
|
-
!embedded && afterSrc && /* @__PURE__ */
|
|
5486
|
-
/* @__PURE__ */
|
|
5487
|
-
/* @__PURE__ */
|
|
5488
|
-
/* @__PURE__ */
|
|
5755
|
+
!embedded && afterSrc && /* @__PURE__ */ jsx12("a", { className: "rk-imgdetail-url", href: afterSrc, target: "_blank", rel: "noopener noreferrer", title: afterSrc, children: afterSrc }),
|
|
5756
|
+
/* @__PURE__ */ jsxs11("div", { className: "rk-imgdetail-actions", children: [
|
|
5757
|
+
/* @__PURE__ */ jsxs11("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => void download(), children: [
|
|
5758
|
+
/* @__PURE__ */ jsx12(IconDownload, { size: 12 }),
|
|
5489
5759
|
" Download"
|
|
5490
5760
|
] }),
|
|
5491
|
-
/* @__PURE__ */
|
|
5761
|
+
/* @__PURE__ */ jsx12("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => window.open(replacement, "_blank", "noopener"), children: "Open" })
|
|
5492
5762
|
] })
|
|
5493
5763
|
] });
|
|
5494
5764
|
}
|
|
5765
|
+
var SYNC_REASON_LABEL = {
|
|
5766
|
+
"token-short": "token too short",
|
|
5767
|
+
"bad-token": "token rejected",
|
|
5768
|
+
"room-full": "room full",
|
|
5769
|
+
unreachable: "server unreachable"
|
|
5770
|
+
};
|
|
5771
|
+
var SYNC_REASON_HELP = {
|
|
5772
|
+
"token-short": "The sync server needs a token of at least 8 characters. Use a longer `token` (or `syncToken`) in <ReviewKit /> and everyone with the link shares items live.",
|
|
5773
|
+
"bad-token": "The sync server rejected the token. Check `syncToken` / `token` in <ReviewKit />.",
|
|
5774
|
+
"room-full": "This page already has the maximum number of reviewers online (16). Try again later.",
|
|
5775
|
+
unreachable: "Could not reach the sync server. Usually the page's Content-Security-Policy is missing the server in connect-src, or the server is down. Items stay on this device meanwhile."
|
|
5776
|
+
};
|
|
5495
5777
|
function Panel() {
|
|
5496
|
-
const { session, panelOpen, activeItemId, badgeCorner, undoStack, preview, unapplied, syncStatus, emblemaPush, peers } = useStore();
|
|
5778
|
+
const { session, panelOpen, activeItemId, badgeCorner, undoStack, preview, unapplied, syncStatus, syncReason, emblemaPush, peers } = useStore();
|
|
5497
5779
|
const dispatch = useDispatch();
|
|
5498
5780
|
const config = useConfig();
|
|
5499
|
-
const [sticky, setStickyState] =
|
|
5500
|
-
const [query, setQuery] =
|
|
5501
|
-
const [typeFilter, setTypeFilter] =
|
|
5502
|
-
const [prioFilter, setPrioFilter] =
|
|
5503
|
-
const [statusFilter, setStatusFilter] =
|
|
5504
|
-
const [filterOpen, setFilterOpen] =
|
|
5505
|
-
const [settingsOpen, setSettingsOpen] =
|
|
5506
|
-
const [emblemaAlive, setEmblemaAlive] =
|
|
5507
|
-
const [emblemaSending, setEmblemaSending] =
|
|
5508
|
-
const [emblemaSync, setEmblemaSync] =
|
|
5781
|
+
const [sticky, setStickyState] = useState9(() => isStickyEnabled(config.token));
|
|
5782
|
+
const [query, setQuery] = useState9("");
|
|
5783
|
+
const [typeFilter, setTypeFilter] = useState9(/* @__PURE__ */ new Set());
|
|
5784
|
+
const [prioFilter, setPrioFilter] = useState9(/* @__PURE__ */ new Set());
|
|
5785
|
+
const [statusFilter, setStatusFilter] = useState9(/* @__PURE__ */ new Set());
|
|
5786
|
+
const [filterOpen, setFilterOpen] = useState9(false);
|
|
5787
|
+
const [settingsOpen, setSettingsOpen] = useState9(false);
|
|
5788
|
+
const [emblemaAlive, setEmblemaAlive] = useState9(null);
|
|
5789
|
+
const [emblemaSending, setEmblemaSending] = useState9(false);
|
|
5790
|
+
const [emblemaSync, setEmblemaSync] = useState9("unknown");
|
|
5509
5791
|
const panelRef = useRef10(null);
|
|
5510
5792
|
const searchRef = useRef10(null);
|
|
5511
5793
|
const importRef = useRef10(null);
|
|
@@ -5526,7 +5808,7 @@ function Panel() {
|
|
|
5526
5808
|
() => typeFilter.size + prioFilter.size + statusFilter.size > 0 ? { types: [...typeFilter], priorities: [...prioFilter], statuses: [...statusFilter] } : null,
|
|
5527
5809
|
[typeFilter, prioFilter, statusFilter]
|
|
5528
5810
|
);
|
|
5529
|
-
|
|
5811
|
+
useEffect10(() => {
|
|
5530
5812
|
dispatch({ type: "SET_FILTER", filter: activeFilter });
|
|
5531
5813
|
return () => dispatch({ type: "SET_FILTER", filter: null });
|
|
5532
5814
|
}, [activeFilter, dispatch]);
|
|
@@ -5563,7 +5845,7 @@ function Panel() {
|
|
|
5563
5845
|
}
|
|
5564
5846
|
return Array.from(map.entries());
|
|
5565
5847
|
}, [filtered]);
|
|
5566
|
-
|
|
5848
|
+
useEffect10(() => {
|
|
5567
5849
|
if (!filterOpen && !settingsOpen) return;
|
|
5568
5850
|
const onDown = (event) => {
|
|
5569
5851
|
const path = event.composedPath();
|
|
@@ -5574,7 +5856,7 @@ function Panel() {
|
|
|
5574
5856
|
document.addEventListener("pointerdown", onDown, true);
|
|
5575
5857
|
return () => document.removeEventListener("pointerdown", onDown, true);
|
|
5576
5858
|
}, [filterOpen, settingsOpen]);
|
|
5577
|
-
|
|
5859
|
+
useEffect10(() => {
|
|
5578
5860
|
if (!settingsOpen) return;
|
|
5579
5861
|
let alive = true;
|
|
5580
5862
|
const probe = () => {
|
|
@@ -5598,7 +5880,7 @@ function Panel() {
|
|
|
5598
5880
|
live: "paired",
|
|
5599
5881
|
off: "not paired"
|
|
5600
5882
|
}[emblemaPairState];
|
|
5601
|
-
|
|
5883
|
+
useEffect10(() => {
|
|
5602
5884
|
if (!panelOpen || activeItemId === null) return;
|
|
5603
5885
|
const row = panelRef.current?.querySelector(`[data-item-id="${activeItemId}"]`);
|
|
5604
5886
|
row?.scrollIntoView({ block: "nearest" });
|
|
@@ -5714,7 +5996,7 @@ function Panel() {
|
|
|
5714
5996
|
panel.style.transform = "";
|
|
5715
5997
|
if (dy > 110) dispatch({ type: "SET_PANEL", open: false });
|
|
5716
5998
|
};
|
|
5717
|
-
return /* @__PURE__ */
|
|
5999
|
+
return /* @__PURE__ */ jsxs11(
|
|
5718
6000
|
"div",
|
|
5719
6001
|
{
|
|
5720
6002
|
ref: panelRef,
|
|
@@ -5724,7 +6006,7 @@ function Panel() {
|
|
|
5724
6006
|
"aria-label": "Review feedback panel",
|
|
5725
6007
|
onKeyDown,
|
|
5726
6008
|
children: [
|
|
5727
|
-
/* @__PURE__ */
|
|
6009
|
+
/* @__PURE__ */ jsx12(
|
|
5728
6010
|
"div",
|
|
5729
6011
|
{
|
|
5730
6012
|
className: "rk-sheet-handle",
|
|
@@ -5735,34 +6017,41 @@ function Panel() {
|
|
|
5735
6017
|
onPointerCancel: onSheetHandleUp
|
|
5736
6018
|
}
|
|
5737
6019
|
),
|
|
5738
|
-
/* @__PURE__ */
|
|
5739
|
-
/* @__PURE__ */
|
|
5740
|
-
/* @__PURE__ */
|
|
5741
|
-
/* @__PURE__ */
|
|
6020
|
+
/* @__PURE__ */ jsxs11("div", { className: "rk-panel-head", children: [
|
|
6021
|
+
/* @__PURE__ */ jsxs11("div", { children: [
|
|
6022
|
+
/* @__PURE__ */ jsx12("div", { className: "rk-panel-title", children: "Feedback" }),
|
|
6023
|
+
/* @__PURE__ */ jsxs11("div", { className: "rk-panel-sub", children: [
|
|
5742
6024
|
items.length,
|
|
5743
6025
|
" item",
|
|
5744
6026
|
items.length === 1 ? "" : "s",
|
|
5745
6027
|
session.author ? ` \xB7 ${session.author}` : "",
|
|
5746
|
-
syncStatus !== "disabled" && /* @__PURE__ */
|
|
5747
|
-
|
|
5748
|
-
|
|
5749
|
-
|
|
5750
|
-
|
|
6028
|
+
syncStatus !== "disabled" && /* @__PURE__ */ jsxs11(
|
|
6029
|
+
"span",
|
|
6030
|
+
{
|
|
6031
|
+
className: `rk-sync rk-sync-${syncStatus}${syncReason ? ` rk-sync-reason-${syncReason}` : ""}`,
|
|
6032
|
+
title: syncStatus === "online" ? "Live: everyone with this review link shares these items in real time" : syncStatus === "connecting" ? "Connecting to the sync server\u2026" : SYNC_REASON_HELP[syncReason ?? "unreachable"],
|
|
6033
|
+
children: [
|
|
6034
|
+
/* @__PURE__ */ jsx12("span", { className: "rk-sync-dot" }),
|
|
6035
|
+
syncStatus === "online" ? `live${peers.length > 0 ? ` \xB7 ${peers.length} other${peers.length === 1 ? "" : "s"}` : ""}` : syncStatus === "connecting" ? "connecting\u2026" : `local only \xB7 ${SYNC_REASON_LABEL[syncReason ?? "unreachable"]}`
|
|
6036
|
+
]
|
|
6037
|
+
}
|
|
6038
|
+
),
|
|
6039
|
+
config.emblema && emblemaPush !== "idle" && /* @__PURE__ */ jsxs11(
|
|
5751
6040
|
"span",
|
|
5752
6041
|
{
|
|
5753
6042
|
className: `rk-sync rk-epush-${emblemaPush}`,
|
|
5754
6043
|
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",
|
|
5755
6044
|
children: [
|
|
5756
|
-
/* @__PURE__ */
|
|
6045
|
+
/* @__PURE__ */ jsx12("span", { className: "rk-sync-dot" }),
|
|
5757
6046
|
emblemaPush === "ok" ? "emblema" : emblemaPush === "sending" ? "emblema\u2026" : emblemaPush === "rejected" ? "emblema rejected" : "emblema offline"
|
|
5758
6047
|
]
|
|
5759
6048
|
}
|
|
5760
6049
|
)
|
|
5761
6050
|
] })
|
|
5762
6051
|
] }),
|
|
5763
|
-
/* @__PURE__ */
|
|
5764
|
-
/* @__PURE__ */
|
|
5765
|
-
/* @__PURE__ */
|
|
6052
|
+
/* @__PURE__ */ jsx12("span", { className: "rk-spacer" }),
|
|
6053
|
+
/* @__PURE__ */ jsxs11("div", { className: "rk-menu-scope rk-menu-anchor", children: [
|
|
6054
|
+
/* @__PURE__ */ jsx12(
|
|
5766
6055
|
"button",
|
|
5767
6056
|
{
|
|
5768
6057
|
type: "button",
|
|
@@ -5778,11 +6067,11 @@ function Panel() {
|
|
|
5778
6067
|
void pingEmblema(config.emblema).then((port) => setEmblemaAlive(port !== null));
|
|
5779
6068
|
}
|
|
5780
6069
|
},
|
|
5781
|
-
children: /* @__PURE__ */
|
|
6070
|
+
children: /* @__PURE__ */ jsx12(IconGear, { size: 15 })
|
|
5782
6071
|
}
|
|
5783
6072
|
),
|
|
5784
|
-
settingsOpen && /* @__PURE__ */
|
|
5785
|
-
config.token && /* @__PURE__ */
|
|
6073
|
+
settingsOpen && /* @__PURE__ */ jsxs11("div", { className: "rk-menu", role: "menu", "aria-label": "Session settings", children: [
|
|
6074
|
+
config.token && /* @__PURE__ */ jsxs11(
|
|
5786
6075
|
"button",
|
|
5787
6076
|
{
|
|
5788
6077
|
type: "button",
|
|
@@ -5797,12 +6086,12 @@ function Panel() {
|
|
|
5797
6086
|
toast(dispatch, next ? "Review stays on in this tab" : "Review active only via the link", "info");
|
|
5798
6087
|
},
|
|
5799
6088
|
children: [
|
|
5800
|
-
/* @__PURE__ */
|
|
6089
|
+
/* @__PURE__ */ jsx12("span", { className: `rk-menu-check${sticky ? " rk-on" : ""}` }),
|
|
5801
6090
|
"Keep review on in this tab"
|
|
5802
6091
|
]
|
|
5803
6092
|
}
|
|
5804
6093
|
),
|
|
5805
|
-
config.emblema && /* @__PURE__ */
|
|
6094
|
+
config.emblema && /* @__PURE__ */ jsxs11(
|
|
5806
6095
|
"button",
|
|
5807
6096
|
{
|
|
5808
6097
|
type: "button",
|
|
@@ -5832,7 +6121,7 @@ function Panel() {
|
|
|
5832
6121
|
}).finally(() => setEmblemaSending(false));
|
|
5833
6122
|
},
|
|
5834
6123
|
children: [
|
|
5835
|
-
/* @__PURE__ */
|
|
6124
|
+
/* @__PURE__ */ jsx12(
|
|
5836
6125
|
"span",
|
|
5837
6126
|
{
|
|
5838
6127
|
className: "rk-emblema-dot",
|
|
@@ -5843,25 +6132,40 @@ function Panel() {
|
|
|
5843
6132
|
]
|
|
5844
6133
|
}
|
|
5845
6134
|
),
|
|
5846
|
-
/* @__PURE__ */
|
|
6135
|
+
/* @__PURE__ */ jsxs11(
|
|
5847
6136
|
"button",
|
|
5848
6137
|
{
|
|
5849
6138
|
type: "button",
|
|
5850
6139
|
role: "menuitem",
|
|
5851
6140
|
className: "rk-menu-item",
|
|
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",
|
|
6141
|
+
title: emblemaPairState === "stale" ? "The local sync agent is not answering \u2014 run `npx -p @satanwagen/reviewkit-cli reviewkit-emblema serve` in the project" : "Pair this project with the Emblema app via a sync key",
|
|
5853
6142
|
onClick: () => {
|
|
5854
6143
|
setSettingsOpen(false);
|
|
5855
6144
|
dispatch({ type: "SET_EMBLEMA_CONNECT", open: true });
|
|
5856
6145
|
},
|
|
5857
6146
|
children: [
|
|
5858
|
-
/* @__PURE__ */
|
|
6147
|
+
/* @__PURE__ */ jsx12("span", { className: "rk-emblema-dot", "data-state": emblemaPairState }),
|
|
5859
6148
|
"Connect to Emblema\u2026",
|
|
5860
|
-
/* @__PURE__ */
|
|
6149
|
+
/* @__PURE__ */ jsx12("span", { className: "rk-menu-count", children: emblemaPairLabel })
|
|
5861
6150
|
]
|
|
5862
6151
|
}
|
|
5863
6152
|
),
|
|
5864
|
-
/* @__PURE__ */
|
|
6153
|
+
/* @__PURE__ */ jsx12(
|
|
6154
|
+
"button",
|
|
6155
|
+
{
|
|
6156
|
+
type: "button",
|
|
6157
|
+
role: "menuitem",
|
|
6158
|
+
className: "rk-menu-item",
|
|
6159
|
+
title: resolveSyncToken(config) ? "Pair the reviewkit terminal CLI / Claude Code MCP bridge with this site" : "Needs live sync (sync is off on this page) \u2014 the terminal reads the shared room",
|
|
6160
|
+
disabled: !resolveSyncToken(config),
|
|
6161
|
+
onClick: () => {
|
|
6162
|
+
setSettingsOpen(false);
|
|
6163
|
+
dispatch({ type: "SET_TERMINAL_CONNECT", open: true });
|
|
6164
|
+
},
|
|
6165
|
+
children: "Connect terminal / agent\u2026"
|
|
6166
|
+
}
|
|
6167
|
+
),
|
|
6168
|
+
/* @__PURE__ */ jsx12(
|
|
5865
6169
|
"button",
|
|
5866
6170
|
{
|
|
5867
6171
|
type: "button",
|
|
@@ -5874,31 +6178,31 @@ function Panel() {
|
|
|
5874
6178
|
)
|
|
5875
6179
|
] })
|
|
5876
6180
|
] }),
|
|
5877
|
-
/* @__PURE__ */
|
|
6181
|
+
/* @__PURE__ */ jsx12(
|
|
5878
6182
|
"button",
|
|
5879
6183
|
{
|
|
5880
6184
|
type: "button",
|
|
5881
6185
|
className: "rk-icon-btn",
|
|
5882
6186
|
"aria-label": "Keyboard shortcuts",
|
|
5883
6187
|
onClick: () => dispatch({ type: "SET_CHEATSHEET", open: true }),
|
|
5884
|
-
children: /* @__PURE__ */
|
|
6188
|
+
children: /* @__PURE__ */ jsx12(IconKeyboard, { size: 15 })
|
|
5885
6189
|
}
|
|
5886
6190
|
),
|
|
5887
|
-
/* @__PURE__ */
|
|
6191
|
+
/* @__PURE__ */ jsx12(
|
|
5888
6192
|
"button",
|
|
5889
6193
|
{
|
|
5890
6194
|
type: "button",
|
|
5891
6195
|
className: "rk-icon-btn",
|
|
5892
6196
|
"aria-label": "Close panel",
|
|
5893
6197
|
onClick: () => dispatch({ type: "SET_PANEL", open: false }),
|
|
5894
|
-
children: /* @__PURE__ */
|
|
6198
|
+
children: /* @__PURE__ */ jsx12(IconClose, { size: 14 })
|
|
5895
6199
|
}
|
|
5896
6200
|
)
|
|
5897
6201
|
] }),
|
|
5898
|
-
/* @__PURE__ */
|
|
5899
|
-
/* @__PURE__ */
|
|
5900
|
-
/* @__PURE__ */
|
|
5901
|
-
/* @__PURE__ */
|
|
6202
|
+
/* @__PURE__ */ jsxs11("div", { className: "rk-view-row", children: [
|
|
6203
|
+
/* @__PURE__ */ jsx12("div", { className: "rk-view-info", children: /* @__PURE__ */ jsx12("div", { className: "rk-view-title", children: "Page view" }) }),
|
|
6204
|
+
/* @__PURE__ */ jsxs11("div", { className: "rk-seg rk-view-toggle", role: "group", "aria-label": "Page view (P to toggle)", children: [
|
|
6205
|
+
/* @__PURE__ */ jsx12(
|
|
5902
6206
|
"button",
|
|
5903
6207
|
{
|
|
5904
6208
|
type: "button",
|
|
@@ -5908,7 +6212,7 @@ function Panel() {
|
|
|
5908
6212
|
children: "Original"
|
|
5909
6213
|
}
|
|
5910
6214
|
),
|
|
5911
|
-
/* @__PURE__ */
|
|
6215
|
+
/* @__PURE__ */ jsx12(
|
|
5912
6216
|
"button",
|
|
5913
6217
|
{
|
|
5914
6218
|
type: "button",
|
|
@@ -5920,8 +6224,8 @@ function Panel() {
|
|
|
5920
6224
|
)
|
|
5921
6225
|
] })
|
|
5922
6226
|
] }),
|
|
5923
|
-
/* @__PURE__ */
|
|
5924
|
-
/* @__PURE__ */
|
|
6227
|
+
/* @__PURE__ */ jsxs11("div", { className: "rk-panel-tools", children: [
|
|
6228
|
+
/* @__PURE__ */ jsxs11(
|
|
5925
6229
|
"button",
|
|
5926
6230
|
{
|
|
5927
6231
|
type: "button",
|
|
@@ -5932,15 +6236,15 @@ function Panel() {
|
|
|
5932
6236
|
dispatch({ type: "SET_MODE", mode: "pick" });
|
|
5933
6237
|
},
|
|
5934
6238
|
children: [
|
|
5935
|
-
/* @__PURE__ */
|
|
6239
|
+
/* @__PURE__ */ jsx12(IconTarget, { size: 14 }),
|
|
5936
6240
|
" Pick an element"
|
|
5937
6241
|
]
|
|
5938
6242
|
}
|
|
5939
6243
|
),
|
|
5940
|
-
/* @__PURE__ */
|
|
5941
|
-
/* @__PURE__ */
|
|
5942
|
-
/* @__PURE__ */
|
|
5943
|
-
/* @__PURE__ */
|
|
6244
|
+
/* @__PURE__ */ jsxs11("div", { className: "rk-search-row", children: [
|
|
6245
|
+
/* @__PURE__ */ jsxs11("div", { className: "rk-search", children: [
|
|
6246
|
+
/* @__PURE__ */ jsx12(IconSearch, { size: 13 }),
|
|
6247
|
+
/* @__PURE__ */ jsx12(
|
|
5944
6248
|
"input",
|
|
5945
6249
|
{
|
|
5946
6250
|
ref: searchRef,
|
|
@@ -5952,8 +6256,8 @@ function Panel() {
|
|
|
5952
6256
|
}
|
|
5953
6257
|
)
|
|
5954
6258
|
] }),
|
|
5955
|
-
/* @__PURE__ */
|
|
5956
|
-
/* @__PURE__ */
|
|
6259
|
+
/* @__PURE__ */ jsxs11("div", { className: "rk-menu-scope rk-menu-anchor", children: [
|
|
6260
|
+
/* @__PURE__ */ jsxs11(
|
|
5957
6261
|
"button",
|
|
5958
6262
|
{
|
|
5959
6263
|
type: "button",
|
|
@@ -5965,15 +6269,15 @@ function Panel() {
|
|
|
5965
6269
|
setSettingsOpen(false);
|
|
5966
6270
|
},
|
|
5967
6271
|
children: [
|
|
5968
|
-
/* @__PURE__ */
|
|
6272
|
+
/* @__PURE__ */ jsx12(IconFilter, { size: 13 }),
|
|
5969
6273
|
"Filter",
|
|
5970
|
-
typeFilter.size + prioFilter.size + statusFilter.size > 0 && /* @__PURE__ */
|
|
6274
|
+
typeFilter.size + prioFilter.size + statusFilter.size > 0 && /* @__PURE__ */ jsx12("span", { className: "rk-badge-count", children: typeFilter.size + prioFilter.size + statusFilter.size })
|
|
5971
6275
|
]
|
|
5972
6276
|
}
|
|
5973
6277
|
),
|
|
5974
|
-
filterOpen && /* @__PURE__ */
|
|
5975
|
-
/* @__PURE__ */
|
|
5976
|
-
TYPE_FILTERS.map((type) => /* @__PURE__ */
|
|
6278
|
+
filterOpen && /* @__PURE__ */ jsxs11("div", { className: "rk-menu", role: "menu", "aria-label": "Filter items", children: [
|
|
6279
|
+
/* @__PURE__ */ jsx12("div", { className: "rk-menu-title", children: "Type" }),
|
|
6280
|
+
TYPE_FILTERS.map((type) => /* @__PURE__ */ jsxs11(
|
|
5977
6281
|
"button",
|
|
5978
6282
|
{
|
|
5979
6283
|
type: "button",
|
|
@@ -5987,16 +6291,16 @@ function Panel() {
|
|
|
5987
6291
|
setTypeFilter(next);
|
|
5988
6292
|
},
|
|
5989
6293
|
children: [
|
|
5990
|
-
/* @__PURE__ */
|
|
6294
|
+
/* @__PURE__ */ jsx12("span", { className: `rk-menu-check${typeFilter.has(type) ? " rk-on" : ""}` }),
|
|
5991
6295
|
iconForType(type, 12),
|
|
5992
|
-
/* @__PURE__ */
|
|
5993
|
-
/* @__PURE__ */
|
|
6296
|
+
/* @__PURE__ */ jsx12("span", { className: "rk-menu-label", children: type }),
|
|
6297
|
+
/* @__PURE__ */ jsx12("span", { className: "rk-menu-count", children: typeCounts.get(type) ?? 0 })
|
|
5994
6298
|
]
|
|
5995
6299
|
},
|
|
5996
6300
|
type
|
|
5997
6301
|
)),
|
|
5998
|
-
/* @__PURE__ */
|
|
5999
|
-
PRIORITY_FILTERS.map((priority) => /* @__PURE__ */
|
|
6302
|
+
/* @__PURE__ */ jsx12("div", { className: "rk-menu-title", children: "Priority" }),
|
|
6303
|
+
PRIORITY_FILTERS.map((priority) => /* @__PURE__ */ jsxs11(
|
|
6000
6304
|
"button",
|
|
6001
6305
|
{
|
|
6002
6306
|
type: "button",
|
|
@@ -6010,15 +6314,15 @@ function Panel() {
|
|
|
6010
6314
|
setPrioFilter(next);
|
|
6011
6315
|
},
|
|
6012
6316
|
children: [
|
|
6013
|
-
/* @__PURE__ */
|
|
6014
|
-
/* @__PURE__ */
|
|
6015
|
-
/* @__PURE__ */
|
|
6317
|
+
/* @__PURE__ */ jsx12("span", { className: `rk-menu-check${prioFilter.has(priority) ? " rk-on" : ""}` }),
|
|
6318
|
+
/* @__PURE__ */ jsx12("span", { className: "rk-menu-label", children: PRIORITY_LABELS[priority] }),
|
|
6319
|
+
/* @__PURE__ */ jsx12("span", { className: "rk-menu-count", children: prioCounts.get(priority) ?? 0 })
|
|
6016
6320
|
]
|
|
6017
6321
|
},
|
|
6018
6322
|
priority
|
|
6019
6323
|
)),
|
|
6020
|
-
/* @__PURE__ */
|
|
6021
|
-
STATUSES.map((status) => /* @__PURE__ */
|
|
6324
|
+
/* @__PURE__ */ jsx12("div", { className: "rk-menu-title", children: "Status" }),
|
|
6325
|
+
STATUSES.map((status) => /* @__PURE__ */ jsxs11(
|
|
6022
6326
|
"button",
|
|
6023
6327
|
{
|
|
6024
6328
|
type: "button",
|
|
@@ -6032,15 +6336,15 @@ function Panel() {
|
|
|
6032
6336
|
setStatusFilter(next);
|
|
6033
6337
|
},
|
|
6034
6338
|
children: [
|
|
6035
|
-
/* @__PURE__ */
|
|
6036
|
-
/* @__PURE__ */
|
|
6037
|
-
/* @__PURE__ */
|
|
6038
|
-
/* @__PURE__ */
|
|
6339
|
+
/* @__PURE__ */ jsx12("span", { className: `rk-menu-check${statusFilter.has(status) ? " rk-on" : ""}` }),
|
|
6340
|
+
/* @__PURE__ */ jsx12("span", { className: `rk-status-dot rk-st-${status}` }),
|
|
6341
|
+
/* @__PURE__ */ jsx12("span", { className: "rk-menu-label", children: status }),
|
|
6342
|
+
/* @__PURE__ */ jsx12("span", { className: "rk-menu-count", children: statusCounts.get(status) ?? 0 })
|
|
6039
6343
|
]
|
|
6040
6344
|
},
|
|
6041
6345
|
status
|
|
6042
6346
|
)),
|
|
6043
|
-
/* @__PURE__ */
|
|
6347
|
+
/* @__PURE__ */ jsx12(
|
|
6044
6348
|
"button",
|
|
6045
6349
|
{
|
|
6046
6350
|
type: "button",
|
|
@@ -6060,24 +6364,24 @@ function Panel() {
|
|
|
6060
6364
|
] })
|
|
6061
6365
|
] })
|
|
6062
6366
|
] }),
|
|
6063
|
-
preview && unapplied > 0 && /* @__PURE__ */
|
|
6367
|
+
preview && unapplied > 0 && /* @__PURE__ */ jsxs11("div", { className: "rk-unplaced", role: "status", children: [
|
|
6064
6368
|
unapplied,
|
|
6065
6369
|
" saved change",
|
|
6066
6370
|
unapplied === 1 ? "" : "s",
|
|
6067
6371
|
" couldn\u2019t be placed on the current page \u2014 the page has changed since they were captured."
|
|
6068
6372
|
] }),
|
|
6069
|
-
/* @__PURE__ */
|
|
6070
|
-
/* @__PURE__ */
|
|
6071
|
-
/* @__PURE__ */
|
|
6072
|
-
/* @__PURE__ */
|
|
6073
|
-
] }) : groups.map(([route, entries]) => /* @__PURE__ */
|
|
6074
|
-
/* @__PURE__ */
|
|
6373
|
+
/* @__PURE__ */ jsx12("div", { className: "rk-panel-list", children: filtered.length === 0 ? /* @__PURE__ */ jsxs11("div", { className: "rk-empty", children: [
|
|
6374
|
+
/* @__PURE__ */ jsx12("div", { className: "rk-empty-art", children: /* @__PURE__ */ jsx12(IconTarget, { size: 22 }) }),
|
|
6375
|
+
/* @__PURE__ */ jsx12("div", { className: "rk-empty-title", children: items.length === 0 ? "Nothing here yet" : "No matches" }),
|
|
6376
|
+
/* @__PURE__ */ jsx12("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." })
|
|
6377
|
+
] }) : groups.map(([route, entries]) => /* @__PURE__ */ jsxs11("div", { children: [
|
|
6378
|
+
/* @__PURE__ */ jsx12("div", { className: "rk-group-title", children: route }),
|
|
6075
6379
|
entries.map(({ item, number }) => {
|
|
6076
6380
|
const active = item.id === activeItemId;
|
|
6077
6381
|
const orphan = orphanIds.has(item.id);
|
|
6078
6382
|
const hiddenEl = hiddenIds.has(item.id);
|
|
6079
|
-
return /* @__PURE__ */
|
|
6080
|
-
/* @__PURE__ */
|
|
6383
|
+
return /* @__PURE__ */ jsxs11("div", { children: [
|
|
6384
|
+
/* @__PURE__ */ jsxs11(
|
|
6081
6385
|
"div",
|
|
6082
6386
|
{
|
|
6083
6387
|
"data-item-id": item.id,
|
|
@@ -6092,18 +6396,18 @@ function Panel() {
|
|
|
6092
6396
|
}
|
|
6093
6397
|
},
|
|
6094
6398
|
children: [
|
|
6095
|
-
/* @__PURE__ */
|
|
6096
|
-
/* @__PURE__ */
|
|
6097
|
-
/* @__PURE__ */
|
|
6098
|
-
/* @__PURE__ */
|
|
6399
|
+
/* @__PURE__ */ jsx12("span", { className: "rk-item-num", children: number }),
|
|
6400
|
+
/* @__PURE__ */ jsx12("span", { className: "rk-item-icon", children: iconForType(item.type) }),
|
|
6401
|
+
/* @__PURE__ */ jsxs11("span", { className: "rk-item-body", children: [
|
|
6402
|
+
/* @__PURE__ */ jsxs11("span", { className: "rk-item-snippet", children: [
|
|
6099
6403
|
item.target.tagName,
|
|
6100
6404
|
" \xB7 ",
|
|
6101
6405
|
item.target.textSnippet || item.target.selector
|
|
6102
6406
|
] }),
|
|
6103
|
-
/* @__PURE__ */
|
|
6104
|
-
/* @__PURE__ */
|
|
6105
|
-
/* @__PURE__ */
|
|
6106
|
-
/* @__PURE__ */
|
|
6407
|
+
/* @__PURE__ */ jsx12("span", { className: "rk-item-change", children: changeSummary(item) }),
|
|
6408
|
+
/* @__PURE__ */ jsxs11("span", { className: "rk-item-meta", children: [
|
|
6409
|
+
/* @__PURE__ */ jsxs11("span", { className: "rk-author", title: new Date(item.createdAt).toLocaleString(), children: [
|
|
6410
|
+
/* @__PURE__ */ jsx12(
|
|
6107
6411
|
"span",
|
|
6108
6412
|
{
|
|
6109
6413
|
className: "rk-author-dot",
|
|
@@ -6111,15 +6415,15 @@ function Panel() {
|
|
|
6111
6415
|
}
|
|
6112
6416
|
),
|
|
6113
6417
|
item.author?.name ?? "Unknown",
|
|
6114
|
-
/* @__PURE__ */
|
|
6418
|
+
/* @__PURE__ */ jsxs11("span", { className: "rk-time", children: [
|
|
6115
6419
|
" \xB7 ",
|
|
6116
6420
|
timeAgo(item.createdAt)
|
|
6117
6421
|
] })
|
|
6118
6422
|
] }),
|
|
6119
|
-
item.priority === "must" && /* @__PURE__ */
|
|
6120
|
-
item.status !== "open" && /* @__PURE__ */
|
|
6121
|
-
orphan && /* @__PURE__ */
|
|
6122
|
-
hiddenEl && /* @__PURE__ */
|
|
6423
|
+
item.priority === "must" && /* @__PURE__ */ jsx12("span", { className: "rk-badge-mini rk-must", children: "must" }),
|
|
6424
|
+
item.status !== "open" && /* @__PURE__ */ jsx12("span", { className: `rk-badge-mini rk-${item.status}`, children: item.status }),
|
|
6425
|
+
orphan && /* @__PURE__ */ jsx12("span", { className: "rk-badge-mini rk-orphaned", children: "unanchored" }),
|
|
6426
|
+
hiddenEl && /* @__PURE__ */ jsx12(
|
|
6123
6427
|
"span",
|
|
6124
6428
|
{
|
|
6125
6429
|
className: "rk-badge-mini rk-hidden-el",
|
|
@@ -6127,14 +6431,14 @@ function Panel() {
|
|
|
6127
6431
|
children: "hidden"
|
|
6128
6432
|
}
|
|
6129
6433
|
),
|
|
6130
|
-
item.note && /* @__PURE__ */
|
|
6131
|
-
peers.filter((peer) => peer.typingActive && peer.typingItemId === item.id).map((peer) => /* @__PURE__ */
|
|
6434
|
+
item.note && /* @__PURE__ */ jsx12("span", { className: "rk-badge-mini", children: "note" }),
|
|
6435
|
+
peers.filter((peer) => peer.typingActive && peer.typingItemId === item.id).map((peer) => /* @__PURE__ */ jsxs11("span", { className: "rk-badge-mini", style: { color: peer.color }, children: [
|
|
6132
6436
|
peer.name || "peer",
|
|
6133
6437
|
" is writing\u2026"
|
|
6134
6438
|
] }, peer.id))
|
|
6135
6439
|
] })
|
|
6136
6440
|
] }),
|
|
6137
|
-
/* @__PURE__ */
|
|
6441
|
+
/* @__PURE__ */ jsx12("span", { className: "rk-item-actions", children: /* @__PURE__ */ jsx12(
|
|
6138
6442
|
"button",
|
|
6139
6443
|
{
|
|
6140
6444
|
type: "button",
|
|
@@ -6149,15 +6453,15 @@ function Panel() {
|
|
|
6149
6453
|
"info"
|
|
6150
6454
|
);
|
|
6151
6455
|
},
|
|
6152
|
-
children: /* @__PURE__ */
|
|
6456
|
+
children: /* @__PURE__ */ jsx12(IconTrash, { size: 13 })
|
|
6153
6457
|
}
|
|
6154
6458
|
) })
|
|
6155
6459
|
]
|
|
6156
6460
|
}
|
|
6157
6461
|
),
|
|
6158
|
-
active && /* @__PURE__ */
|
|
6159
|
-
/* @__PURE__ */
|
|
6160
|
-
/* @__PURE__ */
|
|
6462
|
+
active && /* @__PURE__ */ jsxs11("div", { className: "rk-item-edit", children: [
|
|
6463
|
+
/* @__PURE__ */ jsxs11("div", { className: "rk-detail-byline", title: new Date(item.createdAt).toLocaleString(), children: [
|
|
6464
|
+
/* @__PURE__ */ jsx12(
|
|
6161
6465
|
"span",
|
|
6162
6466
|
{
|
|
6163
6467
|
className: "rk-author-dot",
|
|
@@ -6168,8 +6472,8 @@ function Panel() {
|
|
|
6168
6472
|
" \xB7 ",
|
|
6169
6473
|
timeAgo(item.createdAt)
|
|
6170
6474
|
] }),
|
|
6171
|
-
isCopyItem(item) && /* @__PURE__ */
|
|
6172
|
-
isImageItem(item) && /* @__PURE__ */
|
|
6475
|
+
isCopyItem(item) && /* @__PURE__ */ jsx12(CopyDiff, { before: item.payload.before, after: item.payload.after }),
|
|
6476
|
+
isImageItem(item) && /* @__PURE__ */ jsx12(
|
|
6173
6477
|
ImageDetail,
|
|
6174
6478
|
{
|
|
6175
6479
|
beforeSrc: item.payload.beforeSrc,
|
|
@@ -6177,7 +6481,7 @@ function Panel() {
|
|
|
6177
6481
|
afterDataUrl: item.payload.afterDataUrl
|
|
6178
6482
|
}
|
|
6179
6483
|
),
|
|
6180
|
-
isKnownItemType(item.type) && item.type !== "move" && /* @__PURE__ */
|
|
6484
|
+
isKnownItemType(item.type) && item.type !== "move" && /* @__PURE__ */ jsx12(
|
|
6181
6485
|
"textarea",
|
|
6182
6486
|
{
|
|
6183
6487
|
className: "rk-textarea",
|
|
@@ -6187,7 +6491,7 @@ function Panel() {
|
|
|
6187
6491
|
onChange: (event) => dispatch({ type: "UPDATE_ITEM", id: item.id, patch: withPayloadText(item, event.target.value) })
|
|
6188
6492
|
}
|
|
6189
6493
|
),
|
|
6190
|
-
/* @__PURE__ */
|
|
6494
|
+
/* @__PURE__ */ jsx12(
|
|
6191
6495
|
"input",
|
|
6192
6496
|
{
|
|
6193
6497
|
className: "rk-input",
|
|
@@ -6197,9 +6501,9 @@ function Panel() {
|
|
|
6197
6501
|
onChange: (event) => dispatch({ type: "UPDATE_ITEM", id: item.id, patch: { note: event.target.value } })
|
|
6198
6502
|
}
|
|
6199
6503
|
),
|
|
6200
|
-
/* @__PURE__ */
|
|
6201
|
-
/* @__PURE__ */
|
|
6202
|
-
/* @__PURE__ */
|
|
6504
|
+
/* @__PURE__ */ jsxs11("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
|
|
6505
|
+
/* @__PURE__ */ jsxs11("div", { className: "rk-seg", role: "group", "aria-label": "Priority", children: [
|
|
6506
|
+
/* @__PURE__ */ jsx12(
|
|
6203
6507
|
"button",
|
|
6204
6508
|
{
|
|
6205
6509
|
type: "button",
|
|
@@ -6208,7 +6512,7 @@ function Panel() {
|
|
|
6208
6512
|
children: "Must"
|
|
6209
6513
|
}
|
|
6210
6514
|
),
|
|
6211
|
-
/* @__PURE__ */
|
|
6515
|
+
/* @__PURE__ */ jsx12(
|
|
6212
6516
|
"button",
|
|
6213
6517
|
{
|
|
6214
6518
|
type: "button",
|
|
@@ -6218,7 +6522,7 @@ function Panel() {
|
|
|
6218
6522
|
}
|
|
6219
6523
|
)
|
|
6220
6524
|
] }),
|
|
6221
|
-
/* @__PURE__ */
|
|
6525
|
+
/* @__PURE__ */ jsx12("div", { className: "rk-seg", role: "group", "aria-label": "Status", children: STATUSES.map((status) => /* @__PURE__ */ jsx12(
|
|
6222
6526
|
"button",
|
|
6223
6527
|
{
|
|
6224
6528
|
type: "button",
|
|
@@ -6233,22 +6537,22 @@ function Panel() {
|
|
|
6233
6537
|
] }, item.id);
|
|
6234
6538
|
})
|
|
6235
6539
|
] }, route)) }),
|
|
6236
|
-
/* @__PURE__ */
|
|
6237
|
-
/* @__PURE__ */
|
|
6238
|
-
/* @__PURE__ */
|
|
6540
|
+
/* @__PURE__ */ jsxs11("div", { className: "rk-panel-foot", children: [
|
|
6541
|
+
/* @__PURE__ */ jsxs11("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: onExport, disabled: items.length === 0, children: [
|
|
6542
|
+
/* @__PURE__ */ jsx12(IconDownload, { size: 13 }),
|
|
6239
6543
|
" Export"
|
|
6240
6544
|
] }),
|
|
6241
|
-
/* @__PURE__ */
|
|
6242
|
-
/* @__PURE__ */
|
|
6545
|
+
/* @__PURE__ */ jsxs11("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => void onCopy(), disabled: items.length === 0, children: [
|
|
6546
|
+
/* @__PURE__ */ jsx12(IconCopyClipboard, { size: 13 }),
|
|
6243
6547
|
" Copy"
|
|
6244
6548
|
] }),
|
|
6245
|
-
/* @__PURE__ */
|
|
6246
|
-
/* @__PURE__ */
|
|
6549
|
+
/* @__PURE__ */ jsxs11("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => importRef.current?.click(), children: [
|
|
6550
|
+
/* @__PURE__ */ jsx12(IconUpload, { size: 13 }),
|
|
6247
6551
|
" Import"
|
|
6248
6552
|
] }),
|
|
6249
|
-
/* @__PURE__ */
|
|
6250
|
-
undoStack.length > 0 && /* @__PURE__ */
|
|
6251
|
-
/* @__PURE__ */
|
|
6553
|
+
/* @__PURE__ */ jsx12("span", { className: "rk-spacer" }),
|
|
6554
|
+
undoStack.length > 0 && /* @__PURE__ */ jsx12("button", { type: "button", className: "rk-icon-btn", "aria-label": "Undo last change (\u2318Z)", onClick: () => dispatch({ type: "UNDO" }), children: /* @__PURE__ */ jsx12(IconUndo, { size: 14 }) }),
|
|
6555
|
+
/* @__PURE__ */ jsx12(
|
|
6252
6556
|
"button",
|
|
6253
6557
|
{
|
|
6254
6558
|
type: "button",
|
|
@@ -6259,7 +6563,7 @@ function Panel() {
|
|
|
6259
6563
|
children: "Clear"
|
|
6260
6564
|
}
|
|
6261
6565
|
),
|
|
6262
|
-
/* @__PURE__ */
|
|
6566
|
+
/* @__PURE__ */ jsx12(
|
|
6263
6567
|
"button",
|
|
6264
6568
|
{
|
|
6265
6569
|
type: "button",
|
|
@@ -6269,7 +6573,7 @@ function Panel() {
|
|
|
6269
6573
|
children: "Exit review"
|
|
6270
6574
|
}
|
|
6271
6575
|
),
|
|
6272
|
-
/* @__PURE__ */
|
|
6576
|
+
/* @__PURE__ */ jsx12(
|
|
6273
6577
|
"input",
|
|
6274
6578
|
{
|
|
6275
6579
|
ref: importRef,
|
|
@@ -6290,8 +6594,8 @@ function Panel() {
|
|
|
6290
6594
|
}
|
|
6291
6595
|
|
|
6292
6596
|
// src/client/components/Presence.tsx
|
|
6293
|
-
import { useEffect as
|
|
6294
|
-
import { Fragment as
|
|
6597
|
+
import { useEffect as useEffect11, useRef as useRef11 } from "react";
|
|
6598
|
+
import { Fragment as Fragment7, jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
6295
6599
|
function initials(name) {
|
|
6296
6600
|
const parts = name.trim().split(/\s+/).filter(Boolean);
|
|
6297
6601
|
if (parts.length === 0) return "\xB7";
|
|
@@ -6301,8 +6605,8 @@ function initials(name) {
|
|
|
6301
6605
|
function PresenceStrip() {
|
|
6302
6606
|
const { peers, syncStatus } = useStore();
|
|
6303
6607
|
if (syncStatus === "disabled" || peers.length === 0) return null;
|
|
6304
|
-
return /* @__PURE__ */
|
|
6305
|
-
peers.slice(0, 5).map((peer) => /* @__PURE__ */
|
|
6608
|
+
return /* @__PURE__ */ jsxs12("div", { className: "rk-presence", "aria-label": `${peers.length} reviewer${peers.length === 1 ? "" : "s"} online`, children: [
|
|
6609
|
+
peers.slice(0, 5).map((peer) => /* @__PURE__ */ jsx13(
|
|
6306
6610
|
"span",
|
|
6307
6611
|
{
|
|
6308
6612
|
className: "rk-avatar",
|
|
@@ -6312,7 +6616,7 @@ function PresenceStrip() {
|
|
|
6312
6616
|
},
|
|
6313
6617
|
peer.id
|
|
6314
6618
|
)),
|
|
6315
|
-
peers.length > 5 && /* @__PURE__ */
|
|
6619
|
+
peers.length > 5 && /* @__PURE__ */ jsxs12("span", { className: "rk-avatar rk-avatar-more", children: [
|
|
6316
6620
|
"+",
|
|
6317
6621
|
peers.length - 5
|
|
6318
6622
|
] })
|
|
@@ -6336,7 +6640,7 @@ function PeerCursors() {
|
|
|
6336
6640
|
}
|
|
6337
6641
|
}
|
|
6338
6642
|
peersRef.current = peers;
|
|
6339
|
-
|
|
6643
|
+
useEffect11(() => {
|
|
6340
6644
|
const reduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
6341
6645
|
let raf = 0;
|
|
6342
6646
|
let last = performance.now();
|
|
@@ -6441,8 +6745,8 @@ function PeerCursors() {
|
|
|
6441
6745
|
return () => cancelAnimationFrame(raf);
|
|
6442
6746
|
}, []);
|
|
6443
6747
|
if (peers.length === 0) return null;
|
|
6444
|
-
return /* @__PURE__ */
|
|
6445
|
-
peers.map((peer) => /* @__PURE__ */
|
|
6748
|
+
return /* @__PURE__ */ jsxs12(Fragment7, { children: [
|
|
6749
|
+
peers.map((peer) => /* @__PURE__ */ jsx13(
|
|
6446
6750
|
"div",
|
|
6447
6751
|
{
|
|
6448
6752
|
ref: (el) => {
|
|
@@ -6454,7 +6758,7 @@ function PeerCursors() {
|
|
|
6454
6758
|
},
|
|
6455
6759
|
`ring-${peer.id}`
|
|
6456
6760
|
)),
|
|
6457
|
-
peers.map((peer, index) => /* @__PURE__ */
|
|
6761
|
+
peers.map((peer, index) => /* @__PURE__ */ jsxs12(
|
|
6458
6762
|
"div",
|
|
6459
6763
|
{
|
|
6460
6764
|
ref: (el) => {
|
|
@@ -6464,8 +6768,8 @@ function PeerCursors() {
|
|
|
6464
6768
|
className: "rk-peer-cursor",
|
|
6465
6769
|
style: { opacity: 0 },
|
|
6466
6770
|
children: [
|
|
6467
|
-
/* @__PURE__ */
|
|
6468
|
-
/* @__PURE__ */
|
|
6771
|
+
/* @__PURE__ */ jsx13("svg", { width: "14", height: "18", viewBox: "0 0 14 18", "aria-hidden": "true", children: /* @__PURE__ */ jsx13("path", { d: "M1 1l12 7.5-5.2 1.2L5 16z", fill: peer.color, stroke: "rgba(0,0,0,0.25)", strokeWidth: "1" }) }),
|
|
6772
|
+
/* @__PURE__ */ jsxs12(
|
|
6469
6773
|
"span",
|
|
6470
6774
|
{
|
|
6471
6775
|
className: "rk-peer-name",
|
|
@@ -6484,19 +6788,19 @@ function PeerCursors() {
|
|
|
6484
6788
|
}
|
|
6485
6789
|
|
|
6486
6790
|
// src/client/components/QuickComment.tsx
|
|
6487
|
-
import { useEffect as
|
|
6488
|
-
import { jsx as
|
|
6791
|
+
import { useEffect as useEffect12, useRef as useRef12, useState as useState10 } from "react";
|
|
6792
|
+
import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
6489
6793
|
function QuickComment() {
|
|
6490
6794
|
const { quick } = useStore();
|
|
6491
6795
|
if (!quick) return null;
|
|
6492
|
-
return /* @__PURE__ */
|
|
6796
|
+
return /* @__PURE__ */ jsx14(QuickComposerCard, { quick }, quick.id);
|
|
6493
6797
|
}
|
|
6494
6798
|
function QuickComposerCard({ quick }) {
|
|
6495
6799
|
const { route, session } = useStore();
|
|
6496
6800
|
const dispatch = useDispatch();
|
|
6497
|
-
const [text, setText] =
|
|
6801
|
+
const [text, setText] = useState10("");
|
|
6498
6802
|
const fieldRef = useRef12(null);
|
|
6499
|
-
|
|
6803
|
+
useEffect12(() => {
|
|
6500
6804
|
const field = fieldRef.current;
|
|
6501
6805
|
if (!field) return;
|
|
6502
6806
|
field.focus();
|
|
@@ -6549,18 +6853,18 @@ function QuickComposerCard({ quick }) {
|
|
|
6549
6853
|
};
|
|
6550
6854
|
const x = Math.min(Math.max(quick.x, 8), window.innerWidth - 288);
|
|
6551
6855
|
const y = Math.min(Math.max(quick.y + 12, 8), window.innerHeight - 108);
|
|
6552
|
-
return /* @__PURE__ */
|
|
6553
|
-
/* @__PURE__ */
|
|
6554
|
-
/* @__PURE__ */
|
|
6555
|
-
/* @__PURE__ */
|
|
6556
|
-
/* @__PURE__ */
|
|
6557
|
-
/* @__PURE__ */
|
|
6856
|
+
return /* @__PURE__ */ jsxs13("div", { className: "rk-quick", style: { transform: `translate3d(${x}px, ${y}px, 0)` }, role: "dialog", "aria-label": "Quick comment", children: [
|
|
6857
|
+
/* @__PURE__ */ jsxs13("div", { className: "rk-quick-head", children: [
|
|
6858
|
+
/* @__PURE__ */ jsx14(IconComment, { size: 12 }),
|
|
6859
|
+
/* @__PURE__ */ jsx14("span", { children: "Comment here" }),
|
|
6860
|
+
/* @__PURE__ */ jsxs13("span", { className: "rk-hint", children: [
|
|
6861
|
+
/* @__PURE__ */ jsx14("span", { className: "rk-kbd", children: "\u21B5" }),
|
|
6558
6862
|
" save \xB7 ",
|
|
6559
|
-
/* @__PURE__ */
|
|
6863
|
+
/* @__PURE__ */ jsx14("span", { className: "rk-kbd", children: "esc" }),
|
|
6560
6864
|
" cancel"
|
|
6561
6865
|
] })
|
|
6562
6866
|
] }),
|
|
6563
|
-
/* @__PURE__ */
|
|
6867
|
+
/* @__PURE__ */ jsx14(
|
|
6564
6868
|
"textarea",
|
|
6565
6869
|
{
|
|
6566
6870
|
ref: fieldRef,
|
|
@@ -6576,8 +6880,8 @@ function QuickComposerCard({ quick }) {
|
|
|
6576
6880
|
}
|
|
6577
6881
|
|
|
6578
6882
|
// src/client/components/PickLayer.tsx
|
|
6579
|
-
import { useEffect as
|
|
6580
|
-
import { Fragment as
|
|
6883
|
+
import { useEffect as useEffect13, useRef as useRef13, useState as useState11 } from "react";
|
|
6884
|
+
import { Fragment as Fragment8, jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
6581
6885
|
function applyRect(el, rect, pad2 = 3) {
|
|
6582
6886
|
if (!el) return;
|
|
6583
6887
|
if (!rect) {
|
|
@@ -6592,14 +6896,14 @@ function applyRect(el, rect, pad2 = 3) {
|
|
|
6592
6896
|
function PickLayer() {
|
|
6593
6897
|
const { mode, selection, tool } = useStore();
|
|
6594
6898
|
const dispatch = useDispatch();
|
|
6595
|
-
const [hovered, setHovered] =
|
|
6899
|
+
const [hovered, setHovered] = useState11(null);
|
|
6596
6900
|
const outlineRef = useRef13(null);
|
|
6597
6901
|
const labelRef = useRef13(null);
|
|
6598
6902
|
const selectRef = useRef13(null);
|
|
6599
6903
|
const hoveredRef = useRef13(null);
|
|
6600
6904
|
hoveredRef.current = hovered;
|
|
6601
6905
|
const picking = mode === "pick";
|
|
6602
|
-
|
|
6906
|
+
useEffect13(() => {
|
|
6603
6907
|
if (!picking) {
|
|
6604
6908
|
setHovered(null);
|
|
6605
6909
|
return;
|
|
@@ -6643,7 +6947,7 @@ function PickLayer() {
|
|
|
6643
6947
|
document.removeEventListener("mousedown", swallow, true);
|
|
6644
6948
|
};
|
|
6645
6949
|
}, [picking, tool, dispatch]);
|
|
6646
|
-
|
|
6950
|
+
useEffect13(() => {
|
|
6647
6951
|
if (!picking) return;
|
|
6648
6952
|
const body = document.body;
|
|
6649
6953
|
const prev = body.style.cursor;
|
|
@@ -6653,7 +6957,7 @@ function PickLayer() {
|
|
|
6653
6957
|
if (body.getAttribute("style") === "") body.removeAttribute("style");
|
|
6654
6958
|
};
|
|
6655
6959
|
}, [picking, tool]);
|
|
6656
|
-
|
|
6960
|
+
useEffect13(() => {
|
|
6657
6961
|
let raf = 0;
|
|
6658
6962
|
const tick = () => {
|
|
6659
6963
|
const hoverEl = hoveredRef.current;
|
|
@@ -6679,21 +6983,21 @@ function PickLayer() {
|
|
|
6679
6983
|
raf = requestAnimationFrame(tick);
|
|
6680
6984
|
return () => cancelAnimationFrame(raf);
|
|
6681
6985
|
}, [picking, selection]);
|
|
6682
|
-
return /* @__PURE__ */
|
|
6683
|
-
picking && /* @__PURE__ */
|
|
6684
|
-
/* @__PURE__ */
|
|
6685
|
-
/* @__PURE__ */
|
|
6686
|
-
/* @__PURE__ */
|
|
6687
|
-
/* @__PURE__ */
|
|
6688
|
-
] }) : /* @__PURE__ */
|
|
6986
|
+
return /* @__PURE__ */ jsxs14(Fragment8, { children: [
|
|
6987
|
+
picking && /* @__PURE__ */ jsxs14(Fragment8, { children: [
|
|
6988
|
+
/* @__PURE__ */ jsx15("div", { ref: outlineRef, className: "rk-outline", style: { opacity: 0 } }),
|
|
6989
|
+
/* @__PURE__ */ jsx15("div", { ref: labelRef, className: "rk-outline-label", style: { opacity: 0 }, children: hovered ? /* @__PURE__ */ jsxs14(Fragment8, { children: [
|
|
6990
|
+
/* @__PURE__ */ jsx15("span", { className: "rk-tag", children: hovered.tagName.toLowerCase() }),
|
|
6991
|
+
/* @__PURE__ */ jsx15("span", { children: describeElement(hovered).replace(/^[a-z0-9]+ · /, "") })
|
|
6992
|
+
] }) : /* @__PURE__ */ jsx15("span", { children: "Pick an element" }) })
|
|
6689
6993
|
] }),
|
|
6690
|
-
selection && /* @__PURE__ */
|
|
6994
|
+
selection && /* @__PURE__ */ jsx15("div", { ref: selectRef, className: "rk-select-ring", style: { opacity: 0 } })
|
|
6691
6995
|
] });
|
|
6692
6996
|
}
|
|
6693
6997
|
|
|
6694
6998
|
// src/client/components/Pins.tsx
|
|
6695
|
-
import { useEffect as
|
|
6696
|
-
import { Fragment as
|
|
6999
|
+
import { useEffect as useEffect14, useMemo as useMemo4, useRef as useRef14, useState as useState12 } from "react";
|
|
7000
|
+
import { Fragment as Fragment9, jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
6697
7001
|
var STATUS_LABELS = {
|
|
6698
7002
|
open: "open",
|
|
6699
7003
|
accepted: "accepted",
|
|
@@ -6705,22 +7009,22 @@ var RERESOLVE_MS = 800;
|
|
|
6705
7009
|
function Pins() {
|
|
6706
7010
|
const { session, route, activeItemId, editor, mode, filter } = useStore();
|
|
6707
7011
|
const dispatch = useDispatch();
|
|
6708
|
-
const [clusters, setClusters] =
|
|
6709
|
-
const [orphanCount, setOrphanCount] =
|
|
7012
|
+
const [clusters, setClusters] = useState12([]);
|
|
7013
|
+
const [orphanCount, setOrphanCount] = useState12(0);
|
|
6710
7014
|
const wrapRefs = useRef14(/* @__PURE__ */ new Map());
|
|
6711
7015
|
const visibleCache = useRef14(/* @__PURE__ */ new Map());
|
|
6712
7016
|
const highlightRef = useRef14(null);
|
|
6713
7017
|
const hoveredItems = useRef14(null);
|
|
6714
7018
|
const elementCache = useRef14(/* @__PURE__ */ new Map());
|
|
6715
7019
|
const lastResolve = useRef14(0);
|
|
6716
|
-
const [newestId, setNewestId] =
|
|
7020
|
+
const [newestId, setNewestId] = useState12(null);
|
|
6717
7021
|
const prevCount = useRef14(0);
|
|
6718
7022
|
const items = useMemo4(() => {
|
|
6719
7023
|
const all = session?.items ?? [];
|
|
6720
7024
|
return all.map((item, index) => ({ item, number: index + 1 })).filter(({ item }) => item.route === route);
|
|
6721
7025
|
}, [session, route]);
|
|
6722
7026
|
const byId = new Map(items.map(({ item }) => [item.id, item]));
|
|
6723
|
-
|
|
7027
|
+
useEffect14(() => {
|
|
6724
7028
|
const count = session?.items.length ?? 0;
|
|
6725
7029
|
if (count > prevCount.current && session && count > 0) {
|
|
6726
7030
|
const id = session.items[count - 1].id;
|
|
@@ -6731,7 +7035,7 @@ function Pins() {
|
|
|
6731
7035
|
}
|
|
6732
7036
|
prevCount.current = count;
|
|
6733
7037
|
}, [session]);
|
|
6734
|
-
|
|
7038
|
+
useEffect14(() => {
|
|
6735
7039
|
let raf = 0;
|
|
6736
7040
|
let lastSignature = "";
|
|
6737
7041
|
const tick = (time) => {
|
|
@@ -6815,8 +7119,8 @@ function Pins() {
|
|
|
6815
7119
|
dispatch({ type: "SET_ACTIVE_ITEM", id });
|
|
6816
7120
|
dispatch({ type: "SET_PANEL", open: true });
|
|
6817
7121
|
};
|
|
6818
|
-
return /* @__PURE__ */
|
|
6819
|
-
/* @__PURE__ */
|
|
7122
|
+
return /* @__PURE__ */ jsxs15(Fragment9, { children: [
|
|
7123
|
+
/* @__PURE__ */ jsx16("div", { ref: highlightRef, className: "rk-hl-ring", style: { opacity: 0 } }),
|
|
6820
7124
|
clusters.map((cluster) => {
|
|
6821
7125
|
const isCluster = cluster.ids.length > 1;
|
|
6822
7126
|
const isActive = activeItemId !== null && cluster.ids.includes(activeItemId);
|
|
@@ -6826,7 +7130,7 @@ function Pins() {
|
|
|
6826
7130
|
const status = statuses.size === 1 ? members[0]?.status : void 0;
|
|
6827
7131
|
const dimmed = filter !== null && members.length > 0 && !members.some((item) => itemMatchesFilter(item, filter));
|
|
6828
7132
|
const statusHint = isCluster ? status ? ` \xB7 all ${STATUS_LABELS[status] ?? status}` : "" : ` \xB7 ${STATUS_LABELS[members[0]?.status ?? "open"] ?? members[0]?.status}`;
|
|
6829
|
-
return /* @__PURE__ */
|
|
7133
|
+
return /* @__PURE__ */ jsx16(
|
|
6830
7134
|
"div",
|
|
6831
7135
|
{
|
|
6832
7136
|
ref: (el) => {
|
|
@@ -6834,7 +7138,7 @@ function Pins() {
|
|
|
6834
7138
|
else wrapRefs.current.delete(cluster.key);
|
|
6835
7139
|
},
|
|
6836
7140
|
className: `rk-pin-wrap${picking ? " rk-pin-ghost" : ""}`,
|
|
6837
|
-
children: /* @__PURE__ */
|
|
7141
|
+
children: /* @__PURE__ */ jsx16(
|
|
6838
7142
|
"button",
|
|
6839
7143
|
{
|
|
6840
7144
|
type: "button",
|
|
@@ -6856,7 +7160,7 @@ function Pins() {
|
|
|
6856
7160
|
cluster.key
|
|
6857
7161
|
);
|
|
6858
7162
|
}),
|
|
6859
|
-
orphanCount > 0 && /* @__PURE__ */
|
|
7163
|
+
orphanCount > 0 && /* @__PURE__ */ jsxs15(
|
|
6860
7164
|
"button",
|
|
6861
7165
|
{
|
|
6862
7166
|
type: "button",
|
|
@@ -6864,7 +7168,7 @@ function Pins() {
|
|
|
6864
7168
|
style: { bottom: 16, left: "50%", transform: "translateX(-50%)" },
|
|
6865
7169
|
onClick: () => dispatch({ type: "SET_PANEL", open: true }),
|
|
6866
7170
|
children: [
|
|
6867
|
-
/* @__PURE__ */
|
|
7171
|
+
/* @__PURE__ */ jsx16(IconUnlink, { size: 13 }),
|
|
6868
7172
|
orphanCount,
|
|
6869
7173
|
" unanchored item",
|
|
6870
7174
|
orphanCount === 1 ? "" : "s"
|
|
@@ -6875,13 +7179,13 @@ function Pins() {
|
|
|
6875
7179
|
}
|
|
6876
7180
|
|
|
6877
7181
|
// src/client/components/Toolbar.tsx
|
|
6878
|
-
import { useEffect as
|
|
6879
|
-
import { Fragment as
|
|
7182
|
+
import { useEffect as useEffect15, useLayoutEffect as useLayoutEffect3, useRef as useRef15, useState as useState13 } from "react";
|
|
7183
|
+
import { Fragment as Fragment10, jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
6880
7184
|
var TOOLS = [
|
|
6881
|
-
{ tool: "select", hintId: "tool-select", label: "Select", icon: (n) => /* @__PURE__ */
|
|
6882
|
-
{ tool: "copy", hintId: "tool-copy", label: "Rewrite text", icon: (n) => /* @__PURE__ */
|
|
6883
|
-
{ tool: "comment", hintId: "tool-comment", label: "Comment", icon: (n) => /* @__PURE__ */
|
|
6884
|
-
{ tool: "image", hintId: "tool-image", label: "Replace image", icon: (n) => /* @__PURE__ */
|
|
7185
|
+
{ tool: "select", hintId: "tool-select", label: "Select", icon: (n) => /* @__PURE__ */ jsx17(IconTarget, { size: n }) },
|
|
7186
|
+
{ tool: "copy", hintId: "tool-copy", label: "Rewrite text", icon: (n) => /* @__PURE__ */ jsx17(IconText, { size: n }) },
|
|
7187
|
+
{ tool: "comment", hintId: "tool-comment", label: "Comment", icon: (n) => /* @__PURE__ */ jsx17(IconComment, { size: n }) },
|
|
7188
|
+
{ tool: "image", hintId: "tool-image", label: "Replace image", icon: (n) => /* @__PURE__ */ jsx17(IconImage, { size: n }) }
|
|
6885
7189
|
];
|
|
6886
7190
|
var POS_KEY2 = "review-kit:toolbar-pos";
|
|
6887
7191
|
var DRAG_THRESHOLD2 = 6;
|
|
@@ -6890,9 +7194,9 @@ function Toolbar() {
|
|
|
6890
7194
|
const hasPeers = syncStatus !== "disabled" && peers.length > 0;
|
|
6891
7195
|
const dispatch = useDispatch();
|
|
6892
7196
|
const ref = useRef15(null);
|
|
6893
|
-
const [pos, setPos] =
|
|
7197
|
+
const [pos, setPos] = useState13(() => readStoredPos(POS_KEY2));
|
|
6894
7198
|
const drag = useRef15(null);
|
|
6895
|
-
const [dragging, setDragging] =
|
|
7199
|
+
const [dragging, setDragging] = useState13(false);
|
|
6896
7200
|
const justDragged = useRef15(false);
|
|
6897
7201
|
const visible = editor === null || selection !== null;
|
|
6898
7202
|
const applyPos = (next, persist) => {
|
|
@@ -6906,7 +7210,7 @@ function Toolbar() {
|
|
|
6906
7210
|
const clamped = clampPos(pos.x, pos.y, el.offsetWidth, el.offsetHeight);
|
|
6907
7211
|
if (clamped.x !== pos.x || clamped.y !== pos.y) applyPos(clamped, true);
|
|
6908
7212
|
}, [pos, selection, hasPeers, visible]);
|
|
6909
|
-
|
|
7213
|
+
useEffect15(() => {
|
|
6910
7214
|
const onResize = () => {
|
|
6911
7215
|
const el = ref.current;
|
|
6912
7216
|
const current = readStoredPos(POS_KEY2);
|
|
@@ -7019,7 +7323,7 @@ function Toolbar() {
|
|
|
7019
7323
|
mode === "pick" && selection === null ? "rk-ghost" : ""
|
|
7020
7324
|
].filter(Boolean).join(" ");
|
|
7021
7325
|
const style = pos !== null ? { left: 0, top: 0, translate: `${pos.x}px ${pos.y}px` } : void 0;
|
|
7022
|
-
return /* @__PURE__ */
|
|
7326
|
+
return /* @__PURE__ */ jsxs16(
|
|
7023
7327
|
"div",
|
|
7024
7328
|
{
|
|
7025
7329
|
ref,
|
|
@@ -7030,7 +7334,7 @@ function Toolbar() {
|
|
|
7030
7334
|
onPointerDown,
|
|
7031
7335
|
onClickCapture,
|
|
7032
7336
|
children: [
|
|
7033
|
-
/* @__PURE__ */
|
|
7337
|
+
/* @__PURE__ */ jsx17(
|
|
7034
7338
|
"button",
|
|
7035
7339
|
{
|
|
7036
7340
|
type: "button",
|
|
@@ -7038,19 +7342,19 @@ function Toolbar() {
|
|
|
7038
7342
|
"aria-label": "Move the toolbar \u2014 drag, or use arrow keys; double-click to reset its position",
|
|
7039
7343
|
onKeyDown: onGripKeyDown,
|
|
7040
7344
|
onDoubleClick: () => applyPos(null, true),
|
|
7041
|
-
children: /* @__PURE__ */
|
|
7042
|
-
/* @__PURE__ */
|
|
7043
|
-
/* @__PURE__ */
|
|
7044
|
-
/* @__PURE__ */
|
|
7045
|
-
/* @__PURE__ */
|
|
7046
|
-
/* @__PURE__ */
|
|
7047
|
-
/* @__PURE__ */
|
|
7345
|
+
children: /* @__PURE__ */ jsxs16("svg", { width: "8", height: "14", viewBox: "0 0 8 14", "aria-hidden": "true", fill: "currentColor", children: [
|
|
7346
|
+
/* @__PURE__ */ jsx17("circle", { cx: "2", cy: "2", r: "1.1" }),
|
|
7347
|
+
/* @__PURE__ */ jsx17("circle", { cx: "6", cy: "2", r: "1.1" }),
|
|
7348
|
+
/* @__PURE__ */ jsx17("circle", { cx: "2", cy: "7", r: "1.1" }),
|
|
7349
|
+
/* @__PURE__ */ jsx17("circle", { cx: "6", cy: "7", r: "1.1" }),
|
|
7350
|
+
/* @__PURE__ */ jsx17("circle", { cx: "2", cy: "12", r: "1.1" }),
|
|
7351
|
+
/* @__PURE__ */ jsx17("circle", { cx: "6", cy: "12", r: "1.1" })
|
|
7048
7352
|
] })
|
|
7049
7353
|
}
|
|
7050
7354
|
),
|
|
7051
|
-
/* @__PURE__ */
|
|
7052
|
-
hasPeers && /* @__PURE__ */
|
|
7053
|
-
/* @__PURE__ */
|
|
7355
|
+
/* @__PURE__ */ jsx17(PresenceStrip, {}),
|
|
7356
|
+
hasPeers && /* @__PURE__ */ jsx17("span", { className: "rk-toolbar-sep" }),
|
|
7357
|
+
/* @__PURE__ */ jsx17("div", { className: "rk-seg rk-tool-seg", role: "group", "aria-label": "Tools", children: TOOLS.map((entry) => /* @__PURE__ */ jsx17(
|
|
7054
7358
|
"button",
|
|
7055
7359
|
{
|
|
7056
7360
|
type: "button",
|
|
@@ -7062,9 +7366,9 @@ function Toolbar() {
|
|
|
7062
7366
|
},
|
|
7063
7367
|
entry.tool
|
|
7064
7368
|
)) }),
|
|
7065
|
-
selection && /* @__PURE__ */
|
|
7066
|
-
selection && /* @__PURE__ */
|
|
7067
|
-
/* @__PURE__ */
|
|
7369
|
+
selection && /* @__PURE__ */ jsx17("span", { className: "rk-toolbar-sep" }),
|
|
7370
|
+
selection && /* @__PURE__ */ jsxs16(Fragment10, { children: [
|
|
7371
|
+
/* @__PURE__ */ jsxs16(
|
|
7068
7372
|
"button",
|
|
7069
7373
|
{
|
|
7070
7374
|
type: "button",
|
|
@@ -7073,12 +7377,12 @@ function Toolbar() {
|
|
|
7073
7377
|
title: `Rewrite text${keyHint("tool-copy")}`,
|
|
7074
7378
|
onClick: () => open("copy"),
|
|
7075
7379
|
children: [
|
|
7076
|
-
/* @__PURE__ */
|
|
7380
|
+
/* @__PURE__ */ jsx17(IconText, { size: 14 }),
|
|
7077
7381
|
" Rewrite"
|
|
7078
7382
|
]
|
|
7079
7383
|
}
|
|
7080
7384
|
),
|
|
7081
|
-
hasImage && /* @__PURE__ */
|
|
7385
|
+
hasImage && /* @__PURE__ */ jsxs16(
|
|
7082
7386
|
"button",
|
|
7083
7387
|
{
|
|
7084
7388
|
type: "button",
|
|
@@ -7087,12 +7391,12 @@ function Toolbar() {
|
|
|
7087
7391
|
title: `Replace image${keyHint("tool-image")}`,
|
|
7088
7392
|
onClick: () => open("image"),
|
|
7089
7393
|
children: [
|
|
7090
|
-
/* @__PURE__ */
|
|
7394
|
+
/* @__PURE__ */ jsx17(IconImage, { size: 14 }),
|
|
7091
7395
|
" Image"
|
|
7092
7396
|
]
|
|
7093
7397
|
}
|
|
7094
7398
|
),
|
|
7095
|
-
/* @__PURE__ */
|
|
7399
|
+
/* @__PURE__ */ jsxs16(
|
|
7096
7400
|
"button",
|
|
7097
7401
|
{
|
|
7098
7402
|
type: "button",
|
|
@@ -7101,32 +7405,32 @@ function Toolbar() {
|
|
|
7101
7405
|
title: `Comment${keyHint("tool-comment")}`,
|
|
7102
7406
|
onClick: () => open("comment"),
|
|
7103
7407
|
children: [
|
|
7104
|
-
/* @__PURE__ */
|
|
7408
|
+
/* @__PURE__ */ jsx17(IconComment, { size: 14 }),
|
|
7105
7409
|
" Comment"
|
|
7106
7410
|
]
|
|
7107
7411
|
}
|
|
7108
7412
|
),
|
|
7109
|
-
/* @__PURE__ */
|
|
7110
|
-
/* @__PURE__ */
|
|
7413
|
+
/* @__PURE__ */ jsxs16("button", { type: "button", role: "menuitem", className: "rk-toolbar-btn", onClick: () => open("style"), children: [
|
|
7414
|
+
/* @__PURE__ */ jsx17(IconStyle, { size: 14 }),
|
|
7111
7415
|
" Style"
|
|
7112
7416
|
] }),
|
|
7113
|
-
/* @__PURE__ */
|
|
7114
|
-
/* @__PURE__ */
|
|
7417
|
+
/* @__PURE__ */ jsxs16("button", { type: "button", role: "menuitem", className: "rk-toolbar-btn", onClick: () => open("move"), children: [
|
|
7418
|
+
/* @__PURE__ */ jsx17(IconMove, { size: 14 }),
|
|
7115
7419
|
" Move"
|
|
7116
7420
|
] }),
|
|
7117
|
-
/* @__PURE__ */
|
|
7118
|
-
/* @__PURE__ */
|
|
7421
|
+
/* @__PURE__ */ jsxs16("button", { type: "button", role: "menuitem", className: "rk-toolbar-btn rk-danger", onClick: () => open("delete"), children: [
|
|
7422
|
+
/* @__PURE__ */ jsx17(IconTrash, { size: 14 }),
|
|
7119
7423
|
" Delete"
|
|
7120
7424
|
] }),
|
|
7121
|
-
/* @__PURE__ */
|
|
7122
|
-
/* @__PURE__ */
|
|
7425
|
+
/* @__PURE__ */ jsx17("span", { className: "rk-toolbar-sep" }),
|
|
7426
|
+
/* @__PURE__ */ jsx17(
|
|
7123
7427
|
"button",
|
|
7124
7428
|
{
|
|
7125
7429
|
type: "button",
|
|
7126
7430
|
className: "rk-icon-btn",
|
|
7127
7431
|
"aria-label": "Deselect",
|
|
7128
7432
|
onClick: () => dispatch({ type: "SELECT", selection: null }),
|
|
7129
|
-
children: /* @__PURE__ */
|
|
7433
|
+
children: /* @__PURE__ */ jsx17(IconClose, { size: 13 })
|
|
7130
7434
|
}
|
|
7131
7435
|
)
|
|
7132
7436
|
] })
|
|
@@ -7136,27 +7440,27 @@ function Toolbar() {
|
|
|
7136
7440
|
}
|
|
7137
7441
|
|
|
7138
7442
|
// src/client/components/Toast.tsx
|
|
7139
|
-
import { useEffect as
|
|
7140
|
-
import { jsx as
|
|
7443
|
+
import { useEffect as useEffect16 } from "react";
|
|
7444
|
+
import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
7141
7445
|
function ToastRow({ toast: toast2 }) {
|
|
7142
7446
|
const dispatch = useDispatch();
|
|
7143
|
-
|
|
7447
|
+
useEffect16(() => {
|
|
7144
7448
|
const timer = window.setTimeout(() => dispatch({ type: "DISMISS_TOAST", id: toast2.id }), 3500);
|
|
7145
7449
|
return () => window.clearTimeout(timer);
|
|
7146
7450
|
}, [toast2.id, dispatch]);
|
|
7147
|
-
return /* @__PURE__ */
|
|
7148
|
-
toast2.tone === "success" ? /* @__PURE__ */
|
|
7451
|
+
return /* @__PURE__ */ jsxs17("div", { className: `rk-toast rk-${toast2.tone}`, role: "status", children: [
|
|
7452
|
+
toast2.tone === "success" ? /* @__PURE__ */ jsx18(IconCheck, { size: 13 }) : toast2.tone === "error" ? /* @__PURE__ */ jsx18(IconWarning, { size: 13 }) : /* @__PURE__ */ jsx18(IconComment, { size: 13 }),
|
|
7149
7453
|
toast2.message
|
|
7150
7454
|
] });
|
|
7151
7455
|
}
|
|
7152
7456
|
function ToastHost() {
|
|
7153
7457
|
const { toasts } = useStore();
|
|
7154
7458
|
if (toasts.length === 0) return null;
|
|
7155
|
-
return /* @__PURE__ */
|
|
7459
|
+
return /* @__PURE__ */ jsx18("div", { className: "rk-toasts", "aria-live": "polite", children: toasts.map((toast2) => /* @__PURE__ */ jsx18(ToastRow, { toast: toast2 }, toast2.id)) });
|
|
7156
7460
|
}
|
|
7157
7461
|
|
|
7158
7462
|
// src/client/App.tsx
|
|
7159
|
-
import { jsx as
|
|
7463
|
+
import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
7160
7464
|
function App() {
|
|
7161
7465
|
const state = useStore();
|
|
7162
7466
|
const rawDispatch = useDispatch();
|
|
@@ -7166,10 +7470,10 @@ function App() {
|
|
|
7166
7470
|
const storageKey = config.storageKey ?? defaultStorageKey();
|
|
7167
7471
|
useAppliedPreview(state, dispatch);
|
|
7168
7472
|
useEmblemaAutoPush(state, dispatch, config);
|
|
7169
|
-
|
|
7473
|
+
useEffect17(() => {
|
|
7170
7474
|
setEffectAssetsUrl(config.fxAssetsUrl);
|
|
7171
7475
|
}, [config.fxAssetsUrl]);
|
|
7172
|
-
|
|
7476
|
+
useEffect17(() => {
|
|
7173
7477
|
let cancelled = false;
|
|
7174
7478
|
void loadSession(storageKey).then((stored) => {
|
|
7175
7479
|
if (cancelled) return;
|
|
@@ -7187,7 +7491,7 @@ function App() {
|
|
|
7187
7491
|
};
|
|
7188
7492
|
}, [storageKey, config.defaultAuthor, dispatch]);
|
|
7189
7493
|
const { session } = state;
|
|
7190
|
-
|
|
7494
|
+
useEffect17(() => {
|
|
7191
7495
|
if (!session) return;
|
|
7192
7496
|
if (saveTimer.current !== null) window.clearTimeout(saveTimer.current);
|
|
7193
7497
|
saveTimer.current = window.setTimeout(() => {
|
|
@@ -7198,9 +7502,9 @@ function App() {
|
|
|
7198
7502
|
if (saveTimer.current !== null) window.clearTimeout(saveTimer.current);
|
|
7199
7503
|
};
|
|
7200
7504
|
}, [session, storageKey, config]);
|
|
7201
|
-
|
|
7505
|
+
useEffect17(() => trackPointer(), []);
|
|
7202
7506
|
const focusHandled = useRef16(false);
|
|
7203
|
-
|
|
7507
|
+
useEffect17(() => {
|
|
7204
7508
|
if (!session || focusHandled.current) return;
|
|
7205
7509
|
focusHandled.current = true;
|
|
7206
7510
|
const id = takeFocusItem();
|
|
@@ -7225,7 +7529,7 @@ function App() {
|
|
|
7225
7529
|
cancelled = true;
|
|
7226
7530
|
};
|
|
7227
7531
|
}, [session, dispatch]);
|
|
7228
|
-
|
|
7532
|
+
useEffect17(() => {
|
|
7229
7533
|
let last = window.location.pathname;
|
|
7230
7534
|
const check = () => {
|
|
7231
7535
|
if (window.location.pathname !== last) {
|
|
@@ -7242,7 +7546,7 @@ function App() {
|
|
|
7242
7546
|
}, [dispatch]);
|
|
7243
7547
|
const stateRef = useRef16(state);
|
|
7244
7548
|
stateRef.current = state;
|
|
7245
|
-
|
|
7549
|
+
useEffect17(() => {
|
|
7246
7550
|
const onKeyDown = (event) => {
|
|
7247
7551
|
const current = stateRef.current;
|
|
7248
7552
|
for (const def of SHORTCUTS) {
|
|
@@ -7257,7 +7561,7 @@ function App() {
|
|
|
7257
7561
|
document.addEventListener("keydown", onKeyDown);
|
|
7258
7562
|
return () => document.removeEventListener("keydown", onKeyDown);
|
|
7259
7563
|
}, [dispatch]);
|
|
7260
|
-
|
|
7564
|
+
useEffect17(() => {
|
|
7261
7565
|
if (!state.editor) return;
|
|
7262
7566
|
const editorEl = state.editor.element;
|
|
7263
7567
|
const onPointerDown = (event) => {
|
|
@@ -7270,32 +7574,33 @@ function App() {
|
|
|
7270
7574
|
}, [state.editor, dispatch]);
|
|
7271
7575
|
if (!session) return null;
|
|
7272
7576
|
if (state.hidden) {
|
|
7273
|
-
return /* @__PURE__ */
|
|
7577
|
+
return /* @__PURE__ */ jsx19(DispatchContext.Provider, { value: dispatch, children: null });
|
|
7274
7578
|
}
|
|
7275
|
-
return /* @__PURE__ */
|
|
7276
|
-
/* @__PURE__ */
|
|
7277
|
-
/* @__PURE__ */
|
|
7278
|
-
/* @__PURE__ */
|
|
7279
|
-
state.editor?.kind === "copy" && /* @__PURE__ */
|
|
7280
|
-
state.editor?.kind === "image" && /* @__PURE__ */
|
|
7281
|
-
state.editor && state.editor.kind !== "copy" && state.editor.kind !== "image" && /* @__PURE__ */
|
|
7282
|
-
/* @__PURE__ */
|
|
7283
|
-
/* @__PURE__ */
|
|
7284
|
-
/* @__PURE__ */
|
|
7285
|
-
/* @__PURE__ */
|
|
7286
|
-
/* @__PURE__ */
|
|
7287
|
-
/* @__PURE__ */
|
|
7288
|
-
/* @__PURE__ */
|
|
7289
|
-
/* @__PURE__ */
|
|
7290
|
-
/* @__PURE__ */
|
|
7579
|
+
return /* @__PURE__ */ jsxs18(DispatchContext.Provider, { value: dispatch, children: [
|
|
7580
|
+
/* @__PURE__ */ jsx19(PickLayer, {}),
|
|
7581
|
+
/* @__PURE__ */ jsx19(PeerCursors, {}),
|
|
7582
|
+
/* @__PURE__ */ jsx19(Toolbar, {}),
|
|
7583
|
+
state.editor?.kind === "copy" && /* @__PURE__ */ jsx19(InlineEditor, { editor: state.editor }),
|
|
7584
|
+
state.editor?.kind === "image" && /* @__PURE__ */ jsx19(ImageEditor, { editor: state.editor }),
|
|
7585
|
+
state.editor && state.editor.kind !== "copy" && state.editor.kind !== "image" && /* @__PURE__ */ jsx19(NoteComposer, { editor: state.editor }),
|
|
7586
|
+
/* @__PURE__ */ jsx19(Pins, {}),
|
|
7587
|
+
/* @__PURE__ */ jsx19(QuickComment, {}),
|
|
7588
|
+
/* @__PURE__ */ jsx19(Panel, {}),
|
|
7589
|
+
/* @__PURE__ */ jsx19(Badge, {}),
|
|
7590
|
+
/* @__PURE__ */ jsx19(CoachMark, {}),
|
|
7591
|
+
/* @__PURE__ */ jsx19(CheatSheet, {}),
|
|
7592
|
+
/* @__PURE__ */ jsx19(EmblemaConnect, {}),
|
|
7593
|
+
/* @__PURE__ */ jsx19(TerminalConnect, {}),
|
|
7594
|
+
/* @__PURE__ */ jsx19(ConfirmHost, {}),
|
|
7595
|
+
/* @__PURE__ */ jsx19(ToastHost, {})
|
|
7291
7596
|
] });
|
|
7292
7597
|
}
|
|
7293
7598
|
|
|
7294
7599
|
// src/client/ReviewKit.tsx
|
|
7295
|
-
import { jsx as
|
|
7600
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
7296
7601
|
function ShadowHost({ config }) {
|
|
7297
|
-
const [mount, setMount] =
|
|
7298
|
-
|
|
7602
|
+
const [mount, setMount] = useState14(null);
|
|
7603
|
+
useEffect18(() => {
|
|
7299
7604
|
const host = document.createElement("div");
|
|
7300
7605
|
host.setAttribute(HOST_ATTR, "");
|
|
7301
7606
|
host.style.position = "fixed";
|
|
@@ -7331,15 +7636,15 @@ function ShadowHost({ config }) {
|
|
|
7331
7636
|
}, []);
|
|
7332
7637
|
if (!mount) return null;
|
|
7333
7638
|
return createPortal(
|
|
7334
|
-
/* @__PURE__ */
|
|
7639
|
+
/* @__PURE__ */ jsx20(StoreProvider, { config, children: /* @__PURE__ */ jsx20(App, {}) }),
|
|
7335
7640
|
mount
|
|
7336
7641
|
);
|
|
7337
7642
|
}
|
|
7338
7643
|
function ReviewKit(props) {
|
|
7339
|
-
const [active, setActive] =
|
|
7644
|
+
const [active, setActive] = useState14(false);
|
|
7340
7645
|
const { enabled, token, allowedHosts, devAutoOn } = props;
|
|
7341
7646
|
const hostsKey = allowedHosts?.join("\0") ?? "";
|
|
7342
|
-
|
|
7647
|
+
useEffect18(() => {
|
|
7343
7648
|
if (enabled === false) {
|
|
7344
7649
|
setActive(false);
|
|
7345
7650
|
return;
|
|
@@ -7350,7 +7655,7 @@ function ReviewKit(props) {
|
|
|
7350
7655
|
return () => window.removeEventListener(DEACTIVATE_EVENT, onDeactivate);
|
|
7351
7656
|
}, [enabled, token, devAutoOn, hostsKey]);
|
|
7352
7657
|
if (enabled === false || !active) return null;
|
|
7353
|
-
return /* @__PURE__ */
|
|
7658
|
+
return /* @__PURE__ */ jsx20(ShadowHost, { config: props });
|
|
7354
7659
|
}
|
|
7355
7660
|
|
|
7356
7661
|
export {
|
|
@@ -7363,4 +7668,4 @@ export {
|
|
|
7363
7668
|
importSessionFile,
|
|
7364
7669
|
ReviewKit
|
|
7365
7670
|
};
|
|
7366
|
-
//# sourceMappingURL=chunk-
|
|
7671
|
+
//# sourceMappingURL=chunk-VNRVRNZX.js.map
|