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