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