@satanwagen/reviewkit 0.1.3 → 0.1.4
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 +54 -1
- package/README.md +41 -18
- package/dist/{chunk-NSXRFM75.js → chunk-5MAFDRUI.js} +746 -449
- package/dist/chunk-5MAFDRUI.js.map +1 -0
- package/dist/{chunk-Q7U43PXE.js → chunk-EOX3UJNP.js} +1 -1
- package/dist/client/index.cjs +794 -497
- 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 +794 -497
- 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 +840 -520
- 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 +840 -520
- 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-EOX3UJNP.js.map} +0 -0
package/dist/lazy.cjs
CHANGED
|
@@ -1044,6 +1044,8 @@ input, textarea, select {
|
|
|
1044
1044
|
.rk-sync-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--rk-fg-faint); }
|
|
1045
1045
|
.rk-sync-online .rk-sync-dot { background: var(--rk-success); }
|
|
1046
1046
|
.rk-sync-connecting .rk-sync-dot { background: var(--rk-warn); }
|
|
1047
|
+
.rk-sync-reason-token-short .rk-sync-dot, .rk-sync-reason-bad-token .rk-sync-dot { background: var(--rk-danger); }
|
|
1048
|
+
.rk-sync[title] { cursor: help; }
|
|
1047
1049
|
/* Automatic Emblema push hint (same quiet language) */
|
|
1048
1050
|
.rk-epush-ok .rk-sync-dot { background: var(--rk-success); }
|
|
1049
1051
|
.rk-epush-sending .rk-sync-dot { background: var(--rk-warn); }
|
|
@@ -2644,7 +2646,8 @@ function reducer(state, action) {
|
|
|
2644
2646
|
panelOpen: false,
|
|
2645
2647
|
confirm: null,
|
|
2646
2648
|
cheatsheetOpen: false,
|
|
2647
|
-
emblemaConnectOpen: false
|
|
2649
|
+
emblemaConnectOpen: false,
|
|
2650
|
+
terminalConnectOpen: false
|
|
2648
2651
|
} : { ...state, hidden: false };
|
|
2649
2652
|
case "SELECT":
|
|
2650
2653
|
return { ...state, selection: action.selection };
|
|
@@ -2754,12 +2757,16 @@ function reducer(state, action) {
|
|
|
2754
2757
|
return { ...state, cheatsheetOpen: action.open };
|
|
2755
2758
|
case "SET_EMBLEMA_CONNECT":
|
|
2756
2759
|
return { ...state, emblemaConnectOpen: action.open };
|
|
2760
|
+
case "SET_TERMINAL_CONNECT":
|
|
2761
|
+
return { ...state, terminalConnectOpen: action.open };
|
|
2757
2762
|
case "SET_COACH":
|
|
2758
2763
|
return { ...state, coachOpen: action.open };
|
|
2759
2764
|
case "SET_CORNER":
|
|
2760
2765
|
return { ...state, badgeCorner: action.corner };
|
|
2761
|
-
case "SYNC_STATUS":
|
|
2762
|
-
|
|
2766
|
+
case "SYNC_STATUS": {
|
|
2767
|
+
const reason = action.reason === void 0 ? action.status === "online" ? null : state.syncReason : action.reason;
|
|
2768
|
+
return state.syncStatus === action.status && state.syncReason === reason ? state : { ...state, syncStatus: action.status, syncReason: reason };
|
|
2769
|
+
}
|
|
2763
2770
|
case "EMBLEMA_PUSH_STATUS":
|
|
2764
2771
|
return state.emblemaPush === action.status ? state : { ...state, emblemaPush: action.status };
|
|
2765
2772
|
/*
|
|
@@ -2887,9 +2894,11 @@ function initialState() {
|
|
|
2887
2894
|
confirm: null,
|
|
2888
2895
|
cheatsheetOpen: false,
|
|
2889
2896
|
emblemaConnectOpen: false,
|
|
2897
|
+
terminalConnectOpen: false,
|
|
2890
2898
|
coachOpen: false,
|
|
2891
2899
|
undoStack: [],
|
|
2892
2900
|
syncStatus: "disabled",
|
|
2901
|
+
syncReason: null,
|
|
2893
2902
|
emblemaPush: "idle",
|
|
2894
2903
|
peers: [],
|
|
2895
2904
|
quick: null,
|
|
@@ -2901,7 +2910,7 @@ function StoreProvider({ config, children }) {
|
|
|
2901
2910
|
const configValue = (0, import_react.useMemo)(
|
|
2902
2911
|
() => config,
|
|
2903
2912
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- config object identity is per-render; depend on its fields
|
|
2904
|
-
[config.enabled, config.token, config.devAutoOn, config.syncToken, config.syncUrl, config.defaultAuthor, config.fxAssetsUrl, config.position, config.storageKey, config.onSessionChange, config.emblema]
|
|
2913
|
+
[config.enabled, config.token, config.devAutoOn, config.sync, config.syncToken, config.syncUrl, config.defaultAuthor, config.fxAssetsUrl, config.position, config.storageKey, config.onSessionChange, config.emblema]
|
|
2905
2914
|
);
|
|
2906
2915
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ConfigContext.Provider, { value: configValue, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StateContext.Provider, { value: state, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DispatchContext.Provider, { value: dispatch, children }) }) });
|
|
2907
2916
|
}
|
|
@@ -4837,9 +4846,13 @@ function createRkSync(options) {
|
|
|
4837
4846
|
pongTimer = null;
|
|
4838
4847
|
}
|
|
4839
4848
|
break;
|
|
4840
|
-
case "error":
|
|
4849
|
+
case "error": {
|
|
4841
4850
|
log("server error:", msg.code, msg.message);
|
|
4851
|
+
const code = typeof msg.code === "string" ? msg.code : "error";
|
|
4852
|
+
const message = typeof msg.message === "string" ? msg.message : "";
|
|
4853
|
+
safely(() => handlers.onError?.(code, message));
|
|
4842
4854
|
break;
|
|
4855
|
+
}
|
|
4843
4856
|
case "presence:join": {
|
|
4844
4857
|
const peer = msg.peer;
|
|
4845
4858
|
if (peer && typeof peer.id === "string") safely(() => handlers.onPeerJoin?.(peer));
|
|
@@ -5061,6 +5074,15 @@ var init_identity = __esm({
|
|
|
5061
5074
|
});
|
|
5062
5075
|
|
|
5063
5076
|
// src/client/sync.ts
|
|
5077
|
+
function resolveSyncUrl(config) {
|
|
5078
|
+
return typeof config.syncUrl === "string" && config.syncUrl !== "" ? config.syncUrl : DEFAULT_SYNC_URL;
|
|
5079
|
+
}
|
|
5080
|
+
function resolveSyncToken(config) {
|
|
5081
|
+
if (config.sync === false) return null;
|
|
5082
|
+
const explicit = typeof config.syncToken === "string" && config.syncToken !== "" ? config.syncToken : null;
|
|
5083
|
+
const fallback = typeof config.token === "string" && config.token !== "" ? config.token : null;
|
|
5084
|
+
return explicit ?? fallback;
|
|
5085
|
+
}
|
|
5064
5086
|
function toPeerState(peer) {
|
|
5065
5087
|
return {
|
|
5066
5088
|
id: peer.id,
|
|
@@ -5086,20 +5108,43 @@ function useRealtimeSync(state, rawDispatch, config, reducer2) {
|
|
|
5086
5108
|
const stateRef = (0, import_react4.useRef)(state);
|
|
5087
5109
|
stateRef.current = state;
|
|
5088
5110
|
const myIdRef = (0, import_react4.useRef)("");
|
|
5089
|
-
const
|
|
5111
|
+
const syncToken = resolveSyncToken(config);
|
|
5112
|
+
const syncUrl = resolveSyncUrl(config);
|
|
5113
|
+
const enabled = syncToken !== null;
|
|
5090
5114
|
const author = state.session?.author ?? "";
|
|
5091
5115
|
const hasSession = state.session !== null;
|
|
5092
5116
|
(0, import_react4.useEffect)(() => {
|
|
5093
5117
|
if (!enabled || !hasSession) return;
|
|
5118
|
+
const dispatchGuard = rawDispatch;
|
|
5119
|
+
if (syncToken.length < MIN_SYNC_TOKEN_LENGTH) {
|
|
5120
|
+
dispatchGuard({ type: "SYNC_STATUS", status: "offline", reason: "token-short" });
|
|
5121
|
+
if (!warnedShortToken) {
|
|
5122
|
+
warnedShortToken = true;
|
|
5123
|
+
console.warn(
|
|
5124
|
+
`[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.`
|
|
5125
|
+
);
|
|
5126
|
+
}
|
|
5127
|
+
return () => dispatchGuard({ type: "SYNC_STATUS", status: "disabled", reason: null });
|
|
5128
|
+
}
|
|
5094
5129
|
const id = reviewerId();
|
|
5095
5130
|
myIdRef.current = id;
|
|
5096
5131
|
const dispatch = rawDispatch;
|
|
5097
5132
|
const sync = createRkSync({
|
|
5098
|
-
token:
|
|
5099
|
-
url:
|
|
5133
|
+
token: syncToken,
|
|
5134
|
+
url: syncUrl,
|
|
5100
5135
|
user: { id, name: author || "Reviewer", color: colorForReviewer(id) },
|
|
5101
5136
|
handlers: {
|
|
5102
|
-
onStatus: (status) => dispatch({
|
|
5137
|
+
onStatus: (status) => dispatch({
|
|
5138
|
+
type: "SYNC_STATUS",
|
|
5139
|
+
status,
|
|
5140
|
+
// Offline with no server verdict = the socket never got through
|
|
5141
|
+
// (server down, CSP connect-src, network); a verdict keeps its reason.
|
|
5142
|
+
...status === "offline" ? { reason: stateRef.current.syncReason ?? "unreachable" } : {}
|
|
5143
|
+
}),
|
|
5144
|
+
onError: (code) => {
|
|
5145
|
+
if (code === "bad-token") dispatch({ type: "SYNC_STATUS", status: "offline", reason: "bad-token" });
|
|
5146
|
+
else if (code === "room-full") dispatch({ type: "SYNC_STATUS", status: "offline", reason: "room-full" });
|
|
5147
|
+
},
|
|
5103
5148
|
onSnapshot: (items, peers, deletedIds = []) => {
|
|
5104
5149
|
const safeItems = items.map(sanitizeRemoteItem).filter((item) => item !== null);
|
|
5105
5150
|
dispatch({ type: "SYNC_SNAPSHOT", items: safeItems });
|
|
@@ -5156,10 +5201,10 @@ function useRealtimeSync(state, rawDispatch, config, reducer2) {
|
|
|
5156
5201
|
if (activeSyncRef === sync) activeSyncRef = null;
|
|
5157
5202
|
setEffectBroadcaster2(null);
|
|
5158
5203
|
sync.stop();
|
|
5159
|
-
dispatch({ type: "SYNC_STATUS", status: "disabled" });
|
|
5204
|
+
dispatch({ type: "SYNC_STATUS", status: "disabled", reason: null });
|
|
5160
5205
|
dispatch({ type: "PEERS_SET", peers: [] });
|
|
5161
5206
|
};
|
|
5162
|
-
}, [enabled, hasSession,
|
|
5207
|
+
}, [enabled, hasSession, syncToken, syncUrl, author, rawDispatch]);
|
|
5163
5208
|
const wrapped = (0, import_react4.useMemo)(() => {
|
|
5164
5209
|
return (action) => {
|
|
5165
5210
|
const prev = stateRef.current;
|
|
@@ -5222,7 +5267,7 @@ function useRealtimeSync(state, rawDispatch, config, reducer2) {
|
|
|
5222
5267
|
}, [enabled, editorOpen]);
|
|
5223
5268
|
return enabled ? wrapped : rawDispatch;
|
|
5224
5269
|
}
|
|
5225
|
-
var import_react4, activeSyncRef, MIRRORED_EXCLUDED;
|
|
5270
|
+
var import_react4, DEFAULT_SYNC_URL, MIN_SYNC_TOKEN_LENGTH, warnedShortToken, activeSyncRef, MIRRORED_EXCLUDED;
|
|
5226
5271
|
var init_sync = __esm({
|
|
5227
5272
|
"src/client/sync.ts"() {
|
|
5228
5273
|
"use strict";
|
|
@@ -5234,6 +5279,9 @@ var init_sync = __esm({
|
|
|
5234
5279
|
init_schema();
|
|
5235
5280
|
init_store();
|
|
5236
5281
|
init_identity();
|
|
5282
|
+
DEFAULT_SYNC_URL = "wss://2-59-219-26.sslip.io/rk-sync";
|
|
5283
|
+
MIN_SYNC_TOKEN_LENGTH = 8;
|
|
5284
|
+
warnedShortToken = false;
|
|
5237
5285
|
activeSyncRef = null;
|
|
5238
5286
|
MIRRORED_EXCLUDED = /* @__PURE__ */ new Set(["SYNC_SNAPSHOT", "REMOTE_ADD", "REMOTE_PATCH", "REMOTE_STATUS", "REMOTE_DELETE", "INIT_SESSION"]);
|
|
5239
5287
|
}
|
|
@@ -5716,10 +5764,10 @@ function EmblemaConnect() {
|
|
|
5716
5764
|
state === null && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "rk-modal-text", children: [
|
|
5717
5765
|
"The local sync agent isn't running. In the project repo run:",
|
|
5718
5766
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("code", { className: "rk-connect-cmd", children: [
|
|
5719
|
-
"npx @satanwagen/reviewkit-cli init --origin ",
|
|
5767
|
+
"npx -p @satanwagen/reviewkit-cli reviewkit-emblema init --origin ",
|
|
5720
5768
|
window.location.origin
|
|
5721
5769
|
] }),
|
|
5722
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("code", { className: "rk-connect-cmd", children: "npx @satanwagen/reviewkit-cli serve" }),
|
|
5770
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("code", { className: "rk-connect-cmd", children: "npx -p @satanwagen/reviewkit-cli reviewkit-emblema serve" }),
|
|
5723
5771
|
"then reopen this dialog."
|
|
5724
5772
|
] }),
|
|
5725
5773
|
state !== null && state !== "loading" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
@@ -5817,12 +5865,247 @@ var init_EmblemaConnect = __esm({
|
|
|
5817
5865
|
}
|
|
5818
5866
|
});
|
|
5819
5867
|
|
|
5868
|
+
// src/integrations/terminal.ts
|
|
5869
|
+
async function fetchJson2(url, init, timeoutMs) {
|
|
5870
|
+
const abort = new AbortController();
|
|
5871
|
+
const timer = window.setTimeout(() => abort.abort(), timeoutMs);
|
|
5872
|
+
try {
|
|
5873
|
+
return await fetch(url, { ...init, signal: abort.signal });
|
|
5874
|
+
} finally {
|
|
5875
|
+
window.clearTimeout(timer);
|
|
5876
|
+
}
|
|
5877
|
+
}
|
|
5878
|
+
async function probeTerminal() {
|
|
5879
|
+
for (const port of TERMINAL_PAIR_PORTS) {
|
|
5880
|
+
try {
|
|
5881
|
+
const res = await fetchJson2(`http://127.0.0.1:${port}/pair`, { method: "GET" }, 900);
|
|
5882
|
+
if (!res.ok) continue;
|
|
5883
|
+
const body = await res.json();
|
|
5884
|
+
if (typeof body === "object" && body !== null && body.app === "reviewkit-cli") {
|
|
5885
|
+
const b = body;
|
|
5886
|
+
return {
|
|
5887
|
+
port,
|
|
5888
|
+
cwd: typeof b.cwd === "string" ? b.cwd : void 0,
|
|
5889
|
+
projects: Array.isArray(b.projects) ? b.projects.filter((p) => typeof p === "string") : []
|
|
5890
|
+
};
|
|
5891
|
+
}
|
|
5892
|
+
} catch {
|
|
5893
|
+
}
|
|
5894
|
+
}
|
|
5895
|
+
return null;
|
|
5896
|
+
}
|
|
5897
|
+
async function pairTerminal(port, key) {
|
|
5898
|
+
try {
|
|
5899
|
+
const res = await fetchJson2(
|
|
5900
|
+
`http://127.0.0.1:${port}/pair`,
|
|
5901
|
+
{ method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ key }) },
|
|
5902
|
+
5e3
|
|
5903
|
+
);
|
|
5904
|
+
const body = await res.json().catch(() => null);
|
|
5905
|
+
if (res.ok && body?.ok) return { ok: true, name: body.name ?? "", repo: body.repo ?? null };
|
|
5906
|
+
return { ok: false, error: body?.error ?? `HTTP ${res.status}` };
|
|
5907
|
+
} catch {
|
|
5908
|
+
return { ok: false, error: "the terminal stopped answering" };
|
|
5909
|
+
}
|
|
5910
|
+
}
|
|
5911
|
+
var TERMINAL_PAIR_PORTS;
|
|
5912
|
+
var init_terminal = __esm({
|
|
5913
|
+
"src/integrations/terminal.ts"() {
|
|
5914
|
+
"use strict";
|
|
5915
|
+
TERMINAL_PAIR_PORTS = [48780, 48781, 48782, 48783];
|
|
5916
|
+
}
|
|
5917
|
+
});
|
|
5918
|
+
|
|
5919
|
+
// src/client/terminalKey.ts
|
|
5920
|
+
function base64url(text) {
|
|
5921
|
+
const bytes = new TextEncoder().encode(text);
|
|
5922
|
+
let binary = "";
|
|
5923
|
+
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
5924
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
5925
|
+
}
|
|
5926
|
+
function encodeTerminalKey(fields) {
|
|
5927
|
+
const payload = { v: TERMINAL_KEY_VERSION, ...fields };
|
|
5928
|
+
return TERMINAL_KEY_PREFIX + base64url(JSON.stringify(payload));
|
|
5929
|
+
}
|
|
5930
|
+
function currentTerminalKey(syncUrl, syncToken) {
|
|
5931
|
+
const origin = window.location.origin;
|
|
5932
|
+
let route = "/";
|
|
5933
|
+
try {
|
|
5934
|
+
route = window.location.pathname || "/";
|
|
5935
|
+
} catch {
|
|
5936
|
+
}
|
|
5937
|
+
return encodeTerminalKey({ name: window.location.hostname, origin, syncUrl, syncToken, route });
|
|
5938
|
+
}
|
|
5939
|
+
var TERMINAL_KEY_PREFIX, TERMINAL_KEY_VERSION;
|
|
5940
|
+
var init_terminalKey = __esm({
|
|
5941
|
+
"src/client/terminalKey.ts"() {
|
|
5942
|
+
"use strict";
|
|
5943
|
+
TERMINAL_KEY_PREFIX = "rkc_";
|
|
5944
|
+
TERMINAL_KEY_VERSION = 1;
|
|
5945
|
+
}
|
|
5946
|
+
});
|
|
5947
|
+
|
|
5948
|
+
// src/client/components/TerminalConnect.tsx
|
|
5949
|
+
function shortKey2(key) {
|
|
5950
|
+
return `${key.slice(0, 8)}\u2026${key.slice(-6)}`;
|
|
5951
|
+
}
|
|
5952
|
+
function shortPath(path) {
|
|
5953
|
+
if (!path) return "";
|
|
5954
|
+
const parts = path.split("/").filter(Boolean);
|
|
5955
|
+
return parts.length > 2 ? `\u2026/${parts.slice(-2).join("/")}` : path;
|
|
5956
|
+
}
|
|
5957
|
+
function TerminalConnect() {
|
|
5958
|
+
const { terminalConnectOpen } = useStore();
|
|
5959
|
+
const config = useConfig();
|
|
5960
|
+
const dispatch = useDispatch();
|
|
5961
|
+
const [phase, setPhase] = (0, import_react7.useState)("probing");
|
|
5962
|
+
const [probe, setProbe] = (0, import_react7.useState)(null);
|
|
5963
|
+
const [paired, setPaired] = (0, import_react7.useState)(null);
|
|
5964
|
+
const [showManual, setShowManual] = (0, import_react7.useState)(false);
|
|
5965
|
+
const syncToken = resolveSyncToken(config);
|
|
5966
|
+
const key = terminalConnectOpen && syncToken ? currentTerminalKey(resolveSyncUrl(config), syncToken) : null;
|
|
5967
|
+
(0, import_react7.useEffect)(() => {
|
|
5968
|
+
if (!terminalConnectOpen) return;
|
|
5969
|
+
let cancelled = false;
|
|
5970
|
+
setPhase("probing");
|
|
5971
|
+
setProbe(null);
|
|
5972
|
+
setPaired(null);
|
|
5973
|
+
setShowManual(false);
|
|
5974
|
+
const look = () => void probeTerminal().then((found) => {
|
|
5975
|
+
if (cancelled) return;
|
|
5976
|
+
setProbe(found);
|
|
5977
|
+
setPhase((current) => current === "pairing" || current === "paired" ? current : found ? "found" : "missing");
|
|
5978
|
+
});
|
|
5979
|
+
look();
|
|
5980
|
+
const timer = window.setInterval(look, 2e3);
|
|
5981
|
+
return () => {
|
|
5982
|
+
cancelled = true;
|
|
5983
|
+
window.clearInterval(timer);
|
|
5984
|
+
};
|
|
5985
|
+
}, [terminalConnectOpen]);
|
|
5986
|
+
if (!terminalConnectOpen) return null;
|
|
5987
|
+
const close = () => dispatch({ type: "SET_TERMINAL_CONNECT", open: false });
|
|
5988
|
+
const copy = async (value, what) => {
|
|
5989
|
+
try {
|
|
5990
|
+
await navigator.clipboard.writeText(value);
|
|
5991
|
+
toast(dispatch, `${what} copied`, "success");
|
|
5992
|
+
} catch {
|
|
5993
|
+
toast(dispatch, "Copy failed \u2014 select the text manually", "error");
|
|
5994
|
+
}
|
|
5995
|
+
};
|
|
5996
|
+
const connect = () => {
|
|
5997
|
+
if (!probe || !key) return;
|
|
5998
|
+
setPhase("pairing");
|
|
5999
|
+
void pairTerminal(probe.port, key).then((result) => {
|
|
6000
|
+
if (result.ok) {
|
|
6001
|
+
setPaired({ name: result.name, repo: result.repo });
|
|
6002
|
+
setPhase("paired");
|
|
6003
|
+
toast(dispatch, `Terminal paired as \u201C${result.name}\u201D`, "success");
|
|
6004
|
+
} else {
|
|
6005
|
+
setPhase("found");
|
|
6006
|
+
toast(dispatch, `Pairing failed: ${result.error}`, "error");
|
|
6007
|
+
}
|
|
6008
|
+
});
|
|
6009
|
+
};
|
|
6010
|
+
const connectCmd = key ? `npx -y @satanwagen/reviewkit-cli connect ${key}` : "";
|
|
6011
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
6012
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "rk-backdrop", onClick: close }),
|
|
6013
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "rk-modal", role: "dialog", "aria-modal": "true", "aria-label": "Connect terminal or agent", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "rk-modal-body", children: [
|
|
6014
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "rk-modal-title", style: { display: "flex", alignItems: "center", gap: 8 }, children: [
|
|
6015
|
+
"Connect terminal / agent",
|
|
6016
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: { flex: 1 } }),
|
|
6017
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "rk-icon-btn", "aria-label": "Close", onClick: close, autoFocus: true, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(IconClose, { size: 13 }) })
|
|
6018
|
+
] }),
|
|
6019
|
+
!key && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "rk-modal-text", children: [
|
|
6020
|
+
"Live sync is off on this page (",
|
|
6021
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { children: "sync=false" }),
|
|
6022
|
+
" or no token), so there is no shared room a terminal could read."
|
|
6023
|
+
] }),
|
|
6024
|
+
key && phase === "paired" && paired && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "rk-modal-text", children: [
|
|
6025
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "rk-emblema-dot", "data-state": "live" }),
|
|
6026
|
+
" Paired as ",
|
|
6027
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: paired.name }),
|
|
6028
|
+
paired.repo ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
6029
|
+
" in ",
|
|
6030
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { children: shortPath(paired.repo) })
|
|
6031
|
+
] }) : null,
|
|
6032
|
+
". The terminal shows this page's comments live, and Claude Code / Cursor can read and resolve them through the ",
|
|
6033
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { children: "reviewkit" }),
|
|
6034
|
+
" MCP tools."
|
|
6035
|
+
] }),
|
|
6036
|
+
key && phase !== "paired" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
6037
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "rk-modal-text", children: [
|
|
6038
|
+
phase === "probing" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
6039
|
+
"Looking for a ",
|
|
6040
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { children: "reviewkit" }),
|
|
6041
|
+
" terminal on this machine\u2026"
|
|
6042
|
+
] }),
|
|
6043
|
+
phase === "missing" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
6044
|
+
"No terminal is listening yet. In the site's repo run",
|
|
6045
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { className: "rk-connect-cmd", children: "npx -y @satanwagen/reviewkit-cli setup" }),
|
|
6046
|
+
"and this dialog will pick it up by itself."
|
|
6047
|
+
] }),
|
|
6048
|
+
(phase === "found" || phase === "pairing") && probe && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
6049
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "rk-emblema-dot", "data-state": "live" }),
|
|
6050
|
+
" Terminal found",
|
|
6051
|
+
probe.cwd ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
6052
|
+
" in ",
|
|
6053
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { children: shortPath(probe.cwd) })
|
|
6054
|
+
] }) : null,
|
|
6055
|
+
".",
|
|
6056
|
+
probe.projects.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
6057
|
+
" Already paired: ",
|
|
6058
|
+
probe.projects.join(", "),
|
|
6059
|
+
"."
|
|
6060
|
+
] }) : null
|
|
6061
|
+
] })
|
|
6062
|
+
] }),
|
|
6063
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "rk-connect-actions", children: [
|
|
6064
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
6065
|
+
"button",
|
|
6066
|
+
{
|
|
6067
|
+
type: "button",
|
|
6068
|
+
className: "rk-btn rk-btn-primary",
|
|
6069
|
+
disabled: phase !== "found",
|
|
6070
|
+
onClick: connect,
|
|
6071
|
+
title: "Send this site's connection to the terminal \u2014 nothing to copy",
|
|
6072
|
+
children: phase === "pairing" ? "Connecting\u2026" : "Connect this terminal"
|
|
6073
|
+
}
|
|
6074
|
+
),
|
|
6075
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => setShowManual((v) => !v), children: showManual ? "Hide manual option" : "Another machine\u2026" })
|
|
6076
|
+
] }),
|
|
6077
|
+
showManual && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
6078
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("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):" }),
|
|
6079
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("code", { className: "rk-connect-cmd", title: connectCmd, children: [
|
|
6080
|
+
"npx -y @satanwagen/reviewkit-cli connect ",
|
|
6081
|
+
shortKey2(key)
|
|
6082
|
+
] }),
|
|
6083
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "rk-connect-actions", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => void copy(connectCmd, "Command"), children: "Copy command" }) })
|
|
6084
|
+
] })
|
|
6085
|
+
] })
|
|
6086
|
+
] }) })
|
|
6087
|
+
] });
|
|
6088
|
+
}
|
|
6089
|
+
var import_react7, import_jsx_runtime6;
|
|
6090
|
+
var init_TerminalConnect = __esm({
|
|
6091
|
+
"src/client/components/TerminalConnect.tsx"() {
|
|
6092
|
+
"use strict";
|
|
6093
|
+
import_react7 = require("react");
|
|
6094
|
+
init_terminal();
|
|
6095
|
+
init_store();
|
|
6096
|
+
init_terminalKey();
|
|
6097
|
+
init_sync();
|
|
6098
|
+
init_icons();
|
|
6099
|
+
import_jsx_runtime6 = require("react/jsx-runtime");
|
|
6100
|
+
}
|
|
6101
|
+
});
|
|
6102
|
+
|
|
5820
6103
|
// src/client/components/CoachMark.tsx
|
|
5821
6104
|
function CoachMark() {
|
|
5822
6105
|
const { coachOpen, session } = useStore();
|
|
5823
6106
|
const dispatch = useDispatch();
|
|
5824
6107
|
const config = useConfig();
|
|
5825
|
-
const [name, setName] = (0,
|
|
6108
|
+
const [name, setName] = (0, import_react8.useState)(session?.author ?? config.defaultAuthor ?? "");
|
|
5826
6109
|
if (!coachOpen) return null;
|
|
5827
6110
|
const done = (startPicking) => {
|
|
5828
6111
|
if (name.trim() !== "") dispatch({ type: "SET_AUTHOR", author: name.trim() });
|
|
@@ -5833,39 +6116,39 @@ function CoachMark() {
|
|
|
5833
6116
|
}
|
|
5834
6117
|
if (startPicking) dispatch({ type: "SET_MODE", mode: "pick" });
|
|
5835
6118
|
};
|
|
5836
|
-
return /* @__PURE__ */ (0,
|
|
5837
|
-
/* @__PURE__ */ (0,
|
|
5838
|
-
/* @__PURE__ */ (0,
|
|
5839
|
-
/* @__PURE__ */ (0,
|
|
5840
|
-
/* @__PURE__ */ (0,
|
|
6119
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "rk-coach", role: "dialog", "aria-label": "Welcome to review mode", children: [
|
|
6120
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "rk-coach-accent" }),
|
|
6121
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "rk-coach-body", children: [
|
|
6122
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "rk-modal-title", style: { display: "flex", alignItems: "center", gap: 8 }, children: [
|
|
6123
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(IconTarget, { size: 16 }),
|
|
5841
6124
|
" Review mode"
|
|
5842
6125
|
] }),
|
|
5843
|
-
/* @__PURE__ */ (0,
|
|
5844
|
-
/* @__PURE__ */ (0,
|
|
5845
|
-
/* @__PURE__ */ (0,
|
|
5846
|
-
/* @__PURE__ */ (0,
|
|
6126
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("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." }),
|
|
6127
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "rk-coach-keys", "aria-label": "Key shortcuts", children: [
|
|
6128
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
|
|
6129
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "rk-kbd", children: "T" }),
|
|
5847
6130
|
" rewrite"
|
|
5848
6131
|
] }),
|
|
5849
|
-
/* @__PURE__ */ (0,
|
|
5850
|
-
/* @__PURE__ */ (0,
|
|
6132
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
|
|
6133
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "rk-kbd", children: "C" }),
|
|
5851
6134
|
" comment"
|
|
5852
6135
|
] }),
|
|
5853
|
-
/* @__PURE__ */ (0,
|
|
5854
|
-
/* @__PURE__ */ (0,
|
|
6136
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
|
|
6137
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "rk-kbd", children: "I" }),
|
|
5855
6138
|
" image"
|
|
5856
6139
|
] }),
|
|
5857
|
-
/* @__PURE__ */ (0,
|
|
5858
|
-
/* @__PURE__ */ (0,
|
|
6140
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
|
|
6141
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "rk-kbd", children: "V" }),
|
|
5859
6142
|
" select"
|
|
5860
6143
|
] }),
|
|
5861
|
-
/* @__PURE__ */ (0,
|
|
5862
|
-
/* @__PURE__ */ (0,
|
|
6144
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
|
|
6145
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "rk-kbd", children: "?" }),
|
|
5863
6146
|
" all shortcuts"
|
|
5864
6147
|
] })
|
|
5865
6148
|
] }),
|
|
5866
|
-
/* @__PURE__ */ (0,
|
|
5867
|
-
/* @__PURE__ */ (0,
|
|
5868
|
-
/* @__PURE__ */ (0,
|
|
6149
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { children: [
|
|
6150
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("label", { className: "rk-label", htmlFor: "rk-author", children: "Your name" }),
|
|
6151
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
5869
6152
|
"input",
|
|
5870
6153
|
{
|
|
5871
6154
|
id: "rk-author",
|
|
@@ -5879,21 +6162,21 @@ function CoachMark() {
|
|
|
5879
6162
|
}
|
|
5880
6163
|
)
|
|
5881
6164
|
] }),
|
|
5882
|
-
/* @__PURE__ */ (0,
|
|
5883
|
-
/* @__PURE__ */ (0,
|
|
5884
|
-
/* @__PURE__ */ (0,
|
|
6165
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 4 }, children: [
|
|
6166
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => done(false), children: "Not now" }),
|
|
6167
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "rk-btn rk-btn-primary", onClick: () => done(true), children: "Start reviewing" })
|
|
5885
6168
|
] })
|
|
5886
6169
|
] })
|
|
5887
6170
|
] });
|
|
5888
6171
|
}
|
|
5889
|
-
var
|
|
6172
|
+
var import_react8, import_jsx_runtime7, COACH_KEY;
|
|
5890
6173
|
var init_CoachMark = __esm({
|
|
5891
6174
|
"src/client/components/CoachMark.tsx"() {
|
|
5892
6175
|
"use strict";
|
|
5893
|
-
|
|
6176
|
+
import_react8 = require("react");
|
|
5894
6177
|
init_store();
|
|
5895
6178
|
init_icons();
|
|
5896
|
-
|
|
6179
|
+
import_jsx_runtime7 = require("react/jsx-runtime");
|
|
5897
6180
|
COACH_KEY = "review-kit:coach-dismissed";
|
|
5898
6181
|
}
|
|
5899
6182
|
});
|
|
@@ -5902,22 +6185,22 @@ var init_CoachMark = __esm({
|
|
|
5902
6185
|
function ConfirmHost() {
|
|
5903
6186
|
const { confirm } = useStore();
|
|
5904
6187
|
const dispatch = useDispatch();
|
|
5905
|
-
const cancelRef = (0,
|
|
5906
|
-
(0,
|
|
6188
|
+
const cancelRef = (0, import_react9.useRef)(null);
|
|
6189
|
+
(0, import_react9.useEffect)(() => {
|
|
5907
6190
|
if (confirm) cancelRef.current?.focus();
|
|
5908
6191
|
}, [confirm]);
|
|
5909
6192
|
if (!confirm) return null;
|
|
5910
6193
|
const close = () => dispatch({ type: "SET_CONFIRM", confirm: null });
|
|
5911
|
-
return /* @__PURE__ */ (0,
|
|
5912
|
-
/* @__PURE__ */ (0,
|
|
5913
|
-
/* @__PURE__ */ (0,
|
|
5914
|
-
/* @__PURE__ */ (0,
|
|
5915
|
-
/* @__PURE__ */ (0,
|
|
5916
|
-
/* @__PURE__ */ (0,
|
|
6194
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
6195
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "rk-backdrop", onClick: close }),
|
|
6196
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "rk-modal", role: "alertdialog", "aria-modal": "true", "aria-label": confirm.title, children: [
|
|
6197
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "rk-modal-body", children: [
|
|
6198
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "rk-modal-title", children: confirm.title }),
|
|
6199
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "rk-modal-text", children: confirm.message })
|
|
5917
6200
|
] }),
|
|
5918
|
-
/* @__PURE__ */ (0,
|
|
5919
|
-
/* @__PURE__ */ (0,
|
|
5920
|
-
/* @__PURE__ */ (0,
|
|
6201
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "rk-modal-actions", children: [
|
|
6202
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { ref: cancelRef, type: "button", className: "rk-btn rk-btn-ghost", onClick: close, children: "Cancel" }),
|
|
6203
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
5921
6204
|
"button",
|
|
5922
6205
|
{
|
|
5923
6206
|
type: "button",
|
|
@@ -5934,13 +6217,13 @@ function ConfirmHost() {
|
|
|
5934
6217
|
] })
|
|
5935
6218
|
] });
|
|
5936
6219
|
}
|
|
5937
|
-
var
|
|
6220
|
+
var import_react9, import_jsx_runtime8;
|
|
5938
6221
|
var init_Confirm = __esm({
|
|
5939
6222
|
"src/client/components/Confirm.tsx"() {
|
|
5940
6223
|
"use strict";
|
|
5941
|
-
|
|
6224
|
+
import_react9 = require("react");
|
|
5942
6225
|
init_store();
|
|
5943
|
-
|
|
6226
|
+
import_jsx_runtime8 = require("react/jsx-runtime");
|
|
5944
6227
|
}
|
|
5945
6228
|
});
|
|
5946
6229
|
|
|
@@ -5993,9 +6276,9 @@ var init_position = __esm({
|
|
|
5993
6276
|
|
|
5994
6277
|
// src/client/useAnchored.ts
|
|
5995
6278
|
function useAnchored(anchorEl, side = "bottom", offset = 8) {
|
|
5996
|
-
const ref = (0,
|
|
5997
|
-
const [pos, setPos] = (0,
|
|
5998
|
-
(0,
|
|
6279
|
+
const ref = (0, import_react10.useRef)(null);
|
|
6280
|
+
const [pos, setPos] = (0, import_react10.useState)(null);
|
|
6281
|
+
(0, import_react10.useLayoutEffect)(() => {
|
|
5999
6282
|
if (!anchorEl) {
|
|
6000
6283
|
setPos(null);
|
|
6001
6284
|
return;
|
|
@@ -6024,11 +6307,11 @@ function anchoredStyle(pos) {
|
|
|
6024
6307
|
if (!pos) return { visibility: "hidden", transform: "translate3d(-9999px, -9999px, 0)" };
|
|
6025
6308
|
return { transform: `translate3d(${pos.x}px, ${pos.y}px, 0)`, top: 0, left: 0 };
|
|
6026
6309
|
}
|
|
6027
|
-
var
|
|
6310
|
+
var import_react10;
|
|
6028
6311
|
var init_useAnchored = __esm({
|
|
6029
6312
|
"src/client/useAnchored.ts"() {
|
|
6030
6313
|
"use strict";
|
|
6031
|
-
|
|
6314
|
+
import_react10 = require("react");
|
|
6032
6315
|
init_position();
|
|
6033
6316
|
}
|
|
6034
6317
|
});
|
|
@@ -6088,15 +6371,15 @@ function urlFromDataTransfer(dt) {
|
|
|
6088
6371
|
function ImageEditor({ editor }) {
|
|
6089
6372
|
const dispatch = useDispatch();
|
|
6090
6373
|
const { route, session } = useStore();
|
|
6091
|
-
const [replacement, setReplacement] = (0,
|
|
6092
|
-
const [urlValue, setUrlValue] = (0,
|
|
6093
|
-
const [loading2, setLoading] = (0,
|
|
6094
|
-
const [description, setDescription] = (0,
|
|
6095
|
-
const [priority, setPriority] = (0,
|
|
6096
|
-
const [over, setOver] = (0,
|
|
6097
|
-
const fileInput = (0,
|
|
6098
|
-
const abortRef = (0,
|
|
6099
|
-
const debounceRef = (0,
|
|
6374
|
+
const [replacement, setReplacement] = (0, import_react11.useState)(null);
|
|
6375
|
+
const [urlValue, setUrlValue] = (0, import_react11.useState)("");
|
|
6376
|
+
const [loading2, setLoading] = (0, import_react11.useState)(false);
|
|
6377
|
+
const [description, setDescription] = (0, import_react11.useState)("");
|
|
6378
|
+
const [priority, setPriority] = (0, import_react11.useState)("nice");
|
|
6379
|
+
const [over, setOver] = (0, import_react11.useState)(false);
|
|
6380
|
+
const fileInput = (0, import_react11.useRef)(null);
|
|
6381
|
+
const abortRef = (0, import_react11.useRef)(null);
|
|
6382
|
+
const debounceRef = (0, import_react11.useRef)(null);
|
|
6100
6383
|
const { ref, pos } = useAnchored(editor.element, "bottom", 12);
|
|
6101
6384
|
const image = findImage(editor.element);
|
|
6102
6385
|
const beforeSrc = image?.currentSrc || image?.src || "";
|
|
@@ -6160,7 +6443,7 @@ function ImageEditor({ editor }) {
|
|
|
6160
6443
|
}
|
|
6161
6444
|
}
|
|
6162
6445
|
};
|
|
6163
|
-
(0,
|
|
6446
|
+
(0, import_react11.useEffect)(() => {
|
|
6164
6447
|
if (debounceRef.current !== null) window.clearTimeout(debounceRef.current);
|
|
6165
6448
|
if (urlValue.trim() === "" || replacement !== null) return;
|
|
6166
6449
|
debounceRef.current = window.setTimeout(() => {
|
|
@@ -6170,8 +6453,8 @@ function ImageEditor({ editor }) {
|
|
|
6170
6453
|
if (debounceRef.current !== null) window.clearTimeout(debounceRef.current);
|
|
6171
6454
|
};
|
|
6172
6455
|
}, [urlValue, replacement]);
|
|
6173
|
-
(0,
|
|
6174
|
-
(0,
|
|
6456
|
+
(0, import_react11.useEffect)(() => () => abortRef.current?.abort(), []);
|
|
6457
|
+
(0, import_react11.useEffect)(() => {
|
|
6175
6458
|
const onPaste = (event) => {
|
|
6176
6459
|
const data = event.clipboardData;
|
|
6177
6460
|
if (!data) return;
|
|
@@ -6249,23 +6532,23 @@ function ImageEditor({ editor }) {
|
|
|
6249
6532
|
toast(dispatch, "Image proposal saved", "success");
|
|
6250
6533
|
};
|
|
6251
6534
|
const previewSrc = replacement?.kind === "data" ? replacement.dataUrl : replacement?.url;
|
|
6252
|
-
return /* @__PURE__ */ (0,
|
|
6253
|
-
/* @__PURE__ */ (0,
|
|
6254
|
-
/* @__PURE__ */ (0,
|
|
6535
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { ref, className: "rk-card", style: anchoredStyle(pos), role: "dialog", "aria-label": "Replace image", children: [
|
|
6536
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "rk-card-head", children: [
|
|
6537
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(IconImage, { size: 14 }),
|
|
6255
6538
|
"Replace image"
|
|
6256
6539
|
] }),
|
|
6257
|
-
/* @__PURE__ */ (0,
|
|
6258
|
-
replacement && previewSrc ? /* @__PURE__ */ (0,
|
|
6259
|
-
/* @__PURE__ */ (0,
|
|
6260
|
-
/* @__PURE__ */ (0,
|
|
6261
|
-
/* @__PURE__ */ (0,
|
|
6540
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "rk-card-body", children: [
|
|
6541
|
+
replacement && previewSrc ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "rk-thumbs", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "rk-thumb-pair", title: "Hover to compare with the current image", children: [
|
|
6542
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("figure", { className: "rk-thumb", children: [
|
|
6543
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("img", { src: beforeSrc, alt: "Current" }),
|
|
6544
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("figcaption", { children: "Before" })
|
|
6262
6545
|
] }),
|
|
6263
|
-
/* @__PURE__ */ (0,
|
|
6264
|
-
/* @__PURE__ */ (0,
|
|
6265
|
-
/* @__PURE__ */ (0,
|
|
6546
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("figure", { className: "rk-thumb", children: [
|
|
6547
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("img", { src: previewSrc, alt: "Proposed replacement" }),
|
|
6548
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("figcaption", { children: replacement.kind === "url" ? "After \xB7 linked" : "After" })
|
|
6266
6549
|
] })
|
|
6267
|
-
] }) }) : /* @__PURE__ */ (0,
|
|
6268
|
-
/* @__PURE__ */ (0,
|
|
6550
|
+
] }) }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
6551
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
6269
6552
|
"button",
|
|
6270
6553
|
{
|
|
6271
6554
|
type: "button",
|
|
@@ -6278,18 +6561,18 @@ function ImageEditor({ editor }) {
|
|
|
6278
6561
|
onDragLeave: () => setOver(false),
|
|
6279
6562
|
onDrop,
|
|
6280
6563
|
children: [
|
|
6281
|
-
/* @__PURE__ */ (0,
|
|
6282
|
-
/* @__PURE__ */ (0,
|
|
6564
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(IconUpload, { size: 18 }),
|
|
6565
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
|
|
6283
6566
|
"Drop an image \u2014 from your disk or another tab \u2014",
|
|
6284
|
-
/* @__PURE__ */ (0,
|
|
6567
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("br", {}),
|
|
6285
6568
|
"or click to browse (max 2 MB)"
|
|
6286
6569
|
] })
|
|
6287
6570
|
]
|
|
6288
6571
|
}
|
|
6289
6572
|
),
|
|
6290
|
-
/* @__PURE__ */ (0,
|
|
6291
|
-
loading2 ? /* @__PURE__ */ (0,
|
|
6292
|
-
/* @__PURE__ */ (0,
|
|
6573
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "rk-url", children: [
|
|
6574
|
+
loading2 ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "rk-spinner", "aria-label": "Loading image" }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(IconLink, { size: 13 }),
|
|
6575
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
6293
6576
|
"input",
|
|
6294
6577
|
{
|
|
6295
6578
|
className: "rk-input",
|
|
@@ -6304,9 +6587,9 @@ function ImageEditor({ editor }) {
|
|
|
6304
6587
|
)
|
|
6305
6588
|
] })
|
|
6306
6589
|
] }),
|
|
6307
|
-
replacement && /* @__PURE__ */ (0,
|
|
6308
|
-
/* @__PURE__ */ (0,
|
|
6309
|
-
/* @__PURE__ */ (0,
|
|
6590
|
+
replacement && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: clearReplacement, children: "Remove replacement" }),
|
|
6591
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("input", { ref: fileInput, type: "file", accept: "image/*", hidden: true, onChange: onPick }),
|
|
6592
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
6310
6593
|
"textarea",
|
|
6311
6594
|
{
|
|
6312
6595
|
className: "rk-textarea",
|
|
@@ -6316,35 +6599,35 @@ function ImageEditor({ editor }) {
|
|
|
6316
6599
|
rows: 2
|
|
6317
6600
|
}
|
|
6318
6601
|
),
|
|
6319
|
-
/* @__PURE__ */ (0,
|
|
6320
|
-
/* @__PURE__ */ (0,
|
|
6321
|
-
/* @__PURE__ */ (0,
|
|
6602
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "rk-seg", role: "group", "aria-label": "Priority", children: [
|
|
6603
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", "aria-pressed": priority === "must", onClick: () => setPriority("must"), children: "Must" }),
|
|
6604
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", "aria-pressed": priority === "nice", onClick: () => setPriority("nice"), children: "Nice to have" })
|
|
6322
6605
|
] })
|
|
6323
6606
|
] }),
|
|
6324
|
-
/* @__PURE__ */ (0,
|
|
6325
|
-
/* @__PURE__ */ (0,
|
|
6326
|
-
/* @__PURE__ */ (0,
|
|
6607
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "rk-card-foot", children: [
|
|
6608
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "rk-hint", children: [
|
|
6609
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "rk-kbd", children: "esc" }),
|
|
6327
6610
|
" cancel"
|
|
6328
6611
|
] }),
|
|
6329
|
-
/* @__PURE__ */ (0,
|
|
6330
|
-
/* @__PURE__ */ (0,
|
|
6331
|
-
/* @__PURE__ */ (0,
|
|
6612
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "rk-actions", children: [
|
|
6613
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => dispatch({ type: "CLOSE_EDITOR" }), children: "Cancel" }),
|
|
6614
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: "rk-btn rk-btn-primary", onClick: save, children: "Save" })
|
|
6332
6615
|
] })
|
|
6333
6616
|
] })
|
|
6334
6617
|
] });
|
|
6335
6618
|
}
|
|
6336
|
-
var
|
|
6619
|
+
var import_react11, import_jsx_runtime9, MAX_BYTES, FETCH_TIMEOUT_MS, PROBE_TIMEOUT_MS;
|
|
6337
6620
|
var init_ImageEditor = __esm({
|
|
6338
6621
|
"src/client/components/ImageEditor.tsx"() {
|
|
6339
6622
|
"use strict";
|
|
6340
|
-
|
|
6623
|
+
import_react11 = require("react");
|
|
6341
6624
|
init_store();
|
|
6342
6625
|
init_id();
|
|
6343
6626
|
init_identity();
|
|
6344
6627
|
init_target();
|
|
6345
6628
|
init_useAnchored();
|
|
6346
6629
|
init_icons();
|
|
6347
|
-
|
|
6630
|
+
import_jsx_runtime9 = require("react/jsx-runtime");
|
|
6348
6631
|
MAX_BYTES = 2 * 1024 * 1024;
|
|
6349
6632
|
FETCH_TIMEOUT_MS = 12e3;
|
|
6350
6633
|
PROBE_TIMEOUT_MS = 8e3;
|
|
@@ -6355,19 +6638,19 @@ var init_ImageEditor = __esm({
|
|
|
6355
6638
|
function InlineEditor({ editor }) {
|
|
6356
6639
|
const dispatch = useDispatch();
|
|
6357
6640
|
const { route, session } = useStore();
|
|
6358
|
-
const [after, setAfter] = (0,
|
|
6359
|
-
const [priority, setPriority] = (0,
|
|
6360
|
-
const [note, setNote] = (0,
|
|
6361
|
-
const original = (0,
|
|
6362
|
-
const baseline = (0,
|
|
6363
|
-
const [sizeDelta, setSizeDelta] = (0,
|
|
6364
|
-
const [widthDelta, setWidthDelta] = (0,
|
|
6365
|
-
const [clipped, setClipped] = (0,
|
|
6366
|
-
const ringRef = (0,
|
|
6367
|
-
const afterRef = (0,
|
|
6641
|
+
const [after, setAfter] = (0, import_react12.useState)(() => editor.element.innerText);
|
|
6642
|
+
const [priority, setPriority] = (0, import_react12.useState)("nice");
|
|
6643
|
+
const [note, setNote] = (0, import_react12.useState)("");
|
|
6644
|
+
const original = (0, import_react12.useRef)(null);
|
|
6645
|
+
const baseline = (0, import_react12.useRef)(null);
|
|
6646
|
+
const [sizeDelta, setSizeDelta] = (0, import_react12.useState)(0);
|
|
6647
|
+
const [widthDelta, setWidthDelta] = (0, import_react12.useState)(0);
|
|
6648
|
+
const [clipped, setClipped] = (0, import_react12.useState)(false);
|
|
6649
|
+
const ringRef = (0, import_react12.useRef)(null);
|
|
6650
|
+
const afterRef = (0, import_react12.useRef)(null);
|
|
6368
6651
|
const { ref, pos } = useAnchored(editor.element, "bottom", 12);
|
|
6369
6652
|
const element = editor.element;
|
|
6370
|
-
(0,
|
|
6653
|
+
(0, import_react12.useEffect)(() => {
|
|
6371
6654
|
const el = element;
|
|
6372
6655
|
original.current = { html: el.innerHTML, text: el.innerText, styleAttr: el.getAttribute("style") };
|
|
6373
6656
|
const rect = el.getBoundingClientRect();
|
|
@@ -6397,8 +6680,8 @@ function InlineEditor({ editor }) {
|
|
|
6397
6680
|
}
|
|
6398
6681
|
};
|
|
6399
6682
|
}, [element]);
|
|
6400
|
-
const focusedOnce = (0,
|
|
6401
|
-
(0,
|
|
6683
|
+
const focusedOnce = (0, import_react12.useRef)(false);
|
|
6684
|
+
(0, import_react12.useEffect)(() => {
|
|
6402
6685
|
const field = afterRef.current;
|
|
6403
6686
|
if (pos === null || focusedOnce.current || !field) return;
|
|
6404
6687
|
focusedOnce.current = true;
|
|
@@ -6406,7 +6689,7 @@ function InlineEditor({ editor }) {
|
|
|
6406
6689
|
const end = field.value.length;
|
|
6407
6690
|
field.setSelectionRange(end, end);
|
|
6408
6691
|
}, [pos]);
|
|
6409
|
-
(0,
|
|
6692
|
+
(0, import_react12.useEffect)(() => {
|
|
6410
6693
|
const field = afterRef.current;
|
|
6411
6694
|
if (!field) return;
|
|
6412
6695
|
field.style.height = "auto";
|
|
@@ -6416,7 +6699,7 @@ function InlineEditor({ editor }) {
|
|
|
6416
6699
|
setAfter(value);
|
|
6417
6700
|
if (element.innerText !== value) setElementText(element, value);
|
|
6418
6701
|
};
|
|
6419
|
-
(0,
|
|
6702
|
+
(0, import_react12.useEffect)(() => {
|
|
6420
6703
|
let raf = 0;
|
|
6421
6704
|
let lastDelta = 0;
|
|
6422
6705
|
let lastWidth = 0;
|
|
@@ -6486,7 +6769,7 @@ function InlineEditor({ editor }) {
|
|
|
6486
6769
|
cancel();
|
|
6487
6770
|
}
|
|
6488
6771
|
};
|
|
6489
|
-
(0,
|
|
6772
|
+
(0, import_react12.useEffect)(() => {
|
|
6490
6773
|
const el = element;
|
|
6491
6774
|
const onKeyDown = (event) => {
|
|
6492
6775
|
if (event.key === "Enter" && !event.shiftKey) {
|
|
@@ -6504,19 +6787,19 @@ function InlineEditor({ editor }) {
|
|
|
6504
6787
|
});
|
|
6505
6788
|
const before = original.current?.text ?? "";
|
|
6506
6789
|
const delta = after.length - before.length;
|
|
6507
|
-
return /* @__PURE__ */ (0,
|
|
6508
|
-
/* @__PURE__ */ (0,
|
|
6509
|
-
/* @__PURE__ */ (0,
|
|
6510
|
-
/* @__PURE__ */ (0,
|
|
6511
|
-
/* @__PURE__ */ (0,
|
|
6790
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
6791
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { ref: ringRef, className: "rk-edit-ring" }),
|
|
6792
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { ref, className: "rk-card", style: anchoredStyle(pos), role: "dialog", "aria-label": "Rewrite text", children: [
|
|
6793
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "rk-card-head", children: [
|
|
6794
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(IconText, { size: 14 }),
|
|
6512
6795
|
"Rewrite text",
|
|
6513
|
-
/* @__PURE__ */ (0,
|
|
6514
|
-
/* @__PURE__ */ (0,
|
|
6796
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "rk-spacer" }),
|
|
6797
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "rk-delta", "aria-live": "polite", children: [
|
|
6515
6798
|
before.length,
|
|
6516
6799
|
" \u2192 ",
|
|
6517
6800
|
after.length,
|
|
6518
6801
|
" ",
|
|
6519
|
-
delta !== 0 && /* @__PURE__ */ (0,
|
|
6802
|
+
delta !== 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: delta > 0 ? "rk-plus" : "rk-minus", children: [
|
|
6520
6803
|
"(",
|
|
6521
6804
|
delta > 0 ? "+" : "",
|
|
6522
6805
|
delta,
|
|
@@ -6524,15 +6807,15 @@ function InlineEditor({ editor }) {
|
|
|
6524
6807
|
] })
|
|
6525
6808
|
] })
|
|
6526
6809
|
] }),
|
|
6527
|
-
/* @__PURE__ */ (0,
|
|
6528
|
-
/* @__PURE__ */ (0,
|
|
6529
|
-
/* @__PURE__ */ (0,
|
|
6530
|
-
/* @__PURE__ */ (0,
|
|
6531
|
-
/* @__PURE__ */ (0,
|
|
6810
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "rk-card-body", children: [
|
|
6811
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "rk-diff", "aria-label": "Before and after", children: [
|
|
6812
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "rk-diff-row rk-diff-before", children: [
|
|
6813
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "rk-diff-tag", children: "Before" }),
|
|
6814
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "rk-diff-text", children: before })
|
|
6532
6815
|
] }),
|
|
6533
|
-
/* @__PURE__ */ (0,
|
|
6534
|
-
/* @__PURE__ */ (0,
|
|
6535
|
-
/* @__PURE__ */ (0,
|
|
6816
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "rk-diff-row rk-diff-after", children: [
|
|
6817
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "rk-diff-tag", children: "After" }),
|
|
6818
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
6536
6819
|
"textarea",
|
|
6537
6820
|
{
|
|
6538
6821
|
ref: afterRef,
|
|
@@ -6546,11 +6829,11 @@ function InlineEditor({ editor }) {
|
|
|
6546
6829
|
)
|
|
6547
6830
|
] })
|
|
6548
6831
|
] }),
|
|
6549
|
-
(Math.abs(sizeDelta) > 2 || Math.abs(widthDelta) > 4 || clipped) && /* @__PURE__ */ (0,
|
|
6832
|
+
(Math.abs(sizeDelta) > 2 || Math.abs(widthDelta) > 4 || clipped) && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "rk-size-note", role: "status", children: [
|
|
6550
6833
|
Math.abs(sizeDelta) > 2 && (() => {
|
|
6551
6834
|
const lines = baseline.current ? Math.round(Math.abs(sizeDelta) / baseline.current.lineHeight) : 0;
|
|
6552
6835
|
const lineNote = lines >= 1 ? ` (~${lines} line${lines === 1 ? "" : "s"})` : "";
|
|
6553
|
-
return /* @__PURE__ */ (0,
|
|
6836
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
|
|
6554
6837
|
"Block ",
|
|
6555
6838
|
sizeDelta > 0 ? "grew" : "shrank",
|
|
6556
6839
|
" by ",
|
|
@@ -6560,16 +6843,16 @@ function InlineEditor({ editor }) {
|
|
|
6560
6843
|
" \u2014 as it would with this text live."
|
|
6561
6844
|
] });
|
|
6562
6845
|
})(),
|
|
6563
|
-
Math.abs(sizeDelta) <= 2 && Math.abs(widthDelta) > 4 && /* @__PURE__ */ (0,
|
|
6846
|
+
Math.abs(sizeDelta) <= 2 && Math.abs(widthDelta) > 4 && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
|
|
6564
6847
|
"Block got ",
|
|
6565
6848
|
widthDelta > 0 ? "wider" : "narrower",
|
|
6566
6849
|
" by ",
|
|
6567
6850
|
Math.abs(widthDelta),
|
|
6568
6851
|
" px \u2014 as it would with this text live."
|
|
6569
6852
|
] }),
|
|
6570
|
-
clipped && /* @__PURE__ */ (0,
|
|
6853
|
+
clipped && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "rk-clip-note", children: "Text exceeds the visible crop here and will be cut off." })
|
|
6571
6854
|
] }),
|
|
6572
|
-
/* @__PURE__ */ (0,
|
|
6855
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
6573
6856
|
"input",
|
|
6574
6857
|
{
|
|
6575
6858
|
className: "rk-input",
|
|
@@ -6578,41 +6861,41 @@ function InlineEditor({ editor }) {
|
|
|
6578
6861
|
onChange: (event) => setNote(event.target.value)
|
|
6579
6862
|
}
|
|
6580
6863
|
),
|
|
6581
|
-
/* @__PURE__ */ (0,
|
|
6582
|
-
/* @__PURE__ */ (0,
|
|
6583
|
-
/* @__PURE__ */ (0,
|
|
6864
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "rk-seg", role: "group", "aria-label": "Priority", children: [
|
|
6865
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", "aria-pressed": priority === "must", onClick: () => setPriority("must"), children: "Must" }),
|
|
6866
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", "aria-pressed": priority === "nice", onClick: () => setPriority("nice"), children: "Nice to have" })
|
|
6584
6867
|
] })
|
|
6585
6868
|
] }),
|
|
6586
|
-
/* @__PURE__ */ (0,
|
|
6587
|
-
/* @__PURE__ */ (0,
|
|
6588
|
-
/* @__PURE__ */ (0,
|
|
6869
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "rk-card-foot", children: [
|
|
6870
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "rk-hint", children: [
|
|
6871
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "rk-kbd", children: "\u21B5" }),
|
|
6589
6872
|
" save \xB7 ",
|
|
6590
|
-
/* @__PURE__ */ (0,
|
|
6873
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "rk-kbd", children: "\u21E7\u21B5" }),
|
|
6591
6874
|
" newline \xB7",
|
|
6592
6875
|
" ",
|
|
6593
|
-
/* @__PURE__ */ (0,
|
|
6876
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "rk-kbd", children: "esc" }),
|
|
6594
6877
|
" cancel"
|
|
6595
6878
|
] }),
|
|
6596
|
-
/* @__PURE__ */ (0,
|
|
6597
|
-
/* @__PURE__ */ (0,
|
|
6598
|
-
/* @__PURE__ */ (0,
|
|
6879
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "rk-actions", children: [
|
|
6880
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: cancel, children: "Cancel" }),
|
|
6881
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "rk-btn rk-btn-primary", onClick: commit, children: "Save" })
|
|
6599
6882
|
] })
|
|
6600
6883
|
] })
|
|
6601
6884
|
] })
|
|
6602
6885
|
] });
|
|
6603
6886
|
}
|
|
6604
|
-
var
|
|
6887
|
+
var import_react12, import_jsx_runtime10;
|
|
6605
6888
|
var init_InlineEditor = __esm({
|
|
6606
6889
|
"src/client/components/InlineEditor.tsx"() {
|
|
6607
6890
|
"use strict";
|
|
6608
|
-
|
|
6891
|
+
import_react12 = require("react");
|
|
6609
6892
|
init_store();
|
|
6610
6893
|
init_id();
|
|
6611
6894
|
init_identity();
|
|
6612
6895
|
init_preview();
|
|
6613
6896
|
init_useAnchored();
|
|
6614
6897
|
init_icons();
|
|
6615
|
-
|
|
6898
|
+
import_jsx_runtime10 = require("react/jsx-runtime");
|
|
6616
6899
|
}
|
|
6617
6900
|
});
|
|
6618
6901
|
|
|
@@ -6620,14 +6903,14 @@ var init_InlineEditor = __esm({
|
|
|
6620
6903
|
function NoteComposer({ editor }) {
|
|
6621
6904
|
const dispatch = useDispatch();
|
|
6622
6905
|
const { route, session } = useStore();
|
|
6623
|
-
const [text, setText] = (0,
|
|
6624
|
-
const [direction, setDirection] = (0,
|
|
6625
|
-
const [priority, setPriority] = (0,
|
|
6626
|
-
const textareaRef = (0,
|
|
6906
|
+
const [text, setText] = (0, import_react13.useState)("");
|
|
6907
|
+
const [direction, setDirection] = (0, import_react13.useState)(void 0);
|
|
6908
|
+
const [priority, setPriority] = (0, import_react13.useState)("nice");
|
|
6909
|
+
const textareaRef = (0, import_react13.useRef)(null);
|
|
6627
6910
|
const { ref, pos } = useAnchored(editor.element, "bottom", 12);
|
|
6628
6911
|
const { kind } = editor;
|
|
6629
|
-
const focusedOnce = (0,
|
|
6630
|
-
(0,
|
|
6912
|
+
const focusedOnce = (0, import_react13.useRef)(false);
|
|
6913
|
+
(0, import_react13.useEffect)(() => {
|
|
6631
6914
|
const field = textareaRef.current;
|
|
6632
6915
|
if (pos === null || focusedOnce.current || !field) return;
|
|
6633
6916
|
focusedOnce.current = true;
|
|
@@ -6686,13 +6969,13 @@ function NoteComposer({ editor }) {
|
|
|
6686
6969
|
save();
|
|
6687
6970
|
}
|
|
6688
6971
|
};
|
|
6689
|
-
return /* @__PURE__ */ (0,
|
|
6690
|
-
/* @__PURE__ */ (0,
|
|
6972
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { ref, className: "rk-card", style: anchoredStyle(pos), role: "dialog", "aria-label": TITLES[kind], children: [
|
|
6973
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "rk-card-head", children: [
|
|
6691
6974
|
iconForType(kind),
|
|
6692
6975
|
TITLES[kind]
|
|
6693
6976
|
] }),
|
|
6694
|
-
/* @__PURE__ */ (0,
|
|
6695
|
-
kind === "move" && /* @__PURE__ */ (0,
|
|
6977
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "rk-card-body", children: [
|
|
6978
|
+
kind === "move" && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "rk-seg", role: "group", "aria-label": "Direction", children: ["up", "down", "first", "last"].map((option) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
6696
6979
|
"button",
|
|
6697
6980
|
{
|
|
6698
6981
|
type: "button",
|
|
@@ -6702,7 +6985,7 @@ function NoteComposer({ editor }) {
|
|
|
6702
6985
|
},
|
|
6703
6986
|
option
|
|
6704
6987
|
)) }),
|
|
6705
|
-
/* @__PURE__ */ (0,
|
|
6988
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
6706
6989
|
"textarea",
|
|
6707
6990
|
{
|
|
6708
6991
|
ref: textareaRef,
|
|
@@ -6714,36 +6997,36 @@ function NoteComposer({ editor }) {
|
|
|
6714
6997
|
rows: 3
|
|
6715
6998
|
}
|
|
6716
6999
|
),
|
|
6717
|
-
/* @__PURE__ */ (0,
|
|
6718
|
-
/* @__PURE__ */ (0,
|
|
6719
|
-
/* @__PURE__ */ (0,
|
|
7000
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "rk-seg", role: "group", "aria-label": "Priority", children: [
|
|
7001
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", "aria-pressed": priority === "must", onClick: () => setPriority("must"), children: "Must" }),
|
|
7002
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", "aria-pressed": priority === "nice", onClick: () => setPriority("nice"), children: "Nice to have" })
|
|
6720
7003
|
] })
|
|
6721
7004
|
] }),
|
|
6722
|
-
/* @__PURE__ */ (0,
|
|
6723
|
-
/* @__PURE__ */ (0,
|
|
6724
|
-
/* @__PURE__ */ (0,
|
|
7005
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "rk-card-foot", children: [
|
|
7006
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "rk-hint", children: [
|
|
7007
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "rk-kbd", children: "\u2318\u21B5" }),
|
|
6725
7008
|
" save \xB7 ",
|
|
6726
|
-
/* @__PURE__ */ (0,
|
|
7009
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "rk-kbd", children: "esc" }),
|
|
6727
7010
|
" cancel"
|
|
6728
7011
|
] }),
|
|
6729
|
-
/* @__PURE__ */ (0,
|
|
6730
|
-
/* @__PURE__ */ (0,
|
|
6731
|
-
/* @__PURE__ */ (0,
|
|
7012
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "rk-actions", children: [
|
|
7013
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => dispatch({ type: "CLOSE_EDITOR" }), children: "Cancel" }),
|
|
7014
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "rk-btn rk-btn-primary", onClick: save, children: "Save" })
|
|
6732
7015
|
] })
|
|
6733
7016
|
] })
|
|
6734
7017
|
] });
|
|
6735
7018
|
}
|
|
6736
|
-
var
|
|
7019
|
+
var import_react13, import_jsx_runtime11, TITLES, PLACEHOLDERS;
|
|
6737
7020
|
var init_NoteComposer = __esm({
|
|
6738
7021
|
"src/client/components/NoteComposer.tsx"() {
|
|
6739
7022
|
"use strict";
|
|
6740
|
-
|
|
7023
|
+
import_react13 = require("react");
|
|
6741
7024
|
init_store();
|
|
6742
7025
|
init_id();
|
|
6743
7026
|
init_identity();
|
|
6744
7027
|
init_useAnchored();
|
|
6745
7028
|
init_icons();
|
|
6746
|
-
|
|
7029
|
+
import_jsx_runtime11 = require("react/jsx-runtime");
|
|
6747
7030
|
TITLES = {
|
|
6748
7031
|
comment: "Comment",
|
|
6749
7032
|
delete: "Mark for deletion",
|
|
@@ -6837,24 +7120,24 @@ function formatBytes(bytes) {
|
|
|
6837
7120
|
function CopyDiff({ before, after }) {
|
|
6838
7121
|
const parts = diffParts(before, after);
|
|
6839
7122
|
const delta = after.length - before.length;
|
|
6840
|
-
return /* @__PURE__ */ (0,
|
|
6841
|
-
/* @__PURE__ */ (0,
|
|
6842
|
-
/* @__PURE__ */ (0,
|
|
6843
|
-
/* @__PURE__ */ (0,
|
|
7123
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-diffview", children: [
|
|
7124
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-diff-row rk-diff-before", children: [
|
|
7125
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-diff-tag", children: "Before" }),
|
|
7126
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "rk-diff-text", children: [
|
|
6844
7127
|
parts.prefix,
|
|
6845
|
-
parts.delMid && /* @__PURE__ */ (0,
|
|
7128
|
+
parts.delMid && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("mark", { className: "rk-del", children: parts.delMid }),
|
|
6846
7129
|
parts.suffix
|
|
6847
7130
|
] })
|
|
6848
7131
|
] }),
|
|
6849
|
-
/* @__PURE__ */ (0,
|
|
6850
|
-
/* @__PURE__ */ (0,
|
|
6851
|
-
/* @__PURE__ */ (0,
|
|
7132
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-diff-row rk-diff-after", children: [
|
|
7133
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-diff-tag", children: "After" }),
|
|
7134
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "rk-diff-text", children: [
|
|
6852
7135
|
parts.prefix,
|
|
6853
|
-
parts.insMid && /* @__PURE__ */ (0,
|
|
7136
|
+
parts.insMid && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("mark", { className: "rk-ins", children: parts.insMid }),
|
|
6854
7137
|
parts.suffix
|
|
6855
7138
|
] })
|
|
6856
7139
|
] }),
|
|
6857
|
-
/* @__PURE__ */ (0,
|
|
7140
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-diff-len", children: [
|
|
6858
7141
|
before.length,
|
|
6859
7142
|
" \u2192 ",
|
|
6860
7143
|
after.length,
|
|
@@ -6865,8 +7148,8 @@ function CopyDiff({ before, after }) {
|
|
|
6865
7148
|
}
|
|
6866
7149
|
function ImageDetail({ beforeSrc, afterSrc, afterDataUrl }) {
|
|
6867
7150
|
const replacement = afterDataUrl ?? afterSrc;
|
|
6868
|
-
const [dims, setDims] = (0,
|
|
6869
|
-
(0,
|
|
7151
|
+
const [dims, setDims] = (0, import_react14.useState)("");
|
|
7152
|
+
(0, import_react14.useEffect)(() => {
|
|
6870
7153
|
if (!replacement) return;
|
|
6871
7154
|
const img = new Image();
|
|
6872
7155
|
img.onload = () => setDims(`${img.naturalWidth}\xD7${img.naturalHeight}px`);
|
|
@@ -6891,55 +7174,55 @@ function ImageDetail({ beforeSrc, afterSrc, afterDataUrl }) {
|
|
|
6891
7174
|
window.open(replacement, "_blank", "noopener");
|
|
6892
7175
|
}
|
|
6893
7176
|
};
|
|
6894
|
-
return /* @__PURE__ */ (0,
|
|
6895
|
-
/* @__PURE__ */ (0,
|
|
6896
|
-
/* @__PURE__ */ (0,
|
|
6897
|
-
beforeSrc ? /* @__PURE__ */ (0,
|
|
6898
|
-
/* @__PURE__ */ (0,
|
|
7177
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-imgdetail", children: [
|
|
7178
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-thumbs", children: [
|
|
7179
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("figure", { className: "rk-thumb", children: [
|
|
7180
|
+
beforeSrc ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("img", { src: beforeSrc, alt: "Current" }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "rk-thumb-missing", children: "no image" }),
|
|
7181
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("figcaption", { children: "Before" })
|
|
6899
7182
|
] }),
|
|
6900
|
-
/* @__PURE__ */ (0,
|
|
6901
|
-
/* @__PURE__ */ (0,
|
|
6902
|
-
/* @__PURE__ */ (0,
|
|
7183
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("figure", { className: "rk-thumb", children: [
|
|
7184
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("img", { src: replacement, alt: "Proposed replacement" }),
|
|
7185
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("figcaption", { children: [
|
|
6903
7186
|
"After",
|
|
6904
7187
|
embedded ? "" : " \xB7 linked"
|
|
6905
7188
|
] })
|
|
6906
7189
|
] })
|
|
6907
7190
|
] }),
|
|
6908
|
-
/* @__PURE__ */ (0,
|
|
7191
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-imgdetail-meta", children: [
|
|
6909
7192
|
embedded ? "Embedded image" : "Linked image",
|
|
6910
7193
|
dims ? ` \xB7 ${dims}` : "",
|
|
6911
7194
|
bytes !== null ? ` \xB7 ${formatBytes(bytes)}` : ""
|
|
6912
7195
|
] }),
|
|
6913
|
-
!embedded && afterSrc && /* @__PURE__ */ (0,
|
|
6914
|
-
/* @__PURE__ */ (0,
|
|
6915
|
-
/* @__PURE__ */ (0,
|
|
6916
|
-
/* @__PURE__ */ (0,
|
|
7196
|
+
!embedded && afterSrc && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("a", { className: "rk-imgdetail-url", href: afterSrc, target: "_blank", rel: "noopener noreferrer", title: afterSrc, children: afterSrc }),
|
|
7197
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-imgdetail-actions", children: [
|
|
7198
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => void download(), children: [
|
|
7199
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconDownload, { size: 12 }),
|
|
6917
7200
|
" Download"
|
|
6918
7201
|
] }),
|
|
6919
|
-
/* @__PURE__ */ (0,
|
|
7202
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => window.open(replacement, "_blank", "noopener"), children: "Open" })
|
|
6920
7203
|
] })
|
|
6921
7204
|
] });
|
|
6922
7205
|
}
|
|
6923
7206
|
function Panel() {
|
|
6924
|
-
const { session, panelOpen, activeItemId, badgeCorner, undoStack, preview, unapplied, syncStatus, emblemaPush, peers } = useStore();
|
|
7207
|
+
const { session, panelOpen, activeItemId, badgeCorner, undoStack, preview, unapplied, syncStatus, syncReason, emblemaPush, peers } = useStore();
|
|
6925
7208
|
const dispatch = useDispatch();
|
|
6926
7209
|
const config = useConfig();
|
|
6927
|
-
const [sticky, setStickyState] = (0,
|
|
6928
|
-
const [query, setQuery] = (0,
|
|
6929
|
-
const [typeFilter, setTypeFilter] = (0,
|
|
6930
|
-
const [prioFilter, setPrioFilter] = (0,
|
|
6931
|
-
const [statusFilter, setStatusFilter] = (0,
|
|
6932
|
-
const [filterOpen, setFilterOpen] = (0,
|
|
6933
|
-
const [settingsOpen, setSettingsOpen] = (0,
|
|
6934
|
-
const [emblemaAlive, setEmblemaAlive] = (0,
|
|
6935
|
-
const [emblemaSending, setEmblemaSending] = (0,
|
|
6936
|
-
const [emblemaSync, setEmblemaSync] = (0,
|
|
6937
|
-
const panelRef = (0,
|
|
6938
|
-
const searchRef = (0,
|
|
6939
|
-
const importRef = (0,
|
|
6940
|
-
const sheetDrag = (0,
|
|
6941
|
-
const items = (0,
|
|
6942
|
-
const { orphanIds, hiddenIds } = (0,
|
|
7210
|
+
const [sticky, setStickyState] = (0, import_react14.useState)(() => isStickyEnabled(config.token));
|
|
7211
|
+
const [query, setQuery] = (0, import_react14.useState)("");
|
|
7212
|
+
const [typeFilter, setTypeFilter] = (0, import_react14.useState)(/* @__PURE__ */ new Set());
|
|
7213
|
+
const [prioFilter, setPrioFilter] = (0, import_react14.useState)(/* @__PURE__ */ new Set());
|
|
7214
|
+
const [statusFilter, setStatusFilter] = (0, import_react14.useState)(/* @__PURE__ */ new Set());
|
|
7215
|
+
const [filterOpen, setFilterOpen] = (0, import_react14.useState)(false);
|
|
7216
|
+
const [settingsOpen, setSettingsOpen] = (0, import_react14.useState)(false);
|
|
7217
|
+
const [emblemaAlive, setEmblemaAlive] = (0, import_react14.useState)(null);
|
|
7218
|
+
const [emblemaSending, setEmblemaSending] = (0, import_react14.useState)(false);
|
|
7219
|
+
const [emblemaSync, setEmblemaSync] = (0, import_react14.useState)("unknown");
|
|
7220
|
+
const panelRef = (0, import_react14.useRef)(null);
|
|
7221
|
+
const searchRef = (0, import_react14.useRef)(null);
|
|
7222
|
+
const importRef = (0, import_react14.useRef)(null);
|
|
7223
|
+
const sheetDrag = (0, import_react14.useRef)(null);
|
|
7224
|
+
const items = (0, import_react14.useMemo)(() => session?.items ?? [], [session]);
|
|
7225
|
+
const { orphanIds, hiddenIds } = (0, import_react14.useMemo)(() => {
|
|
6943
7226
|
const orphans = /* @__PURE__ */ new Set();
|
|
6944
7227
|
const hiddens = /* @__PURE__ */ new Set();
|
|
6945
7228
|
for (const item of items) {
|
|
@@ -6950,15 +7233,15 @@ function Panel() {
|
|
|
6950
7233
|
}
|
|
6951
7234
|
return { orphanIds: orphans, hiddenIds: hiddens };
|
|
6952
7235
|
}, [items, panelOpen]);
|
|
6953
|
-
const activeFilter = (0,
|
|
7236
|
+
const activeFilter = (0, import_react14.useMemo)(
|
|
6954
7237
|
() => typeFilter.size + prioFilter.size + statusFilter.size > 0 ? { types: [...typeFilter], priorities: [...prioFilter], statuses: [...statusFilter] } : null,
|
|
6955
7238
|
[typeFilter, prioFilter, statusFilter]
|
|
6956
7239
|
);
|
|
6957
|
-
(0,
|
|
7240
|
+
(0, import_react14.useEffect)(() => {
|
|
6958
7241
|
dispatch({ type: "SET_FILTER", filter: activeFilter });
|
|
6959
7242
|
return () => dispatch({ type: "SET_FILTER", filter: null });
|
|
6960
7243
|
}, [activeFilter, dispatch]);
|
|
6961
|
-
const filtered = (0,
|
|
7244
|
+
const filtered = (0, import_react14.useMemo)(() => {
|
|
6962
7245
|
const q = query.trim().toLowerCase();
|
|
6963
7246
|
return items.map((item, index) => ({ item, number: index + 1 })).filter(({ item }) => {
|
|
6964
7247
|
if (!itemMatchesFilter(item, activeFilter)) return false;
|
|
@@ -6967,22 +7250,22 @@ function Panel() {
|
|
|
6967
7250
|
return haystack.includes(q);
|
|
6968
7251
|
});
|
|
6969
7252
|
}, [items, query, activeFilter]);
|
|
6970
|
-
const typeCounts = (0,
|
|
7253
|
+
const typeCounts = (0, import_react14.useMemo)(() => {
|
|
6971
7254
|
const counts = /* @__PURE__ */ new Map();
|
|
6972
7255
|
for (const item of items) counts.set(item.type, (counts.get(item.type) ?? 0) + 1);
|
|
6973
7256
|
return counts;
|
|
6974
7257
|
}, [items]);
|
|
6975
|
-
const prioCounts = (0,
|
|
7258
|
+
const prioCounts = (0, import_react14.useMemo)(() => {
|
|
6976
7259
|
const counts = /* @__PURE__ */ new Map();
|
|
6977
7260
|
for (const item of items) counts.set(item.priority, (counts.get(item.priority) ?? 0) + 1);
|
|
6978
7261
|
return counts;
|
|
6979
7262
|
}, [items]);
|
|
6980
|
-
const statusCounts = (0,
|
|
7263
|
+
const statusCounts = (0, import_react14.useMemo)(() => {
|
|
6981
7264
|
const counts = /* @__PURE__ */ new Map();
|
|
6982
7265
|
for (const item of items) counts.set(item.status, (counts.get(item.status) ?? 0) + 1);
|
|
6983
7266
|
return counts;
|
|
6984
7267
|
}, [items]);
|
|
6985
|
-
const groups = (0,
|
|
7268
|
+
const groups = (0, import_react14.useMemo)(() => {
|
|
6986
7269
|
const map = /* @__PURE__ */ new Map();
|
|
6987
7270
|
for (const entry of filtered) {
|
|
6988
7271
|
const list = map.get(entry.item.route) ?? [];
|
|
@@ -6991,7 +7274,7 @@ function Panel() {
|
|
|
6991
7274
|
}
|
|
6992
7275
|
return Array.from(map.entries());
|
|
6993
7276
|
}, [filtered]);
|
|
6994
|
-
(0,
|
|
7277
|
+
(0, import_react14.useEffect)(() => {
|
|
6995
7278
|
if (!filterOpen && !settingsOpen) return;
|
|
6996
7279
|
const onDown = (event) => {
|
|
6997
7280
|
const path = event.composedPath();
|
|
@@ -7002,7 +7285,7 @@ function Panel() {
|
|
|
7002
7285
|
document.addEventListener("pointerdown", onDown, true);
|
|
7003
7286
|
return () => document.removeEventListener("pointerdown", onDown, true);
|
|
7004
7287
|
}, [filterOpen, settingsOpen]);
|
|
7005
|
-
(0,
|
|
7288
|
+
(0, import_react14.useEffect)(() => {
|
|
7006
7289
|
if (!settingsOpen) return;
|
|
7007
7290
|
let alive = true;
|
|
7008
7291
|
const probe = () => {
|
|
@@ -7026,7 +7309,7 @@ function Panel() {
|
|
|
7026
7309
|
live: "paired",
|
|
7027
7310
|
off: "not paired"
|
|
7028
7311
|
}[emblemaPairState];
|
|
7029
|
-
(0,
|
|
7312
|
+
(0, import_react14.useEffect)(() => {
|
|
7030
7313
|
if (!panelOpen || activeItemId === null) return;
|
|
7031
7314
|
const row = panelRef.current?.querySelector(`[data-item-id="${activeItemId}"]`);
|
|
7032
7315
|
row?.scrollIntoView({ block: "nearest" });
|
|
@@ -7142,7 +7425,7 @@ function Panel() {
|
|
|
7142
7425
|
panel.style.transform = "";
|
|
7143
7426
|
if (dy > 110) dispatch({ type: "SET_PANEL", open: false });
|
|
7144
7427
|
};
|
|
7145
|
-
return /* @__PURE__ */ (0,
|
|
7428
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
7146
7429
|
"div",
|
|
7147
7430
|
{
|
|
7148
7431
|
ref: panelRef,
|
|
@@ -7152,7 +7435,7 @@ function Panel() {
|
|
|
7152
7435
|
"aria-label": "Review feedback panel",
|
|
7153
7436
|
onKeyDown,
|
|
7154
7437
|
children: [
|
|
7155
|
-
/* @__PURE__ */ (0,
|
|
7438
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7156
7439
|
"div",
|
|
7157
7440
|
{
|
|
7158
7441
|
className: "rk-sheet-handle",
|
|
@@ -7163,34 +7446,41 @@ function Panel() {
|
|
|
7163
7446
|
onPointerCancel: onSheetHandleUp
|
|
7164
7447
|
}
|
|
7165
7448
|
),
|
|
7166
|
-
/* @__PURE__ */ (0,
|
|
7167
|
-
/* @__PURE__ */ (0,
|
|
7168
|
-
/* @__PURE__ */ (0,
|
|
7169
|
-
/* @__PURE__ */ (0,
|
|
7449
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-panel-head", children: [
|
|
7450
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
|
|
7451
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "rk-panel-title", children: "Feedback" }),
|
|
7452
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-panel-sub", children: [
|
|
7170
7453
|
items.length,
|
|
7171
7454
|
" item",
|
|
7172
7455
|
items.length === 1 ? "" : "s",
|
|
7173
7456
|
session.author ? ` \xB7 ${session.author}` : "",
|
|
7174
|
-
syncStatus !== "disabled" && /* @__PURE__ */ (0,
|
|
7175
|
-
|
|
7176
|
-
|
|
7177
|
-
|
|
7178
|
-
|
|
7457
|
+
syncStatus !== "disabled" && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
7458
|
+
"span",
|
|
7459
|
+
{
|
|
7460
|
+
className: `rk-sync rk-sync-${syncStatus}${syncReason ? ` rk-sync-reason-${syncReason}` : ""}`,
|
|
7461
|
+
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"],
|
|
7462
|
+
children: [
|
|
7463
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-sync-dot" }),
|
|
7464
|
+
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"]}`
|
|
7465
|
+
]
|
|
7466
|
+
}
|
|
7467
|
+
),
|
|
7468
|
+
config.emblema && emblemaPush !== "idle" && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
7179
7469
|
"span",
|
|
7180
7470
|
{
|
|
7181
7471
|
className: `rk-sync rk-epush-${emblemaPush}`,
|
|
7182
7472
|
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",
|
|
7183
7473
|
children: [
|
|
7184
|
-
/* @__PURE__ */ (0,
|
|
7474
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-sync-dot" }),
|
|
7185
7475
|
emblemaPush === "ok" ? "emblema" : emblemaPush === "sending" ? "emblema\u2026" : emblemaPush === "rejected" ? "emblema rejected" : "emblema offline"
|
|
7186
7476
|
]
|
|
7187
7477
|
}
|
|
7188
7478
|
)
|
|
7189
7479
|
] })
|
|
7190
7480
|
] }),
|
|
7191
|
-
/* @__PURE__ */ (0,
|
|
7192
|
-
/* @__PURE__ */ (0,
|
|
7193
|
-
/* @__PURE__ */ (0,
|
|
7481
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-spacer" }),
|
|
7482
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-menu-scope rk-menu-anchor", children: [
|
|
7483
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7194
7484
|
"button",
|
|
7195
7485
|
{
|
|
7196
7486
|
type: "button",
|
|
@@ -7206,11 +7496,11 @@ function Panel() {
|
|
|
7206
7496
|
void pingEmblema(config.emblema).then((port) => setEmblemaAlive(port !== null));
|
|
7207
7497
|
}
|
|
7208
7498
|
},
|
|
7209
|
-
children: /* @__PURE__ */ (0,
|
|
7499
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconGear, { size: 15 })
|
|
7210
7500
|
}
|
|
7211
7501
|
),
|
|
7212
|
-
settingsOpen && /* @__PURE__ */ (0,
|
|
7213
|
-
config.token && /* @__PURE__ */ (0,
|
|
7502
|
+
settingsOpen && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-menu", role: "menu", "aria-label": "Session settings", children: [
|
|
7503
|
+
config.token && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
7214
7504
|
"button",
|
|
7215
7505
|
{
|
|
7216
7506
|
type: "button",
|
|
@@ -7225,12 +7515,12 @@ function Panel() {
|
|
|
7225
7515
|
toast(dispatch, next ? "Review stays on in this tab" : "Review active only via the link", "info");
|
|
7226
7516
|
},
|
|
7227
7517
|
children: [
|
|
7228
|
-
/* @__PURE__ */ (0,
|
|
7518
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: `rk-menu-check${sticky ? " rk-on" : ""}` }),
|
|
7229
7519
|
"Keep review on in this tab"
|
|
7230
7520
|
]
|
|
7231
7521
|
}
|
|
7232
7522
|
),
|
|
7233
|
-
config.emblema && /* @__PURE__ */ (0,
|
|
7523
|
+
config.emblema && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
7234
7524
|
"button",
|
|
7235
7525
|
{
|
|
7236
7526
|
type: "button",
|
|
@@ -7260,7 +7550,7 @@ function Panel() {
|
|
|
7260
7550
|
}).finally(() => setEmblemaSending(false));
|
|
7261
7551
|
},
|
|
7262
7552
|
children: [
|
|
7263
|
-
/* @__PURE__ */ (0,
|
|
7553
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7264
7554
|
"span",
|
|
7265
7555
|
{
|
|
7266
7556
|
className: "rk-emblema-dot",
|
|
@@ -7271,25 +7561,40 @@ function Panel() {
|
|
|
7271
7561
|
]
|
|
7272
7562
|
}
|
|
7273
7563
|
),
|
|
7274
|
-
/* @__PURE__ */ (0,
|
|
7564
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
7275
7565
|
"button",
|
|
7276
7566
|
{
|
|
7277
7567
|
type: "button",
|
|
7278
7568
|
role: "menuitem",
|
|
7279
7569
|
className: "rk-menu-item",
|
|
7280
|
-
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",
|
|
7570
|
+
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",
|
|
7281
7571
|
onClick: () => {
|
|
7282
7572
|
setSettingsOpen(false);
|
|
7283
7573
|
dispatch({ type: "SET_EMBLEMA_CONNECT", open: true });
|
|
7284
7574
|
},
|
|
7285
7575
|
children: [
|
|
7286
|
-
/* @__PURE__ */ (0,
|
|
7576
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-emblema-dot", "data-state": emblemaPairState }),
|
|
7287
7577
|
"Connect to Emblema\u2026",
|
|
7288
|
-
/* @__PURE__ */ (0,
|
|
7578
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-menu-count", children: emblemaPairLabel })
|
|
7289
7579
|
]
|
|
7290
7580
|
}
|
|
7291
7581
|
),
|
|
7292
|
-
/* @__PURE__ */ (0,
|
|
7582
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7583
|
+
"button",
|
|
7584
|
+
{
|
|
7585
|
+
type: "button",
|
|
7586
|
+
role: "menuitem",
|
|
7587
|
+
className: "rk-menu-item",
|
|
7588
|
+
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",
|
|
7589
|
+
disabled: !resolveSyncToken(config),
|
|
7590
|
+
onClick: () => {
|
|
7591
|
+
setSettingsOpen(false);
|
|
7592
|
+
dispatch({ type: "SET_TERMINAL_CONNECT", open: true });
|
|
7593
|
+
},
|
|
7594
|
+
children: "Connect terminal / agent\u2026"
|
|
7595
|
+
}
|
|
7596
|
+
),
|
|
7597
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7293
7598
|
"button",
|
|
7294
7599
|
{
|
|
7295
7600
|
type: "button",
|
|
@@ -7302,31 +7607,31 @@ function Panel() {
|
|
|
7302
7607
|
)
|
|
7303
7608
|
] })
|
|
7304
7609
|
] }),
|
|
7305
|
-
/* @__PURE__ */ (0,
|
|
7610
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7306
7611
|
"button",
|
|
7307
7612
|
{
|
|
7308
7613
|
type: "button",
|
|
7309
7614
|
className: "rk-icon-btn",
|
|
7310
7615
|
"aria-label": "Keyboard shortcuts",
|
|
7311
7616
|
onClick: () => dispatch({ type: "SET_CHEATSHEET", open: true }),
|
|
7312
|
-
children: /* @__PURE__ */ (0,
|
|
7617
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconKeyboard, { size: 15 })
|
|
7313
7618
|
}
|
|
7314
7619
|
),
|
|
7315
|
-
/* @__PURE__ */ (0,
|
|
7620
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7316
7621
|
"button",
|
|
7317
7622
|
{
|
|
7318
7623
|
type: "button",
|
|
7319
7624
|
className: "rk-icon-btn",
|
|
7320
7625
|
"aria-label": "Close panel",
|
|
7321
7626
|
onClick: () => dispatch({ type: "SET_PANEL", open: false }),
|
|
7322
|
-
children: /* @__PURE__ */ (0,
|
|
7627
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconClose, { size: 14 })
|
|
7323
7628
|
}
|
|
7324
7629
|
)
|
|
7325
7630
|
] }),
|
|
7326
|
-
/* @__PURE__ */ (0,
|
|
7327
|
-
/* @__PURE__ */ (0,
|
|
7328
|
-
/* @__PURE__ */ (0,
|
|
7329
|
-
/* @__PURE__ */ (0,
|
|
7631
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-view-row", children: [
|
|
7632
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "rk-view-info", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "rk-view-title", children: "Page view" }) }),
|
|
7633
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-seg rk-view-toggle", role: "group", "aria-label": "Page view (P to toggle)", children: [
|
|
7634
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7330
7635
|
"button",
|
|
7331
7636
|
{
|
|
7332
7637
|
type: "button",
|
|
@@ -7336,7 +7641,7 @@ function Panel() {
|
|
|
7336
7641
|
children: "Original"
|
|
7337
7642
|
}
|
|
7338
7643
|
),
|
|
7339
|
-
/* @__PURE__ */ (0,
|
|
7644
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7340
7645
|
"button",
|
|
7341
7646
|
{
|
|
7342
7647
|
type: "button",
|
|
@@ -7348,8 +7653,8 @@ function Panel() {
|
|
|
7348
7653
|
)
|
|
7349
7654
|
] })
|
|
7350
7655
|
] }),
|
|
7351
|
-
/* @__PURE__ */ (0,
|
|
7352
|
-
/* @__PURE__ */ (0,
|
|
7656
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-panel-tools", children: [
|
|
7657
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
7353
7658
|
"button",
|
|
7354
7659
|
{
|
|
7355
7660
|
type: "button",
|
|
@@ -7360,15 +7665,15 @@ function Panel() {
|
|
|
7360
7665
|
dispatch({ type: "SET_MODE", mode: "pick" });
|
|
7361
7666
|
},
|
|
7362
7667
|
children: [
|
|
7363
|
-
/* @__PURE__ */ (0,
|
|
7668
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconTarget, { size: 14 }),
|
|
7364
7669
|
" Pick an element"
|
|
7365
7670
|
]
|
|
7366
7671
|
}
|
|
7367
7672
|
),
|
|
7368
|
-
/* @__PURE__ */ (0,
|
|
7369
|
-
/* @__PURE__ */ (0,
|
|
7370
|
-
/* @__PURE__ */ (0,
|
|
7371
|
-
/* @__PURE__ */ (0,
|
|
7673
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-search-row", children: [
|
|
7674
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-search", children: [
|
|
7675
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconSearch, { size: 13 }),
|
|
7676
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7372
7677
|
"input",
|
|
7373
7678
|
{
|
|
7374
7679
|
ref: searchRef,
|
|
@@ -7380,8 +7685,8 @@ function Panel() {
|
|
|
7380
7685
|
}
|
|
7381
7686
|
)
|
|
7382
7687
|
] }),
|
|
7383
|
-
/* @__PURE__ */ (0,
|
|
7384
|
-
/* @__PURE__ */ (0,
|
|
7688
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-menu-scope rk-menu-anchor", children: [
|
|
7689
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
7385
7690
|
"button",
|
|
7386
7691
|
{
|
|
7387
7692
|
type: "button",
|
|
@@ -7393,15 +7698,15 @@ function Panel() {
|
|
|
7393
7698
|
setSettingsOpen(false);
|
|
7394
7699
|
},
|
|
7395
7700
|
children: [
|
|
7396
|
-
/* @__PURE__ */ (0,
|
|
7701
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconFilter, { size: 13 }),
|
|
7397
7702
|
"Filter",
|
|
7398
|
-
typeFilter.size + prioFilter.size + statusFilter.size > 0 && /* @__PURE__ */ (0,
|
|
7703
|
+
typeFilter.size + prioFilter.size + statusFilter.size > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-badge-count", children: typeFilter.size + prioFilter.size + statusFilter.size })
|
|
7399
7704
|
]
|
|
7400
7705
|
}
|
|
7401
7706
|
),
|
|
7402
|
-
filterOpen && /* @__PURE__ */ (0,
|
|
7403
|
-
/* @__PURE__ */ (0,
|
|
7404
|
-
TYPE_FILTERS.map((type) => /* @__PURE__ */ (0,
|
|
7707
|
+
filterOpen && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-menu", role: "menu", "aria-label": "Filter items", children: [
|
|
7708
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "rk-menu-title", children: "Type" }),
|
|
7709
|
+
TYPE_FILTERS.map((type) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
7405
7710
|
"button",
|
|
7406
7711
|
{
|
|
7407
7712
|
type: "button",
|
|
@@ -7415,16 +7720,16 @@ function Panel() {
|
|
|
7415
7720
|
setTypeFilter(next);
|
|
7416
7721
|
},
|
|
7417
7722
|
children: [
|
|
7418
|
-
/* @__PURE__ */ (0,
|
|
7723
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: `rk-menu-check${typeFilter.has(type) ? " rk-on" : ""}` }),
|
|
7419
7724
|
iconForType(type, 12),
|
|
7420
|
-
/* @__PURE__ */ (0,
|
|
7421
|
-
/* @__PURE__ */ (0,
|
|
7725
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-menu-label", children: type }),
|
|
7726
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-menu-count", children: typeCounts.get(type) ?? 0 })
|
|
7422
7727
|
]
|
|
7423
7728
|
},
|
|
7424
7729
|
type
|
|
7425
7730
|
)),
|
|
7426
|
-
/* @__PURE__ */ (0,
|
|
7427
|
-
PRIORITY_FILTERS.map((priority) => /* @__PURE__ */ (0,
|
|
7731
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "rk-menu-title", children: "Priority" }),
|
|
7732
|
+
PRIORITY_FILTERS.map((priority) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
7428
7733
|
"button",
|
|
7429
7734
|
{
|
|
7430
7735
|
type: "button",
|
|
@@ -7438,15 +7743,15 @@ function Panel() {
|
|
|
7438
7743
|
setPrioFilter(next);
|
|
7439
7744
|
},
|
|
7440
7745
|
children: [
|
|
7441
|
-
/* @__PURE__ */ (0,
|
|
7442
|
-
/* @__PURE__ */ (0,
|
|
7443
|
-
/* @__PURE__ */ (0,
|
|
7746
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: `rk-menu-check${prioFilter.has(priority) ? " rk-on" : ""}` }),
|
|
7747
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-menu-label", children: PRIORITY_LABELS[priority] }),
|
|
7748
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-menu-count", children: prioCounts.get(priority) ?? 0 })
|
|
7444
7749
|
]
|
|
7445
7750
|
},
|
|
7446
7751
|
priority
|
|
7447
7752
|
)),
|
|
7448
|
-
/* @__PURE__ */ (0,
|
|
7449
|
-
STATUSES.map((status) => /* @__PURE__ */ (0,
|
|
7753
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "rk-menu-title", children: "Status" }),
|
|
7754
|
+
STATUSES.map((status) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
7450
7755
|
"button",
|
|
7451
7756
|
{
|
|
7452
7757
|
type: "button",
|
|
@@ -7460,15 +7765,15 @@ function Panel() {
|
|
|
7460
7765
|
setStatusFilter(next);
|
|
7461
7766
|
},
|
|
7462
7767
|
children: [
|
|
7463
|
-
/* @__PURE__ */ (0,
|
|
7464
|
-
/* @__PURE__ */ (0,
|
|
7465
|
-
/* @__PURE__ */ (0,
|
|
7466
|
-
/* @__PURE__ */ (0,
|
|
7768
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: `rk-menu-check${statusFilter.has(status) ? " rk-on" : ""}` }),
|
|
7769
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: `rk-status-dot rk-st-${status}` }),
|
|
7770
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-menu-label", children: status }),
|
|
7771
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-menu-count", children: statusCounts.get(status) ?? 0 })
|
|
7467
7772
|
]
|
|
7468
7773
|
},
|
|
7469
7774
|
status
|
|
7470
7775
|
)),
|
|
7471
|
-
/* @__PURE__ */ (0,
|
|
7776
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7472
7777
|
"button",
|
|
7473
7778
|
{
|
|
7474
7779
|
type: "button",
|
|
@@ -7488,24 +7793,24 @@ function Panel() {
|
|
|
7488
7793
|
] })
|
|
7489
7794
|
] })
|
|
7490
7795
|
] }),
|
|
7491
|
-
preview && unapplied > 0 && /* @__PURE__ */ (0,
|
|
7796
|
+
preview && unapplied > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-unplaced", role: "status", children: [
|
|
7492
7797
|
unapplied,
|
|
7493
7798
|
" saved change",
|
|
7494
7799
|
unapplied === 1 ? "" : "s",
|
|
7495
7800
|
" couldn\u2019t be placed on the current page \u2014 the page has changed since they were captured."
|
|
7496
7801
|
] }),
|
|
7497
|
-
/* @__PURE__ */ (0,
|
|
7498
|
-
/* @__PURE__ */ (0,
|
|
7499
|
-
/* @__PURE__ */ (0,
|
|
7500
|
-
/* @__PURE__ */ (0,
|
|
7501
|
-
] }) : groups.map(([route, entries]) => /* @__PURE__ */ (0,
|
|
7502
|
-
/* @__PURE__ */ (0,
|
|
7802
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "rk-panel-list", children: filtered.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-empty", children: [
|
|
7803
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "rk-empty-art", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconTarget, { size: 22 }) }),
|
|
7804
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "rk-empty-title", children: items.length === 0 ? "Nothing here yet" : "No matches" }),
|
|
7805
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("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." })
|
|
7806
|
+
] }) : groups.map(([route, entries]) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
|
|
7807
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "rk-group-title", children: route }),
|
|
7503
7808
|
entries.map(({ item, number }) => {
|
|
7504
7809
|
const active2 = item.id === activeItemId;
|
|
7505
7810
|
const orphan = orphanIds.has(item.id);
|
|
7506
7811
|
const hiddenEl = hiddenIds.has(item.id);
|
|
7507
|
-
return /* @__PURE__ */ (0,
|
|
7508
|
-
/* @__PURE__ */ (0,
|
|
7812
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
|
|
7813
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
7509
7814
|
"div",
|
|
7510
7815
|
{
|
|
7511
7816
|
"data-item-id": item.id,
|
|
@@ -7520,18 +7825,18 @@ function Panel() {
|
|
|
7520
7825
|
}
|
|
7521
7826
|
},
|
|
7522
7827
|
children: [
|
|
7523
|
-
/* @__PURE__ */ (0,
|
|
7524
|
-
/* @__PURE__ */ (0,
|
|
7525
|
-
/* @__PURE__ */ (0,
|
|
7526
|
-
/* @__PURE__ */ (0,
|
|
7828
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-item-num", children: number }),
|
|
7829
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-item-icon", children: iconForType(item.type) }),
|
|
7830
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "rk-item-body", children: [
|
|
7831
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "rk-item-snippet", children: [
|
|
7527
7832
|
item.target.tagName,
|
|
7528
7833
|
" \xB7 ",
|
|
7529
7834
|
item.target.textSnippet || item.target.selector
|
|
7530
7835
|
] }),
|
|
7531
|
-
/* @__PURE__ */ (0,
|
|
7532
|
-
/* @__PURE__ */ (0,
|
|
7533
|
-
/* @__PURE__ */ (0,
|
|
7534
|
-
/* @__PURE__ */ (0,
|
|
7836
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-item-change", children: changeSummary(item) }),
|
|
7837
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "rk-item-meta", children: [
|
|
7838
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "rk-author", title: new Date(item.createdAt).toLocaleString(), children: [
|
|
7839
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7535
7840
|
"span",
|
|
7536
7841
|
{
|
|
7537
7842
|
className: "rk-author-dot",
|
|
@@ -7539,15 +7844,15 @@ function Panel() {
|
|
|
7539
7844
|
}
|
|
7540
7845
|
),
|
|
7541
7846
|
item.author?.name ?? "Unknown",
|
|
7542
|
-
/* @__PURE__ */ (0,
|
|
7847
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "rk-time", children: [
|
|
7543
7848
|
" \xB7 ",
|
|
7544
7849
|
timeAgo(item.createdAt)
|
|
7545
7850
|
] })
|
|
7546
7851
|
] }),
|
|
7547
|
-
item.priority === "must" && /* @__PURE__ */ (0,
|
|
7548
|
-
item.status !== "open" && /* @__PURE__ */ (0,
|
|
7549
|
-
orphan && /* @__PURE__ */ (0,
|
|
7550
|
-
hiddenEl && /* @__PURE__ */ (0,
|
|
7852
|
+
item.priority === "must" && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-badge-mini rk-must", children: "must" }),
|
|
7853
|
+
item.status !== "open" && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: `rk-badge-mini rk-${item.status}`, children: item.status }),
|
|
7854
|
+
orphan && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-badge-mini rk-orphaned", children: "unanchored" }),
|
|
7855
|
+
hiddenEl && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7551
7856
|
"span",
|
|
7552
7857
|
{
|
|
7553
7858
|
className: "rk-badge-mini rk-hidden-el",
|
|
@@ -7555,14 +7860,14 @@ function Panel() {
|
|
|
7555
7860
|
children: "hidden"
|
|
7556
7861
|
}
|
|
7557
7862
|
),
|
|
7558
|
-
item.note && /* @__PURE__ */ (0,
|
|
7559
|
-
peers.filter((peer) => peer.typingActive && peer.typingItemId === item.id).map((peer) => /* @__PURE__ */ (0,
|
|
7863
|
+
item.note && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-badge-mini", children: "note" }),
|
|
7864
|
+
peers.filter((peer) => peer.typingActive && peer.typingItemId === item.id).map((peer) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "rk-badge-mini", style: { color: peer.color }, children: [
|
|
7560
7865
|
peer.name || "peer",
|
|
7561
7866
|
" is writing\u2026"
|
|
7562
7867
|
] }, peer.id))
|
|
7563
7868
|
] })
|
|
7564
7869
|
] }),
|
|
7565
|
-
/* @__PURE__ */ (0,
|
|
7870
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-item-actions", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7566
7871
|
"button",
|
|
7567
7872
|
{
|
|
7568
7873
|
type: "button",
|
|
@@ -7577,15 +7882,15 @@ function Panel() {
|
|
|
7577
7882
|
"info"
|
|
7578
7883
|
);
|
|
7579
7884
|
},
|
|
7580
|
-
children: /* @__PURE__ */ (0,
|
|
7885
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconTrash, { size: 13 })
|
|
7581
7886
|
}
|
|
7582
7887
|
) })
|
|
7583
7888
|
]
|
|
7584
7889
|
}
|
|
7585
7890
|
),
|
|
7586
|
-
active2 && /* @__PURE__ */ (0,
|
|
7587
|
-
/* @__PURE__ */ (0,
|
|
7588
|
-
/* @__PURE__ */ (0,
|
|
7891
|
+
active2 && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-item-edit", children: [
|
|
7892
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-detail-byline", title: new Date(item.createdAt).toLocaleString(), children: [
|
|
7893
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7589
7894
|
"span",
|
|
7590
7895
|
{
|
|
7591
7896
|
className: "rk-author-dot",
|
|
@@ -7596,8 +7901,8 @@ function Panel() {
|
|
|
7596
7901
|
" \xB7 ",
|
|
7597
7902
|
timeAgo(item.createdAt)
|
|
7598
7903
|
] }),
|
|
7599
|
-
isCopyItem(item) && /* @__PURE__ */ (0,
|
|
7600
|
-
isImageItem(item) && /* @__PURE__ */ (0,
|
|
7904
|
+
isCopyItem(item) && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CopyDiff, { before: item.payload.before, after: item.payload.after }),
|
|
7905
|
+
isImageItem(item) && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7601
7906
|
ImageDetail,
|
|
7602
7907
|
{
|
|
7603
7908
|
beforeSrc: item.payload.beforeSrc,
|
|
@@ -7605,7 +7910,7 @@ function Panel() {
|
|
|
7605
7910
|
afterDataUrl: item.payload.afterDataUrl
|
|
7606
7911
|
}
|
|
7607
7912
|
),
|
|
7608
|
-
isKnownItemType(item.type) && item.type !== "move" && /* @__PURE__ */ (0,
|
|
7913
|
+
isKnownItemType(item.type) && item.type !== "move" && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7609
7914
|
"textarea",
|
|
7610
7915
|
{
|
|
7611
7916
|
className: "rk-textarea",
|
|
@@ -7615,7 +7920,7 @@ function Panel() {
|
|
|
7615
7920
|
onChange: (event) => dispatch({ type: "UPDATE_ITEM", id: item.id, patch: withPayloadText(item, event.target.value) })
|
|
7616
7921
|
}
|
|
7617
7922
|
),
|
|
7618
|
-
/* @__PURE__ */ (0,
|
|
7923
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7619
7924
|
"input",
|
|
7620
7925
|
{
|
|
7621
7926
|
className: "rk-input",
|
|
@@ -7625,9 +7930,9 @@ function Panel() {
|
|
|
7625
7930
|
onChange: (event) => dispatch({ type: "UPDATE_ITEM", id: item.id, patch: { note: event.target.value } })
|
|
7626
7931
|
}
|
|
7627
7932
|
),
|
|
7628
|
-
/* @__PURE__ */ (0,
|
|
7629
|
-
/* @__PURE__ */ (0,
|
|
7630
|
-
/* @__PURE__ */ (0,
|
|
7933
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
|
|
7934
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-seg", role: "group", "aria-label": "Priority", children: [
|
|
7935
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7631
7936
|
"button",
|
|
7632
7937
|
{
|
|
7633
7938
|
type: "button",
|
|
@@ -7636,7 +7941,7 @@ function Panel() {
|
|
|
7636
7941
|
children: "Must"
|
|
7637
7942
|
}
|
|
7638
7943
|
),
|
|
7639
|
-
/* @__PURE__ */ (0,
|
|
7944
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7640
7945
|
"button",
|
|
7641
7946
|
{
|
|
7642
7947
|
type: "button",
|
|
@@ -7646,7 +7951,7 @@ function Panel() {
|
|
|
7646
7951
|
}
|
|
7647
7952
|
)
|
|
7648
7953
|
] }),
|
|
7649
|
-
/* @__PURE__ */ (0,
|
|
7954
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "rk-seg", role: "group", "aria-label": "Status", children: STATUSES.map((status) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7650
7955
|
"button",
|
|
7651
7956
|
{
|
|
7652
7957
|
type: "button",
|
|
@@ -7661,22 +7966,22 @@ function Panel() {
|
|
|
7661
7966
|
] }, item.id);
|
|
7662
7967
|
})
|
|
7663
7968
|
] }, route)) }),
|
|
7664
|
-
/* @__PURE__ */ (0,
|
|
7665
|
-
/* @__PURE__ */ (0,
|
|
7666
|
-
/* @__PURE__ */ (0,
|
|
7969
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-panel-foot", children: [
|
|
7970
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: onExport, disabled: items.length === 0, children: [
|
|
7971
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconDownload, { size: 13 }),
|
|
7667
7972
|
" Export"
|
|
7668
7973
|
] }),
|
|
7669
|
-
/* @__PURE__ */ (0,
|
|
7670
|
-
/* @__PURE__ */ (0,
|
|
7974
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => void onCopy(), disabled: items.length === 0, children: [
|
|
7975
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconCopyClipboard, { size: 13 }),
|
|
7671
7976
|
" Copy"
|
|
7672
7977
|
] }),
|
|
7673
|
-
/* @__PURE__ */ (0,
|
|
7674
|
-
/* @__PURE__ */ (0,
|
|
7978
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => importRef.current?.click(), children: [
|
|
7979
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconUpload, { size: 13 }),
|
|
7675
7980
|
" Import"
|
|
7676
7981
|
] }),
|
|
7677
|
-
/* @__PURE__ */ (0,
|
|
7678
|
-
undoStack.length > 0 && /* @__PURE__ */ (0,
|
|
7679
|
-
/* @__PURE__ */ (0,
|
|
7982
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-spacer" }),
|
|
7983
|
+
undoStack.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: "rk-icon-btn", "aria-label": "Undo last change (\u2318Z)", onClick: () => dispatch({ type: "UNDO" }), children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconUndo, { size: 14 }) }),
|
|
7984
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7680
7985
|
"button",
|
|
7681
7986
|
{
|
|
7682
7987
|
type: "button",
|
|
@@ -7687,7 +7992,7 @@ function Panel() {
|
|
|
7687
7992
|
children: "Clear"
|
|
7688
7993
|
}
|
|
7689
7994
|
),
|
|
7690
|
-
/* @__PURE__ */ (0,
|
|
7995
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7691
7996
|
"button",
|
|
7692
7997
|
{
|
|
7693
7998
|
type: "button",
|
|
@@ -7697,7 +8002,7 @@ function Panel() {
|
|
|
7697
8002
|
children: "Exit review"
|
|
7698
8003
|
}
|
|
7699
8004
|
),
|
|
7700
|
-
/* @__PURE__ */ (0,
|
|
8005
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7701
8006
|
"input",
|
|
7702
8007
|
{
|
|
7703
8008
|
ref: importRef,
|
|
@@ -7716,13 +8021,14 @@ function Panel() {
|
|
|
7716
8021
|
}
|
|
7717
8022
|
);
|
|
7718
8023
|
}
|
|
7719
|
-
var
|
|
8024
|
+
var import_react14, import_jsx_runtime12, TYPE_FILTERS, PRIORITY_FILTERS, STATUSES, PRIORITY_LABELS, SYNC_REASON_LABEL, SYNC_REASON_HELP;
|
|
7720
8025
|
var init_Panel = __esm({
|
|
7721
8026
|
"src/client/components/Panel.tsx"() {
|
|
7722
8027
|
"use strict";
|
|
7723
|
-
|
|
8028
|
+
import_react14 = require("react");
|
|
7724
8029
|
init_schema();
|
|
7725
8030
|
init_env();
|
|
8031
|
+
init_sync();
|
|
7726
8032
|
init_emblema();
|
|
7727
8033
|
init_exportSession();
|
|
7728
8034
|
init_shortcuts();
|
|
@@ -7730,11 +8036,23 @@ var init_Panel = __esm({
|
|
|
7730
8036
|
init_target();
|
|
7731
8037
|
init_store();
|
|
7732
8038
|
init_icons();
|
|
7733
|
-
|
|
8039
|
+
import_jsx_runtime12 = require("react/jsx-runtime");
|
|
7734
8040
|
TYPE_FILTERS = ["copy", "image", "comment", "delete", "move", "style"];
|
|
7735
8041
|
PRIORITY_FILTERS = ["must", "nice"];
|
|
7736
8042
|
STATUSES = ["open", "accepted", "rejected", "applied"];
|
|
7737
8043
|
PRIORITY_LABELS = { must: "Must", nice: "Nice to have" };
|
|
8044
|
+
SYNC_REASON_LABEL = {
|
|
8045
|
+
"token-short": "token too short",
|
|
8046
|
+
"bad-token": "token rejected",
|
|
8047
|
+
"room-full": "room full",
|
|
8048
|
+
unreachable: "server unreachable"
|
|
8049
|
+
};
|
|
8050
|
+
SYNC_REASON_HELP = {
|
|
8051
|
+
"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.",
|
|
8052
|
+
"bad-token": "The sync server rejected the token. Check `syncToken` / `token` in <ReviewKit />.",
|
|
8053
|
+
"room-full": "This page already has the maximum number of reviewers online (16). Try again later.",
|
|
8054
|
+
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."
|
|
8055
|
+
};
|
|
7738
8056
|
}
|
|
7739
8057
|
});
|
|
7740
8058
|
|
|
@@ -7748,8 +8066,8 @@ function initials(name) {
|
|
|
7748
8066
|
function PresenceStrip() {
|
|
7749
8067
|
const { peers, syncStatus } = useStore();
|
|
7750
8068
|
if (syncStatus === "disabled" || peers.length === 0) return null;
|
|
7751
|
-
return /* @__PURE__ */ (0,
|
|
7752
|
-
peers.slice(0, 5).map((peer) => /* @__PURE__ */ (0,
|
|
8069
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "rk-presence", "aria-label": `${peers.length} reviewer${peers.length === 1 ? "" : "s"} online`, children: [
|
|
8070
|
+
peers.slice(0, 5).map((peer) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
7753
8071
|
"span",
|
|
7754
8072
|
{
|
|
7755
8073
|
className: "rk-avatar",
|
|
@@ -7759,7 +8077,7 @@ function PresenceStrip() {
|
|
|
7759
8077
|
},
|
|
7760
8078
|
peer.id
|
|
7761
8079
|
)),
|
|
7762
|
-
peers.length > 5 && /* @__PURE__ */ (0,
|
|
8080
|
+
peers.length > 5 && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "rk-avatar rk-avatar-more", children: [
|
|
7763
8081
|
"+",
|
|
7764
8082
|
peers.length - 5
|
|
7765
8083
|
] })
|
|
@@ -7767,13 +8085,13 @@ function PresenceStrip() {
|
|
|
7767
8085
|
}
|
|
7768
8086
|
function PeerCursors() {
|
|
7769
8087
|
const { peers } = useStore();
|
|
7770
|
-
const ringRefs = (0,
|
|
7771
|
-
const cursorRefs = (0,
|
|
7772
|
-
const motion = (0,
|
|
8088
|
+
const ringRefs = (0, import_react15.useRef)(/* @__PURE__ */ new Map());
|
|
8089
|
+
const cursorRefs = (0, import_react15.useRef)(/* @__PURE__ */ new Map());
|
|
8090
|
+
const motion = (0, import_react15.useRef)(
|
|
7773
8091
|
/* @__PURE__ */ new Map()
|
|
7774
8092
|
);
|
|
7775
|
-
const peersRef = (0,
|
|
7776
|
-
const seen = (0,
|
|
8093
|
+
const peersRef = (0, import_react15.useRef)(peers);
|
|
8094
|
+
const seen = (0, import_react15.useRef)(/* @__PURE__ */ new Map());
|
|
7777
8095
|
for (const peer of peers) {
|
|
7778
8096
|
const sig = peer.cursor ? `${peer.cursor.x},${peer.cursor.y},${peer.cursor.ox},${peer.cursor.oy}` : "";
|
|
7779
8097
|
if (seen.current.get(peer.id) !== sig) {
|
|
@@ -7783,7 +8101,7 @@ function PeerCursors() {
|
|
|
7783
8101
|
}
|
|
7784
8102
|
}
|
|
7785
8103
|
peersRef.current = peers;
|
|
7786
|
-
(0,
|
|
8104
|
+
(0, import_react15.useEffect)(() => {
|
|
7787
8105
|
const reduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
7788
8106
|
let raf = 0;
|
|
7789
8107
|
let last = performance.now();
|
|
@@ -7888,8 +8206,8 @@ function PeerCursors() {
|
|
|
7888
8206
|
return () => cancelAnimationFrame(raf);
|
|
7889
8207
|
}, []);
|
|
7890
8208
|
if (peers.length === 0) return null;
|
|
7891
|
-
return /* @__PURE__ */ (0,
|
|
7892
|
-
peers.map((peer) => /* @__PURE__ */ (0,
|
|
8209
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
8210
|
+
peers.map((peer) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
7893
8211
|
"div",
|
|
7894
8212
|
{
|
|
7895
8213
|
ref: (el) => {
|
|
@@ -7901,7 +8219,7 @@ function PeerCursors() {
|
|
|
7901
8219
|
},
|
|
7902
8220
|
`ring-${peer.id}`
|
|
7903
8221
|
)),
|
|
7904
|
-
peers.map((peer, index) => /* @__PURE__ */ (0,
|
|
8222
|
+
peers.map((peer, index) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
7905
8223
|
"div",
|
|
7906
8224
|
{
|
|
7907
8225
|
ref: (el) => {
|
|
@@ -7911,8 +8229,8 @@ function PeerCursors() {
|
|
|
7911
8229
|
className: "rk-peer-cursor",
|
|
7912
8230
|
style: { opacity: 0 },
|
|
7913
8231
|
children: [
|
|
7914
|
-
/* @__PURE__ */ (0,
|
|
7915
|
-
/* @__PURE__ */ (0,
|
|
8232
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("svg", { width: "14", height: "18", viewBox: "0 0 14 18", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("path", { d: "M1 1l12 7.5-5.2 1.2L5 16z", fill: peer.color, stroke: "rgba(0,0,0,0.25)", strokeWidth: "1" }) }),
|
|
8233
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
7916
8234
|
"span",
|
|
7917
8235
|
{
|
|
7918
8236
|
className: "rk-peer-name",
|
|
@@ -7929,14 +8247,14 @@ function PeerCursors() {
|
|
|
7929
8247
|
))
|
|
7930
8248
|
] });
|
|
7931
8249
|
}
|
|
7932
|
-
var
|
|
8250
|
+
var import_react15, import_jsx_runtime13;
|
|
7933
8251
|
var init_Presence = __esm({
|
|
7934
8252
|
"src/client/components/Presence.tsx"() {
|
|
7935
8253
|
"use strict";
|
|
7936
|
-
|
|
8254
|
+
import_react15 = require("react");
|
|
7937
8255
|
init_store();
|
|
7938
8256
|
init_target();
|
|
7939
|
-
|
|
8257
|
+
import_jsx_runtime13 = require("react/jsx-runtime");
|
|
7940
8258
|
}
|
|
7941
8259
|
});
|
|
7942
8260
|
|
|
@@ -7944,14 +8262,14 @@ var init_Presence = __esm({
|
|
|
7944
8262
|
function QuickComment() {
|
|
7945
8263
|
const { quick } = useStore();
|
|
7946
8264
|
if (!quick) return null;
|
|
7947
|
-
return /* @__PURE__ */ (0,
|
|
8265
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(QuickComposerCard, { quick }, quick.id);
|
|
7948
8266
|
}
|
|
7949
8267
|
function QuickComposerCard({ quick }) {
|
|
7950
8268
|
const { route, session } = useStore();
|
|
7951
8269
|
const dispatch = useDispatch();
|
|
7952
|
-
const [text, setText] = (0,
|
|
7953
|
-
const fieldRef = (0,
|
|
7954
|
-
(0,
|
|
8270
|
+
const [text, setText] = (0, import_react16.useState)("");
|
|
8271
|
+
const fieldRef = (0, import_react16.useRef)(null);
|
|
8272
|
+
(0, import_react16.useEffect)(() => {
|
|
7955
8273
|
const field = fieldRef.current;
|
|
7956
8274
|
if (!field) return;
|
|
7957
8275
|
field.focus();
|
|
@@ -8004,18 +8322,18 @@ function QuickComposerCard({ quick }) {
|
|
|
8004
8322
|
};
|
|
8005
8323
|
const x = Math.min(Math.max(quick.x, 8), window.innerWidth - 288);
|
|
8006
8324
|
const y = Math.min(Math.max(quick.y + 12, 8), window.innerHeight - 108);
|
|
8007
|
-
return /* @__PURE__ */ (0,
|
|
8008
|
-
/* @__PURE__ */ (0,
|
|
8009
|
-
/* @__PURE__ */ (0,
|
|
8010
|
-
/* @__PURE__ */ (0,
|
|
8011
|
-
/* @__PURE__ */ (0,
|
|
8012
|
-
/* @__PURE__ */ (0,
|
|
8325
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "rk-quick", style: { transform: `translate3d(${x}px, ${y}px, 0)` }, role: "dialog", "aria-label": "Quick comment", children: [
|
|
8326
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "rk-quick-head", children: [
|
|
8327
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(IconComment, { size: 12 }),
|
|
8328
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Comment here" }),
|
|
8329
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "rk-hint", children: [
|
|
8330
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "rk-kbd", children: "\u21B5" }),
|
|
8013
8331
|
" save \xB7 ",
|
|
8014
|
-
/* @__PURE__ */ (0,
|
|
8332
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "rk-kbd", children: "esc" }),
|
|
8015
8333
|
" cancel"
|
|
8016
8334
|
] })
|
|
8017
8335
|
] }),
|
|
8018
|
-
/* @__PURE__ */ (0,
|
|
8336
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
8019
8337
|
"textarea",
|
|
8020
8338
|
{
|
|
8021
8339
|
ref: fieldRef,
|
|
@@ -8029,11 +8347,11 @@ function QuickComposerCard({ quick }) {
|
|
|
8029
8347
|
)
|
|
8030
8348
|
] });
|
|
8031
8349
|
}
|
|
8032
|
-
var
|
|
8350
|
+
var import_react16, import_jsx_runtime14;
|
|
8033
8351
|
var init_QuickComment = __esm({
|
|
8034
8352
|
"src/client/components/QuickComment.tsx"() {
|
|
8035
8353
|
"use strict";
|
|
8036
|
-
|
|
8354
|
+
import_react16 = require("react");
|
|
8037
8355
|
init_effectCatalog();
|
|
8038
8356
|
init_effectsLazy();
|
|
8039
8357
|
init_id();
|
|
@@ -8042,7 +8360,7 @@ var init_QuickComment = __esm({
|
|
|
8042
8360
|
init_sync();
|
|
8043
8361
|
init_store();
|
|
8044
8362
|
init_icons();
|
|
8045
|
-
|
|
8363
|
+
import_jsx_runtime14 = require("react/jsx-runtime");
|
|
8046
8364
|
}
|
|
8047
8365
|
});
|
|
8048
8366
|
|
|
@@ -8061,14 +8379,14 @@ function applyRect(el, rect, pad2 = 3) {
|
|
|
8061
8379
|
function PickLayer() {
|
|
8062
8380
|
const { mode, selection, tool } = useStore();
|
|
8063
8381
|
const dispatch = useDispatch();
|
|
8064
|
-
const [hovered, setHovered] = (0,
|
|
8065
|
-
const outlineRef = (0,
|
|
8066
|
-
const labelRef = (0,
|
|
8067
|
-
const selectRef = (0,
|
|
8068
|
-
const hoveredRef = (0,
|
|
8382
|
+
const [hovered, setHovered] = (0, import_react17.useState)(null);
|
|
8383
|
+
const outlineRef = (0, import_react17.useRef)(null);
|
|
8384
|
+
const labelRef = (0, import_react17.useRef)(null);
|
|
8385
|
+
const selectRef = (0, import_react17.useRef)(null);
|
|
8386
|
+
const hoveredRef = (0, import_react17.useRef)(null);
|
|
8069
8387
|
hoveredRef.current = hovered;
|
|
8070
8388
|
const picking = mode === "pick";
|
|
8071
|
-
(0,
|
|
8389
|
+
(0, import_react17.useEffect)(() => {
|
|
8072
8390
|
if (!picking) {
|
|
8073
8391
|
setHovered(null);
|
|
8074
8392
|
return;
|
|
@@ -8112,7 +8430,7 @@ function PickLayer() {
|
|
|
8112
8430
|
document.removeEventListener("mousedown", swallow, true);
|
|
8113
8431
|
};
|
|
8114
8432
|
}, [picking, tool, dispatch]);
|
|
8115
|
-
(0,
|
|
8433
|
+
(0, import_react17.useEffect)(() => {
|
|
8116
8434
|
if (!picking) return;
|
|
8117
8435
|
const body = document.body;
|
|
8118
8436
|
const prev = body.style.cursor;
|
|
@@ -8122,7 +8440,7 @@ function PickLayer() {
|
|
|
8122
8440
|
if (body.getAttribute("style") === "") body.removeAttribute("style");
|
|
8123
8441
|
};
|
|
8124
8442
|
}, [picking, tool]);
|
|
8125
|
-
(0,
|
|
8443
|
+
(0, import_react17.useEffect)(() => {
|
|
8126
8444
|
let raf = 0;
|
|
8127
8445
|
const tick = () => {
|
|
8128
8446
|
const hoverEl = hoveredRef.current;
|
|
@@ -8148,26 +8466,26 @@ function PickLayer() {
|
|
|
8148
8466
|
raf = requestAnimationFrame(tick);
|
|
8149
8467
|
return () => cancelAnimationFrame(raf);
|
|
8150
8468
|
}, [picking, selection]);
|
|
8151
|
-
return /* @__PURE__ */ (0,
|
|
8152
|
-
picking && /* @__PURE__ */ (0,
|
|
8153
|
-
/* @__PURE__ */ (0,
|
|
8154
|
-
/* @__PURE__ */ (0,
|
|
8155
|
-
/* @__PURE__ */ (0,
|
|
8156
|
-
/* @__PURE__ */ (0,
|
|
8157
|
-
] }) : /* @__PURE__ */ (0,
|
|
8469
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
8470
|
+
picking && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
8471
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { ref: outlineRef, className: "rk-outline", style: { opacity: 0 } }),
|
|
8472
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { ref: labelRef, className: "rk-outline-label", style: { opacity: 0 }, children: hovered ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
8473
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "rk-tag", children: hovered.tagName.toLowerCase() }),
|
|
8474
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: describeElement(hovered).replace(/^[a-z0-9]+ · /, "") })
|
|
8475
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: "Pick an element" }) })
|
|
8158
8476
|
] }),
|
|
8159
|
-
selection && /* @__PURE__ */ (0,
|
|
8477
|
+
selection && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { ref: selectRef, className: "rk-select-ring", style: { opacity: 0 } })
|
|
8160
8478
|
] });
|
|
8161
8479
|
}
|
|
8162
|
-
var
|
|
8480
|
+
var import_react17, import_jsx_runtime15;
|
|
8163
8481
|
var init_PickLayer = __esm({
|
|
8164
8482
|
"src/client/components/PickLayer.tsx"() {
|
|
8165
8483
|
"use strict";
|
|
8166
|
-
|
|
8484
|
+
import_react17 = require("react");
|
|
8167
8485
|
init_shortcuts();
|
|
8168
8486
|
init_target();
|
|
8169
8487
|
init_store();
|
|
8170
|
-
|
|
8488
|
+
import_jsx_runtime15 = require("react/jsx-runtime");
|
|
8171
8489
|
}
|
|
8172
8490
|
});
|
|
8173
8491
|
|
|
@@ -8175,22 +8493,22 @@ var init_PickLayer = __esm({
|
|
|
8175
8493
|
function Pins() {
|
|
8176
8494
|
const { session, route, activeItemId, editor, mode, filter } = useStore();
|
|
8177
8495
|
const dispatch = useDispatch();
|
|
8178
|
-
const [clusters, setClusters] = (0,
|
|
8179
|
-
const [orphanCount, setOrphanCount] = (0,
|
|
8180
|
-
const wrapRefs = (0,
|
|
8181
|
-
const visibleCache = (0,
|
|
8182
|
-
const highlightRef = (0,
|
|
8183
|
-
const hoveredItems = (0,
|
|
8184
|
-
const elementCache = (0,
|
|
8185
|
-
const lastResolve = (0,
|
|
8186
|
-
const [newestId, setNewestId] = (0,
|
|
8187
|
-
const prevCount = (0,
|
|
8188
|
-
const items = (0,
|
|
8496
|
+
const [clusters, setClusters] = (0, import_react18.useState)([]);
|
|
8497
|
+
const [orphanCount, setOrphanCount] = (0, import_react18.useState)(0);
|
|
8498
|
+
const wrapRefs = (0, import_react18.useRef)(/* @__PURE__ */ new Map());
|
|
8499
|
+
const visibleCache = (0, import_react18.useRef)(/* @__PURE__ */ new Map());
|
|
8500
|
+
const highlightRef = (0, import_react18.useRef)(null);
|
|
8501
|
+
const hoveredItems = (0, import_react18.useRef)(null);
|
|
8502
|
+
const elementCache = (0, import_react18.useRef)(/* @__PURE__ */ new Map());
|
|
8503
|
+
const lastResolve = (0, import_react18.useRef)(0);
|
|
8504
|
+
const [newestId, setNewestId] = (0, import_react18.useState)(null);
|
|
8505
|
+
const prevCount = (0, import_react18.useRef)(0);
|
|
8506
|
+
const items = (0, import_react18.useMemo)(() => {
|
|
8189
8507
|
const all = session?.items ?? [];
|
|
8190
8508
|
return all.map((item, index) => ({ item, number: index + 1 })).filter(({ item }) => item.route === route);
|
|
8191
8509
|
}, [session, route]);
|
|
8192
8510
|
const byId = new Map(items.map(({ item }) => [item.id, item]));
|
|
8193
|
-
(0,
|
|
8511
|
+
(0, import_react18.useEffect)(() => {
|
|
8194
8512
|
const count = session?.items.length ?? 0;
|
|
8195
8513
|
if (count > prevCount.current && session && count > 0) {
|
|
8196
8514
|
const id = session.items[count - 1].id;
|
|
@@ -8201,7 +8519,7 @@ function Pins() {
|
|
|
8201
8519
|
}
|
|
8202
8520
|
prevCount.current = count;
|
|
8203
8521
|
}, [session]);
|
|
8204
|
-
(0,
|
|
8522
|
+
(0, import_react18.useEffect)(() => {
|
|
8205
8523
|
let raf = 0;
|
|
8206
8524
|
let lastSignature = "";
|
|
8207
8525
|
const tick = (time) => {
|
|
@@ -8285,8 +8603,8 @@ function Pins() {
|
|
|
8285
8603
|
dispatch({ type: "SET_ACTIVE_ITEM", id });
|
|
8286
8604
|
dispatch({ type: "SET_PANEL", open: true });
|
|
8287
8605
|
};
|
|
8288
|
-
return /* @__PURE__ */ (0,
|
|
8289
|
-
/* @__PURE__ */ (0,
|
|
8606
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
8607
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: highlightRef, className: "rk-hl-ring", style: { opacity: 0 } }),
|
|
8290
8608
|
clusters.map((cluster) => {
|
|
8291
8609
|
const isCluster = cluster.ids.length > 1;
|
|
8292
8610
|
const isActive = activeItemId !== null && cluster.ids.includes(activeItemId);
|
|
@@ -8296,7 +8614,7 @@ function Pins() {
|
|
|
8296
8614
|
const status = statuses.size === 1 ? members[0]?.status : void 0;
|
|
8297
8615
|
const dimmed = filter !== null && members.length > 0 && !members.some((item) => itemMatchesFilter(item, filter));
|
|
8298
8616
|
const statusHint = isCluster ? status ? ` \xB7 all ${STATUS_LABELS[status] ?? status}` : "" : ` \xB7 ${STATUS_LABELS[members[0]?.status ?? "open"] ?? members[0]?.status}`;
|
|
8299
|
-
return /* @__PURE__ */ (0,
|
|
8617
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
8300
8618
|
"div",
|
|
8301
8619
|
{
|
|
8302
8620
|
ref: (el) => {
|
|
@@ -8304,7 +8622,7 @@ function Pins() {
|
|
|
8304
8622
|
else wrapRefs.current.delete(cluster.key);
|
|
8305
8623
|
},
|
|
8306
8624
|
className: `rk-pin-wrap${picking ? " rk-pin-ghost" : ""}`,
|
|
8307
|
-
children: /* @__PURE__ */ (0,
|
|
8625
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
8308
8626
|
"button",
|
|
8309
8627
|
{
|
|
8310
8628
|
type: "button",
|
|
@@ -8326,7 +8644,7 @@ function Pins() {
|
|
|
8326
8644
|
cluster.key
|
|
8327
8645
|
);
|
|
8328
8646
|
}),
|
|
8329
|
-
orphanCount > 0 && /* @__PURE__ */ (0,
|
|
8647
|
+
orphanCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
8330
8648
|
"button",
|
|
8331
8649
|
{
|
|
8332
8650
|
type: "button",
|
|
@@ -8334,7 +8652,7 @@ function Pins() {
|
|
|
8334
8652
|
style: { bottom: 16, left: "50%", transform: "translateX(-50%)" },
|
|
8335
8653
|
onClick: () => dispatch({ type: "SET_PANEL", open: true }),
|
|
8336
8654
|
children: [
|
|
8337
|
-
/* @__PURE__ */ (0,
|
|
8655
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(IconUnlink, { size: 13 }),
|
|
8338
8656
|
orphanCount,
|
|
8339
8657
|
" unanchored item",
|
|
8340
8658
|
orphanCount === 1 ? "" : "s"
|
|
@@ -8343,15 +8661,15 @@ function Pins() {
|
|
|
8343
8661
|
)
|
|
8344
8662
|
] });
|
|
8345
8663
|
}
|
|
8346
|
-
var
|
|
8664
|
+
var import_react18, import_jsx_runtime16, STATUS_LABELS, CLUSTER_RADIUS, RERESOLVE_MS;
|
|
8347
8665
|
var init_Pins = __esm({
|
|
8348
8666
|
"src/client/components/Pins.tsx"() {
|
|
8349
8667
|
"use strict";
|
|
8350
|
-
|
|
8668
|
+
import_react18 = require("react");
|
|
8351
8669
|
init_target();
|
|
8352
8670
|
init_store();
|
|
8353
8671
|
init_icons();
|
|
8354
|
-
|
|
8672
|
+
import_jsx_runtime16 = require("react/jsx-runtime");
|
|
8355
8673
|
STATUS_LABELS = {
|
|
8356
8674
|
open: "open",
|
|
8357
8675
|
accepted: "accepted",
|
|
@@ -8368,24 +8686,24 @@ function Toolbar() {
|
|
|
8368
8686
|
const { selection, editor, peers, syncStatus, mode, tool } = useStore();
|
|
8369
8687
|
const hasPeers = syncStatus !== "disabled" && peers.length > 0;
|
|
8370
8688
|
const dispatch = useDispatch();
|
|
8371
|
-
const ref = (0,
|
|
8372
|
-
const [pos, setPos] = (0,
|
|
8373
|
-
const drag = (0,
|
|
8374
|
-
const [dragging, setDragging] = (0,
|
|
8375
|
-
const justDragged = (0,
|
|
8689
|
+
const ref = (0, import_react19.useRef)(null);
|
|
8690
|
+
const [pos, setPos] = (0, import_react19.useState)(() => readStoredPos(POS_KEY2));
|
|
8691
|
+
const drag = (0, import_react19.useRef)(null);
|
|
8692
|
+
const [dragging, setDragging] = (0, import_react19.useState)(false);
|
|
8693
|
+
const justDragged = (0, import_react19.useRef)(false);
|
|
8376
8694
|
const visible = editor === null || selection !== null;
|
|
8377
8695
|
const applyPos = (next, persist) => {
|
|
8378
8696
|
if (next === null && ref.current) ref.current.style.bottom = "";
|
|
8379
8697
|
setPos(next);
|
|
8380
8698
|
if (persist) storePos(POS_KEY2, next);
|
|
8381
8699
|
};
|
|
8382
|
-
(0,
|
|
8700
|
+
(0, import_react19.useLayoutEffect)(() => {
|
|
8383
8701
|
const el = ref.current;
|
|
8384
8702
|
if (!el || pos === null) return;
|
|
8385
8703
|
const clamped = clampPos(pos.x, pos.y, el.offsetWidth, el.offsetHeight);
|
|
8386
8704
|
if (clamped.x !== pos.x || clamped.y !== pos.y) applyPos(clamped, true);
|
|
8387
8705
|
}, [pos, selection, hasPeers, visible]);
|
|
8388
|
-
(0,
|
|
8706
|
+
(0, import_react19.useEffect)(() => {
|
|
8389
8707
|
const onResize = () => {
|
|
8390
8708
|
const el = ref.current;
|
|
8391
8709
|
const current = readStoredPos(POS_KEY2);
|
|
@@ -8498,7 +8816,7 @@ function Toolbar() {
|
|
|
8498
8816
|
mode === "pick" && selection === null ? "rk-ghost" : ""
|
|
8499
8817
|
].filter(Boolean).join(" ");
|
|
8500
8818
|
const style = pos !== null ? { left: 0, top: 0, translate: `${pos.x}px ${pos.y}px` } : void 0;
|
|
8501
|
-
return /* @__PURE__ */ (0,
|
|
8819
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
8502
8820
|
"div",
|
|
8503
8821
|
{
|
|
8504
8822
|
ref,
|
|
@@ -8509,7 +8827,7 @@ function Toolbar() {
|
|
|
8509
8827
|
onPointerDown,
|
|
8510
8828
|
onClickCapture,
|
|
8511
8829
|
children: [
|
|
8512
|
-
/* @__PURE__ */ (0,
|
|
8830
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
8513
8831
|
"button",
|
|
8514
8832
|
{
|
|
8515
8833
|
type: "button",
|
|
@@ -8517,19 +8835,19 @@ function Toolbar() {
|
|
|
8517
8835
|
"aria-label": "Move the toolbar \u2014 drag, or use arrow keys; double-click to reset its position",
|
|
8518
8836
|
onKeyDown: onGripKeyDown,
|
|
8519
8837
|
onDoubleClick: () => applyPos(null, true),
|
|
8520
|
-
children: /* @__PURE__ */ (0,
|
|
8521
|
-
/* @__PURE__ */ (0,
|
|
8522
|
-
/* @__PURE__ */ (0,
|
|
8523
|
-
/* @__PURE__ */ (0,
|
|
8524
|
-
/* @__PURE__ */ (0,
|
|
8525
|
-
/* @__PURE__ */ (0,
|
|
8526
|
-
/* @__PURE__ */ (0,
|
|
8838
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("svg", { width: "8", height: "14", viewBox: "0 0 8 14", "aria-hidden": "true", fill: "currentColor", children: [
|
|
8839
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "2", cy: "2", r: "1.1" }),
|
|
8840
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "6", cy: "2", r: "1.1" }),
|
|
8841
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "2", cy: "7", r: "1.1" }),
|
|
8842
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "6", cy: "7", r: "1.1" }),
|
|
8843
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "2", cy: "12", r: "1.1" }),
|
|
8844
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "6", cy: "12", r: "1.1" })
|
|
8527
8845
|
] })
|
|
8528
8846
|
}
|
|
8529
8847
|
),
|
|
8530
|
-
/* @__PURE__ */ (0,
|
|
8531
|
-
hasPeers && /* @__PURE__ */ (0,
|
|
8532
|
-
/* @__PURE__ */ (0,
|
|
8848
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(PresenceStrip, {}),
|
|
8849
|
+
hasPeers && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "rk-toolbar-sep" }),
|
|
8850
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "rk-seg rk-tool-seg", role: "group", "aria-label": "Tools", children: TOOLS.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
8533
8851
|
"button",
|
|
8534
8852
|
{
|
|
8535
8853
|
type: "button",
|
|
@@ -8541,9 +8859,9 @@ function Toolbar() {
|
|
|
8541
8859
|
},
|
|
8542
8860
|
entry.tool
|
|
8543
8861
|
)) }),
|
|
8544
|
-
selection && /* @__PURE__ */ (0,
|
|
8545
|
-
selection && /* @__PURE__ */ (0,
|
|
8546
|
-
/* @__PURE__ */ (0,
|
|
8862
|
+
selection && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "rk-toolbar-sep" }),
|
|
8863
|
+
selection && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
8864
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
8547
8865
|
"button",
|
|
8548
8866
|
{
|
|
8549
8867
|
type: "button",
|
|
@@ -8552,12 +8870,12 @@ function Toolbar() {
|
|
|
8552
8870
|
title: `Rewrite text${keyHint("tool-copy")}`,
|
|
8553
8871
|
onClick: () => open("copy"),
|
|
8554
8872
|
children: [
|
|
8555
|
-
/* @__PURE__ */ (0,
|
|
8873
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconText, { size: 14 }),
|
|
8556
8874
|
" Rewrite"
|
|
8557
8875
|
]
|
|
8558
8876
|
}
|
|
8559
8877
|
),
|
|
8560
|
-
hasImage && /* @__PURE__ */ (0,
|
|
8878
|
+
hasImage && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
8561
8879
|
"button",
|
|
8562
8880
|
{
|
|
8563
8881
|
type: "button",
|
|
@@ -8566,12 +8884,12 @@ function Toolbar() {
|
|
|
8566
8884
|
title: `Replace image${keyHint("tool-image")}`,
|
|
8567
8885
|
onClick: () => open("image"),
|
|
8568
8886
|
children: [
|
|
8569
|
-
/* @__PURE__ */ (0,
|
|
8887
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconImage, { size: 14 }),
|
|
8570
8888
|
" Image"
|
|
8571
8889
|
]
|
|
8572
8890
|
}
|
|
8573
8891
|
),
|
|
8574
|
-
/* @__PURE__ */ (0,
|
|
8892
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
8575
8893
|
"button",
|
|
8576
8894
|
{
|
|
8577
8895
|
type: "button",
|
|
@@ -8580,32 +8898,32 @@ function Toolbar() {
|
|
|
8580
8898
|
title: `Comment${keyHint("tool-comment")}`,
|
|
8581
8899
|
onClick: () => open("comment"),
|
|
8582
8900
|
children: [
|
|
8583
|
-
/* @__PURE__ */ (0,
|
|
8901
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconComment, { size: 14 }),
|
|
8584
8902
|
" Comment"
|
|
8585
8903
|
]
|
|
8586
8904
|
}
|
|
8587
8905
|
),
|
|
8588
|
-
/* @__PURE__ */ (0,
|
|
8589
|
-
/* @__PURE__ */ (0,
|
|
8906
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("button", { type: "button", role: "menuitem", className: "rk-toolbar-btn", onClick: () => open("style"), children: [
|
|
8907
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconStyle, { size: 14 }),
|
|
8590
8908
|
" Style"
|
|
8591
8909
|
] }),
|
|
8592
|
-
/* @__PURE__ */ (0,
|
|
8593
|
-
/* @__PURE__ */ (0,
|
|
8910
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("button", { type: "button", role: "menuitem", className: "rk-toolbar-btn", onClick: () => open("move"), children: [
|
|
8911
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconMove, { size: 14 }),
|
|
8594
8912
|
" Move"
|
|
8595
8913
|
] }),
|
|
8596
|
-
/* @__PURE__ */ (0,
|
|
8597
|
-
/* @__PURE__ */ (0,
|
|
8914
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("button", { type: "button", role: "menuitem", className: "rk-toolbar-btn rk-danger", onClick: () => open("delete"), children: [
|
|
8915
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconTrash, { size: 14 }),
|
|
8598
8916
|
" Delete"
|
|
8599
8917
|
] }),
|
|
8600
|
-
/* @__PURE__ */ (0,
|
|
8601
|
-
/* @__PURE__ */ (0,
|
|
8918
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "rk-toolbar-sep" }),
|
|
8919
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
8602
8920
|
"button",
|
|
8603
8921
|
{
|
|
8604
8922
|
type: "button",
|
|
8605
8923
|
className: "rk-icon-btn",
|
|
8606
8924
|
"aria-label": "Deselect",
|
|
8607
8925
|
onClick: () => dispatch({ type: "SELECT", selection: null }),
|
|
8608
|
-
children: /* @__PURE__ */ (0,
|
|
8926
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconClose, { size: 13 })
|
|
8609
8927
|
}
|
|
8610
8928
|
)
|
|
8611
8929
|
] })
|
|
@@ -8613,11 +8931,11 @@ function Toolbar() {
|
|
|
8613
8931
|
}
|
|
8614
8932
|
);
|
|
8615
8933
|
}
|
|
8616
|
-
var
|
|
8934
|
+
var import_react19, import_jsx_runtime17, TOOLS, POS_KEY2, DRAG_THRESHOLD2;
|
|
8617
8935
|
var init_Toolbar = __esm({
|
|
8618
8936
|
"src/client/components/Toolbar.tsx"() {
|
|
8619
8937
|
"use strict";
|
|
8620
|
-
|
|
8938
|
+
import_react19 = require("react");
|
|
8621
8939
|
init_dragPosition();
|
|
8622
8940
|
init_store();
|
|
8623
8941
|
init_preview();
|
|
@@ -8625,12 +8943,12 @@ var init_Toolbar = __esm({
|
|
|
8625
8943
|
init_target();
|
|
8626
8944
|
init_Presence();
|
|
8627
8945
|
init_icons();
|
|
8628
|
-
|
|
8946
|
+
import_jsx_runtime17 = require("react/jsx-runtime");
|
|
8629
8947
|
TOOLS = [
|
|
8630
|
-
{ tool: "select", hintId: "tool-select", label: "Select", icon: (n) => /* @__PURE__ */ (0,
|
|
8631
|
-
{ tool: "copy", hintId: "tool-copy", label: "Rewrite text", icon: (n) => /* @__PURE__ */ (0,
|
|
8632
|
-
{ tool: "comment", hintId: "tool-comment", label: "Comment", icon: (n) => /* @__PURE__ */ (0,
|
|
8633
|
-
{ tool: "image", hintId: "tool-image", label: "Replace image", icon: (n) => /* @__PURE__ */ (0,
|
|
8948
|
+
{ tool: "select", hintId: "tool-select", label: "Select", icon: (n) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconTarget, { size: n }) },
|
|
8949
|
+
{ tool: "copy", hintId: "tool-copy", label: "Rewrite text", icon: (n) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconText, { size: n }) },
|
|
8950
|
+
{ tool: "comment", hintId: "tool-comment", label: "Comment", icon: (n) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconComment, { size: n }) },
|
|
8951
|
+
{ tool: "image", hintId: "tool-image", label: "Replace image", icon: (n) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconImage, { size: n }) }
|
|
8634
8952
|
];
|
|
8635
8953
|
POS_KEY2 = "review-kit:toolbar-pos";
|
|
8636
8954
|
DRAG_THRESHOLD2 = 6;
|
|
@@ -8640,28 +8958,28 @@ var init_Toolbar = __esm({
|
|
|
8640
8958
|
// src/client/components/Toast.tsx
|
|
8641
8959
|
function ToastRow({ toast: toast2 }) {
|
|
8642
8960
|
const dispatch = useDispatch();
|
|
8643
|
-
(0,
|
|
8961
|
+
(0, import_react20.useEffect)(() => {
|
|
8644
8962
|
const timer = window.setTimeout(() => dispatch({ type: "DISMISS_TOAST", id: toast2.id }), 3500);
|
|
8645
8963
|
return () => window.clearTimeout(timer);
|
|
8646
8964
|
}, [toast2.id, dispatch]);
|
|
8647
|
-
return /* @__PURE__ */ (0,
|
|
8648
|
-
toast2.tone === "success" ? /* @__PURE__ */ (0,
|
|
8965
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: `rk-toast rk-${toast2.tone}`, role: "status", children: [
|
|
8966
|
+
toast2.tone === "success" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconCheck, { size: 13 }) : toast2.tone === "error" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconWarning, { size: 13 }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(IconComment, { size: 13 }),
|
|
8649
8967
|
toast2.message
|
|
8650
8968
|
] });
|
|
8651
8969
|
}
|
|
8652
8970
|
function ToastHost() {
|
|
8653
8971
|
const { toasts } = useStore();
|
|
8654
8972
|
if (toasts.length === 0) return null;
|
|
8655
|
-
return /* @__PURE__ */ (0,
|
|
8973
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "rk-toasts", "aria-live": "polite", children: toasts.map((toast2) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ToastRow, { toast: toast2 }, toast2.id)) });
|
|
8656
8974
|
}
|
|
8657
|
-
var
|
|
8975
|
+
var import_react20, import_jsx_runtime18;
|
|
8658
8976
|
var init_Toast = __esm({
|
|
8659
8977
|
"src/client/components/Toast.tsx"() {
|
|
8660
8978
|
"use strict";
|
|
8661
|
-
|
|
8979
|
+
import_react20 = require("react");
|
|
8662
8980
|
init_store();
|
|
8663
8981
|
init_icons();
|
|
8664
|
-
|
|
8982
|
+
import_jsx_runtime18 = require("react/jsx-runtime");
|
|
8665
8983
|
}
|
|
8666
8984
|
});
|
|
8667
8985
|
|
|
@@ -8671,14 +8989,14 @@ function App() {
|
|
|
8671
8989
|
const rawDispatch = useDispatch();
|
|
8672
8990
|
const config = useConfig();
|
|
8673
8991
|
const dispatch = useRealtimeSync(state, rawDispatch, config, reducer);
|
|
8674
|
-
const saveTimer = (0,
|
|
8992
|
+
const saveTimer = (0, import_react21.useRef)(null);
|
|
8675
8993
|
const storageKey = config.storageKey ?? defaultStorageKey();
|
|
8676
8994
|
useAppliedPreview(state, dispatch);
|
|
8677
8995
|
useEmblemaAutoPush(state, dispatch, config);
|
|
8678
|
-
(0,
|
|
8996
|
+
(0, import_react21.useEffect)(() => {
|
|
8679
8997
|
setEffectAssetsUrl(config.fxAssetsUrl);
|
|
8680
8998
|
}, [config.fxAssetsUrl]);
|
|
8681
|
-
(0,
|
|
8999
|
+
(0, import_react21.useEffect)(() => {
|
|
8682
9000
|
let cancelled = false;
|
|
8683
9001
|
void loadSession(storageKey).then((stored) => {
|
|
8684
9002
|
if (cancelled) return;
|
|
@@ -8696,7 +9014,7 @@ function App() {
|
|
|
8696
9014
|
};
|
|
8697
9015
|
}, [storageKey, config.defaultAuthor, dispatch]);
|
|
8698
9016
|
const { session } = state;
|
|
8699
|
-
(0,
|
|
9017
|
+
(0, import_react21.useEffect)(() => {
|
|
8700
9018
|
if (!session) return;
|
|
8701
9019
|
if (saveTimer.current !== null) window.clearTimeout(saveTimer.current);
|
|
8702
9020
|
saveTimer.current = window.setTimeout(() => {
|
|
@@ -8707,9 +9025,9 @@ function App() {
|
|
|
8707
9025
|
if (saveTimer.current !== null) window.clearTimeout(saveTimer.current);
|
|
8708
9026
|
};
|
|
8709
9027
|
}, [session, storageKey, config]);
|
|
8710
|
-
(0,
|
|
8711
|
-
const focusHandled = (0,
|
|
8712
|
-
(0,
|
|
9028
|
+
(0, import_react21.useEffect)(() => trackPointer(), []);
|
|
9029
|
+
const focusHandled = (0, import_react21.useRef)(false);
|
|
9030
|
+
(0, import_react21.useEffect)(() => {
|
|
8713
9031
|
if (!session || focusHandled.current) return;
|
|
8714
9032
|
focusHandled.current = true;
|
|
8715
9033
|
const id = takeFocusItem();
|
|
@@ -8734,7 +9052,7 @@ function App() {
|
|
|
8734
9052
|
cancelled = true;
|
|
8735
9053
|
};
|
|
8736
9054
|
}, [session, dispatch]);
|
|
8737
|
-
(0,
|
|
9055
|
+
(0, import_react21.useEffect)(() => {
|
|
8738
9056
|
let last = window.location.pathname;
|
|
8739
9057
|
const check = () => {
|
|
8740
9058
|
if (window.location.pathname !== last) {
|
|
@@ -8749,9 +9067,9 @@ function App() {
|
|
|
8749
9067
|
window.removeEventListener("popstate", check);
|
|
8750
9068
|
};
|
|
8751
9069
|
}, [dispatch]);
|
|
8752
|
-
const stateRef = (0,
|
|
9070
|
+
const stateRef = (0, import_react21.useRef)(state);
|
|
8753
9071
|
stateRef.current = state;
|
|
8754
|
-
(0,
|
|
9072
|
+
(0, import_react21.useEffect)(() => {
|
|
8755
9073
|
const onKeyDown = (event) => {
|
|
8756
9074
|
const current = stateRef.current;
|
|
8757
9075
|
for (const def of SHORTCUTS) {
|
|
@@ -8766,7 +9084,7 @@ function App() {
|
|
|
8766
9084
|
document.addEventListener("keydown", onKeyDown);
|
|
8767
9085
|
return () => document.removeEventListener("keydown", onKeyDown);
|
|
8768
9086
|
}, [dispatch]);
|
|
8769
|
-
(0,
|
|
9087
|
+
(0, import_react21.useEffect)(() => {
|
|
8770
9088
|
if (!state.editor) return;
|
|
8771
9089
|
const editorEl = state.editor.element;
|
|
8772
9090
|
const onPointerDown = (event) => {
|
|
@@ -8779,31 +9097,32 @@ function App() {
|
|
|
8779
9097
|
}, [state.editor, dispatch]);
|
|
8780
9098
|
if (!session) return null;
|
|
8781
9099
|
if (state.hidden) {
|
|
8782
|
-
return /* @__PURE__ */ (0,
|
|
8783
|
-
}
|
|
8784
|
-
return /* @__PURE__ */ (0,
|
|
8785
|
-
/* @__PURE__ */ (0,
|
|
8786
|
-
/* @__PURE__ */ (0,
|
|
8787
|
-
/* @__PURE__ */ (0,
|
|
8788
|
-
state.editor?.kind === "copy" && /* @__PURE__ */ (0,
|
|
8789
|
-
state.editor?.kind === "image" && /* @__PURE__ */ (0,
|
|
8790
|
-
state.editor && state.editor.kind !== "copy" && state.editor.kind !== "image" && /* @__PURE__ */ (0,
|
|
8791
|
-
/* @__PURE__ */ (0,
|
|
8792
|
-
/* @__PURE__ */ (0,
|
|
8793
|
-
/* @__PURE__ */ (0,
|
|
8794
|
-
/* @__PURE__ */ (0,
|
|
8795
|
-
/* @__PURE__ */ (0,
|
|
8796
|
-
/* @__PURE__ */ (0,
|
|
8797
|
-
/* @__PURE__ */ (0,
|
|
8798
|
-
/* @__PURE__ */ (0,
|
|
8799
|
-
/* @__PURE__ */ (0,
|
|
9100
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DispatchContext.Provider, { value: dispatch, children: null });
|
|
9101
|
+
}
|
|
9102
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(DispatchContext.Provider, { value: dispatch, children: [
|
|
9103
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(PickLayer, {}),
|
|
9104
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(PeerCursors, {}),
|
|
9105
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Toolbar, {}),
|
|
9106
|
+
state.editor?.kind === "copy" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(InlineEditor, { editor: state.editor }),
|
|
9107
|
+
state.editor?.kind === "image" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ImageEditor, { editor: state.editor }),
|
|
9108
|
+
state.editor && state.editor.kind !== "copy" && state.editor.kind !== "image" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(NoteComposer, { editor: state.editor }),
|
|
9109
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Pins, {}),
|
|
9110
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(QuickComment, {}),
|
|
9111
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Panel, {}),
|
|
9112
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Badge, {}),
|
|
9113
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(CoachMark, {}),
|
|
9114
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(CheatSheet, {}),
|
|
9115
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(EmblemaConnect, {}),
|
|
9116
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TerminalConnect, {}),
|
|
9117
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ConfirmHost, {}),
|
|
9118
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ToastHost, {})
|
|
8800
9119
|
] });
|
|
8801
9120
|
}
|
|
8802
|
-
var
|
|
9121
|
+
var import_react21, import_jsx_runtime19;
|
|
8803
9122
|
var init_App = __esm({
|
|
8804
9123
|
"src/client/App.tsx"() {
|
|
8805
9124
|
"use strict";
|
|
8806
|
-
|
|
9125
|
+
import_react21 = require("react");
|
|
8807
9126
|
init_env();
|
|
8808
9127
|
init_persist();
|
|
8809
9128
|
init_reveal();
|
|
@@ -8819,6 +9138,7 @@ var init_App = __esm({
|
|
|
8819
9138
|
init_Badge();
|
|
8820
9139
|
init_CheatSheet();
|
|
8821
9140
|
init_EmblemaConnect();
|
|
9141
|
+
init_TerminalConnect();
|
|
8822
9142
|
init_CoachMark();
|
|
8823
9143
|
init_Confirm();
|
|
8824
9144
|
init_ImageEditor();
|
|
@@ -8831,14 +9151,14 @@ var init_App = __esm({
|
|
|
8831
9151
|
init_Pins();
|
|
8832
9152
|
init_Toolbar();
|
|
8833
9153
|
init_Toast();
|
|
8834
|
-
|
|
9154
|
+
import_jsx_runtime19 = require("react/jsx-runtime");
|
|
8835
9155
|
}
|
|
8836
9156
|
});
|
|
8837
9157
|
|
|
8838
9158
|
// src/client/ReviewKit.tsx
|
|
8839
9159
|
function ShadowHost({ config }) {
|
|
8840
|
-
const [mount, setMount] = (0,
|
|
8841
|
-
(0,
|
|
9160
|
+
const [mount, setMount] = (0, import_react22.useState)(null);
|
|
9161
|
+
(0, import_react22.useEffect)(() => {
|
|
8842
9162
|
const host = document.createElement("div");
|
|
8843
9163
|
host.setAttribute(HOST_ATTR, "");
|
|
8844
9164
|
host.style.position = "fixed";
|
|
@@ -8874,15 +9194,15 @@ function ShadowHost({ config }) {
|
|
|
8874
9194
|
}, []);
|
|
8875
9195
|
if (!mount) return null;
|
|
8876
9196
|
return (0, import_react_dom.createPortal)(
|
|
8877
|
-
/* @__PURE__ */ (0,
|
|
9197
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StoreProvider, { config, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(App, {}) }),
|
|
8878
9198
|
mount
|
|
8879
9199
|
);
|
|
8880
9200
|
}
|
|
8881
9201
|
function ReviewKit(props) {
|
|
8882
|
-
const [active2, setActive] = (0,
|
|
9202
|
+
const [active2, setActive] = (0, import_react22.useState)(false);
|
|
8883
9203
|
const { enabled, token, allowedHosts, devAutoOn } = props;
|
|
8884
9204
|
const hostsKey = allowedHosts?.join("\0") ?? "";
|
|
8885
|
-
(0,
|
|
9205
|
+
(0, import_react22.useEffect)(() => {
|
|
8886
9206
|
if (enabled === false) {
|
|
8887
9207
|
setActive(false);
|
|
8888
9208
|
return;
|
|
@@ -8893,13 +9213,13 @@ function ReviewKit(props) {
|
|
|
8893
9213
|
return () => window.removeEventListener(DEACTIVATE_EVENT, onDeactivate);
|
|
8894
9214
|
}, [enabled, token, devAutoOn, hostsKey]);
|
|
8895
9215
|
if (enabled === false || !active2) return null;
|
|
8896
|
-
return /* @__PURE__ */ (0,
|
|
9216
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ShadowHost, { config: props });
|
|
8897
9217
|
}
|
|
8898
|
-
var
|
|
9218
|
+
var import_react22, import_react_dom, import_jsx_runtime20;
|
|
8899
9219
|
var init_ReviewKit = __esm({
|
|
8900
9220
|
"src/client/ReviewKit.tsx"() {
|
|
8901
9221
|
"use strict";
|
|
8902
|
-
|
|
9222
|
+
import_react22 = require("react");
|
|
8903
9223
|
import_react_dom = require("react-dom");
|
|
8904
9224
|
init_env();
|
|
8905
9225
|
init_pointer();
|
|
@@ -8907,7 +9227,7 @@ var init_ReviewKit = __esm({
|
|
|
8907
9227
|
init_target();
|
|
8908
9228
|
init_store();
|
|
8909
9229
|
init_App();
|
|
8910
|
-
|
|
9230
|
+
import_jsx_runtime20 = require("react/jsx-runtime");
|
|
8911
9231
|
}
|
|
8912
9232
|
});
|
|
8913
9233
|
|
|
@@ -8954,19 +9274,19 @@ __export(lazy_exports, {
|
|
|
8954
9274
|
module.exports = __toCommonJS(lazy_exports);
|
|
8955
9275
|
|
|
8956
9276
|
// src/LazyReviewKit.tsx
|
|
8957
|
-
var
|
|
9277
|
+
var import_react23 = require("react");
|
|
8958
9278
|
init_activate();
|
|
8959
|
-
var
|
|
9279
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
8960
9280
|
var coreModule = null;
|
|
8961
9281
|
function loadCore() {
|
|
8962
9282
|
if (!coreModule) coreModule = Promise.resolve().then(() => (init_client(), client_exports)).then((mod) => mod.ReviewKit);
|
|
8963
9283
|
return coreModule;
|
|
8964
9284
|
}
|
|
8965
9285
|
function LazyReviewKit(props) {
|
|
8966
|
-
const [Core, setCore] = (0,
|
|
9286
|
+
const [Core, setCore] = (0, import_react23.useState)(null);
|
|
8967
9287
|
const { enabled, token, allowedHosts, devAutoOn } = props;
|
|
8968
9288
|
const hostsKey = allowedHosts?.join(" ") ?? "";
|
|
8969
|
-
(0,
|
|
9289
|
+
(0, import_react23.useEffect)(() => {
|
|
8970
9290
|
if (!shouldActivate({ enabled, token, allowedHosts, devAutoOn })) return;
|
|
8971
9291
|
let cancelled = false;
|
|
8972
9292
|
loadCore().then((component) => {
|
|
@@ -8979,7 +9299,7 @@ function LazyReviewKit(props) {
|
|
|
8979
9299
|
};
|
|
8980
9300
|
}, [enabled, token, devAutoOn, hostsKey]);
|
|
8981
9301
|
if (!Core || enabled === false) return null;
|
|
8982
|
-
return /* @__PURE__ */ (0,
|
|
9302
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Core, { ...props });
|
|
8983
9303
|
}
|
|
8984
9304
|
// Annotate the CommonJS export names for ESM import in node:
|
|
8985
9305
|
0 && (module.exports = {
|