@satanwagen/reviewkit 0.1.3 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +181 -1
- package/README.md +43 -18
- package/dist/{chunk-Q7U43PXE.js → chunk-L7JLBD7Q.js} +1 -1
- package/dist/{chunk-NSXRFM75.js → chunk-VNRVRNZX.js} +755 -450
- package/dist/chunk-VNRVRNZX.js.map +1 -0
- package/dist/client/index.cjs +803 -498
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.js +1 -1
- package/dist/{index-Dl2Fl0qr.d.cts → index-CWGkg1-E.d.cts} +17 -8
- package/dist/{index-BUSmAweg.d.ts → index-DPsjkvaY.d.ts} +17 -8
- package/dist/index.cjs +803 -498
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/lazy.cjs +849 -521
- package/dist/lazy.cjs.map +1 -1
- package/dist/lazy.d.cts +1 -1
- package/dist/lazy.d.ts +1 -1
- package/dist/lazy.js +1 -1
- package/dist/next.cjs +849 -521
- package/dist/next.cjs.map +1 -1
- package/dist/next.d.cts +1 -1
- package/dist/next.d.ts +1 -1
- package/dist/next.js +1 -1
- package/package.json +4 -2
- package/dist/chunk-NSXRFM75.js.map +0 -1
- /package/dist/{chunk-Q7U43PXE.js.map → chunk-L7JLBD7Q.js.map} +0 -0
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,20 @@ var init_identity = __esm({
|
|
|
5062
5075
|
});
|
|
5063
5076
|
|
|
5064
5077
|
// src/client/sync.ts
|
|
5078
|
+
function normalizeRoute(route) {
|
|
5079
|
+
let r = String(route ?? "/");
|
|
5080
|
+
if (!r.startsWith("/")) r = "/" + r;
|
|
5081
|
+
return r.length > 1 ? r.replace(/\/+$/, "") : r;
|
|
5082
|
+
}
|
|
5083
|
+
function resolveSyncUrl(config) {
|
|
5084
|
+
return typeof config.syncUrl === "string" && config.syncUrl !== "" ? config.syncUrl : DEFAULT_SYNC_URL;
|
|
5085
|
+
}
|
|
5086
|
+
function resolveSyncToken(config) {
|
|
5087
|
+
if (config.sync === false) return null;
|
|
5088
|
+
const explicit = typeof config.syncToken === "string" && config.syncToken !== "" ? config.syncToken : null;
|
|
5089
|
+
const fallback = typeof config.token === "string" && config.token !== "" ? config.token : null;
|
|
5090
|
+
return explicit ?? fallback;
|
|
5091
|
+
}
|
|
5065
5092
|
function toPeerState(peer) {
|
|
5066
5093
|
return {
|
|
5067
5094
|
id: peer.id,
|
|
@@ -5087,20 +5114,43 @@ function useRealtimeSync(state, rawDispatch, config, reducer2) {
|
|
|
5087
5114
|
const stateRef = (0, import_react4.useRef)(state);
|
|
5088
5115
|
stateRef.current = state;
|
|
5089
5116
|
const myIdRef = (0, import_react4.useRef)("");
|
|
5090
|
-
const
|
|
5117
|
+
const syncToken = resolveSyncToken(config);
|
|
5118
|
+
const syncUrl = resolveSyncUrl(config);
|
|
5119
|
+
const enabled = syncToken !== null;
|
|
5091
5120
|
const author = state.session?.author ?? "";
|
|
5092
5121
|
const hasSession = state.session !== null;
|
|
5093
5122
|
(0, import_react4.useEffect)(() => {
|
|
5094
5123
|
if (!enabled || !hasSession) return;
|
|
5124
|
+
const dispatchGuard = rawDispatch;
|
|
5125
|
+
if (syncToken.length < MIN_SYNC_TOKEN_LENGTH) {
|
|
5126
|
+
dispatchGuard({ type: "SYNC_STATUS", status: "offline", reason: "token-short" });
|
|
5127
|
+
if (!warnedShortToken) {
|
|
5128
|
+
warnedShortToken = true;
|
|
5129
|
+
console.warn(
|
|
5130
|
+
`[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.`
|
|
5131
|
+
);
|
|
5132
|
+
}
|
|
5133
|
+
return () => dispatchGuard({ type: "SYNC_STATUS", status: "disabled", reason: null });
|
|
5134
|
+
}
|
|
5095
5135
|
const id = reviewerId();
|
|
5096
5136
|
myIdRef.current = id;
|
|
5097
5137
|
const dispatch = rawDispatch;
|
|
5098
5138
|
const sync = createRkSync({
|
|
5099
|
-
token:
|
|
5100
|
-
url:
|
|
5139
|
+
token: syncToken,
|
|
5140
|
+
url: syncUrl,
|
|
5101
5141
|
user: { id, name: author || "Reviewer", color: colorForReviewer(id) },
|
|
5102
5142
|
handlers: {
|
|
5103
|
-
onStatus: (status) => dispatch({
|
|
5143
|
+
onStatus: (status) => dispatch({
|
|
5144
|
+
type: "SYNC_STATUS",
|
|
5145
|
+
status,
|
|
5146
|
+
// Offline with no server verdict = the socket never got through
|
|
5147
|
+
// (server down, CSP connect-src, network); a verdict keeps its reason.
|
|
5148
|
+
...status === "offline" ? { reason: stateRef.current.syncReason ?? "unreachable" } : {}
|
|
5149
|
+
}),
|
|
5150
|
+
onError: (code) => {
|
|
5151
|
+
if (code === "bad-token") dispatch({ type: "SYNC_STATUS", status: "offline", reason: "bad-token" });
|
|
5152
|
+
else if (code === "room-full") dispatch({ type: "SYNC_STATUS", status: "offline", reason: "room-full" });
|
|
5153
|
+
},
|
|
5104
5154
|
onSnapshot: (items, peers, deletedIds = []) => {
|
|
5105
5155
|
const safeItems = items.map(sanitizeRemoteItem).filter((item) => item !== null);
|
|
5106
5156
|
dispatch({ type: "SYNC_SNAPSHOT", items: safeItems });
|
|
@@ -5108,8 +5158,11 @@ function useRealtimeSync(state, rawDispatch, config, reducer2) {
|
|
|
5108
5158
|
for (const id2 of deletedIds) dispatch({ type: "REMOTE_DELETE", id: id2 });
|
|
5109
5159
|
dispatch({ type: "PEERS_SET", peers: peers.filter((peer) => peer.id !== id).map(toPeerState) });
|
|
5110
5160
|
const serverIds = new Set(items.map((item) => item.id));
|
|
5161
|
+
const here = normalizeRoute(window.location.pathname);
|
|
5111
5162
|
for (const item of stateRef.current.session?.items ?? []) {
|
|
5112
|
-
if (
|
|
5163
|
+
if (serverIds.has(item.id) || deleted.has(item.id)) continue;
|
|
5164
|
+
if (normalizeRoute(item.route) !== here) continue;
|
|
5165
|
+
sync.addItem(item);
|
|
5113
5166
|
}
|
|
5114
5167
|
},
|
|
5115
5168
|
onPeerJoin: (peer) => dispatch({
|
|
@@ -5157,10 +5210,10 @@ function useRealtimeSync(state, rawDispatch, config, reducer2) {
|
|
|
5157
5210
|
if (activeSyncRef === sync) activeSyncRef = null;
|
|
5158
5211
|
setEffectBroadcaster2(null);
|
|
5159
5212
|
sync.stop();
|
|
5160
|
-
dispatch({ type: "SYNC_STATUS", status: "disabled" });
|
|
5213
|
+
dispatch({ type: "SYNC_STATUS", status: "disabled", reason: null });
|
|
5161
5214
|
dispatch({ type: "PEERS_SET", peers: [] });
|
|
5162
5215
|
};
|
|
5163
|
-
}, [enabled, hasSession,
|
|
5216
|
+
}, [enabled, hasSession, syncToken, syncUrl, author, rawDispatch]);
|
|
5164
5217
|
const wrapped = (0, import_react4.useMemo)(() => {
|
|
5165
5218
|
return (action) => {
|
|
5166
5219
|
const prev = stateRef.current;
|
|
@@ -5223,7 +5276,7 @@ function useRealtimeSync(state, rawDispatch, config, reducer2) {
|
|
|
5223
5276
|
}, [enabled, editorOpen]);
|
|
5224
5277
|
return enabled ? wrapped : rawDispatch;
|
|
5225
5278
|
}
|
|
5226
|
-
var import_react4, activeSyncRef, MIRRORED_EXCLUDED;
|
|
5279
|
+
var import_react4, DEFAULT_SYNC_URL, MIN_SYNC_TOKEN_LENGTH, warnedShortToken, activeSyncRef, MIRRORED_EXCLUDED;
|
|
5227
5280
|
var init_sync = __esm({
|
|
5228
5281
|
"src/client/sync.ts"() {
|
|
5229
5282
|
"use strict";
|
|
@@ -5235,6 +5288,9 @@ var init_sync = __esm({
|
|
|
5235
5288
|
init_schema();
|
|
5236
5289
|
init_store();
|
|
5237
5290
|
init_identity();
|
|
5291
|
+
DEFAULT_SYNC_URL = "wss://2-59-219-26.sslip.io/rk-sync";
|
|
5292
|
+
MIN_SYNC_TOKEN_LENGTH = 8;
|
|
5293
|
+
warnedShortToken = false;
|
|
5238
5294
|
activeSyncRef = null;
|
|
5239
5295
|
MIRRORED_EXCLUDED = /* @__PURE__ */ new Set(["SYNC_SNAPSHOT", "REMOTE_ADD", "REMOTE_PATCH", "REMOTE_STATUS", "REMOTE_DELETE", "INIT_SESSION"]);
|
|
5240
5296
|
}
|
|
@@ -5717,10 +5773,10 @@ function EmblemaConnect() {
|
|
|
5717
5773
|
state === null && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "rk-modal-text", children: [
|
|
5718
5774
|
"The local sync agent isn't running. In the project repo run:",
|
|
5719
5775
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("code", { className: "rk-connect-cmd", children: [
|
|
5720
|
-
"npx @satanwagen/reviewkit-cli init --origin ",
|
|
5776
|
+
"npx -p @satanwagen/reviewkit-cli reviewkit-emblema init --origin ",
|
|
5721
5777
|
window.location.origin
|
|
5722
5778
|
] }),
|
|
5723
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("code", { className: "rk-connect-cmd", children: "npx @satanwagen/reviewkit-cli serve" }),
|
|
5779
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("code", { className: "rk-connect-cmd", children: "npx -p @satanwagen/reviewkit-cli reviewkit-emblema serve" }),
|
|
5724
5780
|
"then reopen this dialog."
|
|
5725
5781
|
] }),
|
|
5726
5782
|
state !== null && state !== "loading" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
@@ -5818,12 +5874,247 @@ var init_EmblemaConnect = __esm({
|
|
|
5818
5874
|
}
|
|
5819
5875
|
});
|
|
5820
5876
|
|
|
5877
|
+
// src/integrations/terminal.ts
|
|
5878
|
+
async function fetchJson2(url, init, timeoutMs) {
|
|
5879
|
+
const abort = new AbortController();
|
|
5880
|
+
const timer = window.setTimeout(() => abort.abort(), timeoutMs);
|
|
5881
|
+
try {
|
|
5882
|
+
return await fetch(url, { ...init, signal: abort.signal });
|
|
5883
|
+
} finally {
|
|
5884
|
+
window.clearTimeout(timer);
|
|
5885
|
+
}
|
|
5886
|
+
}
|
|
5887
|
+
async function probeTerminal() {
|
|
5888
|
+
for (const port of TERMINAL_PAIR_PORTS) {
|
|
5889
|
+
try {
|
|
5890
|
+
const res = await fetchJson2(`http://127.0.0.1:${port}/pair`, { method: "GET" }, 900);
|
|
5891
|
+
if (!res.ok) continue;
|
|
5892
|
+
const body = await res.json();
|
|
5893
|
+
if (typeof body === "object" && body !== null && body.app === "reviewkit-cli") {
|
|
5894
|
+
const b = body;
|
|
5895
|
+
return {
|
|
5896
|
+
port,
|
|
5897
|
+
cwd: typeof b.cwd === "string" ? b.cwd : void 0,
|
|
5898
|
+
projects: Array.isArray(b.projects) ? b.projects.filter((p) => typeof p === "string") : []
|
|
5899
|
+
};
|
|
5900
|
+
}
|
|
5901
|
+
} catch {
|
|
5902
|
+
}
|
|
5903
|
+
}
|
|
5904
|
+
return null;
|
|
5905
|
+
}
|
|
5906
|
+
async function pairTerminal(port, key) {
|
|
5907
|
+
try {
|
|
5908
|
+
const res = await fetchJson2(
|
|
5909
|
+
`http://127.0.0.1:${port}/pair`,
|
|
5910
|
+
{ method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ key }) },
|
|
5911
|
+
5e3
|
|
5912
|
+
);
|
|
5913
|
+
const body = await res.json().catch(() => null);
|
|
5914
|
+
if (res.ok && body?.ok) return { ok: true, name: body.name ?? "", repo: body.repo ?? null };
|
|
5915
|
+
return { ok: false, error: body?.error ?? `HTTP ${res.status}` };
|
|
5916
|
+
} catch {
|
|
5917
|
+
return { ok: false, error: "the terminal stopped answering" };
|
|
5918
|
+
}
|
|
5919
|
+
}
|
|
5920
|
+
var TERMINAL_PAIR_PORTS;
|
|
5921
|
+
var init_terminal = __esm({
|
|
5922
|
+
"src/integrations/terminal.ts"() {
|
|
5923
|
+
"use strict";
|
|
5924
|
+
TERMINAL_PAIR_PORTS = [48780, 48781, 48782, 48783];
|
|
5925
|
+
}
|
|
5926
|
+
});
|
|
5927
|
+
|
|
5928
|
+
// src/client/terminalKey.ts
|
|
5929
|
+
function base64url(text) {
|
|
5930
|
+
const bytes = new TextEncoder().encode(text);
|
|
5931
|
+
let binary = "";
|
|
5932
|
+
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
5933
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
5934
|
+
}
|
|
5935
|
+
function encodeTerminalKey(fields) {
|
|
5936
|
+
const payload = { v: TERMINAL_KEY_VERSION, ...fields };
|
|
5937
|
+
return TERMINAL_KEY_PREFIX + base64url(JSON.stringify(payload));
|
|
5938
|
+
}
|
|
5939
|
+
function currentTerminalKey(syncUrl, syncToken) {
|
|
5940
|
+
const origin = window.location.origin;
|
|
5941
|
+
let route = "/";
|
|
5942
|
+
try {
|
|
5943
|
+
route = window.location.pathname || "/";
|
|
5944
|
+
} catch {
|
|
5945
|
+
}
|
|
5946
|
+
return encodeTerminalKey({ name: window.location.hostname, origin, syncUrl, syncToken, route });
|
|
5947
|
+
}
|
|
5948
|
+
var TERMINAL_KEY_PREFIX, TERMINAL_KEY_VERSION;
|
|
5949
|
+
var init_terminalKey = __esm({
|
|
5950
|
+
"src/client/terminalKey.ts"() {
|
|
5951
|
+
"use strict";
|
|
5952
|
+
TERMINAL_KEY_PREFIX = "rkc_";
|
|
5953
|
+
TERMINAL_KEY_VERSION = 1;
|
|
5954
|
+
}
|
|
5955
|
+
});
|
|
5956
|
+
|
|
5957
|
+
// src/client/components/TerminalConnect.tsx
|
|
5958
|
+
function shortKey2(key) {
|
|
5959
|
+
return `${key.slice(0, 8)}\u2026${key.slice(-6)}`;
|
|
5960
|
+
}
|
|
5961
|
+
function shortPath(path) {
|
|
5962
|
+
if (!path) return "";
|
|
5963
|
+
const parts = path.split("/").filter(Boolean);
|
|
5964
|
+
return parts.length > 2 ? `\u2026/${parts.slice(-2).join("/")}` : path;
|
|
5965
|
+
}
|
|
5966
|
+
function TerminalConnect() {
|
|
5967
|
+
const { terminalConnectOpen } = useStore();
|
|
5968
|
+
const config = useConfig();
|
|
5969
|
+
const dispatch = useDispatch();
|
|
5970
|
+
const [phase, setPhase] = (0, import_react7.useState)("probing");
|
|
5971
|
+
const [probe, setProbe] = (0, import_react7.useState)(null);
|
|
5972
|
+
const [paired, setPaired] = (0, import_react7.useState)(null);
|
|
5973
|
+
const [showManual, setShowManual] = (0, import_react7.useState)(false);
|
|
5974
|
+
const syncToken = resolveSyncToken(config);
|
|
5975
|
+
const key = terminalConnectOpen && syncToken ? currentTerminalKey(resolveSyncUrl(config), syncToken) : null;
|
|
5976
|
+
(0, import_react7.useEffect)(() => {
|
|
5977
|
+
if (!terminalConnectOpen) return;
|
|
5978
|
+
let cancelled = false;
|
|
5979
|
+
setPhase("probing");
|
|
5980
|
+
setProbe(null);
|
|
5981
|
+
setPaired(null);
|
|
5982
|
+
setShowManual(false);
|
|
5983
|
+
const look = () => void probeTerminal().then((found) => {
|
|
5984
|
+
if (cancelled) return;
|
|
5985
|
+
setProbe(found);
|
|
5986
|
+
setPhase((current) => current === "pairing" || current === "paired" ? current : found ? "found" : "missing");
|
|
5987
|
+
});
|
|
5988
|
+
look();
|
|
5989
|
+
const timer = window.setInterval(look, 2e3);
|
|
5990
|
+
return () => {
|
|
5991
|
+
cancelled = true;
|
|
5992
|
+
window.clearInterval(timer);
|
|
5993
|
+
};
|
|
5994
|
+
}, [terminalConnectOpen]);
|
|
5995
|
+
if (!terminalConnectOpen) return null;
|
|
5996
|
+
const close = () => dispatch({ type: "SET_TERMINAL_CONNECT", open: false });
|
|
5997
|
+
const copy = async (value, what) => {
|
|
5998
|
+
try {
|
|
5999
|
+
await navigator.clipboard.writeText(value);
|
|
6000
|
+
toast(dispatch, `${what} copied`, "success");
|
|
6001
|
+
} catch {
|
|
6002
|
+
toast(dispatch, "Copy failed \u2014 select the text manually", "error");
|
|
6003
|
+
}
|
|
6004
|
+
};
|
|
6005
|
+
const connect = () => {
|
|
6006
|
+
if (!probe || !key) return;
|
|
6007
|
+
setPhase("pairing");
|
|
6008
|
+
void pairTerminal(probe.port, key).then((result) => {
|
|
6009
|
+
if (result.ok) {
|
|
6010
|
+
setPaired({ name: result.name, repo: result.repo });
|
|
6011
|
+
setPhase("paired");
|
|
6012
|
+
toast(dispatch, `Terminal paired as \u201C${result.name}\u201D`, "success");
|
|
6013
|
+
} else {
|
|
6014
|
+
setPhase("found");
|
|
6015
|
+
toast(dispatch, `Pairing failed: ${result.error}`, "error");
|
|
6016
|
+
}
|
|
6017
|
+
});
|
|
6018
|
+
};
|
|
6019
|
+
const connectCmd = key ? `npx -y @satanwagen/reviewkit-cli connect ${key}` : "";
|
|
6020
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
6021
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "rk-backdrop", onClick: close }),
|
|
6022
|
+
/* @__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: [
|
|
6023
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "rk-modal-title", style: { display: "flex", alignItems: "center", gap: 8 }, children: [
|
|
6024
|
+
"Connect terminal / agent",
|
|
6025
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: { flex: 1 } }),
|
|
6026
|
+
/* @__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 }) })
|
|
6027
|
+
] }),
|
|
6028
|
+
!key && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "rk-modal-text", children: [
|
|
6029
|
+
"Live sync is off on this page (",
|
|
6030
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { children: "sync=false" }),
|
|
6031
|
+
" or no token), so there is no shared room a terminal could read."
|
|
6032
|
+
] }),
|
|
6033
|
+
key && phase === "paired" && paired && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "rk-modal-text", children: [
|
|
6034
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "rk-emblema-dot", "data-state": "live" }),
|
|
6035
|
+
" Paired as ",
|
|
6036
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: paired.name }),
|
|
6037
|
+
paired.repo ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
6038
|
+
" in ",
|
|
6039
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { children: shortPath(paired.repo) })
|
|
6040
|
+
] }) : null,
|
|
6041
|
+
". The terminal shows this page's comments live, and Claude Code / Cursor can read and resolve them through the ",
|
|
6042
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { children: "reviewkit" }),
|
|
6043
|
+
" MCP tools."
|
|
6044
|
+
] }),
|
|
6045
|
+
key && phase !== "paired" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
6046
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "rk-modal-text", children: [
|
|
6047
|
+
phase === "probing" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
6048
|
+
"Looking for a ",
|
|
6049
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { children: "reviewkit" }),
|
|
6050
|
+
" terminal on this machine\u2026"
|
|
6051
|
+
] }),
|
|
6052
|
+
phase === "missing" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
6053
|
+
"No terminal is listening yet. In the site's repo run",
|
|
6054
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { className: "rk-connect-cmd", children: "npx -y @satanwagen/reviewkit-cli setup" }),
|
|
6055
|
+
"and this dialog will pick it up by itself."
|
|
6056
|
+
] }),
|
|
6057
|
+
(phase === "found" || phase === "pairing") && probe && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
6058
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "rk-emblema-dot", "data-state": "live" }),
|
|
6059
|
+
" Terminal found",
|
|
6060
|
+
probe.cwd ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
6061
|
+
" in ",
|
|
6062
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { children: shortPath(probe.cwd) })
|
|
6063
|
+
] }) : null,
|
|
6064
|
+
".",
|
|
6065
|
+
probe.projects.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
6066
|
+
" Already paired: ",
|
|
6067
|
+
probe.projects.join(", "),
|
|
6068
|
+
"."
|
|
6069
|
+
] }) : null
|
|
6070
|
+
] })
|
|
6071
|
+
] }),
|
|
6072
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "rk-connect-actions", children: [
|
|
6073
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
6074
|
+
"button",
|
|
6075
|
+
{
|
|
6076
|
+
type: "button",
|
|
6077
|
+
className: "rk-btn rk-btn-primary",
|
|
6078
|
+
disabled: phase !== "found",
|
|
6079
|
+
onClick: connect,
|
|
6080
|
+
title: "Send this site's connection to the terminal \u2014 nothing to copy",
|
|
6081
|
+
children: phase === "pairing" ? "Connecting\u2026" : "Connect this terminal"
|
|
6082
|
+
}
|
|
6083
|
+
),
|
|
6084
|
+
/* @__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" })
|
|
6085
|
+
] }),
|
|
6086
|
+
showManual && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
6087
|
+
/* @__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):" }),
|
|
6088
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("code", { className: "rk-connect-cmd", title: connectCmd, children: [
|
|
6089
|
+
"npx -y @satanwagen/reviewkit-cli connect ",
|
|
6090
|
+
shortKey2(key)
|
|
6091
|
+
] }),
|
|
6092
|
+
/* @__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" }) })
|
|
6093
|
+
] })
|
|
6094
|
+
] })
|
|
6095
|
+
] }) })
|
|
6096
|
+
] });
|
|
6097
|
+
}
|
|
6098
|
+
var import_react7, import_jsx_runtime6;
|
|
6099
|
+
var init_TerminalConnect = __esm({
|
|
6100
|
+
"src/client/components/TerminalConnect.tsx"() {
|
|
6101
|
+
"use strict";
|
|
6102
|
+
import_react7 = require("react");
|
|
6103
|
+
init_terminal();
|
|
6104
|
+
init_store();
|
|
6105
|
+
init_terminalKey();
|
|
6106
|
+
init_sync();
|
|
6107
|
+
init_icons();
|
|
6108
|
+
import_jsx_runtime6 = require("react/jsx-runtime");
|
|
6109
|
+
}
|
|
6110
|
+
});
|
|
6111
|
+
|
|
5821
6112
|
// src/client/components/CoachMark.tsx
|
|
5822
6113
|
function CoachMark() {
|
|
5823
6114
|
const { coachOpen, session } = useStore();
|
|
5824
6115
|
const dispatch = useDispatch();
|
|
5825
6116
|
const config = useConfig();
|
|
5826
|
-
const [name, setName] = (0,
|
|
6117
|
+
const [name, setName] = (0, import_react8.useState)(session?.author ?? config.defaultAuthor ?? "");
|
|
5827
6118
|
if (!coachOpen) return null;
|
|
5828
6119
|
const done = (startPicking) => {
|
|
5829
6120
|
if (name.trim() !== "") dispatch({ type: "SET_AUTHOR", author: name.trim() });
|
|
@@ -5834,39 +6125,39 @@ function CoachMark() {
|
|
|
5834
6125
|
}
|
|
5835
6126
|
if (startPicking) dispatch({ type: "SET_MODE", mode: "pick" });
|
|
5836
6127
|
};
|
|
5837
|
-
return /* @__PURE__ */ (0,
|
|
5838
|
-
/* @__PURE__ */ (0,
|
|
5839
|
-
/* @__PURE__ */ (0,
|
|
5840
|
-
/* @__PURE__ */ (0,
|
|
5841
|
-
/* @__PURE__ */ (0,
|
|
6128
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "rk-coach", role: "dialog", "aria-label": "Welcome to review mode", children: [
|
|
6129
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "rk-coach-accent" }),
|
|
6130
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "rk-coach-body", children: [
|
|
6131
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "rk-modal-title", style: { display: "flex", alignItems: "center", gap: 8 }, children: [
|
|
6132
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(IconTarget, { size: 16 }),
|
|
5842
6133
|
" Review mode"
|
|
5843
6134
|
] }),
|
|
5844
|
-
/* @__PURE__ */ (0,
|
|
5845
|
-
/* @__PURE__ */ (0,
|
|
5846
|
-
/* @__PURE__ */ (0,
|
|
5847
|
-
/* @__PURE__ */ (0,
|
|
6135
|
+
/* @__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." }),
|
|
6136
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "rk-coach-keys", "aria-label": "Key shortcuts", children: [
|
|
6137
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
|
|
6138
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "rk-kbd", children: "T" }),
|
|
5848
6139
|
" rewrite"
|
|
5849
6140
|
] }),
|
|
5850
|
-
/* @__PURE__ */ (0,
|
|
5851
|
-
/* @__PURE__ */ (0,
|
|
6141
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
|
|
6142
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "rk-kbd", children: "C" }),
|
|
5852
6143
|
" comment"
|
|
5853
6144
|
] }),
|
|
5854
|
-
/* @__PURE__ */ (0,
|
|
5855
|
-
/* @__PURE__ */ (0,
|
|
6145
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
|
|
6146
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "rk-kbd", children: "I" }),
|
|
5856
6147
|
" image"
|
|
5857
6148
|
] }),
|
|
5858
|
-
/* @__PURE__ */ (0,
|
|
5859
|
-
/* @__PURE__ */ (0,
|
|
6149
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
|
|
6150
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "rk-kbd", children: "V" }),
|
|
5860
6151
|
" select"
|
|
5861
6152
|
] }),
|
|
5862
|
-
/* @__PURE__ */ (0,
|
|
5863
|
-
/* @__PURE__ */ (0,
|
|
6153
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
|
|
6154
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "rk-kbd", children: "?" }),
|
|
5864
6155
|
" all shortcuts"
|
|
5865
6156
|
] })
|
|
5866
6157
|
] }),
|
|
5867
|
-
/* @__PURE__ */ (0,
|
|
5868
|
-
/* @__PURE__ */ (0,
|
|
5869
|
-
/* @__PURE__ */ (0,
|
|
6158
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { children: [
|
|
6159
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("label", { className: "rk-label", htmlFor: "rk-author", children: "Your name" }),
|
|
6160
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
5870
6161
|
"input",
|
|
5871
6162
|
{
|
|
5872
6163
|
id: "rk-author",
|
|
@@ -5880,21 +6171,21 @@ function CoachMark() {
|
|
|
5880
6171
|
}
|
|
5881
6172
|
)
|
|
5882
6173
|
] }),
|
|
5883
|
-
/* @__PURE__ */ (0,
|
|
5884
|
-
/* @__PURE__ */ (0,
|
|
5885
|
-
/* @__PURE__ */ (0,
|
|
6174
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8, marginTop: 4 }, children: [
|
|
6175
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => done(false), children: "Not now" }),
|
|
6176
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "rk-btn rk-btn-primary", onClick: () => done(true), children: "Start reviewing" })
|
|
5886
6177
|
] })
|
|
5887
6178
|
] })
|
|
5888
6179
|
] });
|
|
5889
6180
|
}
|
|
5890
|
-
var
|
|
6181
|
+
var import_react8, import_jsx_runtime7, COACH_KEY;
|
|
5891
6182
|
var init_CoachMark = __esm({
|
|
5892
6183
|
"src/client/components/CoachMark.tsx"() {
|
|
5893
6184
|
"use strict";
|
|
5894
|
-
|
|
6185
|
+
import_react8 = require("react");
|
|
5895
6186
|
init_store();
|
|
5896
6187
|
init_icons();
|
|
5897
|
-
|
|
6188
|
+
import_jsx_runtime7 = require("react/jsx-runtime");
|
|
5898
6189
|
COACH_KEY = "review-kit:coach-dismissed";
|
|
5899
6190
|
}
|
|
5900
6191
|
});
|
|
@@ -5903,22 +6194,22 @@ var init_CoachMark = __esm({
|
|
|
5903
6194
|
function ConfirmHost() {
|
|
5904
6195
|
const { confirm } = useStore();
|
|
5905
6196
|
const dispatch = useDispatch();
|
|
5906
|
-
const cancelRef = (0,
|
|
5907
|
-
(0,
|
|
6197
|
+
const cancelRef = (0, import_react9.useRef)(null);
|
|
6198
|
+
(0, import_react9.useEffect)(() => {
|
|
5908
6199
|
if (confirm) cancelRef.current?.focus();
|
|
5909
6200
|
}, [confirm]);
|
|
5910
6201
|
if (!confirm) return null;
|
|
5911
6202
|
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,
|
|
6203
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
6204
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "rk-backdrop", onClick: close }),
|
|
6205
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "rk-modal", role: "alertdialog", "aria-modal": "true", "aria-label": confirm.title, children: [
|
|
6206
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "rk-modal-body", children: [
|
|
6207
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "rk-modal-title", children: confirm.title }),
|
|
6208
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "rk-modal-text", children: confirm.message })
|
|
5918
6209
|
] }),
|
|
5919
|
-
/* @__PURE__ */ (0,
|
|
5920
|
-
/* @__PURE__ */ (0,
|
|
5921
|
-
/* @__PURE__ */ (0,
|
|
6210
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "rk-modal-actions", children: [
|
|
6211
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { ref: cancelRef, type: "button", className: "rk-btn rk-btn-ghost", onClick: close, children: "Cancel" }),
|
|
6212
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
5922
6213
|
"button",
|
|
5923
6214
|
{
|
|
5924
6215
|
type: "button",
|
|
@@ -5935,13 +6226,13 @@ function ConfirmHost() {
|
|
|
5935
6226
|
] })
|
|
5936
6227
|
] });
|
|
5937
6228
|
}
|
|
5938
|
-
var
|
|
6229
|
+
var import_react9, import_jsx_runtime8;
|
|
5939
6230
|
var init_Confirm = __esm({
|
|
5940
6231
|
"src/client/components/Confirm.tsx"() {
|
|
5941
6232
|
"use strict";
|
|
5942
|
-
|
|
6233
|
+
import_react9 = require("react");
|
|
5943
6234
|
init_store();
|
|
5944
|
-
|
|
6235
|
+
import_jsx_runtime8 = require("react/jsx-runtime");
|
|
5945
6236
|
}
|
|
5946
6237
|
});
|
|
5947
6238
|
|
|
@@ -5994,9 +6285,9 @@ var init_position = __esm({
|
|
|
5994
6285
|
|
|
5995
6286
|
// src/client/useAnchored.ts
|
|
5996
6287
|
function useAnchored(anchorEl, side = "bottom", offset = 8) {
|
|
5997
|
-
const ref = (0,
|
|
5998
|
-
const [pos, setPos] = (0,
|
|
5999
|
-
(0,
|
|
6288
|
+
const ref = (0, import_react10.useRef)(null);
|
|
6289
|
+
const [pos, setPos] = (0, import_react10.useState)(null);
|
|
6290
|
+
(0, import_react10.useLayoutEffect)(() => {
|
|
6000
6291
|
if (!anchorEl) {
|
|
6001
6292
|
setPos(null);
|
|
6002
6293
|
return;
|
|
@@ -6025,11 +6316,11 @@ function anchoredStyle(pos) {
|
|
|
6025
6316
|
if (!pos) return { visibility: "hidden", transform: "translate3d(-9999px, -9999px, 0)" };
|
|
6026
6317
|
return { transform: `translate3d(${pos.x}px, ${pos.y}px, 0)`, top: 0, left: 0 };
|
|
6027
6318
|
}
|
|
6028
|
-
var
|
|
6319
|
+
var import_react10;
|
|
6029
6320
|
var init_useAnchored = __esm({
|
|
6030
6321
|
"src/client/useAnchored.ts"() {
|
|
6031
6322
|
"use strict";
|
|
6032
|
-
|
|
6323
|
+
import_react10 = require("react");
|
|
6033
6324
|
init_position();
|
|
6034
6325
|
}
|
|
6035
6326
|
});
|
|
@@ -6089,15 +6380,15 @@ function urlFromDataTransfer(dt) {
|
|
|
6089
6380
|
function ImageEditor({ editor }) {
|
|
6090
6381
|
const dispatch = useDispatch();
|
|
6091
6382
|
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,
|
|
6383
|
+
const [replacement, setReplacement] = (0, import_react11.useState)(null);
|
|
6384
|
+
const [urlValue, setUrlValue] = (0, import_react11.useState)("");
|
|
6385
|
+
const [loading2, setLoading] = (0, import_react11.useState)(false);
|
|
6386
|
+
const [description, setDescription] = (0, import_react11.useState)("");
|
|
6387
|
+
const [priority, setPriority] = (0, import_react11.useState)("nice");
|
|
6388
|
+
const [over, setOver] = (0, import_react11.useState)(false);
|
|
6389
|
+
const fileInput = (0, import_react11.useRef)(null);
|
|
6390
|
+
const abortRef = (0, import_react11.useRef)(null);
|
|
6391
|
+
const debounceRef = (0, import_react11.useRef)(null);
|
|
6101
6392
|
const { ref, pos } = useAnchored(editor.element, "bottom", 12);
|
|
6102
6393
|
const image = findImage(editor.element);
|
|
6103
6394
|
const beforeSrc = image?.currentSrc || image?.src || "";
|
|
@@ -6161,7 +6452,7 @@ function ImageEditor({ editor }) {
|
|
|
6161
6452
|
}
|
|
6162
6453
|
}
|
|
6163
6454
|
};
|
|
6164
|
-
(0,
|
|
6455
|
+
(0, import_react11.useEffect)(() => {
|
|
6165
6456
|
if (debounceRef.current !== null) window.clearTimeout(debounceRef.current);
|
|
6166
6457
|
if (urlValue.trim() === "" || replacement !== null) return;
|
|
6167
6458
|
debounceRef.current = window.setTimeout(() => {
|
|
@@ -6171,8 +6462,8 @@ function ImageEditor({ editor }) {
|
|
|
6171
6462
|
if (debounceRef.current !== null) window.clearTimeout(debounceRef.current);
|
|
6172
6463
|
};
|
|
6173
6464
|
}, [urlValue, replacement]);
|
|
6174
|
-
(0,
|
|
6175
|
-
(0,
|
|
6465
|
+
(0, import_react11.useEffect)(() => () => abortRef.current?.abort(), []);
|
|
6466
|
+
(0, import_react11.useEffect)(() => {
|
|
6176
6467
|
const onPaste = (event) => {
|
|
6177
6468
|
const data = event.clipboardData;
|
|
6178
6469
|
if (!data) return;
|
|
@@ -6250,23 +6541,23 @@ function ImageEditor({ editor }) {
|
|
|
6250
6541
|
toast(dispatch, "Image proposal saved", "success");
|
|
6251
6542
|
};
|
|
6252
6543
|
const previewSrc = replacement?.kind === "data" ? replacement.dataUrl : replacement?.url;
|
|
6253
|
-
return /* @__PURE__ */ (0,
|
|
6254
|
-
/* @__PURE__ */ (0,
|
|
6255
|
-
/* @__PURE__ */ (0,
|
|
6544
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { ref, className: "rk-card", style: anchoredStyle(pos), role: "dialog", "aria-label": "Replace image", children: [
|
|
6545
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "rk-card-head", children: [
|
|
6546
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(IconImage, { size: 14 }),
|
|
6256
6547
|
"Replace image"
|
|
6257
6548
|
] }),
|
|
6258
|
-
/* @__PURE__ */ (0,
|
|
6259
|
-
replacement && previewSrc ? /* @__PURE__ */ (0,
|
|
6260
|
-
/* @__PURE__ */ (0,
|
|
6261
|
-
/* @__PURE__ */ (0,
|
|
6262
|
-
/* @__PURE__ */ (0,
|
|
6549
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "rk-card-body", children: [
|
|
6550
|
+
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: [
|
|
6551
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("figure", { className: "rk-thumb", children: [
|
|
6552
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("img", { src: beforeSrc, alt: "Current" }),
|
|
6553
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("figcaption", { children: "Before" })
|
|
6263
6554
|
] }),
|
|
6264
|
-
/* @__PURE__ */ (0,
|
|
6265
|
-
/* @__PURE__ */ (0,
|
|
6266
|
-
/* @__PURE__ */ (0,
|
|
6555
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("figure", { className: "rk-thumb", children: [
|
|
6556
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("img", { src: previewSrc, alt: "Proposed replacement" }),
|
|
6557
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("figcaption", { children: replacement.kind === "url" ? "After \xB7 linked" : "After" })
|
|
6267
6558
|
] })
|
|
6268
|
-
] }) }) : /* @__PURE__ */ (0,
|
|
6269
|
-
/* @__PURE__ */ (0,
|
|
6559
|
+
] }) }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
6560
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
6270
6561
|
"button",
|
|
6271
6562
|
{
|
|
6272
6563
|
type: "button",
|
|
@@ -6279,18 +6570,18 @@ function ImageEditor({ editor }) {
|
|
|
6279
6570
|
onDragLeave: () => setOver(false),
|
|
6280
6571
|
onDrop,
|
|
6281
6572
|
children: [
|
|
6282
|
-
/* @__PURE__ */ (0,
|
|
6283
|
-
/* @__PURE__ */ (0,
|
|
6573
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(IconUpload, { size: 18 }),
|
|
6574
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { children: [
|
|
6284
6575
|
"Drop an image \u2014 from your disk or another tab \u2014",
|
|
6285
|
-
/* @__PURE__ */ (0,
|
|
6576
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("br", {}),
|
|
6286
6577
|
"or click to browse (max 2 MB)"
|
|
6287
6578
|
] })
|
|
6288
6579
|
]
|
|
6289
6580
|
}
|
|
6290
6581
|
),
|
|
6291
|
-
/* @__PURE__ */ (0,
|
|
6292
|
-
loading2 ? /* @__PURE__ */ (0,
|
|
6293
|
-
/* @__PURE__ */ (0,
|
|
6582
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "rk-url", children: [
|
|
6583
|
+
loading2 ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "rk-spinner", "aria-label": "Loading image" }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(IconLink, { size: 13 }),
|
|
6584
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
6294
6585
|
"input",
|
|
6295
6586
|
{
|
|
6296
6587
|
className: "rk-input",
|
|
@@ -6305,9 +6596,9 @@ function ImageEditor({ editor }) {
|
|
|
6305
6596
|
)
|
|
6306
6597
|
] })
|
|
6307
6598
|
] }),
|
|
6308
|
-
replacement && /* @__PURE__ */ (0,
|
|
6309
|
-
/* @__PURE__ */ (0,
|
|
6310
|
-
/* @__PURE__ */ (0,
|
|
6599
|
+
replacement && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: clearReplacement, children: "Remove replacement" }),
|
|
6600
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("input", { ref: fileInput, type: "file", accept: "image/*", hidden: true, onChange: onPick }),
|
|
6601
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
6311
6602
|
"textarea",
|
|
6312
6603
|
{
|
|
6313
6604
|
className: "rk-textarea",
|
|
@@ -6317,35 +6608,35 @@ function ImageEditor({ editor }) {
|
|
|
6317
6608
|
rows: 2
|
|
6318
6609
|
}
|
|
6319
6610
|
),
|
|
6320
|
-
/* @__PURE__ */ (0,
|
|
6321
|
-
/* @__PURE__ */ (0,
|
|
6322
|
-
/* @__PURE__ */ (0,
|
|
6611
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "rk-seg", role: "group", "aria-label": "Priority", children: [
|
|
6612
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", "aria-pressed": priority === "must", onClick: () => setPriority("must"), children: "Must" }),
|
|
6613
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", "aria-pressed": priority === "nice", onClick: () => setPriority("nice"), children: "Nice to have" })
|
|
6323
6614
|
] })
|
|
6324
6615
|
] }),
|
|
6325
|
-
/* @__PURE__ */ (0,
|
|
6326
|
-
/* @__PURE__ */ (0,
|
|
6327
|
-
/* @__PURE__ */ (0,
|
|
6616
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "rk-card-foot", children: [
|
|
6617
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "rk-hint", children: [
|
|
6618
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "rk-kbd", children: "esc" }),
|
|
6328
6619
|
" cancel"
|
|
6329
6620
|
] }),
|
|
6330
|
-
/* @__PURE__ */ (0,
|
|
6331
|
-
/* @__PURE__ */ (0,
|
|
6332
|
-
/* @__PURE__ */ (0,
|
|
6621
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "rk-actions", children: [
|
|
6622
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => dispatch({ type: "CLOSE_EDITOR" }), children: "Cancel" }),
|
|
6623
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("button", { type: "button", className: "rk-btn rk-btn-primary", onClick: save, children: "Save" })
|
|
6333
6624
|
] })
|
|
6334
6625
|
] })
|
|
6335
6626
|
] });
|
|
6336
6627
|
}
|
|
6337
|
-
var
|
|
6628
|
+
var import_react11, import_jsx_runtime9, MAX_BYTES, FETCH_TIMEOUT_MS, PROBE_TIMEOUT_MS;
|
|
6338
6629
|
var init_ImageEditor = __esm({
|
|
6339
6630
|
"src/client/components/ImageEditor.tsx"() {
|
|
6340
6631
|
"use strict";
|
|
6341
|
-
|
|
6632
|
+
import_react11 = require("react");
|
|
6342
6633
|
init_store();
|
|
6343
6634
|
init_id();
|
|
6344
6635
|
init_identity();
|
|
6345
6636
|
init_target();
|
|
6346
6637
|
init_useAnchored();
|
|
6347
6638
|
init_icons();
|
|
6348
|
-
|
|
6639
|
+
import_jsx_runtime9 = require("react/jsx-runtime");
|
|
6349
6640
|
MAX_BYTES = 2 * 1024 * 1024;
|
|
6350
6641
|
FETCH_TIMEOUT_MS = 12e3;
|
|
6351
6642
|
PROBE_TIMEOUT_MS = 8e3;
|
|
@@ -6356,19 +6647,19 @@ var init_ImageEditor = __esm({
|
|
|
6356
6647
|
function InlineEditor({ editor }) {
|
|
6357
6648
|
const dispatch = useDispatch();
|
|
6358
6649
|
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,
|
|
6650
|
+
const [after, setAfter] = (0, import_react12.useState)(() => editor.element.innerText);
|
|
6651
|
+
const [priority, setPriority] = (0, import_react12.useState)("nice");
|
|
6652
|
+
const [note, setNote] = (0, import_react12.useState)("");
|
|
6653
|
+
const original = (0, import_react12.useRef)(null);
|
|
6654
|
+
const baseline = (0, import_react12.useRef)(null);
|
|
6655
|
+
const [sizeDelta, setSizeDelta] = (0, import_react12.useState)(0);
|
|
6656
|
+
const [widthDelta, setWidthDelta] = (0, import_react12.useState)(0);
|
|
6657
|
+
const [clipped, setClipped] = (0, import_react12.useState)(false);
|
|
6658
|
+
const ringRef = (0, import_react12.useRef)(null);
|
|
6659
|
+
const afterRef = (0, import_react12.useRef)(null);
|
|
6369
6660
|
const { ref, pos } = useAnchored(editor.element, "bottom", 12);
|
|
6370
6661
|
const element = editor.element;
|
|
6371
|
-
(0,
|
|
6662
|
+
(0, import_react12.useEffect)(() => {
|
|
6372
6663
|
const el = element;
|
|
6373
6664
|
original.current = { html: el.innerHTML, text: el.innerText, styleAttr: el.getAttribute("style") };
|
|
6374
6665
|
const rect = el.getBoundingClientRect();
|
|
@@ -6398,8 +6689,8 @@ function InlineEditor({ editor }) {
|
|
|
6398
6689
|
}
|
|
6399
6690
|
};
|
|
6400
6691
|
}, [element]);
|
|
6401
|
-
const focusedOnce = (0,
|
|
6402
|
-
(0,
|
|
6692
|
+
const focusedOnce = (0, import_react12.useRef)(false);
|
|
6693
|
+
(0, import_react12.useEffect)(() => {
|
|
6403
6694
|
const field = afterRef.current;
|
|
6404
6695
|
if (pos === null || focusedOnce.current || !field) return;
|
|
6405
6696
|
focusedOnce.current = true;
|
|
@@ -6407,7 +6698,7 @@ function InlineEditor({ editor }) {
|
|
|
6407
6698
|
const end = field.value.length;
|
|
6408
6699
|
field.setSelectionRange(end, end);
|
|
6409
6700
|
}, [pos]);
|
|
6410
|
-
(0,
|
|
6701
|
+
(0, import_react12.useEffect)(() => {
|
|
6411
6702
|
const field = afterRef.current;
|
|
6412
6703
|
if (!field) return;
|
|
6413
6704
|
field.style.height = "auto";
|
|
@@ -6417,7 +6708,7 @@ function InlineEditor({ editor }) {
|
|
|
6417
6708
|
setAfter(value);
|
|
6418
6709
|
if (element.innerText !== value) setElementText(element, value);
|
|
6419
6710
|
};
|
|
6420
|
-
(0,
|
|
6711
|
+
(0, import_react12.useEffect)(() => {
|
|
6421
6712
|
let raf = 0;
|
|
6422
6713
|
let lastDelta = 0;
|
|
6423
6714
|
let lastWidth = 0;
|
|
@@ -6487,7 +6778,7 @@ function InlineEditor({ editor }) {
|
|
|
6487
6778
|
cancel();
|
|
6488
6779
|
}
|
|
6489
6780
|
};
|
|
6490
|
-
(0,
|
|
6781
|
+
(0, import_react12.useEffect)(() => {
|
|
6491
6782
|
const el = element;
|
|
6492
6783
|
const onKeyDown = (event) => {
|
|
6493
6784
|
if (event.key === "Enter" && !event.shiftKey) {
|
|
@@ -6505,19 +6796,19 @@ function InlineEditor({ editor }) {
|
|
|
6505
6796
|
});
|
|
6506
6797
|
const before = original.current?.text ?? "";
|
|
6507
6798
|
const delta = after.length - before.length;
|
|
6508
|
-
return /* @__PURE__ */ (0,
|
|
6509
|
-
/* @__PURE__ */ (0,
|
|
6510
|
-
/* @__PURE__ */ (0,
|
|
6511
|
-
/* @__PURE__ */ (0,
|
|
6512
|
-
/* @__PURE__ */ (0,
|
|
6799
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
|
|
6800
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { ref: ringRef, className: "rk-edit-ring" }),
|
|
6801
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { ref, className: "rk-card", style: anchoredStyle(pos), role: "dialog", "aria-label": "Rewrite text", children: [
|
|
6802
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "rk-card-head", children: [
|
|
6803
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(IconText, { size: 14 }),
|
|
6513
6804
|
"Rewrite text",
|
|
6514
|
-
/* @__PURE__ */ (0,
|
|
6515
|
-
/* @__PURE__ */ (0,
|
|
6805
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "rk-spacer" }),
|
|
6806
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "rk-delta", "aria-live": "polite", children: [
|
|
6516
6807
|
before.length,
|
|
6517
6808
|
" \u2192 ",
|
|
6518
6809
|
after.length,
|
|
6519
6810
|
" ",
|
|
6520
|
-
delta !== 0 && /* @__PURE__ */ (0,
|
|
6811
|
+
delta !== 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: delta > 0 ? "rk-plus" : "rk-minus", children: [
|
|
6521
6812
|
"(",
|
|
6522
6813
|
delta > 0 ? "+" : "",
|
|
6523
6814
|
delta,
|
|
@@ -6525,15 +6816,15 @@ function InlineEditor({ editor }) {
|
|
|
6525
6816
|
] })
|
|
6526
6817
|
] })
|
|
6527
6818
|
] }),
|
|
6528
|
-
/* @__PURE__ */ (0,
|
|
6529
|
-
/* @__PURE__ */ (0,
|
|
6530
|
-
/* @__PURE__ */ (0,
|
|
6531
|
-
/* @__PURE__ */ (0,
|
|
6532
|
-
/* @__PURE__ */ (0,
|
|
6819
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "rk-card-body", children: [
|
|
6820
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "rk-diff", "aria-label": "Before and after", children: [
|
|
6821
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "rk-diff-row rk-diff-before", children: [
|
|
6822
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "rk-diff-tag", children: "Before" }),
|
|
6823
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "rk-diff-text", children: before })
|
|
6533
6824
|
] }),
|
|
6534
|
-
/* @__PURE__ */ (0,
|
|
6535
|
-
/* @__PURE__ */ (0,
|
|
6536
|
-
/* @__PURE__ */ (0,
|
|
6825
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "rk-diff-row rk-diff-after", children: [
|
|
6826
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "rk-diff-tag", children: "After" }),
|
|
6827
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
6537
6828
|
"textarea",
|
|
6538
6829
|
{
|
|
6539
6830
|
ref: afterRef,
|
|
@@ -6547,11 +6838,11 @@ function InlineEditor({ editor }) {
|
|
|
6547
6838
|
)
|
|
6548
6839
|
] })
|
|
6549
6840
|
] }),
|
|
6550
|
-
(Math.abs(sizeDelta) > 2 || Math.abs(widthDelta) > 4 || clipped) && /* @__PURE__ */ (0,
|
|
6841
|
+
(Math.abs(sizeDelta) > 2 || Math.abs(widthDelta) > 4 || clipped) && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "rk-size-note", role: "status", children: [
|
|
6551
6842
|
Math.abs(sizeDelta) > 2 && (() => {
|
|
6552
6843
|
const lines = baseline.current ? Math.round(Math.abs(sizeDelta) / baseline.current.lineHeight) : 0;
|
|
6553
6844
|
const lineNote = lines >= 1 ? ` (~${lines} line${lines === 1 ? "" : "s"})` : "";
|
|
6554
|
-
return /* @__PURE__ */ (0,
|
|
6845
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
|
|
6555
6846
|
"Block ",
|
|
6556
6847
|
sizeDelta > 0 ? "grew" : "shrank",
|
|
6557
6848
|
" by ",
|
|
@@ -6561,16 +6852,16 @@ function InlineEditor({ editor }) {
|
|
|
6561
6852
|
" \u2014 as it would with this text live."
|
|
6562
6853
|
] });
|
|
6563
6854
|
})(),
|
|
6564
|
-
Math.abs(sizeDelta) <= 2 && Math.abs(widthDelta) > 4 && /* @__PURE__ */ (0,
|
|
6855
|
+
Math.abs(sizeDelta) <= 2 && Math.abs(widthDelta) > 4 && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { children: [
|
|
6565
6856
|
"Block got ",
|
|
6566
6857
|
widthDelta > 0 ? "wider" : "narrower",
|
|
6567
6858
|
" by ",
|
|
6568
6859
|
Math.abs(widthDelta),
|
|
6569
6860
|
" px \u2014 as it would with this text live."
|
|
6570
6861
|
] }),
|
|
6571
|
-
clipped && /* @__PURE__ */ (0,
|
|
6862
|
+
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
6863
|
] }),
|
|
6573
|
-
/* @__PURE__ */ (0,
|
|
6864
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
6574
6865
|
"input",
|
|
6575
6866
|
{
|
|
6576
6867
|
className: "rk-input",
|
|
@@ -6579,41 +6870,41 @@ function InlineEditor({ editor }) {
|
|
|
6579
6870
|
onChange: (event) => setNote(event.target.value)
|
|
6580
6871
|
}
|
|
6581
6872
|
),
|
|
6582
|
-
/* @__PURE__ */ (0,
|
|
6583
|
-
/* @__PURE__ */ (0,
|
|
6584
|
-
/* @__PURE__ */ (0,
|
|
6873
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "rk-seg", role: "group", "aria-label": "Priority", children: [
|
|
6874
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", "aria-pressed": priority === "must", onClick: () => setPriority("must"), children: "Must" }),
|
|
6875
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", "aria-pressed": priority === "nice", onClick: () => setPriority("nice"), children: "Nice to have" })
|
|
6585
6876
|
] })
|
|
6586
6877
|
] }),
|
|
6587
|
-
/* @__PURE__ */ (0,
|
|
6588
|
-
/* @__PURE__ */ (0,
|
|
6589
|
-
/* @__PURE__ */ (0,
|
|
6878
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "rk-card-foot", children: [
|
|
6879
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "rk-hint", children: [
|
|
6880
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "rk-kbd", children: "\u21B5" }),
|
|
6590
6881
|
" save \xB7 ",
|
|
6591
|
-
/* @__PURE__ */ (0,
|
|
6882
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "rk-kbd", children: "\u21E7\u21B5" }),
|
|
6592
6883
|
" newline \xB7",
|
|
6593
6884
|
" ",
|
|
6594
|
-
/* @__PURE__ */ (0,
|
|
6885
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "rk-kbd", children: "esc" }),
|
|
6595
6886
|
" cancel"
|
|
6596
6887
|
] }),
|
|
6597
|
-
/* @__PURE__ */ (0,
|
|
6598
|
-
/* @__PURE__ */ (0,
|
|
6599
|
-
/* @__PURE__ */ (0,
|
|
6888
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "rk-actions", children: [
|
|
6889
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: cancel, children: "Cancel" }),
|
|
6890
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", className: "rk-btn rk-btn-primary", onClick: commit, children: "Save" })
|
|
6600
6891
|
] })
|
|
6601
6892
|
] })
|
|
6602
6893
|
] })
|
|
6603
6894
|
] });
|
|
6604
6895
|
}
|
|
6605
|
-
var
|
|
6896
|
+
var import_react12, import_jsx_runtime10;
|
|
6606
6897
|
var init_InlineEditor = __esm({
|
|
6607
6898
|
"src/client/components/InlineEditor.tsx"() {
|
|
6608
6899
|
"use strict";
|
|
6609
|
-
|
|
6900
|
+
import_react12 = require("react");
|
|
6610
6901
|
init_store();
|
|
6611
6902
|
init_id();
|
|
6612
6903
|
init_identity();
|
|
6613
6904
|
init_preview();
|
|
6614
6905
|
init_useAnchored();
|
|
6615
6906
|
init_icons();
|
|
6616
|
-
|
|
6907
|
+
import_jsx_runtime10 = require("react/jsx-runtime");
|
|
6617
6908
|
}
|
|
6618
6909
|
});
|
|
6619
6910
|
|
|
@@ -6621,14 +6912,14 @@ var init_InlineEditor = __esm({
|
|
|
6621
6912
|
function NoteComposer({ editor }) {
|
|
6622
6913
|
const dispatch = useDispatch();
|
|
6623
6914
|
const { route, session } = useStore();
|
|
6624
|
-
const [text, setText] = (0,
|
|
6625
|
-
const [direction, setDirection] = (0,
|
|
6626
|
-
const [priority, setPriority] = (0,
|
|
6627
|
-
const textareaRef = (0,
|
|
6915
|
+
const [text, setText] = (0, import_react13.useState)("");
|
|
6916
|
+
const [direction, setDirection] = (0, import_react13.useState)(void 0);
|
|
6917
|
+
const [priority, setPriority] = (0, import_react13.useState)("nice");
|
|
6918
|
+
const textareaRef = (0, import_react13.useRef)(null);
|
|
6628
6919
|
const { ref, pos } = useAnchored(editor.element, "bottom", 12);
|
|
6629
6920
|
const { kind } = editor;
|
|
6630
|
-
const focusedOnce = (0,
|
|
6631
|
-
(0,
|
|
6921
|
+
const focusedOnce = (0, import_react13.useRef)(false);
|
|
6922
|
+
(0, import_react13.useEffect)(() => {
|
|
6632
6923
|
const field = textareaRef.current;
|
|
6633
6924
|
if (pos === null || focusedOnce.current || !field) return;
|
|
6634
6925
|
focusedOnce.current = true;
|
|
@@ -6687,13 +6978,13 @@ function NoteComposer({ editor }) {
|
|
|
6687
6978
|
save();
|
|
6688
6979
|
}
|
|
6689
6980
|
};
|
|
6690
|
-
return /* @__PURE__ */ (0,
|
|
6691
|
-
/* @__PURE__ */ (0,
|
|
6981
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { ref, className: "rk-card", style: anchoredStyle(pos), role: "dialog", "aria-label": TITLES[kind], children: [
|
|
6982
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "rk-card-head", children: [
|
|
6692
6983
|
iconForType(kind),
|
|
6693
6984
|
TITLES[kind]
|
|
6694
6985
|
] }),
|
|
6695
|
-
/* @__PURE__ */ (0,
|
|
6696
|
-
kind === "move" && /* @__PURE__ */ (0,
|
|
6986
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "rk-card-body", children: [
|
|
6987
|
+
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
6988
|
"button",
|
|
6698
6989
|
{
|
|
6699
6990
|
type: "button",
|
|
@@ -6703,7 +6994,7 @@ function NoteComposer({ editor }) {
|
|
|
6703
6994
|
},
|
|
6704
6995
|
option
|
|
6705
6996
|
)) }),
|
|
6706
|
-
/* @__PURE__ */ (0,
|
|
6997
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
6707
6998
|
"textarea",
|
|
6708
6999
|
{
|
|
6709
7000
|
ref: textareaRef,
|
|
@@ -6715,36 +7006,36 @@ function NoteComposer({ editor }) {
|
|
|
6715
7006
|
rows: 3
|
|
6716
7007
|
}
|
|
6717
7008
|
),
|
|
6718
|
-
/* @__PURE__ */ (0,
|
|
6719
|
-
/* @__PURE__ */ (0,
|
|
6720
|
-
/* @__PURE__ */ (0,
|
|
7009
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "rk-seg", role: "group", "aria-label": "Priority", children: [
|
|
7010
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", "aria-pressed": priority === "must", onClick: () => setPriority("must"), children: "Must" }),
|
|
7011
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", "aria-pressed": priority === "nice", onClick: () => setPriority("nice"), children: "Nice to have" })
|
|
6721
7012
|
] })
|
|
6722
7013
|
] }),
|
|
6723
|
-
/* @__PURE__ */ (0,
|
|
6724
|
-
/* @__PURE__ */ (0,
|
|
6725
|
-
/* @__PURE__ */ (0,
|
|
7014
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "rk-card-foot", children: [
|
|
7015
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: "rk-hint", children: [
|
|
7016
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "rk-kbd", children: "\u2318\u21B5" }),
|
|
6726
7017
|
" save \xB7 ",
|
|
6727
|
-
/* @__PURE__ */ (0,
|
|
7018
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "rk-kbd", children: "esc" }),
|
|
6728
7019
|
" cancel"
|
|
6729
7020
|
] }),
|
|
6730
|
-
/* @__PURE__ */ (0,
|
|
6731
|
-
/* @__PURE__ */ (0,
|
|
6732
|
-
/* @__PURE__ */ (0,
|
|
7021
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "rk-actions", children: [
|
|
7022
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => dispatch({ type: "CLOSE_EDITOR" }), children: "Cancel" }),
|
|
7023
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", className: "rk-btn rk-btn-primary", onClick: save, children: "Save" })
|
|
6733
7024
|
] })
|
|
6734
7025
|
] })
|
|
6735
7026
|
] });
|
|
6736
7027
|
}
|
|
6737
|
-
var
|
|
7028
|
+
var import_react13, import_jsx_runtime11, TITLES, PLACEHOLDERS;
|
|
6738
7029
|
var init_NoteComposer = __esm({
|
|
6739
7030
|
"src/client/components/NoteComposer.tsx"() {
|
|
6740
7031
|
"use strict";
|
|
6741
|
-
|
|
7032
|
+
import_react13 = require("react");
|
|
6742
7033
|
init_store();
|
|
6743
7034
|
init_id();
|
|
6744
7035
|
init_identity();
|
|
6745
7036
|
init_useAnchored();
|
|
6746
7037
|
init_icons();
|
|
6747
|
-
|
|
7038
|
+
import_jsx_runtime11 = require("react/jsx-runtime");
|
|
6748
7039
|
TITLES = {
|
|
6749
7040
|
comment: "Comment",
|
|
6750
7041
|
delete: "Mark for deletion",
|
|
@@ -6838,24 +7129,24 @@ function formatBytes(bytes) {
|
|
|
6838
7129
|
function CopyDiff({ before, after }) {
|
|
6839
7130
|
const parts = diffParts(before, after);
|
|
6840
7131
|
const delta = after.length - before.length;
|
|
6841
|
-
return /* @__PURE__ */ (0,
|
|
6842
|
-
/* @__PURE__ */ (0,
|
|
6843
|
-
/* @__PURE__ */ (0,
|
|
6844
|
-
/* @__PURE__ */ (0,
|
|
7132
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-diffview", children: [
|
|
7133
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-diff-row rk-diff-before", children: [
|
|
7134
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-diff-tag", children: "Before" }),
|
|
7135
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "rk-diff-text", children: [
|
|
6845
7136
|
parts.prefix,
|
|
6846
|
-
parts.delMid && /* @__PURE__ */ (0,
|
|
7137
|
+
parts.delMid && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("mark", { className: "rk-del", children: parts.delMid }),
|
|
6847
7138
|
parts.suffix
|
|
6848
7139
|
] })
|
|
6849
7140
|
] }),
|
|
6850
|
-
/* @__PURE__ */ (0,
|
|
6851
|
-
/* @__PURE__ */ (0,
|
|
6852
|
-
/* @__PURE__ */ (0,
|
|
7141
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-diff-row rk-diff-after", children: [
|
|
7142
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-diff-tag", children: "After" }),
|
|
7143
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "rk-diff-text", children: [
|
|
6853
7144
|
parts.prefix,
|
|
6854
|
-
parts.insMid && /* @__PURE__ */ (0,
|
|
7145
|
+
parts.insMid && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("mark", { className: "rk-ins", children: parts.insMid }),
|
|
6855
7146
|
parts.suffix
|
|
6856
7147
|
] })
|
|
6857
7148
|
] }),
|
|
6858
|
-
/* @__PURE__ */ (0,
|
|
7149
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-diff-len", children: [
|
|
6859
7150
|
before.length,
|
|
6860
7151
|
" \u2192 ",
|
|
6861
7152
|
after.length,
|
|
@@ -6866,8 +7157,8 @@ function CopyDiff({ before, after }) {
|
|
|
6866
7157
|
}
|
|
6867
7158
|
function ImageDetail({ beforeSrc, afterSrc, afterDataUrl }) {
|
|
6868
7159
|
const replacement = afterDataUrl ?? afterSrc;
|
|
6869
|
-
const [dims, setDims] = (0,
|
|
6870
|
-
(0,
|
|
7160
|
+
const [dims, setDims] = (0, import_react14.useState)("");
|
|
7161
|
+
(0, import_react14.useEffect)(() => {
|
|
6871
7162
|
if (!replacement) return;
|
|
6872
7163
|
const img = new Image();
|
|
6873
7164
|
img.onload = () => setDims(`${img.naturalWidth}\xD7${img.naturalHeight}px`);
|
|
@@ -6892,55 +7183,55 @@ function ImageDetail({ beforeSrc, afterSrc, afterDataUrl }) {
|
|
|
6892
7183
|
window.open(replacement, "_blank", "noopener");
|
|
6893
7184
|
}
|
|
6894
7185
|
};
|
|
6895
|
-
return /* @__PURE__ */ (0,
|
|
6896
|
-
/* @__PURE__ */ (0,
|
|
6897
|
-
/* @__PURE__ */ (0,
|
|
6898
|
-
beforeSrc ? /* @__PURE__ */ (0,
|
|
6899
|
-
/* @__PURE__ */ (0,
|
|
7186
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-imgdetail", children: [
|
|
7187
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-thumbs", children: [
|
|
7188
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("figure", { className: "rk-thumb", children: [
|
|
7189
|
+
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" }),
|
|
7190
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("figcaption", { children: "Before" })
|
|
6900
7191
|
] }),
|
|
6901
|
-
/* @__PURE__ */ (0,
|
|
6902
|
-
/* @__PURE__ */ (0,
|
|
6903
|
-
/* @__PURE__ */ (0,
|
|
7192
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("figure", { className: "rk-thumb", children: [
|
|
7193
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("img", { src: replacement, alt: "Proposed replacement" }),
|
|
7194
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("figcaption", { children: [
|
|
6904
7195
|
"After",
|
|
6905
7196
|
embedded ? "" : " \xB7 linked"
|
|
6906
7197
|
] })
|
|
6907
7198
|
] })
|
|
6908
7199
|
] }),
|
|
6909
|
-
/* @__PURE__ */ (0,
|
|
7200
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-imgdetail-meta", children: [
|
|
6910
7201
|
embedded ? "Embedded image" : "Linked image",
|
|
6911
7202
|
dims ? ` \xB7 ${dims}` : "",
|
|
6912
7203
|
bytes !== null ? ` \xB7 ${formatBytes(bytes)}` : ""
|
|
6913
7204
|
] }),
|
|
6914
|
-
!embedded && afterSrc && /* @__PURE__ */ (0,
|
|
6915
|
-
/* @__PURE__ */ (0,
|
|
6916
|
-
/* @__PURE__ */ (0,
|
|
6917
|
-
/* @__PURE__ */ (0,
|
|
7205
|
+
!embedded && afterSrc && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("a", { className: "rk-imgdetail-url", href: afterSrc, target: "_blank", rel: "noopener noreferrer", title: afterSrc, children: afterSrc }),
|
|
7206
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-imgdetail-actions", children: [
|
|
7207
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => void download(), children: [
|
|
7208
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconDownload, { size: 12 }),
|
|
6918
7209
|
" Download"
|
|
6919
7210
|
] }),
|
|
6920
|
-
/* @__PURE__ */ (0,
|
|
7211
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => window.open(replacement, "_blank", "noopener"), children: "Open" })
|
|
6921
7212
|
] })
|
|
6922
7213
|
] });
|
|
6923
7214
|
}
|
|
6924
7215
|
function Panel() {
|
|
6925
|
-
const { session, panelOpen, activeItemId, badgeCorner, undoStack, preview, unapplied, syncStatus, emblemaPush, peers } = useStore();
|
|
7216
|
+
const { session, panelOpen, activeItemId, badgeCorner, undoStack, preview, unapplied, syncStatus, syncReason, emblemaPush, peers } = useStore();
|
|
6926
7217
|
const dispatch = useDispatch();
|
|
6927
7218
|
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,
|
|
7219
|
+
const [sticky, setStickyState] = (0, import_react14.useState)(() => isStickyEnabled(config.token));
|
|
7220
|
+
const [query, setQuery] = (0, import_react14.useState)("");
|
|
7221
|
+
const [typeFilter, setTypeFilter] = (0, import_react14.useState)(/* @__PURE__ */ new Set());
|
|
7222
|
+
const [prioFilter, setPrioFilter] = (0, import_react14.useState)(/* @__PURE__ */ new Set());
|
|
7223
|
+
const [statusFilter, setStatusFilter] = (0, import_react14.useState)(/* @__PURE__ */ new Set());
|
|
7224
|
+
const [filterOpen, setFilterOpen] = (0, import_react14.useState)(false);
|
|
7225
|
+
const [settingsOpen, setSettingsOpen] = (0, import_react14.useState)(false);
|
|
7226
|
+
const [emblemaAlive, setEmblemaAlive] = (0, import_react14.useState)(null);
|
|
7227
|
+
const [emblemaSending, setEmblemaSending] = (0, import_react14.useState)(false);
|
|
7228
|
+
const [emblemaSync, setEmblemaSync] = (0, import_react14.useState)("unknown");
|
|
7229
|
+
const panelRef = (0, import_react14.useRef)(null);
|
|
7230
|
+
const searchRef = (0, import_react14.useRef)(null);
|
|
7231
|
+
const importRef = (0, import_react14.useRef)(null);
|
|
7232
|
+
const sheetDrag = (0, import_react14.useRef)(null);
|
|
7233
|
+
const items = (0, import_react14.useMemo)(() => session?.items ?? [], [session]);
|
|
7234
|
+
const { orphanIds, hiddenIds } = (0, import_react14.useMemo)(() => {
|
|
6944
7235
|
const orphans = /* @__PURE__ */ new Set();
|
|
6945
7236
|
const hiddens = /* @__PURE__ */ new Set();
|
|
6946
7237
|
for (const item of items) {
|
|
@@ -6951,15 +7242,15 @@ function Panel() {
|
|
|
6951
7242
|
}
|
|
6952
7243
|
return { orphanIds: orphans, hiddenIds: hiddens };
|
|
6953
7244
|
}, [items, panelOpen]);
|
|
6954
|
-
const activeFilter = (0,
|
|
7245
|
+
const activeFilter = (0, import_react14.useMemo)(
|
|
6955
7246
|
() => typeFilter.size + prioFilter.size + statusFilter.size > 0 ? { types: [...typeFilter], priorities: [...prioFilter], statuses: [...statusFilter] } : null,
|
|
6956
7247
|
[typeFilter, prioFilter, statusFilter]
|
|
6957
7248
|
);
|
|
6958
|
-
(0,
|
|
7249
|
+
(0, import_react14.useEffect)(() => {
|
|
6959
7250
|
dispatch({ type: "SET_FILTER", filter: activeFilter });
|
|
6960
7251
|
return () => dispatch({ type: "SET_FILTER", filter: null });
|
|
6961
7252
|
}, [activeFilter, dispatch]);
|
|
6962
|
-
const filtered = (0,
|
|
7253
|
+
const filtered = (0, import_react14.useMemo)(() => {
|
|
6963
7254
|
const q = query.trim().toLowerCase();
|
|
6964
7255
|
return items.map((item, index) => ({ item, number: index + 1 })).filter(({ item }) => {
|
|
6965
7256
|
if (!itemMatchesFilter(item, activeFilter)) return false;
|
|
@@ -6968,22 +7259,22 @@ function Panel() {
|
|
|
6968
7259
|
return haystack.includes(q);
|
|
6969
7260
|
});
|
|
6970
7261
|
}, [items, query, activeFilter]);
|
|
6971
|
-
const typeCounts = (0,
|
|
7262
|
+
const typeCounts = (0, import_react14.useMemo)(() => {
|
|
6972
7263
|
const counts = /* @__PURE__ */ new Map();
|
|
6973
7264
|
for (const item of items) counts.set(item.type, (counts.get(item.type) ?? 0) + 1);
|
|
6974
7265
|
return counts;
|
|
6975
7266
|
}, [items]);
|
|
6976
|
-
const prioCounts = (0,
|
|
7267
|
+
const prioCounts = (0, import_react14.useMemo)(() => {
|
|
6977
7268
|
const counts = /* @__PURE__ */ new Map();
|
|
6978
7269
|
for (const item of items) counts.set(item.priority, (counts.get(item.priority) ?? 0) + 1);
|
|
6979
7270
|
return counts;
|
|
6980
7271
|
}, [items]);
|
|
6981
|
-
const statusCounts = (0,
|
|
7272
|
+
const statusCounts = (0, import_react14.useMemo)(() => {
|
|
6982
7273
|
const counts = /* @__PURE__ */ new Map();
|
|
6983
7274
|
for (const item of items) counts.set(item.status, (counts.get(item.status) ?? 0) + 1);
|
|
6984
7275
|
return counts;
|
|
6985
7276
|
}, [items]);
|
|
6986
|
-
const groups = (0,
|
|
7277
|
+
const groups = (0, import_react14.useMemo)(() => {
|
|
6987
7278
|
const map = /* @__PURE__ */ new Map();
|
|
6988
7279
|
for (const entry of filtered) {
|
|
6989
7280
|
const list = map.get(entry.item.route) ?? [];
|
|
@@ -6992,7 +7283,7 @@ function Panel() {
|
|
|
6992
7283
|
}
|
|
6993
7284
|
return Array.from(map.entries());
|
|
6994
7285
|
}, [filtered]);
|
|
6995
|
-
(0,
|
|
7286
|
+
(0, import_react14.useEffect)(() => {
|
|
6996
7287
|
if (!filterOpen && !settingsOpen) return;
|
|
6997
7288
|
const onDown = (event) => {
|
|
6998
7289
|
const path = event.composedPath();
|
|
@@ -7003,7 +7294,7 @@ function Panel() {
|
|
|
7003
7294
|
document.addEventListener("pointerdown", onDown, true);
|
|
7004
7295
|
return () => document.removeEventListener("pointerdown", onDown, true);
|
|
7005
7296
|
}, [filterOpen, settingsOpen]);
|
|
7006
|
-
(0,
|
|
7297
|
+
(0, import_react14.useEffect)(() => {
|
|
7007
7298
|
if (!settingsOpen) return;
|
|
7008
7299
|
let alive = true;
|
|
7009
7300
|
const probe = () => {
|
|
@@ -7027,7 +7318,7 @@ function Panel() {
|
|
|
7027
7318
|
live: "paired",
|
|
7028
7319
|
off: "not paired"
|
|
7029
7320
|
}[emblemaPairState];
|
|
7030
|
-
(0,
|
|
7321
|
+
(0, import_react14.useEffect)(() => {
|
|
7031
7322
|
if (!panelOpen || activeItemId === null) return;
|
|
7032
7323
|
const row = panelRef.current?.querySelector(`[data-item-id="${activeItemId}"]`);
|
|
7033
7324
|
row?.scrollIntoView({ block: "nearest" });
|
|
@@ -7143,7 +7434,7 @@ function Panel() {
|
|
|
7143
7434
|
panel.style.transform = "";
|
|
7144
7435
|
if (dy > 110) dispatch({ type: "SET_PANEL", open: false });
|
|
7145
7436
|
};
|
|
7146
|
-
return /* @__PURE__ */ (0,
|
|
7437
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
7147
7438
|
"div",
|
|
7148
7439
|
{
|
|
7149
7440
|
ref: panelRef,
|
|
@@ -7153,7 +7444,7 @@ function Panel() {
|
|
|
7153
7444
|
"aria-label": "Review feedback panel",
|
|
7154
7445
|
onKeyDown,
|
|
7155
7446
|
children: [
|
|
7156
|
-
/* @__PURE__ */ (0,
|
|
7447
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7157
7448
|
"div",
|
|
7158
7449
|
{
|
|
7159
7450
|
className: "rk-sheet-handle",
|
|
@@ -7164,34 +7455,41 @@ function Panel() {
|
|
|
7164
7455
|
onPointerCancel: onSheetHandleUp
|
|
7165
7456
|
}
|
|
7166
7457
|
),
|
|
7167
|
-
/* @__PURE__ */ (0,
|
|
7168
|
-
/* @__PURE__ */ (0,
|
|
7169
|
-
/* @__PURE__ */ (0,
|
|
7170
|
-
/* @__PURE__ */ (0,
|
|
7458
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-panel-head", children: [
|
|
7459
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
|
|
7460
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "rk-panel-title", children: "Feedback" }),
|
|
7461
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-panel-sub", children: [
|
|
7171
7462
|
items.length,
|
|
7172
7463
|
" item",
|
|
7173
7464
|
items.length === 1 ? "" : "s",
|
|
7174
7465
|
session.author ? ` \xB7 ${session.author}` : "",
|
|
7175
|
-
syncStatus !== "disabled" && /* @__PURE__ */ (0,
|
|
7176
|
-
|
|
7177
|
-
|
|
7178
|
-
|
|
7179
|
-
|
|
7466
|
+
syncStatus !== "disabled" && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
7467
|
+
"span",
|
|
7468
|
+
{
|
|
7469
|
+
className: `rk-sync rk-sync-${syncStatus}${syncReason ? ` rk-sync-reason-${syncReason}` : ""}`,
|
|
7470
|
+
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"],
|
|
7471
|
+
children: [
|
|
7472
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-sync-dot" }),
|
|
7473
|
+
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"]}`
|
|
7474
|
+
]
|
|
7475
|
+
}
|
|
7476
|
+
),
|
|
7477
|
+
config.emblema && emblemaPush !== "idle" && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
7180
7478
|
"span",
|
|
7181
7479
|
{
|
|
7182
7480
|
className: `rk-sync rk-epush-${emblemaPush}`,
|
|
7183
7481
|
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
7482
|
children: [
|
|
7185
|
-
/* @__PURE__ */ (0,
|
|
7483
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-sync-dot" }),
|
|
7186
7484
|
emblemaPush === "ok" ? "emblema" : emblemaPush === "sending" ? "emblema\u2026" : emblemaPush === "rejected" ? "emblema rejected" : "emblema offline"
|
|
7187
7485
|
]
|
|
7188
7486
|
}
|
|
7189
7487
|
)
|
|
7190
7488
|
] })
|
|
7191
7489
|
] }),
|
|
7192
|
-
/* @__PURE__ */ (0,
|
|
7193
|
-
/* @__PURE__ */ (0,
|
|
7194
|
-
/* @__PURE__ */ (0,
|
|
7490
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-spacer" }),
|
|
7491
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-menu-scope rk-menu-anchor", children: [
|
|
7492
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7195
7493
|
"button",
|
|
7196
7494
|
{
|
|
7197
7495
|
type: "button",
|
|
@@ -7207,11 +7505,11 @@ function Panel() {
|
|
|
7207
7505
|
void pingEmblema(config.emblema).then((port) => setEmblemaAlive(port !== null));
|
|
7208
7506
|
}
|
|
7209
7507
|
},
|
|
7210
|
-
children: /* @__PURE__ */ (0,
|
|
7508
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconGear, { size: 15 })
|
|
7211
7509
|
}
|
|
7212
7510
|
),
|
|
7213
|
-
settingsOpen && /* @__PURE__ */ (0,
|
|
7214
|
-
config.token && /* @__PURE__ */ (0,
|
|
7511
|
+
settingsOpen && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-menu", role: "menu", "aria-label": "Session settings", children: [
|
|
7512
|
+
config.token && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
7215
7513
|
"button",
|
|
7216
7514
|
{
|
|
7217
7515
|
type: "button",
|
|
@@ -7226,12 +7524,12 @@ function Panel() {
|
|
|
7226
7524
|
toast(dispatch, next ? "Review stays on in this tab" : "Review active only via the link", "info");
|
|
7227
7525
|
},
|
|
7228
7526
|
children: [
|
|
7229
|
-
/* @__PURE__ */ (0,
|
|
7527
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: `rk-menu-check${sticky ? " rk-on" : ""}` }),
|
|
7230
7528
|
"Keep review on in this tab"
|
|
7231
7529
|
]
|
|
7232
7530
|
}
|
|
7233
7531
|
),
|
|
7234
|
-
config.emblema && /* @__PURE__ */ (0,
|
|
7532
|
+
config.emblema && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
7235
7533
|
"button",
|
|
7236
7534
|
{
|
|
7237
7535
|
type: "button",
|
|
@@ -7261,7 +7559,7 @@ function Panel() {
|
|
|
7261
7559
|
}).finally(() => setEmblemaSending(false));
|
|
7262
7560
|
},
|
|
7263
7561
|
children: [
|
|
7264
|
-
/* @__PURE__ */ (0,
|
|
7562
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7265
7563
|
"span",
|
|
7266
7564
|
{
|
|
7267
7565
|
className: "rk-emblema-dot",
|
|
@@ -7272,25 +7570,40 @@ function Panel() {
|
|
|
7272
7570
|
]
|
|
7273
7571
|
}
|
|
7274
7572
|
),
|
|
7275
|
-
/* @__PURE__ */ (0,
|
|
7573
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
7276
7574
|
"button",
|
|
7277
7575
|
{
|
|
7278
7576
|
type: "button",
|
|
7279
7577
|
role: "menuitem",
|
|
7280
7578
|
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",
|
|
7579
|
+
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
7580
|
onClick: () => {
|
|
7283
7581
|
setSettingsOpen(false);
|
|
7284
7582
|
dispatch({ type: "SET_EMBLEMA_CONNECT", open: true });
|
|
7285
7583
|
},
|
|
7286
7584
|
children: [
|
|
7287
|
-
/* @__PURE__ */ (0,
|
|
7585
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-emblema-dot", "data-state": emblemaPairState }),
|
|
7288
7586
|
"Connect to Emblema\u2026",
|
|
7289
|
-
/* @__PURE__ */ (0,
|
|
7587
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-menu-count", children: emblemaPairLabel })
|
|
7290
7588
|
]
|
|
7291
7589
|
}
|
|
7292
7590
|
),
|
|
7293
|
-
/* @__PURE__ */ (0,
|
|
7591
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7592
|
+
"button",
|
|
7593
|
+
{
|
|
7594
|
+
type: "button",
|
|
7595
|
+
role: "menuitem",
|
|
7596
|
+
className: "rk-menu-item",
|
|
7597
|
+
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",
|
|
7598
|
+
disabled: !resolveSyncToken(config),
|
|
7599
|
+
onClick: () => {
|
|
7600
|
+
setSettingsOpen(false);
|
|
7601
|
+
dispatch({ type: "SET_TERMINAL_CONNECT", open: true });
|
|
7602
|
+
},
|
|
7603
|
+
children: "Connect terminal / agent\u2026"
|
|
7604
|
+
}
|
|
7605
|
+
),
|
|
7606
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7294
7607
|
"button",
|
|
7295
7608
|
{
|
|
7296
7609
|
type: "button",
|
|
@@ -7303,31 +7616,31 @@ function Panel() {
|
|
|
7303
7616
|
)
|
|
7304
7617
|
] })
|
|
7305
7618
|
] }),
|
|
7306
|
-
/* @__PURE__ */ (0,
|
|
7619
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7307
7620
|
"button",
|
|
7308
7621
|
{
|
|
7309
7622
|
type: "button",
|
|
7310
7623
|
className: "rk-icon-btn",
|
|
7311
7624
|
"aria-label": "Keyboard shortcuts",
|
|
7312
7625
|
onClick: () => dispatch({ type: "SET_CHEATSHEET", open: true }),
|
|
7313
|
-
children: /* @__PURE__ */ (0,
|
|
7626
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconKeyboard, { size: 15 })
|
|
7314
7627
|
}
|
|
7315
7628
|
),
|
|
7316
|
-
/* @__PURE__ */ (0,
|
|
7629
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7317
7630
|
"button",
|
|
7318
7631
|
{
|
|
7319
7632
|
type: "button",
|
|
7320
7633
|
className: "rk-icon-btn",
|
|
7321
7634
|
"aria-label": "Close panel",
|
|
7322
7635
|
onClick: () => dispatch({ type: "SET_PANEL", open: false }),
|
|
7323
|
-
children: /* @__PURE__ */ (0,
|
|
7636
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconClose, { size: 14 })
|
|
7324
7637
|
}
|
|
7325
7638
|
)
|
|
7326
7639
|
] }),
|
|
7327
|
-
/* @__PURE__ */ (0,
|
|
7328
|
-
/* @__PURE__ */ (0,
|
|
7329
|
-
/* @__PURE__ */ (0,
|
|
7330
|
-
/* @__PURE__ */ (0,
|
|
7640
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-view-row", children: [
|
|
7641
|
+
/* @__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" }) }),
|
|
7642
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-seg rk-view-toggle", role: "group", "aria-label": "Page view (P to toggle)", children: [
|
|
7643
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7331
7644
|
"button",
|
|
7332
7645
|
{
|
|
7333
7646
|
type: "button",
|
|
@@ -7337,7 +7650,7 @@ function Panel() {
|
|
|
7337
7650
|
children: "Original"
|
|
7338
7651
|
}
|
|
7339
7652
|
),
|
|
7340
|
-
/* @__PURE__ */ (0,
|
|
7653
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7341
7654
|
"button",
|
|
7342
7655
|
{
|
|
7343
7656
|
type: "button",
|
|
@@ -7349,8 +7662,8 @@ function Panel() {
|
|
|
7349
7662
|
)
|
|
7350
7663
|
] })
|
|
7351
7664
|
] }),
|
|
7352
|
-
/* @__PURE__ */ (0,
|
|
7353
|
-
/* @__PURE__ */ (0,
|
|
7665
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-panel-tools", children: [
|
|
7666
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
7354
7667
|
"button",
|
|
7355
7668
|
{
|
|
7356
7669
|
type: "button",
|
|
@@ -7361,15 +7674,15 @@ function Panel() {
|
|
|
7361
7674
|
dispatch({ type: "SET_MODE", mode: "pick" });
|
|
7362
7675
|
},
|
|
7363
7676
|
children: [
|
|
7364
|
-
/* @__PURE__ */ (0,
|
|
7677
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconTarget, { size: 14 }),
|
|
7365
7678
|
" Pick an element"
|
|
7366
7679
|
]
|
|
7367
7680
|
}
|
|
7368
7681
|
),
|
|
7369
|
-
/* @__PURE__ */ (0,
|
|
7370
|
-
/* @__PURE__ */ (0,
|
|
7371
|
-
/* @__PURE__ */ (0,
|
|
7372
|
-
/* @__PURE__ */ (0,
|
|
7682
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-search-row", children: [
|
|
7683
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-search", children: [
|
|
7684
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconSearch, { size: 13 }),
|
|
7685
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7373
7686
|
"input",
|
|
7374
7687
|
{
|
|
7375
7688
|
ref: searchRef,
|
|
@@ -7381,8 +7694,8 @@ function Panel() {
|
|
|
7381
7694
|
}
|
|
7382
7695
|
)
|
|
7383
7696
|
] }),
|
|
7384
|
-
/* @__PURE__ */ (0,
|
|
7385
|
-
/* @__PURE__ */ (0,
|
|
7697
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-menu-scope rk-menu-anchor", children: [
|
|
7698
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
7386
7699
|
"button",
|
|
7387
7700
|
{
|
|
7388
7701
|
type: "button",
|
|
@@ -7394,15 +7707,15 @@ function Panel() {
|
|
|
7394
7707
|
setSettingsOpen(false);
|
|
7395
7708
|
},
|
|
7396
7709
|
children: [
|
|
7397
|
-
/* @__PURE__ */ (0,
|
|
7710
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconFilter, { size: 13 }),
|
|
7398
7711
|
"Filter",
|
|
7399
|
-
typeFilter.size + prioFilter.size + statusFilter.size > 0 && /* @__PURE__ */ (0,
|
|
7712
|
+
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
7713
|
]
|
|
7401
7714
|
}
|
|
7402
7715
|
),
|
|
7403
|
-
filterOpen && /* @__PURE__ */ (0,
|
|
7404
|
-
/* @__PURE__ */ (0,
|
|
7405
|
-
TYPE_FILTERS.map((type) => /* @__PURE__ */ (0,
|
|
7716
|
+
filterOpen && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-menu", role: "menu", "aria-label": "Filter items", children: [
|
|
7717
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "rk-menu-title", children: "Type" }),
|
|
7718
|
+
TYPE_FILTERS.map((type) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
7406
7719
|
"button",
|
|
7407
7720
|
{
|
|
7408
7721
|
type: "button",
|
|
@@ -7416,16 +7729,16 @@ function Panel() {
|
|
|
7416
7729
|
setTypeFilter(next);
|
|
7417
7730
|
},
|
|
7418
7731
|
children: [
|
|
7419
|
-
/* @__PURE__ */ (0,
|
|
7732
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: `rk-menu-check${typeFilter.has(type) ? " rk-on" : ""}` }),
|
|
7420
7733
|
iconForType(type, 12),
|
|
7421
|
-
/* @__PURE__ */ (0,
|
|
7422
|
-
/* @__PURE__ */ (0,
|
|
7734
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-menu-label", children: type }),
|
|
7735
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-menu-count", children: typeCounts.get(type) ?? 0 })
|
|
7423
7736
|
]
|
|
7424
7737
|
},
|
|
7425
7738
|
type
|
|
7426
7739
|
)),
|
|
7427
|
-
/* @__PURE__ */ (0,
|
|
7428
|
-
PRIORITY_FILTERS.map((priority) => /* @__PURE__ */ (0,
|
|
7740
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "rk-menu-title", children: "Priority" }),
|
|
7741
|
+
PRIORITY_FILTERS.map((priority) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
7429
7742
|
"button",
|
|
7430
7743
|
{
|
|
7431
7744
|
type: "button",
|
|
@@ -7439,15 +7752,15 @@ function Panel() {
|
|
|
7439
7752
|
setPrioFilter(next);
|
|
7440
7753
|
},
|
|
7441
7754
|
children: [
|
|
7442
|
-
/* @__PURE__ */ (0,
|
|
7443
|
-
/* @__PURE__ */ (0,
|
|
7444
|
-
/* @__PURE__ */ (0,
|
|
7755
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: `rk-menu-check${prioFilter.has(priority) ? " rk-on" : ""}` }),
|
|
7756
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-menu-label", children: PRIORITY_LABELS[priority] }),
|
|
7757
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-menu-count", children: prioCounts.get(priority) ?? 0 })
|
|
7445
7758
|
]
|
|
7446
7759
|
},
|
|
7447
7760
|
priority
|
|
7448
7761
|
)),
|
|
7449
|
-
/* @__PURE__ */ (0,
|
|
7450
|
-
STATUSES.map((status) => /* @__PURE__ */ (0,
|
|
7762
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "rk-menu-title", children: "Status" }),
|
|
7763
|
+
STATUSES.map((status) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
7451
7764
|
"button",
|
|
7452
7765
|
{
|
|
7453
7766
|
type: "button",
|
|
@@ -7461,15 +7774,15 @@ function Panel() {
|
|
|
7461
7774
|
setStatusFilter(next);
|
|
7462
7775
|
},
|
|
7463
7776
|
children: [
|
|
7464
|
-
/* @__PURE__ */ (0,
|
|
7465
|
-
/* @__PURE__ */ (0,
|
|
7466
|
-
/* @__PURE__ */ (0,
|
|
7467
|
-
/* @__PURE__ */ (0,
|
|
7777
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: `rk-menu-check${statusFilter.has(status) ? " rk-on" : ""}` }),
|
|
7778
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: `rk-status-dot rk-st-${status}` }),
|
|
7779
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-menu-label", children: status }),
|
|
7780
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-menu-count", children: statusCounts.get(status) ?? 0 })
|
|
7468
7781
|
]
|
|
7469
7782
|
},
|
|
7470
7783
|
status
|
|
7471
7784
|
)),
|
|
7472
|
-
/* @__PURE__ */ (0,
|
|
7785
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7473
7786
|
"button",
|
|
7474
7787
|
{
|
|
7475
7788
|
type: "button",
|
|
@@ -7489,24 +7802,24 @@ function Panel() {
|
|
|
7489
7802
|
] })
|
|
7490
7803
|
] })
|
|
7491
7804
|
] }),
|
|
7492
|
-
preview && unapplied > 0 && /* @__PURE__ */ (0,
|
|
7805
|
+
preview && unapplied > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-unplaced", role: "status", children: [
|
|
7493
7806
|
unapplied,
|
|
7494
7807
|
" saved change",
|
|
7495
7808
|
unapplied === 1 ? "" : "s",
|
|
7496
7809
|
" couldn\u2019t be placed on the current page \u2014 the page has changed since they were captured."
|
|
7497
7810
|
] }),
|
|
7498
|
-
/* @__PURE__ */ (0,
|
|
7499
|
-
/* @__PURE__ */ (0,
|
|
7500
|
-
/* @__PURE__ */ (0,
|
|
7501
|
-
/* @__PURE__ */ (0,
|
|
7502
|
-
] }) : groups.map(([route, entries]) => /* @__PURE__ */ (0,
|
|
7503
|
-
/* @__PURE__ */ (0,
|
|
7811
|
+
/* @__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: [
|
|
7812
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "rk-empty-art", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconTarget, { size: 22 }) }),
|
|
7813
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "rk-empty-title", children: items.length === 0 ? "Nothing here yet" : "No matches" }),
|
|
7814
|
+
/* @__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." })
|
|
7815
|
+
] }) : groups.map(([route, entries]) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
|
|
7816
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "rk-group-title", children: route }),
|
|
7504
7817
|
entries.map(({ item, number }) => {
|
|
7505
7818
|
const active2 = item.id === activeItemId;
|
|
7506
7819
|
const orphan = orphanIds.has(item.id);
|
|
7507
7820
|
const hiddenEl = hiddenIds.has(item.id);
|
|
7508
|
-
return /* @__PURE__ */ (0,
|
|
7509
|
-
/* @__PURE__ */ (0,
|
|
7821
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
|
|
7822
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
7510
7823
|
"div",
|
|
7511
7824
|
{
|
|
7512
7825
|
"data-item-id": item.id,
|
|
@@ -7521,18 +7834,18 @@ function Panel() {
|
|
|
7521
7834
|
}
|
|
7522
7835
|
},
|
|
7523
7836
|
children: [
|
|
7524
|
-
/* @__PURE__ */ (0,
|
|
7525
|
-
/* @__PURE__ */ (0,
|
|
7526
|
-
/* @__PURE__ */ (0,
|
|
7527
|
-
/* @__PURE__ */ (0,
|
|
7837
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-item-num", children: number }),
|
|
7838
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-item-icon", children: iconForType(item.type) }),
|
|
7839
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "rk-item-body", children: [
|
|
7840
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "rk-item-snippet", children: [
|
|
7528
7841
|
item.target.tagName,
|
|
7529
7842
|
" \xB7 ",
|
|
7530
7843
|
item.target.textSnippet || item.target.selector
|
|
7531
7844
|
] }),
|
|
7532
|
-
/* @__PURE__ */ (0,
|
|
7533
|
-
/* @__PURE__ */ (0,
|
|
7534
|
-
/* @__PURE__ */ (0,
|
|
7535
|
-
/* @__PURE__ */ (0,
|
|
7845
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-item-change", children: changeSummary(item) }),
|
|
7846
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "rk-item-meta", children: [
|
|
7847
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "rk-author", title: new Date(item.createdAt).toLocaleString(), children: [
|
|
7848
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7536
7849
|
"span",
|
|
7537
7850
|
{
|
|
7538
7851
|
className: "rk-author-dot",
|
|
@@ -7540,15 +7853,15 @@ function Panel() {
|
|
|
7540
7853
|
}
|
|
7541
7854
|
),
|
|
7542
7855
|
item.author?.name ?? "Unknown",
|
|
7543
|
-
/* @__PURE__ */ (0,
|
|
7856
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "rk-time", children: [
|
|
7544
7857
|
" \xB7 ",
|
|
7545
7858
|
timeAgo(item.createdAt)
|
|
7546
7859
|
] })
|
|
7547
7860
|
] }),
|
|
7548
|
-
item.priority === "must" && /* @__PURE__ */ (0,
|
|
7549
|
-
item.status !== "open" && /* @__PURE__ */ (0,
|
|
7550
|
-
orphan && /* @__PURE__ */ (0,
|
|
7551
|
-
hiddenEl && /* @__PURE__ */ (0,
|
|
7861
|
+
item.priority === "must" && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-badge-mini rk-must", children: "must" }),
|
|
7862
|
+
item.status !== "open" && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: `rk-badge-mini rk-${item.status}`, children: item.status }),
|
|
7863
|
+
orphan && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-badge-mini rk-orphaned", children: "unanchored" }),
|
|
7864
|
+
hiddenEl && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7552
7865
|
"span",
|
|
7553
7866
|
{
|
|
7554
7867
|
className: "rk-badge-mini rk-hidden-el",
|
|
@@ -7556,14 +7869,14 @@ function Panel() {
|
|
|
7556
7869
|
children: "hidden"
|
|
7557
7870
|
}
|
|
7558
7871
|
),
|
|
7559
|
-
item.note && /* @__PURE__ */ (0,
|
|
7560
|
-
peers.filter((peer) => peer.typingActive && peer.typingItemId === item.id).map((peer) => /* @__PURE__ */ (0,
|
|
7872
|
+
item.note && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-badge-mini", children: "note" }),
|
|
7873
|
+
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
7874
|
peer.name || "peer",
|
|
7562
7875
|
" is writing\u2026"
|
|
7563
7876
|
] }, peer.id))
|
|
7564
7877
|
] })
|
|
7565
7878
|
] }),
|
|
7566
|
-
/* @__PURE__ */ (0,
|
|
7879
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-item-actions", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7567
7880
|
"button",
|
|
7568
7881
|
{
|
|
7569
7882
|
type: "button",
|
|
@@ -7578,15 +7891,15 @@ function Panel() {
|
|
|
7578
7891
|
"info"
|
|
7579
7892
|
);
|
|
7580
7893
|
},
|
|
7581
|
-
children: /* @__PURE__ */ (0,
|
|
7894
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconTrash, { size: 13 })
|
|
7582
7895
|
}
|
|
7583
7896
|
) })
|
|
7584
7897
|
]
|
|
7585
7898
|
}
|
|
7586
7899
|
),
|
|
7587
|
-
active2 && /* @__PURE__ */ (0,
|
|
7588
|
-
/* @__PURE__ */ (0,
|
|
7589
|
-
/* @__PURE__ */ (0,
|
|
7900
|
+
active2 && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-item-edit", children: [
|
|
7901
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-detail-byline", title: new Date(item.createdAt).toLocaleString(), children: [
|
|
7902
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7590
7903
|
"span",
|
|
7591
7904
|
{
|
|
7592
7905
|
className: "rk-author-dot",
|
|
@@ -7597,8 +7910,8 @@ function Panel() {
|
|
|
7597
7910
|
" \xB7 ",
|
|
7598
7911
|
timeAgo(item.createdAt)
|
|
7599
7912
|
] }),
|
|
7600
|
-
isCopyItem(item) && /* @__PURE__ */ (0,
|
|
7601
|
-
isImageItem(item) && /* @__PURE__ */ (0,
|
|
7913
|
+
isCopyItem(item) && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CopyDiff, { before: item.payload.before, after: item.payload.after }),
|
|
7914
|
+
isImageItem(item) && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7602
7915
|
ImageDetail,
|
|
7603
7916
|
{
|
|
7604
7917
|
beforeSrc: item.payload.beforeSrc,
|
|
@@ -7606,7 +7919,7 @@ function Panel() {
|
|
|
7606
7919
|
afterDataUrl: item.payload.afterDataUrl
|
|
7607
7920
|
}
|
|
7608
7921
|
),
|
|
7609
|
-
isKnownItemType(item.type) && item.type !== "move" && /* @__PURE__ */ (0,
|
|
7922
|
+
isKnownItemType(item.type) && item.type !== "move" && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7610
7923
|
"textarea",
|
|
7611
7924
|
{
|
|
7612
7925
|
className: "rk-textarea",
|
|
@@ -7616,7 +7929,7 @@ function Panel() {
|
|
|
7616
7929
|
onChange: (event) => dispatch({ type: "UPDATE_ITEM", id: item.id, patch: withPayloadText(item, event.target.value) })
|
|
7617
7930
|
}
|
|
7618
7931
|
),
|
|
7619
|
-
/* @__PURE__ */ (0,
|
|
7932
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7620
7933
|
"input",
|
|
7621
7934
|
{
|
|
7622
7935
|
className: "rk-input",
|
|
@@ -7626,9 +7939,9 @@ function Panel() {
|
|
|
7626
7939
|
onChange: (event) => dispatch({ type: "UPDATE_ITEM", id: item.id, patch: { note: event.target.value } })
|
|
7627
7940
|
}
|
|
7628
7941
|
),
|
|
7629
|
-
/* @__PURE__ */ (0,
|
|
7630
|
-
/* @__PURE__ */ (0,
|
|
7631
|
-
/* @__PURE__ */ (0,
|
|
7942
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
|
|
7943
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-seg", role: "group", "aria-label": "Priority", children: [
|
|
7944
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7632
7945
|
"button",
|
|
7633
7946
|
{
|
|
7634
7947
|
type: "button",
|
|
@@ -7637,7 +7950,7 @@ function Panel() {
|
|
|
7637
7950
|
children: "Must"
|
|
7638
7951
|
}
|
|
7639
7952
|
),
|
|
7640
|
-
/* @__PURE__ */ (0,
|
|
7953
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7641
7954
|
"button",
|
|
7642
7955
|
{
|
|
7643
7956
|
type: "button",
|
|
@@ -7647,7 +7960,7 @@ function Panel() {
|
|
|
7647
7960
|
}
|
|
7648
7961
|
)
|
|
7649
7962
|
] }),
|
|
7650
|
-
/* @__PURE__ */ (0,
|
|
7963
|
+
/* @__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
7964
|
"button",
|
|
7652
7965
|
{
|
|
7653
7966
|
type: "button",
|
|
@@ -7662,22 +7975,22 @@ function Panel() {
|
|
|
7662
7975
|
] }, item.id);
|
|
7663
7976
|
})
|
|
7664
7977
|
] }, route)) }),
|
|
7665
|
-
/* @__PURE__ */ (0,
|
|
7666
|
-
/* @__PURE__ */ (0,
|
|
7667
|
-
/* @__PURE__ */ (0,
|
|
7978
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "rk-panel-foot", children: [
|
|
7979
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: onExport, disabled: items.length === 0, children: [
|
|
7980
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconDownload, { size: 13 }),
|
|
7668
7981
|
" Export"
|
|
7669
7982
|
] }),
|
|
7670
|
-
/* @__PURE__ */ (0,
|
|
7671
|
-
/* @__PURE__ */ (0,
|
|
7983
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => void onCopy(), disabled: items.length === 0, children: [
|
|
7984
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconCopyClipboard, { size: 13 }),
|
|
7672
7985
|
" Copy"
|
|
7673
7986
|
] }),
|
|
7674
|
-
/* @__PURE__ */ (0,
|
|
7675
|
-
/* @__PURE__ */ (0,
|
|
7987
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("button", { type: "button", className: "rk-btn rk-btn-ghost", onClick: () => importRef.current?.click(), children: [
|
|
7988
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(IconUpload, { size: 13 }),
|
|
7676
7989
|
" Import"
|
|
7677
7990
|
] }),
|
|
7678
|
-
/* @__PURE__ */ (0,
|
|
7679
|
-
undoStack.length > 0 && /* @__PURE__ */ (0,
|
|
7680
|
-
/* @__PURE__ */ (0,
|
|
7991
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "rk-spacer" }),
|
|
7992
|
+
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 }) }),
|
|
7993
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7681
7994
|
"button",
|
|
7682
7995
|
{
|
|
7683
7996
|
type: "button",
|
|
@@ -7688,7 +8001,7 @@ function Panel() {
|
|
|
7688
8001
|
children: "Clear"
|
|
7689
8002
|
}
|
|
7690
8003
|
),
|
|
7691
|
-
/* @__PURE__ */ (0,
|
|
8004
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7692
8005
|
"button",
|
|
7693
8006
|
{
|
|
7694
8007
|
type: "button",
|
|
@@ -7698,7 +8011,7 @@ function Panel() {
|
|
|
7698
8011
|
children: "Exit review"
|
|
7699
8012
|
}
|
|
7700
8013
|
),
|
|
7701
|
-
/* @__PURE__ */ (0,
|
|
8014
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
7702
8015
|
"input",
|
|
7703
8016
|
{
|
|
7704
8017
|
ref: importRef,
|
|
@@ -7717,13 +8030,14 @@ function Panel() {
|
|
|
7717
8030
|
}
|
|
7718
8031
|
);
|
|
7719
8032
|
}
|
|
7720
|
-
var
|
|
8033
|
+
var import_react14, import_jsx_runtime12, TYPE_FILTERS, PRIORITY_FILTERS, STATUSES, PRIORITY_LABELS, SYNC_REASON_LABEL, SYNC_REASON_HELP;
|
|
7721
8034
|
var init_Panel = __esm({
|
|
7722
8035
|
"src/client/components/Panel.tsx"() {
|
|
7723
8036
|
"use strict";
|
|
7724
|
-
|
|
8037
|
+
import_react14 = require("react");
|
|
7725
8038
|
init_schema();
|
|
7726
8039
|
init_env();
|
|
8040
|
+
init_sync();
|
|
7727
8041
|
init_emblema();
|
|
7728
8042
|
init_exportSession();
|
|
7729
8043
|
init_shortcuts();
|
|
@@ -7731,11 +8045,23 @@ var init_Panel = __esm({
|
|
|
7731
8045
|
init_target();
|
|
7732
8046
|
init_store();
|
|
7733
8047
|
init_icons();
|
|
7734
|
-
|
|
8048
|
+
import_jsx_runtime12 = require("react/jsx-runtime");
|
|
7735
8049
|
TYPE_FILTERS = ["copy", "image", "comment", "delete", "move", "style"];
|
|
7736
8050
|
PRIORITY_FILTERS = ["must", "nice"];
|
|
7737
8051
|
STATUSES = ["open", "accepted", "rejected", "applied"];
|
|
7738
8052
|
PRIORITY_LABELS = { must: "Must", nice: "Nice to have" };
|
|
8053
|
+
SYNC_REASON_LABEL = {
|
|
8054
|
+
"token-short": "token too short",
|
|
8055
|
+
"bad-token": "token rejected",
|
|
8056
|
+
"room-full": "room full",
|
|
8057
|
+
unreachable: "server unreachable"
|
|
8058
|
+
};
|
|
8059
|
+
SYNC_REASON_HELP = {
|
|
8060
|
+
"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.",
|
|
8061
|
+
"bad-token": "The sync server rejected the token. Check `syncToken` / `token` in <ReviewKit />.",
|
|
8062
|
+
"room-full": "This page already has the maximum number of reviewers online (16). Try again later.",
|
|
8063
|
+
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."
|
|
8064
|
+
};
|
|
7739
8065
|
}
|
|
7740
8066
|
});
|
|
7741
8067
|
|
|
@@ -7749,8 +8075,8 @@ function initials(name) {
|
|
|
7749
8075
|
function PresenceStrip() {
|
|
7750
8076
|
const { peers, syncStatus } = useStore();
|
|
7751
8077
|
if (syncStatus === "disabled" || peers.length === 0) return null;
|
|
7752
|
-
return /* @__PURE__ */ (0,
|
|
7753
|
-
peers.slice(0, 5).map((peer) => /* @__PURE__ */ (0,
|
|
8078
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "rk-presence", "aria-label": `${peers.length} reviewer${peers.length === 1 ? "" : "s"} online`, children: [
|
|
8079
|
+
peers.slice(0, 5).map((peer) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
7754
8080
|
"span",
|
|
7755
8081
|
{
|
|
7756
8082
|
className: "rk-avatar",
|
|
@@ -7760,7 +8086,7 @@ function PresenceStrip() {
|
|
|
7760
8086
|
},
|
|
7761
8087
|
peer.id
|
|
7762
8088
|
)),
|
|
7763
|
-
peers.length > 5 && /* @__PURE__ */ (0,
|
|
8089
|
+
peers.length > 5 && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "rk-avatar rk-avatar-more", children: [
|
|
7764
8090
|
"+",
|
|
7765
8091
|
peers.length - 5
|
|
7766
8092
|
] })
|
|
@@ -7768,13 +8094,13 @@ function PresenceStrip() {
|
|
|
7768
8094
|
}
|
|
7769
8095
|
function PeerCursors() {
|
|
7770
8096
|
const { peers } = useStore();
|
|
7771
|
-
const ringRefs = (0,
|
|
7772
|
-
const cursorRefs = (0,
|
|
7773
|
-
const motion = (0,
|
|
8097
|
+
const ringRefs = (0, import_react15.useRef)(/* @__PURE__ */ new Map());
|
|
8098
|
+
const cursorRefs = (0, import_react15.useRef)(/* @__PURE__ */ new Map());
|
|
8099
|
+
const motion = (0, import_react15.useRef)(
|
|
7774
8100
|
/* @__PURE__ */ new Map()
|
|
7775
8101
|
);
|
|
7776
|
-
const peersRef = (0,
|
|
7777
|
-
const seen = (0,
|
|
8102
|
+
const peersRef = (0, import_react15.useRef)(peers);
|
|
8103
|
+
const seen = (0, import_react15.useRef)(/* @__PURE__ */ new Map());
|
|
7778
8104
|
for (const peer of peers) {
|
|
7779
8105
|
const sig = peer.cursor ? `${peer.cursor.x},${peer.cursor.y},${peer.cursor.ox},${peer.cursor.oy}` : "";
|
|
7780
8106
|
if (seen.current.get(peer.id) !== sig) {
|
|
@@ -7784,7 +8110,7 @@ function PeerCursors() {
|
|
|
7784
8110
|
}
|
|
7785
8111
|
}
|
|
7786
8112
|
peersRef.current = peers;
|
|
7787
|
-
(0,
|
|
8113
|
+
(0, import_react15.useEffect)(() => {
|
|
7788
8114
|
const reduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
7789
8115
|
let raf = 0;
|
|
7790
8116
|
let last = performance.now();
|
|
@@ -7889,8 +8215,8 @@ function PeerCursors() {
|
|
|
7889
8215
|
return () => cancelAnimationFrame(raf);
|
|
7890
8216
|
}, []);
|
|
7891
8217
|
if (peers.length === 0) return null;
|
|
7892
|
-
return /* @__PURE__ */ (0,
|
|
7893
|
-
peers.map((peer) => /* @__PURE__ */ (0,
|
|
8218
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
8219
|
+
peers.map((peer) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
7894
8220
|
"div",
|
|
7895
8221
|
{
|
|
7896
8222
|
ref: (el) => {
|
|
@@ -7902,7 +8228,7 @@ function PeerCursors() {
|
|
|
7902
8228
|
},
|
|
7903
8229
|
`ring-${peer.id}`
|
|
7904
8230
|
)),
|
|
7905
|
-
peers.map((peer, index) => /* @__PURE__ */ (0,
|
|
8231
|
+
peers.map((peer, index) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
7906
8232
|
"div",
|
|
7907
8233
|
{
|
|
7908
8234
|
ref: (el) => {
|
|
@@ -7912,8 +8238,8 @@ function PeerCursors() {
|
|
|
7912
8238
|
className: "rk-peer-cursor",
|
|
7913
8239
|
style: { opacity: 0 },
|
|
7914
8240
|
children: [
|
|
7915
|
-
/* @__PURE__ */ (0,
|
|
7916
|
-
/* @__PURE__ */ (0,
|
|
8241
|
+
/* @__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" }) }),
|
|
8242
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
7917
8243
|
"span",
|
|
7918
8244
|
{
|
|
7919
8245
|
className: "rk-peer-name",
|
|
@@ -7930,14 +8256,14 @@ function PeerCursors() {
|
|
|
7930
8256
|
))
|
|
7931
8257
|
] });
|
|
7932
8258
|
}
|
|
7933
|
-
var
|
|
8259
|
+
var import_react15, import_jsx_runtime13;
|
|
7934
8260
|
var init_Presence = __esm({
|
|
7935
8261
|
"src/client/components/Presence.tsx"() {
|
|
7936
8262
|
"use strict";
|
|
7937
|
-
|
|
8263
|
+
import_react15 = require("react");
|
|
7938
8264
|
init_store();
|
|
7939
8265
|
init_target();
|
|
7940
|
-
|
|
8266
|
+
import_jsx_runtime13 = require("react/jsx-runtime");
|
|
7941
8267
|
}
|
|
7942
8268
|
});
|
|
7943
8269
|
|
|
@@ -7945,14 +8271,14 @@ var init_Presence = __esm({
|
|
|
7945
8271
|
function QuickComment() {
|
|
7946
8272
|
const { quick } = useStore();
|
|
7947
8273
|
if (!quick) return null;
|
|
7948
|
-
return /* @__PURE__ */ (0,
|
|
8274
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(QuickComposerCard, { quick }, quick.id);
|
|
7949
8275
|
}
|
|
7950
8276
|
function QuickComposerCard({ quick }) {
|
|
7951
8277
|
const { route, session } = useStore();
|
|
7952
8278
|
const dispatch = useDispatch();
|
|
7953
|
-
const [text, setText] = (0,
|
|
7954
|
-
const fieldRef = (0,
|
|
7955
|
-
(0,
|
|
8279
|
+
const [text, setText] = (0, import_react16.useState)("");
|
|
8280
|
+
const fieldRef = (0, import_react16.useRef)(null);
|
|
8281
|
+
(0, import_react16.useEffect)(() => {
|
|
7956
8282
|
const field = fieldRef.current;
|
|
7957
8283
|
if (!field) return;
|
|
7958
8284
|
field.focus();
|
|
@@ -8005,18 +8331,18 @@ function QuickComposerCard({ quick }) {
|
|
|
8005
8331
|
};
|
|
8006
8332
|
const x = Math.min(Math.max(quick.x, 8), window.innerWidth - 288);
|
|
8007
8333
|
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,
|
|
8334
|
+
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: [
|
|
8335
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "rk-quick-head", children: [
|
|
8336
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(IconComment, { size: 12 }),
|
|
8337
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Comment here" }),
|
|
8338
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "rk-hint", children: [
|
|
8339
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "rk-kbd", children: "\u21B5" }),
|
|
8014
8340
|
" save \xB7 ",
|
|
8015
|
-
/* @__PURE__ */ (0,
|
|
8341
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "rk-kbd", children: "esc" }),
|
|
8016
8342
|
" cancel"
|
|
8017
8343
|
] })
|
|
8018
8344
|
] }),
|
|
8019
|
-
/* @__PURE__ */ (0,
|
|
8345
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
8020
8346
|
"textarea",
|
|
8021
8347
|
{
|
|
8022
8348
|
ref: fieldRef,
|
|
@@ -8030,11 +8356,11 @@ function QuickComposerCard({ quick }) {
|
|
|
8030
8356
|
)
|
|
8031
8357
|
] });
|
|
8032
8358
|
}
|
|
8033
|
-
var
|
|
8359
|
+
var import_react16, import_jsx_runtime14;
|
|
8034
8360
|
var init_QuickComment = __esm({
|
|
8035
8361
|
"src/client/components/QuickComment.tsx"() {
|
|
8036
8362
|
"use strict";
|
|
8037
|
-
|
|
8363
|
+
import_react16 = require("react");
|
|
8038
8364
|
init_effectCatalog();
|
|
8039
8365
|
init_effectsLazy();
|
|
8040
8366
|
init_id();
|
|
@@ -8043,7 +8369,7 @@ var init_QuickComment = __esm({
|
|
|
8043
8369
|
init_sync();
|
|
8044
8370
|
init_store();
|
|
8045
8371
|
init_icons();
|
|
8046
|
-
|
|
8372
|
+
import_jsx_runtime14 = require("react/jsx-runtime");
|
|
8047
8373
|
}
|
|
8048
8374
|
});
|
|
8049
8375
|
|
|
@@ -8062,14 +8388,14 @@ function applyRect(el, rect, pad2 = 3) {
|
|
|
8062
8388
|
function PickLayer() {
|
|
8063
8389
|
const { mode, selection, tool } = useStore();
|
|
8064
8390
|
const dispatch = useDispatch();
|
|
8065
|
-
const [hovered, setHovered] = (0,
|
|
8066
|
-
const outlineRef = (0,
|
|
8067
|
-
const labelRef = (0,
|
|
8068
|
-
const selectRef = (0,
|
|
8069
|
-
const hoveredRef = (0,
|
|
8391
|
+
const [hovered, setHovered] = (0, import_react17.useState)(null);
|
|
8392
|
+
const outlineRef = (0, import_react17.useRef)(null);
|
|
8393
|
+
const labelRef = (0, import_react17.useRef)(null);
|
|
8394
|
+
const selectRef = (0, import_react17.useRef)(null);
|
|
8395
|
+
const hoveredRef = (0, import_react17.useRef)(null);
|
|
8070
8396
|
hoveredRef.current = hovered;
|
|
8071
8397
|
const picking = mode === "pick";
|
|
8072
|
-
(0,
|
|
8398
|
+
(0, import_react17.useEffect)(() => {
|
|
8073
8399
|
if (!picking) {
|
|
8074
8400
|
setHovered(null);
|
|
8075
8401
|
return;
|
|
@@ -8113,7 +8439,7 @@ function PickLayer() {
|
|
|
8113
8439
|
document.removeEventListener("mousedown", swallow, true);
|
|
8114
8440
|
};
|
|
8115
8441
|
}, [picking, tool, dispatch]);
|
|
8116
|
-
(0,
|
|
8442
|
+
(0, import_react17.useEffect)(() => {
|
|
8117
8443
|
if (!picking) return;
|
|
8118
8444
|
const body = document.body;
|
|
8119
8445
|
const prev = body.style.cursor;
|
|
@@ -8123,7 +8449,7 @@ function PickLayer() {
|
|
|
8123
8449
|
if (body.getAttribute("style") === "") body.removeAttribute("style");
|
|
8124
8450
|
};
|
|
8125
8451
|
}, [picking, tool]);
|
|
8126
|
-
(0,
|
|
8452
|
+
(0, import_react17.useEffect)(() => {
|
|
8127
8453
|
let raf = 0;
|
|
8128
8454
|
const tick = () => {
|
|
8129
8455
|
const hoverEl = hoveredRef.current;
|
|
@@ -8149,26 +8475,26 @@ function PickLayer() {
|
|
|
8149
8475
|
raf = requestAnimationFrame(tick);
|
|
8150
8476
|
return () => cancelAnimationFrame(raf);
|
|
8151
8477
|
}, [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,
|
|
8478
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
8479
|
+
picking && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
8480
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { ref: outlineRef, className: "rk-outline", style: { opacity: 0 } }),
|
|
8481
|
+
/* @__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: [
|
|
8482
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "rk-tag", children: hovered.tagName.toLowerCase() }),
|
|
8483
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: describeElement(hovered).replace(/^[a-z0-9]+ · /, "") })
|
|
8484
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: "Pick an element" }) })
|
|
8159
8485
|
] }),
|
|
8160
|
-
selection && /* @__PURE__ */ (0,
|
|
8486
|
+
selection && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { ref: selectRef, className: "rk-select-ring", style: { opacity: 0 } })
|
|
8161
8487
|
] });
|
|
8162
8488
|
}
|
|
8163
|
-
var
|
|
8489
|
+
var import_react17, import_jsx_runtime15;
|
|
8164
8490
|
var init_PickLayer = __esm({
|
|
8165
8491
|
"src/client/components/PickLayer.tsx"() {
|
|
8166
8492
|
"use strict";
|
|
8167
|
-
|
|
8493
|
+
import_react17 = require("react");
|
|
8168
8494
|
init_shortcuts();
|
|
8169
8495
|
init_target();
|
|
8170
8496
|
init_store();
|
|
8171
|
-
|
|
8497
|
+
import_jsx_runtime15 = require("react/jsx-runtime");
|
|
8172
8498
|
}
|
|
8173
8499
|
});
|
|
8174
8500
|
|
|
@@ -8176,22 +8502,22 @@ var init_PickLayer = __esm({
|
|
|
8176
8502
|
function Pins() {
|
|
8177
8503
|
const { session, route, activeItemId, editor, mode, filter } = useStore();
|
|
8178
8504
|
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,
|
|
8505
|
+
const [clusters, setClusters] = (0, import_react18.useState)([]);
|
|
8506
|
+
const [orphanCount, setOrphanCount] = (0, import_react18.useState)(0);
|
|
8507
|
+
const wrapRefs = (0, import_react18.useRef)(/* @__PURE__ */ new Map());
|
|
8508
|
+
const visibleCache = (0, import_react18.useRef)(/* @__PURE__ */ new Map());
|
|
8509
|
+
const highlightRef = (0, import_react18.useRef)(null);
|
|
8510
|
+
const hoveredItems = (0, import_react18.useRef)(null);
|
|
8511
|
+
const elementCache = (0, import_react18.useRef)(/* @__PURE__ */ new Map());
|
|
8512
|
+
const lastResolve = (0, import_react18.useRef)(0);
|
|
8513
|
+
const [newestId, setNewestId] = (0, import_react18.useState)(null);
|
|
8514
|
+
const prevCount = (0, import_react18.useRef)(0);
|
|
8515
|
+
const items = (0, import_react18.useMemo)(() => {
|
|
8190
8516
|
const all = session?.items ?? [];
|
|
8191
8517
|
return all.map((item, index) => ({ item, number: index + 1 })).filter(({ item }) => item.route === route);
|
|
8192
8518
|
}, [session, route]);
|
|
8193
8519
|
const byId = new Map(items.map(({ item }) => [item.id, item]));
|
|
8194
|
-
(0,
|
|
8520
|
+
(0, import_react18.useEffect)(() => {
|
|
8195
8521
|
const count = session?.items.length ?? 0;
|
|
8196
8522
|
if (count > prevCount.current && session && count > 0) {
|
|
8197
8523
|
const id = session.items[count - 1].id;
|
|
@@ -8202,7 +8528,7 @@ function Pins() {
|
|
|
8202
8528
|
}
|
|
8203
8529
|
prevCount.current = count;
|
|
8204
8530
|
}, [session]);
|
|
8205
|
-
(0,
|
|
8531
|
+
(0, import_react18.useEffect)(() => {
|
|
8206
8532
|
let raf = 0;
|
|
8207
8533
|
let lastSignature = "";
|
|
8208
8534
|
const tick = (time) => {
|
|
@@ -8286,8 +8612,8 @@ function Pins() {
|
|
|
8286
8612
|
dispatch({ type: "SET_ACTIVE_ITEM", id });
|
|
8287
8613
|
dispatch({ type: "SET_PANEL", open: true });
|
|
8288
8614
|
};
|
|
8289
|
-
return /* @__PURE__ */ (0,
|
|
8290
|
-
/* @__PURE__ */ (0,
|
|
8615
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
|
|
8616
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { ref: highlightRef, className: "rk-hl-ring", style: { opacity: 0 } }),
|
|
8291
8617
|
clusters.map((cluster) => {
|
|
8292
8618
|
const isCluster = cluster.ids.length > 1;
|
|
8293
8619
|
const isActive = activeItemId !== null && cluster.ids.includes(activeItemId);
|
|
@@ -8297,7 +8623,7 @@ function Pins() {
|
|
|
8297
8623
|
const status = statuses.size === 1 ? members[0]?.status : void 0;
|
|
8298
8624
|
const dimmed = filter !== null && members.length > 0 && !members.some((item) => itemMatchesFilter(item, filter));
|
|
8299
8625
|
const statusHint = isCluster ? status ? ` \xB7 all ${STATUS_LABELS[status] ?? status}` : "" : ` \xB7 ${STATUS_LABELS[members[0]?.status ?? "open"] ?? members[0]?.status}`;
|
|
8300
|
-
return /* @__PURE__ */ (0,
|
|
8626
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
8301
8627
|
"div",
|
|
8302
8628
|
{
|
|
8303
8629
|
ref: (el) => {
|
|
@@ -8305,7 +8631,7 @@ function Pins() {
|
|
|
8305
8631
|
else wrapRefs.current.delete(cluster.key);
|
|
8306
8632
|
},
|
|
8307
8633
|
className: `rk-pin-wrap${picking ? " rk-pin-ghost" : ""}`,
|
|
8308
|
-
children: /* @__PURE__ */ (0,
|
|
8634
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
8309
8635
|
"button",
|
|
8310
8636
|
{
|
|
8311
8637
|
type: "button",
|
|
@@ -8327,7 +8653,7 @@ function Pins() {
|
|
|
8327
8653
|
cluster.key
|
|
8328
8654
|
);
|
|
8329
8655
|
}),
|
|
8330
|
-
orphanCount > 0 && /* @__PURE__ */ (0,
|
|
8656
|
+
orphanCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
8331
8657
|
"button",
|
|
8332
8658
|
{
|
|
8333
8659
|
type: "button",
|
|
@@ -8335,7 +8661,7 @@ function Pins() {
|
|
|
8335
8661
|
style: { bottom: 16, left: "50%", transform: "translateX(-50%)" },
|
|
8336
8662
|
onClick: () => dispatch({ type: "SET_PANEL", open: true }),
|
|
8337
8663
|
children: [
|
|
8338
|
-
/* @__PURE__ */ (0,
|
|
8664
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(IconUnlink, { size: 13 }),
|
|
8339
8665
|
orphanCount,
|
|
8340
8666
|
" unanchored item",
|
|
8341
8667
|
orphanCount === 1 ? "" : "s"
|
|
@@ -8344,15 +8670,15 @@ function Pins() {
|
|
|
8344
8670
|
)
|
|
8345
8671
|
] });
|
|
8346
8672
|
}
|
|
8347
|
-
var
|
|
8673
|
+
var import_react18, import_jsx_runtime16, STATUS_LABELS, CLUSTER_RADIUS, RERESOLVE_MS;
|
|
8348
8674
|
var init_Pins = __esm({
|
|
8349
8675
|
"src/client/components/Pins.tsx"() {
|
|
8350
8676
|
"use strict";
|
|
8351
|
-
|
|
8677
|
+
import_react18 = require("react");
|
|
8352
8678
|
init_target();
|
|
8353
8679
|
init_store();
|
|
8354
8680
|
init_icons();
|
|
8355
|
-
|
|
8681
|
+
import_jsx_runtime16 = require("react/jsx-runtime");
|
|
8356
8682
|
STATUS_LABELS = {
|
|
8357
8683
|
open: "open",
|
|
8358
8684
|
accepted: "accepted",
|
|
@@ -8369,24 +8695,24 @@ function Toolbar() {
|
|
|
8369
8695
|
const { selection, editor, peers, syncStatus, mode, tool } = useStore();
|
|
8370
8696
|
const hasPeers = syncStatus !== "disabled" && peers.length > 0;
|
|
8371
8697
|
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,
|
|
8698
|
+
const ref = (0, import_react19.useRef)(null);
|
|
8699
|
+
const [pos, setPos] = (0, import_react19.useState)(() => readStoredPos(POS_KEY2));
|
|
8700
|
+
const drag = (0, import_react19.useRef)(null);
|
|
8701
|
+
const [dragging, setDragging] = (0, import_react19.useState)(false);
|
|
8702
|
+
const justDragged = (0, import_react19.useRef)(false);
|
|
8377
8703
|
const visible = editor === null || selection !== null;
|
|
8378
8704
|
const applyPos = (next, persist) => {
|
|
8379
8705
|
if (next === null && ref.current) ref.current.style.bottom = "";
|
|
8380
8706
|
setPos(next);
|
|
8381
8707
|
if (persist) storePos(POS_KEY2, next);
|
|
8382
8708
|
};
|
|
8383
|
-
(0,
|
|
8709
|
+
(0, import_react19.useLayoutEffect)(() => {
|
|
8384
8710
|
const el = ref.current;
|
|
8385
8711
|
if (!el || pos === null) return;
|
|
8386
8712
|
const clamped = clampPos(pos.x, pos.y, el.offsetWidth, el.offsetHeight);
|
|
8387
8713
|
if (clamped.x !== pos.x || clamped.y !== pos.y) applyPos(clamped, true);
|
|
8388
8714
|
}, [pos, selection, hasPeers, visible]);
|
|
8389
|
-
(0,
|
|
8715
|
+
(0, import_react19.useEffect)(() => {
|
|
8390
8716
|
const onResize = () => {
|
|
8391
8717
|
const el = ref.current;
|
|
8392
8718
|
const current = readStoredPos(POS_KEY2);
|
|
@@ -8499,7 +8825,7 @@ function Toolbar() {
|
|
|
8499
8825
|
mode === "pick" && selection === null ? "rk-ghost" : ""
|
|
8500
8826
|
].filter(Boolean).join(" ");
|
|
8501
8827
|
const style = pos !== null ? { left: 0, top: 0, translate: `${pos.x}px ${pos.y}px` } : void 0;
|
|
8502
|
-
return /* @__PURE__ */ (0,
|
|
8828
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
8503
8829
|
"div",
|
|
8504
8830
|
{
|
|
8505
8831
|
ref,
|
|
@@ -8510,7 +8836,7 @@ function Toolbar() {
|
|
|
8510
8836
|
onPointerDown,
|
|
8511
8837
|
onClickCapture,
|
|
8512
8838
|
children: [
|
|
8513
|
-
/* @__PURE__ */ (0,
|
|
8839
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
8514
8840
|
"button",
|
|
8515
8841
|
{
|
|
8516
8842
|
type: "button",
|
|
@@ -8518,19 +8844,19 @@ function Toolbar() {
|
|
|
8518
8844
|
"aria-label": "Move the toolbar \u2014 drag, or use arrow keys; double-click to reset its position",
|
|
8519
8845
|
onKeyDown: onGripKeyDown,
|
|
8520
8846
|
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,
|
|
8847
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("svg", { width: "8", height: "14", viewBox: "0 0 8 14", "aria-hidden": "true", fill: "currentColor", children: [
|
|
8848
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "2", cy: "2", r: "1.1" }),
|
|
8849
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "6", cy: "2", r: "1.1" }),
|
|
8850
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "2", cy: "7", r: "1.1" }),
|
|
8851
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "6", cy: "7", r: "1.1" }),
|
|
8852
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "2", cy: "12", r: "1.1" }),
|
|
8853
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("circle", { cx: "6", cy: "12", r: "1.1" })
|
|
8528
8854
|
] })
|
|
8529
8855
|
}
|
|
8530
8856
|
),
|
|
8531
|
-
/* @__PURE__ */ (0,
|
|
8532
|
-
hasPeers && /* @__PURE__ */ (0,
|
|
8533
|
-
/* @__PURE__ */ (0,
|
|
8857
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(PresenceStrip, {}),
|
|
8858
|
+
hasPeers && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "rk-toolbar-sep" }),
|
|
8859
|
+
/* @__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
8860
|
"button",
|
|
8535
8861
|
{
|
|
8536
8862
|
type: "button",
|
|
@@ -8542,9 +8868,9 @@ function Toolbar() {
|
|
|
8542
8868
|
},
|
|
8543
8869
|
entry.tool
|
|
8544
8870
|
)) }),
|
|
8545
|
-
selection && /* @__PURE__ */ (0,
|
|
8546
|
-
selection && /* @__PURE__ */ (0,
|
|
8547
|
-
/* @__PURE__ */ (0,
|
|
8871
|
+
selection && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "rk-toolbar-sep" }),
|
|
8872
|
+
selection && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
|
|
8873
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
8548
8874
|
"button",
|
|
8549
8875
|
{
|
|
8550
8876
|
type: "button",
|
|
@@ -8553,12 +8879,12 @@ function Toolbar() {
|
|
|
8553
8879
|
title: `Rewrite text${keyHint("tool-copy")}`,
|
|
8554
8880
|
onClick: () => open("copy"),
|
|
8555
8881
|
children: [
|
|
8556
|
-
/* @__PURE__ */ (0,
|
|
8882
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconText, { size: 14 }),
|
|
8557
8883
|
" Rewrite"
|
|
8558
8884
|
]
|
|
8559
8885
|
}
|
|
8560
8886
|
),
|
|
8561
|
-
hasImage && /* @__PURE__ */ (0,
|
|
8887
|
+
hasImage && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
8562
8888
|
"button",
|
|
8563
8889
|
{
|
|
8564
8890
|
type: "button",
|
|
@@ -8567,12 +8893,12 @@ function Toolbar() {
|
|
|
8567
8893
|
title: `Replace image${keyHint("tool-image")}`,
|
|
8568
8894
|
onClick: () => open("image"),
|
|
8569
8895
|
children: [
|
|
8570
|
-
/* @__PURE__ */ (0,
|
|
8896
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconImage, { size: 14 }),
|
|
8571
8897
|
" Image"
|
|
8572
8898
|
]
|
|
8573
8899
|
}
|
|
8574
8900
|
),
|
|
8575
|
-
/* @__PURE__ */ (0,
|
|
8901
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
|
|
8576
8902
|
"button",
|
|
8577
8903
|
{
|
|
8578
8904
|
type: "button",
|
|
@@ -8581,32 +8907,32 @@ function Toolbar() {
|
|
|
8581
8907
|
title: `Comment${keyHint("tool-comment")}`,
|
|
8582
8908
|
onClick: () => open("comment"),
|
|
8583
8909
|
children: [
|
|
8584
|
-
/* @__PURE__ */ (0,
|
|
8910
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconComment, { size: 14 }),
|
|
8585
8911
|
" Comment"
|
|
8586
8912
|
]
|
|
8587
8913
|
}
|
|
8588
8914
|
),
|
|
8589
|
-
/* @__PURE__ */ (0,
|
|
8590
|
-
/* @__PURE__ */ (0,
|
|
8915
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("button", { type: "button", role: "menuitem", className: "rk-toolbar-btn", onClick: () => open("style"), children: [
|
|
8916
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconStyle, { size: 14 }),
|
|
8591
8917
|
" Style"
|
|
8592
8918
|
] }),
|
|
8593
|
-
/* @__PURE__ */ (0,
|
|
8594
|
-
/* @__PURE__ */ (0,
|
|
8919
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("button", { type: "button", role: "menuitem", className: "rk-toolbar-btn", onClick: () => open("move"), children: [
|
|
8920
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconMove, { size: 14 }),
|
|
8595
8921
|
" Move"
|
|
8596
8922
|
] }),
|
|
8597
|
-
/* @__PURE__ */ (0,
|
|
8598
|
-
/* @__PURE__ */ (0,
|
|
8923
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("button", { type: "button", role: "menuitem", className: "rk-toolbar-btn rk-danger", onClick: () => open("delete"), children: [
|
|
8924
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconTrash, { size: 14 }),
|
|
8599
8925
|
" Delete"
|
|
8600
8926
|
] }),
|
|
8601
|
-
/* @__PURE__ */ (0,
|
|
8602
|
-
/* @__PURE__ */ (0,
|
|
8927
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "rk-toolbar-sep" }),
|
|
8928
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
8603
8929
|
"button",
|
|
8604
8930
|
{
|
|
8605
8931
|
type: "button",
|
|
8606
8932
|
className: "rk-icon-btn",
|
|
8607
8933
|
"aria-label": "Deselect",
|
|
8608
8934
|
onClick: () => dispatch({ type: "SELECT", selection: null }),
|
|
8609
|
-
children: /* @__PURE__ */ (0,
|
|
8935
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconClose, { size: 13 })
|
|
8610
8936
|
}
|
|
8611
8937
|
)
|
|
8612
8938
|
] })
|
|
@@ -8614,11 +8940,11 @@ function Toolbar() {
|
|
|
8614
8940
|
}
|
|
8615
8941
|
);
|
|
8616
8942
|
}
|
|
8617
|
-
var
|
|
8943
|
+
var import_react19, import_jsx_runtime17, TOOLS, POS_KEY2, DRAG_THRESHOLD2;
|
|
8618
8944
|
var init_Toolbar = __esm({
|
|
8619
8945
|
"src/client/components/Toolbar.tsx"() {
|
|
8620
8946
|
"use strict";
|
|
8621
|
-
|
|
8947
|
+
import_react19 = require("react");
|
|
8622
8948
|
init_dragPosition();
|
|
8623
8949
|
init_store();
|
|
8624
8950
|
init_preview();
|
|
@@ -8626,12 +8952,12 @@ var init_Toolbar = __esm({
|
|
|
8626
8952
|
init_target();
|
|
8627
8953
|
init_Presence();
|
|
8628
8954
|
init_icons();
|
|
8629
|
-
|
|
8955
|
+
import_jsx_runtime17 = require("react/jsx-runtime");
|
|
8630
8956
|
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,
|
|
8957
|
+
{ tool: "select", hintId: "tool-select", label: "Select", icon: (n) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconTarget, { size: n }) },
|
|
8958
|
+
{ tool: "copy", hintId: "tool-copy", label: "Rewrite text", icon: (n) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconText, { size: n }) },
|
|
8959
|
+
{ tool: "comment", hintId: "tool-comment", label: "Comment", icon: (n) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconComment, { size: n }) },
|
|
8960
|
+
{ tool: "image", hintId: "tool-image", label: "Replace image", icon: (n) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconImage, { size: n }) }
|
|
8635
8961
|
];
|
|
8636
8962
|
POS_KEY2 = "review-kit:toolbar-pos";
|
|
8637
8963
|
DRAG_THRESHOLD2 = 6;
|
|
@@ -8641,28 +8967,28 @@ var init_Toolbar = __esm({
|
|
|
8641
8967
|
// src/client/components/Toast.tsx
|
|
8642
8968
|
function ToastRow({ toast: toast2 }) {
|
|
8643
8969
|
const dispatch = useDispatch();
|
|
8644
|
-
(0,
|
|
8970
|
+
(0, import_react20.useEffect)(() => {
|
|
8645
8971
|
const timer = window.setTimeout(() => dispatch({ type: "DISMISS_TOAST", id: toast2.id }), 3500);
|
|
8646
8972
|
return () => window.clearTimeout(timer);
|
|
8647
8973
|
}, [toast2.id, dispatch]);
|
|
8648
|
-
return /* @__PURE__ */ (0,
|
|
8649
|
-
toast2.tone === "success" ? /* @__PURE__ */ (0,
|
|
8974
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: `rk-toast rk-${toast2.tone}`, role: "status", children: [
|
|
8975
|
+
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
8976
|
toast2.message
|
|
8651
8977
|
] });
|
|
8652
8978
|
}
|
|
8653
8979
|
function ToastHost() {
|
|
8654
8980
|
const { toasts } = useStore();
|
|
8655
8981
|
if (toasts.length === 0) return null;
|
|
8656
|
-
return /* @__PURE__ */ (0,
|
|
8982
|
+
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
8983
|
}
|
|
8658
|
-
var
|
|
8984
|
+
var import_react20, import_jsx_runtime18;
|
|
8659
8985
|
var init_Toast = __esm({
|
|
8660
8986
|
"src/client/components/Toast.tsx"() {
|
|
8661
8987
|
"use strict";
|
|
8662
|
-
|
|
8988
|
+
import_react20 = require("react");
|
|
8663
8989
|
init_store();
|
|
8664
8990
|
init_icons();
|
|
8665
|
-
|
|
8991
|
+
import_jsx_runtime18 = require("react/jsx-runtime");
|
|
8666
8992
|
}
|
|
8667
8993
|
});
|
|
8668
8994
|
|
|
@@ -8672,14 +8998,14 @@ function App() {
|
|
|
8672
8998
|
const rawDispatch = useDispatch();
|
|
8673
8999
|
const config = useConfig();
|
|
8674
9000
|
const dispatch = useRealtimeSync(state, rawDispatch, config, reducer);
|
|
8675
|
-
const saveTimer = (0,
|
|
9001
|
+
const saveTimer = (0, import_react21.useRef)(null);
|
|
8676
9002
|
const storageKey = config.storageKey ?? defaultStorageKey();
|
|
8677
9003
|
useAppliedPreview(state, dispatch);
|
|
8678
9004
|
useEmblemaAutoPush(state, dispatch, config);
|
|
8679
|
-
(0,
|
|
9005
|
+
(0, import_react21.useEffect)(() => {
|
|
8680
9006
|
setEffectAssetsUrl(config.fxAssetsUrl);
|
|
8681
9007
|
}, [config.fxAssetsUrl]);
|
|
8682
|
-
(0,
|
|
9008
|
+
(0, import_react21.useEffect)(() => {
|
|
8683
9009
|
let cancelled = false;
|
|
8684
9010
|
void loadSession(storageKey).then((stored) => {
|
|
8685
9011
|
if (cancelled) return;
|
|
@@ -8697,7 +9023,7 @@ function App() {
|
|
|
8697
9023
|
};
|
|
8698
9024
|
}, [storageKey, config.defaultAuthor, dispatch]);
|
|
8699
9025
|
const { session } = state;
|
|
8700
|
-
(0,
|
|
9026
|
+
(0, import_react21.useEffect)(() => {
|
|
8701
9027
|
if (!session) return;
|
|
8702
9028
|
if (saveTimer.current !== null) window.clearTimeout(saveTimer.current);
|
|
8703
9029
|
saveTimer.current = window.setTimeout(() => {
|
|
@@ -8708,9 +9034,9 @@ function App() {
|
|
|
8708
9034
|
if (saveTimer.current !== null) window.clearTimeout(saveTimer.current);
|
|
8709
9035
|
};
|
|
8710
9036
|
}, [session, storageKey, config]);
|
|
8711
|
-
(0,
|
|
8712
|
-
const focusHandled = (0,
|
|
8713
|
-
(0,
|
|
9037
|
+
(0, import_react21.useEffect)(() => trackPointer(), []);
|
|
9038
|
+
const focusHandled = (0, import_react21.useRef)(false);
|
|
9039
|
+
(0, import_react21.useEffect)(() => {
|
|
8714
9040
|
if (!session || focusHandled.current) return;
|
|
8715
9041
|
focusHandled.current = true;
|
|
8716
9042
|
const id = takeFocusItem();
|
|
@@ -8735,7 +9061,7 @@ function App() {
|
|
|
8735
9061
|
cancelled = true;
|
|
8736
9062
|
};
|
|
8737
9063
|
}, [session, dispatch]);
|
|
8738
|
-
(0,
|
|
9064
|
+
(0, import_react21.useEffect)(() => {
|
|
8739
9065
|
let last = window.location.pathname;
|
|
8740
9066
|
const check = () => {
|
|
8741
9067
|
if (window.location.pathname !== last) {
|
|
@@ -8750,9 +9076,9 @@ function App() {
|
|
|
8750
9076
|
window.removeEventListener("popstate", check);
|
|
8751
9077
|
};
|
|
8752
9078
|
}, [dispatch]);
|
|
8753
|
-
const stateRef = (0,
|
|
9079
|
+
const stateRef = (0, import_react21.useRef)(state);
|
|
8754
9080
|
stateRef.current = state;
|
|
8755
|
-
(0,
|
|
9081
|
+
(0, import_react21.useEffect)(() => {
|
|
8756
9082
|
const onKeyDown = (event) => {
|
|
8757
9083
|
const current = stateRef.current;
|
|
8758
9084
|
for (const def of SHORTCUTS) {
|
|
@@ -8767,7 +9093,7 @@ function App() {
|
|
|
8767
9093
|
document.addEventListener("keydown", onKeyDown);
|
|
8768
9094
|
return () => document.removeEventListener("keydown", onKeyDown);
|
|
8769
9095
|
}, [dispatch]);
|
|
8770
|
-
(0,
|
|
9096
|
+
(0, import_react21.useEffect)(() => {
|
|
8771
9097
|
if (!state.editor) return;
|
|
8772
9098
|
const editorEl = state.editor.element;
|
|
8773
9099
|
const onPointerDown = (event) => {
|
|
@@ -8780,31 +9106,32 @@ function App() {
|
|
|
8780
9106
|
}, [state.editor, dispatch]);
|
|
8781
9107
|
if (!session) return null;
|
|
8782
9108
|
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,
|
|
9109
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(DispatchContext.Provider, { value: dispatch, children: null });
|
|
9110
|
+
}
|
|
9111
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(DispatchContext.Provider, { value: dispatch, children: [
|
|
9112
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(PickLayer, {}),
|
|
9113
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(PeerCursors, {}),
|
|
9114
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Toolbar, {}),
|
|
9115
|
+
state.editor?.kind === "copy" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(InlineEditor, { editor: state.editor }),
|
|
9116
|
+
state.editor?.kind === "image" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ImageEditor, { editor: state.editor }),
|
|
9117
|
+
state.editor && state.editor.kind !== "copy" && state.editor.kind !== "image" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(NoteComposer, { editor: state.editor }),
|
|
9118
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Pins, {}),
|
|
9119
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(QuickComment, {}),
|
|
9120
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Panel, {}),
|
|
9121
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Badge, {}),
|
|
9122
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(CoachMark, {}),
|
|
9123
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(CheatSheet, {}),
|
|
9124
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(EmblemaConnect, {}),
|
|
9125
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TerminalConnect, {}),
|
|
9126
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ConfirmHost, {}),
|
|
9127
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(ToastHost, {})
|
|
8801
9128
|
] });
|
|
8802
9129
|
}
|
|
8803
|
-
var
|
|
9130
|
+
var import_react21, import_jsx_runtime19;
|
|
8804
9131
|
var init_App = __esm({
|
|
8805
9132
|
"src/client/App.tsx"() {
|
|
8806
9133
|
"use strict";
|
|
8807
|
-
|
|
9134
|
+
import_react21 = require("react");
|
|
8808
9135
|
init_env();
|
|
8809
9136
|
init_persist();
|
|
8810
9137
|
init_reveal();
|
|
@@ -8820,6 +9147,7 @@ var init_App = __esm({
|
|
|
8820
9147
|
init_Badge();
|
|
8821
9148
|
init_CheatSheet();
|
|
8822
9149
|
init_EmblemaConnect();
|
|
9150
|
+
init_TerminalConnect();
|
|
8823
9151
|
init_CoachMark();
|
|
8824
9152
|
init_Confirm();
|
|
8825
9153
|
init_ImageEditor();
|
|
@@ -8832,14 +9160,14 @@ var init_App = __esm({
|
|
|
8832
9160
|
init_Pins();
|
|
8833
9161
|
init_Toolbar();
|
|
8834
9162
|
init_Toast();
|
|
8835
|
-
|
|
9163
|
+
import_jsx_runtime19 = require("react/jsx-runtime");
|
|
8836
9164
|
}
|
|
8837
9165
|
});
|
|
8838
9166
|
|
|
8839
9167
|
// src/client/ReviewKit.tsx
|
|
8840
9168
|
function ShadowHost({ config }) {
|
|
8841
|
-
const [mount, setMount] = (0,
|
|
8842
|
-
(0,
|
|
9169
|
+
const [mount, setMount] = (0, import_react22.useState)(null);
|
|
9170
|
+
(0, import_react22.useEffect)(() => {
|
|
8843
9171
|
const host = document.createElement("div");
|
|
8844
9172
|
host.setAttribute(HOST_ATTR, "");
|
|
8845
9173
|
host.style.position = "fixed";
|
|
@@ -8875,15 +9203,15 @@ function ShadowHost({ config }) {
|
|
|
8875
9203
|
}, []);
|
|
8876
9204
|
if (!mount) return null;
|
|
8877
9205
|
return (0, import_react_dom.createPortal)(
|
|
8878
|
-
/* @__PURE__ */ (0,
|
|
9206
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StoreProvider, { config, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(App, {}) }),
|
|
8879
9207
|
mount
|
|
8880
9208
|
);
|
|
8881
9209
|
}
|
|
8882
9210
|
function ReviewKit(props) {
|
|
8883
|
-
const [active2, setActive] = (0,
|
|
9211
|
+
const [active2, setActive] = (0, import_react22.useState)(false);
|
|
8884
9212
|
const { enabled, token, allowedHosts, devAutoOn } = props;
|
|
8885
9213
|
const hostsKey = allowedHosts?.join("\0") ?? "";
|
|
8886
|
-
(0,
|
|
9214
|
+
(0, import_react22.useEffect)(() => {
|
|
8887
9215
|
if (enabled === false) {
|
|
8888
9216
|
setActive(false);
|
|
8889
9217
|
return;
|
|
@@ -8894,13 +9222,13 @@ function ReviewKit(props) {
|
|
|
8894
9222
|
return () => window.removeEventListener(DEACTIVATE_EVENT, onDeactivate);
|
|
8895
9223
|
}, [enabled, token, devAutoOn, hostsKey]);
|
|
8896
9224
|
if (enabled === false || !active2) return null;
|
|
8897
|
-
return /* @__PURE__ */ (0,
|
|
9225
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ShadowHost, { config: props });
|
|
8898
9226
|
}
|
|
8899
|
-
var
|
|
9227
|
+
var import_react22, import_react_dom, import_jsx_runtime20;
|
|
8900
9228
|
var init_ReviewKit = __esm({
|
|
8901
9229
|
"src/client/ReviewKit.tsx"() {
|
|
8902
9230
|
"use strict";
|
|
8903
|
-
|
|
9231
|
+
import_react22 = require("react");
|
|
8904
9232
|
import_react_dom = require("react-dom");
|
|
8905
9233
|
init_env();
|
|
8906
9234
|
init_pointer();
|
|
@@ -8908,7 +9236,7 @@ var init_ReviewKit = __esm({
|
|
|
8908
9236
|
init_target();
|
|
8909
9237
|
init_store();
|
|
8910
9238
|
init_App();
|
|
8911
|
-
|
|
9239
|
+
import_jsx_runtime20 = require("react/jsx-runtime");
|
|
8912
9240
|
}
|
|
8913
9241
|
});
|
|
8914
9242
|
|
|
@@ -8955,19 +9283,19 @@ __export(next_exports, {
|
|
|
8955
9283
|
module.exports = __toCommonJS(next_exports);
|
|
8956
9284
|
|
|
8957
9285
|
// src/LazyReviewKit.tsx
|
|
8958
|
-
var
|
|
9286
|
+
var import_react23 = require("react");
|
|
8959
9287
|
init_activate();
|
|
8960
|
-
var
|
|
9288
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
8961
9289
|
var coreModule = null;
|
|
8962
9290
|
function loadCore() {
|
|
8963
9291
|
if (!coreModule) coreModule = Promise.resolve().then(() => (init_client(), client_exports)).then((mod) => mod.ReviewKit);
|
|
8964
9292
|
return coreModule;
|
|
8965
9293
|
}
|
|
8966
9294
|
function LazyReviewKit(props) {
|
|
8967
|
-
const [Core, setCore] = (0,
|
|
9295
|
+
const [Core, setCore] = (0, import_react23.useState)(null);
|
|
8968
9296
|
const { enabled, token, allowedHosts, devAutoOn } = props;
|
|
8969
9297
|
const hostsKey = allowedHosts?.join(" ") ?? "";
|
|
8970
|
-
(0,
|
|
9298
|
+
(0, import_react23.useEffect)(() => {
|
|
8971
9299
|
if (!shouldActivate({ enabled, token, allowedHosts, devAutoOn })) return;
|
|
8972
9300
|
let cancelled = false;
|
|
8973
9301
|
loadCore().then((component) => {
|
|
@@ -8980,7 +9308,7 @@ function LazyReviewKit(props) {
|
|
|
8980
9308
|
};
|
|
8981
9309
|
}, [enabled, token, devAutoOn, hostsKey]);
|
|
8982
9310
|
if (!Core || enabled === false) return null;
|
|
8983
|
-
return /* @__PURE__ */ (0,
|
|
9311
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Core, { ...props });
|
|
8984
9312
|
}
|
|
8985
9313
|
// Annotate the CommonJS export names for ESM import in node:
|
|
8986
9314
|
0 && (module.exports = {
|