reflet-sdk 0.6.8 → 0.6.9

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.
@@ -1,5 +1,5 @@
1
- import { a as EDITORS, c as handoffFileSchema, d as sessionEvidenceSchema, f as sessionHandoffSchema, g as sessionSummarySchema, h as sessionSegmentSchema, l as sessionApiErrorSchema, m as sessionProposalSchema, n as DEVTOOLS_REQUEST_HEADER, p as sessionIdentitySchema, r as DEVTOOLS_ROUTE_BASE, s as analysisStatusSchema, t as DEVTOOLS_ENDPOINTS, u as sessionDetailSchema } from "./protocol-Cg_cI4xS.js";
2
- import { B as clip, D as MoreIcon, G as describeElement, K as getElementRect, M as TargetIcon, R as DEFAULT_WIDGET_LABELS, T as GripIcon, W as buildSelector, Y as redactUrl, Z as inspectReactElement, _ as matchesHotkey, a as uploadBlob, c as useFloatingPosition, g as isSubmitEnter, it as releaseCapture, j as Svg, l as onViewportChange, m as startsInWidget, o as ElementPicker, p as listenToKeydown, q as REDACT_ATTRIBUTE, tt as captureViewport, u as visibleViewport, w as CloseIcon } from "./submit-CafYVnCb.js";
1
+ import { a as EDITORS, c as handoffFileSchema, d as sessionEvidenceSchema, f as sessionHandoffSchema, g as sessionSummarySchema, h as sessionSegmentSchema, l as sessionApiErrorSchema, m as sessionProposalSchema, n as DEVTOOLS_REQUEST_HEADER, p as sessionIdentitySchema, r as DEVTOOLS_ROUTE_BASE, s as analysisStatusSchema, t as DEVTOOLS_ENDPOINTS, u as sessionDetailSchema } from "./protocol-DyAiTtzM.js";
2
+ import { B as clip, D as MoreIcon, G as describeElement, K as getElementRect, M as TargetIcon, R as DEFAULT_WIDGET_LABELS, T as GripIcon, W as buildSelector, Y as redactUrl, Z as inspectReactElement, _ as matchesHotkey, a as uploadBlob, c as useFloatingPosition, g as isSubmitEnter, it as releaseCapture, j as Svg, l as onViewportChange, m as startsInWidget, o as ElementPicker, p as listenToKeydown, q as REDACT_ATTRIBUTE, tt as captureViewport, u as visibleViewport, w as CloseIcon } from "./submit-CSIJr7-R.js";
3
3
  import { t as REFLET_Z_INDEX } from "./z-index-CwokqVq_.js";
4
4
  import { z } from "zod";
5
5
  import { createContext, useContext, useEffect, useId, useLayoutEffect, useRef, useState, useSyncExternalStore } from "react";
@@ -1493,7 +1493,7 @@ function captureFrame() {
1493
1493
  }
1494
1494
  //#endregion
1495
1495
  //#region src/sessions/capture/page/interaction-recorder.ts
1496
- const DWELL_MS = 700;
1496
+ const MIN_DWELL_MS = 700;
1497
1497
  const POINTER_SAMPLE_INTERVAL_MS = 100;
1498
1498
  const SETTLE_DEBOUNCE_MS = 400;
1499
1499
  function eventElement(event) {
@@ -1504,14 +1504,14 @@ function eventElement(event) {
1504
1504
  return element === document.body || element === document.documentElement ? null : element;
1505
1505
  }
1506
1506
  function pointerOf(event) {
1507
- return event instanceof MouseEvent ? {
1507
+ return {
1508
1508
  x: Math.round(event.clientX),
1509
1509
  y: Math.round(event.clientY)
1510
- } : {
1511
- x: 0,
1512
- y: 0
1513
1510
  };
1514
1511
  }
1512
+ function isPhysicalPointerClick(event) {
1513
+ return event instanceof MouseEvent && event.detail > 0;
1514
+ }
1515
1515
  function debounced(signal, run) {
1516
1516
  let settleTimer;
1517
1517
  signal.addEventListener("abort", () => window.clearTimeout(settleTimer));
@@ -1528,34 +1528,50 @@ function recordClick(options) {
1528
1528
  element: describeElementRef(element, options),
1529
1529
  frame: captureFrame(),
1530
1530
  kind: "click",
1531
- pointer: pointerOf(event)
1531
+ pointer: isPhysicalPointerClick(event) ? pointerOf(event) : null
1532
1532
  });
1533
1533
  };
1534
1534
  }
1535
1535
  function watchDwell(options, signal) {
1536
1536
  let hovered = null;
1537
1537
  let lastSampleAt = Number.NEGATIVE_INFINITY;
1538
- let dwellTimer;
1539
- signal.addEventListener("abort", () => window.clearTimeout(dwellTimer));
1540
- return (event) => {
1538
+ let entered = null;
1539
+ const settle = () => {
1540
+ if (!entered) return;
1541
+ const durationMs = options.atMs() - entered.atMs;
1542
+ if (durationMs >= MIN_DWELL_MS) options.onEvent({
1543
+ ...entered,
1544
+ durationMs
1545
+ });
1546
+ entered = null;
1547
+ };
1548
+ signal.addEventListener("abort", settle);
1549
+ const onPointerMove = (event) => {
1550
+ if (!(event instanceof MouseEvent)) return;
1541
1551
  const now = Date.now();
1542
1552
  if (now - lastSampleAt < POINTER_SAMPLE_INTERVAL_MS) return;
1543
1553
  lastSampleAt = now;
1544
1554
  const element = eventElement(event);
1545
1555
  if (element === hovered) return;
1556
+ settle();
1546
1557
  hovered = element;
1547
- window.clearTimeout(dwellTimer);
1548
- if (!element) return;
1549
- const atMs = options.atMs();
1550
- const pointer = pointerOf(event);
1551
- dwellTimer = window.setTimeout(() => options.onEvent({
1552
- atMs,
1553
- durationMs: DWELL_MS,
1558
+ if (element) entered = {
1559
+ atMs: options.atMs(),
1554
1560
  element: describeElementRef(element, options),
1555
1561
  frame: captureFrame(),
1556
1562
  kind: "dwell",
1557
- pointer
1558
- }), DWELL_MS);
1563
+ pointer: pointerOf(event)
1564
+ };
1565
+ };
1566
+ const onPointerLeaveWindow = (event) => {
1567
+ if (event instanceof MouseEvent && event.relatedTarget === null) {
1568
+ settle();
1569
+ hovered = null;
1570
+ }
1571
+ };
1572
+ return {
1573
+ onPointerLeaveWindow,
1574
+ onPointerMove
1559
1575
  };
1560
1576
  }
1561
1577
  function startInteractionRecorder(options) {
@@ -1579,8 +1595,10 @@ function startInteractionRecorder(options) {
1579
1595
  viewportHeight: window.innerHeight,
1580
1596
  viewportWidth: window.innerWidth
1581
1597
  }));
1598
+ const dwell = watchDwell(options, signal);
1582
1599
  document.addEventListener("click", recordClick(options), listen);
1583
- document.addEventListener("pointermove", watchDwell(options, signal), listen);
1600
+ document.addEventListener("pointermove", dwell.onPointerMove, listen);
1601
+ document.addEventListener("pointerout", dwell.onPointerLeaveWindow, listen);
1584
1602
  window.addEventListener("scroll", recordScroll, listen);
1585
1603
  window.addEventListener("resize", recordViewport, listen);
1586
1604
  return { stop: () => controller.abort() };
@@ -1713,6 +1731,12 @@ function blankFieldValues(root) {
1713
1731
  const NAVIGATION_SETTLE_MS = 1500;
1714
1732
  const CAPTURE_FAILED = "The page could not be captured.";
1715
1733
  const CAPTURE_TOO_LARGE = "The screenshot was larger than the upload limit.";
1734
+ const STOPPED_BEFORE_CAPTURE = "Recording stopped before the screenshot was taken.";
1735
+ const stoppedBeforeCapture = (base) => ({
1736
+ ...base,
1737
+ image: null,
1738
+ missingReason: STOPPED_BEFORE_CAPTURE
1739
+ });
1716
1740
  async function shoot(base, maxImageBytes) {
1717
1741
  const image = await captureViewport({
1718
1742
  excludeSelectors: SESSION_MASK_SELECTORS,
@@ -1746,6 +1770,7 @@ function createEvidenceScheduler(options) {
1746
1770
  let lastCaptureAtMs = Number.NEGATIVE_INFINITY;
1747
1771
  let navigationTimer;
1748
1772
  let previousCapture = Promise.resolve();
1773
+ let collectionRun = 0;
1749
1774
  const take = (trigger, request) => {
1750
1775
  if (captured >= limits.maxEvidence) return null;
1751
1776
  captured += 1;
@@ -1760,11 +1785,20 @@ function createEvidenceScheduler(options) {
1760
1785
  note: request.note ?? null,
1761
1786
  trigger
1762
1787
  };
1763
- previousCapture = previousCapture.then(() => shoot(base, limits.maxImageBytes)).then(options.onEvidence);
1788
+ const takenInRun = collectionRun;
1789
+ const captureUnlessStopped = async () => {
1790
+ if (takenInRun !== collectionRun) return stoppedBeforeCapture(base);
1791
+ const evidence = await shoot(base, limits.maxImageBytes);
1792
+ return takenInRun === collectionRun ? evidence : stoppedBeforeCapture(base);
1793
+ };
1794
+ previousCapture = previousCapture.then(captureUnlessStopped).then(options.onEvidence);
1764
1795
  return clientKey;
1765
1796
  };
1766
1797
  return {
1767
- cancelPending: () => window.clearTimeout(navigationTimer),
1798
+ cancelPending: () => {
1799
+ window.clearTimeout(navigationTimer);
1800
+ collectionRun += 1;
1801
+ },
1768
1802
  capture: (request) => take(request.trigger, request),
1769
1803
  navigated: () => {
1770
1804
  window.clearTimeout(navigationTimer);
@@ -5086,17 +5120,22 @@ function AttachLink({ detail, onDone, review }) {
5086
5120
  //#endregion
5087
5121
  //#region src/sessions/ui/review/transcript/remove-evidence.tsx
5088
5122
  const REMOVE_COPY = "Remove this screenshot? The image is deleted for good. Briefs you already copied or exported can't be recalled.";
5089
- function RemoveConfirmation({ evidence, onCancel, review }) {
5123
+ function useFocusWhen(shouldFocus) {
5124
+ const ref = useRef(null);
5125
+ useEffect(() => {
5126
+ if (shouldFocus) ref.current?.focus();
5127
+ }, [shouldFocus]);
5128
+ return ref;
5129
+ }
5130
+ function RemoveConfirmation({ evidence, onCancel, removal }) {
5090
5131
  const { api } = useSessionWorkspace();
5091
5132
  const run = useSessionAction();
5092
- const cancelRef = useRef(null);
5093
- useEffect(() => {
5094
- cancelRef.current?.focus();
5095
- }, []);
5133
+ const cancelRef = useFocusWhen(true);
5096
5134
  const remove = async () => {
5097
5135
  const removed = await run("The screenshot was not removed", () => api.removeEvidence(evidence.id));
5098
5136
  if (removed !== null) {
5099
- review.patch((detail) => withEvidence(detail, removed));
5137
+ removal.review.patch((detail) => withEvidence(detail, removed));
5138
+ removal.onRemoved(removed.id);
5100
5139
  announce("Screenshot removed");
5101
5140
  }
5102
5141
  };
@@ -5120,17 +5159,26 @@ function RemoveConfirmation({ evidence, onCancel, review }) {
5120
5159
  })]
5121
5160
  });
5122
5161
  }
5123
- function RemoveEvidence({ evidence, review }) {
5162
+ function RemoveEvidence({ evidence, removal }) {
5124
5163
  const [isConfirming, setIsConfirming] = useState(false);
5164
+ const [hasCancelled, setHasCancelled] = useState(false);
5165
+ const triggerRef = useFocusWhen(hasCancelled);
5125
5166
  if (isConfirming) return /* @__PURE__ */ jsx(RemoveConfirmation, {
5126
5167
  evidence,
5127
- onCancel: () => setIsConfirming(false),
5128
- review
5168
+ onCancel: () => {
5169
+ setIsConfirming(false);
5170
+ setHasCancelled(true);
5171
+ },
5172
+ removal
5129
5173
  });
5130
5174
  return /* @__PURE__ */ jsx("button", {
5131
5175
  "aria-label": `Remove screenshot at ${formatClock(evidence.atMs)}`,
5132
5176
  className: "dt-ses-link",
5133
- onClick: () => setIsConfirming(true),
5177
+ onClick: () => {
5178
+ setIsConfirming(true);
5179
+ setHasCancelled(false);
5180
+ },
5181
+ ref: triggerRef,
5134
5182
  type: "button",
5135
5183
  children: "Remove"
5136
5184
  });
@@ -5138,6 +5186,21 @@ function RemoveEvidence({ evidence, review }) {
5138
5186
  //#endregion
5139
5187
  //#region src/sessions/ui/review/transcript/evidence-tab.tsx
5140
5188
  const isViewable = (evidence) => evidence.status === "available" && Boolean(evidence.image?.url);
5189
+ function MissingEvidenceItem({ caption, evidence, isJustRemoved }) {
5190
+ const cardRef = useFocusWhen(isJustRemoved);
5191
+ return /* @__PURE__ */ jsxs("li", {
5192
+ className: "dt-card",
5193
+ ref: cardRef,
5194
+ tabIndex: isJustRemoved ? -1 : void 0,
5195
+ children: [/* @__PURE__ */ jsx("p", {
5196
+ className: "dt-meta",
5197
+ children: caption
5198
+ }), /* @__PURE__ */ jsxs("p", {
5199
+ className: "dt-meta",
5200
+ children: ["Screenshot missing: ", evidence.missingReason ?? "not captured."]
5201
+ })]
5202
+ });
5203
+ }
5141
5204
  function LinkEvidenceItem({ link }) {
5142
5205
  return /* @__PURE__ */ jsxs("li", {
5143
5206
  className: "dt-card",
@@ -5163,15 +5226,10 @@ function LinkEvidenceItem({ link }) {
5163
5226
  function EvidenceItem({ evidence, onEnlarge, removal }) {
5164
5227
  const caption = `${formatClock(evidence.atMs)} · ${evidenceCaption(evidence)}`;
5165
5228
  if (evidence.link) return /* @__PURE__ */ jsx(LinkEvidenceItem, { link: evidence.link });
5166
- if (!isViewable(evidence)) return /* @__PURE__ */ jsxs("li", {
5167
- className: "dt-card",
5168
- children: [/* @__PURE__ */ jsx("p", {
5169
- className: "dt-meta",
5170
- children: caption
5171
- }), /* @__PURE__ */ jsxs("p", {
5172
- className: "dt-meta",
5173
- children: ["Screenshot missing: ", evidence.missingReason ?? "not captured."]
5174
- })]
5229
+ if (!isViewable(evidence)) return /* @__PURE__ */ jsx(MissingEvidenceItem, {
5230
+ caption,
5231
+ evidence,
5232
+ isJustRemoved: evidence.id === removal.removedId
5175
5233
  });
5176
5234
  return /* @__PURE__ */ jsxs("li", {
5177
5235
  className: "dt-card",
@@ -5193,7 +5251,7 @@ function EvidenceItem({ evidence, onEnlarge, removal }) {
5193
5251
  }),
5194
5252
  removal.canRemove && /* @__PURE__ */ jsx(RemoveEvidence, {
5195
5253
  evidence,
5196
- review: removal.review
5254
+ removal
5197
5255
  })
5198
5256
  ]
5199
5257
  });
@@ -5220,7 +5278,7 @@ function EnlargedEvidence({ evidence, onBack, removal }) {
5220
5278
  }),
5221
5279
  removal.canRemove && /* @__PURE__ */ jsx(RemoveEvidence, {
5222
5280
  evidence,
5223
- review: removal.review
5281
+ removal
5224
5282
  })
5225
5283
  ] });
5226
5284
  }
@@ -5237,12 +5295,34 @@ function EvidenceList({ evidence, onEnlarge, removal }) {
5237
5295
  }, item.id))
5238
5296
  })] });
5239
5297
  }
5298
+ function AttachLinkAction({ detail, review }) {
5299
+ const [isAttaching, setIsAttaching] = useState(false);
5300
+ if (isAttaching) return /* @__PURE__ */ jsx(AttachLink, {
5301
+ detail,
5302
+ onDone: () => setIsAttaching(false),
5303
+ review
5304
+ });
5305
+ return /* @__PURE__ */ jsx("div", {
5306
+ className: "dt-actions",
5307
+ children: /* @__PURE__ */ jsx("button", {
5308
+ className: "dt-btn",
5309
+ onClick: () => setIsAttaching(true),
5310
+ type: "button",
5311
+ children: "Attach a link"
5312
+ })
5313
+ });
5314
+ }
5240
5315
  function EvidenceTab({ detail, review }) {
5241
5316
  const [enlargedId, setEnlargedId] = useState(null);
5242
- const [isAttaching, setIsAttaching] = useState(false);
5317
+ const [removedId, setRemovedId] = useState(null);
5243
5318
  const enlarged = detail.evidence.find((item) => item.id === enlargedId && isViewable(item));
5244
5319
  const removal = {
5245
5320
  canRemove: detail.session.canEdit,
5321
+ onRemoved: (evidenceId) => {
5322
+ setEnlargedId(null);
5323
+ setRemovedId(evidenceId);
5324
+ },
5325
+ removedId,
5246
5326
  review
5247
5327
  };
5248
5328
  if (enlarged) return /* @__PURE__ */ jsx(EnlargedEvidence, {
@@ -5254,19 +5334,10 @@ function EvidenceTab({ detail, review }) {
5254
5334
  evidence: detail.evidence,
5255
5335
  onEnlarge: setEnlargedId,
5256
5336
  removal
5257
- }), detail.session.canEdit && (isAttaching ? /* @__PURE__ */ jsx(AttachLink, {
5337
+ }), detail.session.canEdit && /* @__PURE__ */ jsx(AttachLinkAction, {
5258
5338
  detail,
5259
- onDone: () => setIsAttaching(false),
5260
5339
  review
5261
- }) : /* @__PURE__ */ jsx("div", {
5262
- className: "dt-actions",
5263
- children: /* @__PURE__ */ jsx("button", {
5264
- className: "dt-btn",
5265
- onClick: () => setIsAttaching(true),
5266
- type: "button",
5267
- children: "Attach a link"
5268
- })
5269
- }))] });
5340
+ })] });
5270
5341
  }
5271
5342
  //#endregion
5272
5343
  //#region src/sessions/ui/review/transcript/segment-row.tsx
@@ -6082,4 +6153,4 @@ function SessionsPanel({ navigation, onStarted, onWriteNote }) {
6082
6153
  //#endregion
6083
6154
  export { announce as A, searchCode as C, openDatabase as D, describeStorageFailure as E, settle as O, probeDevRoute as S, committed as T, teamTransport as _, DevtoolsBar as a, fetchBoardFeedback as b, copyToClipboard as c, PersonIcon as d, SessionWorkspaceProvider as f, devtoolsTransport as g, purgeAccount as h, BarButton as i, reportFailure as j, Notices as k, SESSIONS_STYLES as l, useWorkspaceLoader as m, DEVTOOLS_STYLES as n, DevtoolsBarButtons as o, failureMessage as p, DevtoolsSheet as r, SessionsBarButton as s, SessionsPanel as t, RecordingLayer as u, callReflet as v, startBoardConnect as w, fetchSourceFile as x, disconnectBoard as y };
6084
6155
 
6085
- //# sourceMappingURL=sessions-panel-Dq5j1qcu.js.map
6156
+ //# sourceMappingURL=sessions-panel-CaOJ6vWR.js.map