qapture2 0.7.8 → 0.7.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.
@@ -1741,6 +1741,8 @@ var STR = {
1741
1741
  loc_show: "Show captured location",
1742
1742
  loc_hide: "Hide location",
1743
1743
  loc_locate: "Locate on page",
1744
+ loc_other_page: "This one was filed on {path}, not the page you are on.",
1745
+ loc_go_there: "Go to {path}",
1744
1746
  journey_title: "Testing journey",
1745
1747
  journey_generic: "No test plan was set up for this project, so this is a general one that fits any app. Work through it, or ask whoever set up Qapture to add the real journey to qa.config.",
1746
1748
  export_name_title: "Name your export",
@@ -1896,6 +1898,7 @@ var STR = {
1896
1898
  capture_screen: "Whole screen",
1897
1899
  walk_title: "Walkthrough",
1898
1900
  walk_take_me: "Take me to {path}",
1901
+ walk_taking_you: "Taking you there\u2026",
1899
1902
  walk_reload_hint: "Reload the page instead (use this if the app didn't move)",
1900
1903
  walk_note_title: "Point {n}",
1901
1904
  walk_still_broken: "Still broken",
@@ -1946,6 +1949,8 @@ var STR = {
1946
1949
  loc_show: "\u0625\u0638\u0647\u0627\u0631 \u0627\u0644\u0645\u0648\u0642\u0639 \u0627\u0644\u0645\u064F\u0644\u062A\u0642\u064E\u0637",
1947
1950
  loc_hide: "\u0625\u062E\u0641\u0627\u0621 \u0627\u0644\u0645\u0648\u0642\u0639",
1948
1951
  loc_locate: "\u0625\u0638\u0647\u0627\u0631 \u0639\u0644\u0649 \u0627\u0644\u0635\u0641\u062D\u0629",
1952
+ loc_other_page: "\u0633\u064F\u062C\u0651\u0644\u062A \u0647\u0630\u0647 \u0641\u064A {path}\u060C \u0648\u0644\u064A\u0633\u062A \u0627\u0644\u0635\u0641\u062D\u0629 \u0627\u0644\u062A\u064A \u0623\u0646\u062A \u0641\u064A\u0647\u0627.",
1953
+ loc_go_there: "\u0627\u0630\u0647\u0628 \u0625\u0644\u0649 {path}",
1949
1954
  journey_title: "\u0631\u062D\u0644\u0629 \u0627\u0644\u0627\u062E\u062A\u0628\u0627\u0631",
1950
1955
  journey_generic: "\u0644\u0645 \u064A\u062A\u0645 \u0625\u0639\u062F\u0627\u062F \u062E\u0637\u0629 \u0627\u062E\u062A\u0628\u0627\u0631 \u0644\u0647\u0630\u0627 \u0627\u0644\u0645\u0634\u0631\u0648\u0639\u060C \u0644\u0630\u0644\u0643 \u0647\u0630\u0647 \u062E\u0637\u0629 \u0639\u0627\u0645\u0629 \u062A\u0635\u0644\u062D \u0644\u0623\u064A \u062A\u0637\u0628\u064A\u0642. \u0627\u0639\u0645\u0644 \u0628\u0647\u0627\u060C \u0623\u0648 \u0627\u0637\u0644\u0628 \u0645\u0645\u0646 \u062B\u0628\u0651\u062A Qapture \u0623\u0646 \u064A\u0636\u064A\u0641 \u0631\u062D\u0644\u0629 \u0627\u0644\u0645\u0634\u0631\u0648\u0639 \u0641\u064A qa.config.",
1951
1956
  export_name_title: "\u0633\u0645\u0650\u0651 \u0645\u0644\u0641 \u0627\u0644\u062A\u0635\u062F\u064A\u0631",
@@ -2101,6 +2106,7 @@ var STR = {
2101
2106
  capture_screen: "\u0627\u0644\u0634\u0627\u0634\u0629 \u0643\u0627\u0645\u0644\u0629",
2102
2107
  walk_title: "\u0627\u0644\u062C\u0648\u0644\u0629",
2103
2108
  walk_take_me: "\u062E\u0630\u0646\u064A \u0625\u0644\u0649 {path}",
2109
+ walk_taking_you: "\u062C\u0627\u0631\u064D \u0646\u0642\u0644\u0643\u2026",
2104
2110
  walk_reload_hint: "\u0623\u0639\u062F \u062A\u062D\u0645\u064A\u0644 \u0627\u0644\u0635\u0641\u062D\u0629 \u0628\u062F\u0644\u064B\u0627 \u0645\u0646 \u0630\u0644\u0643 (\u0627\u0633\u062A\u062E\u062F\u0645\u0647 \u0625\u0630\u0627 \u0644\u0645 \u064A\u0646\u062A\u0642\u0644 \u0627\u0644\u062A\u0637\u0628\u064A\u0642)",
2105
2111
  walk_note_title: "\u0627\u0644\u0646\u0642\u0637\u0629 {n}",
2106
2112
  walk_still_broken: "\u0645\u0627 \u0632\u0627\u0644 \u0645\u0639\u0637\u0644\u064B\u0627",
@@ -4218,6 +4224,13 @@ var DENSE_NOTES_KEY = "denseNotes";
4218
4224
  var PANEL_OPEN_KEY = "panelOpen";
4219
4225
  var ACTIVE_TAB_KEY = "activeTab";
4220
4226
  var WALK_KEY = "walk";
4227
+ var SOFT_NAV_PROOF_MS = 700;
4228
+ function pageSignature() {
4229
+ if (typeof document === "undefined" || !document.body) return "";
4230
+ const body = document.body;
4231
+ const text = body.textContent || "";
4232
+ return [document.title, body.childElementCount, text.length, text.slice(0, 200)].join("\0");
4233
+ }
4221
4234
  var GUIDE_SKIPPED_KEY = "guideSkipped";
4222
4235
  var NOTICE_QUEUE_CAP = 3;
4223
4236
  var NOTICE_DURATION_INFO = 4e3;
@@ -5254,16 +5267,23 @@ function QaProvider({
5254
5267
  const walkNavigate = React.useCallback((path, hard = false) => {
5255
5268
  if (typeof window === "undefined" || !path) return;
5256
5269
  const target = path.startsWith("/") ? path : `/${path}`;
5257
- if (hard) {
5270
+ if (hard || target === window.location.pathname) {
5258
5271
  window.location.assign(target);
5259
5272
  return;
5260
5273
  }
5274
+ const before = pageSignature();
5261
5275
  try {
5262
- window.history.pushState({}, "", target);
5263
- window.dispatchEvent(new PopStateEvent("popstate"));
5276
+ window.history.pushState(window.history.state, "", target);
5277
+ window.dispatchEvent(new PopStateEvent("popstate", { state: window.history.state }));
5264
5278
  } catch {
5265
5279
  window.location.assign(target);
5280
+ return;
5266
5281
  }
5282
+ window.setTimeout(() => {
5283
+ if (window.location.pathname !== target) return;
5284
+ if (pageSignature() !== before) return;
5285
+ window.location.assign(target);
5286
+ }, SOFT_NAV_PROOF_MS);
5267
5287
  }, []);
5268
5288
  React.useEffect(() => {
5269
5289
  if (typeof window === "undefined") return;
@@ -6146,11 +6166,17 @@ function flashLocate(target) {
6146
6166
  paint(rect);
6147
6167
  }
6148
6168
  }
6149
- function LocationReveal({ target }) {
6150
- const { t } = useQa();
6169
+ function LocationReveal({
6170
+ target,
6171
+ route
6172
+ }) {
6173
+ const { t, walkNavigate } = useQa();
6151
6174
  const [open, setOpen] = React.useState(false);
6152
6175
  if (!target) return null;
6153
6176
  const r = target.rect;
6177
+ const notePath = (route || "").split("?")[0].split("#")[0];
6178
+ const here = typeof window === "undefined" ? "" : window.location.pathname;
6179
+ const elsewhere = !!notePath && notePath !== here;
6154
6180
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "qa-rounded-lg qa-border qa-border-subtle qa-bg-2", children: [
6155
6181
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "qa-flex qa-items-center qa-gap-1.5 qa-px-2 qa-py-1.5 qa-text-11", children: [
6156
6182
  /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "CheckCircle2", size: 14, className: "qa-text-success" }),
@@ -6214,7 +6240,21 @@ function LocationReveal({ target }) {
6214
6240
  "\xD7",
6215
6241
  Math.round(r.height)
6216
6242
  ] }),
6217
- /* @__PURE__ */ jsxRuntime.jsxs(
6243
+ elsewhere ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6244
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "qa-mt-1 qa-mb-1 qa-m-0 qa-text-lo", children: t("loc_other_page", { path: notePath }) }),
6245
+ /* @__PURE__ */ jsxRuntime.jsxs(
6246
+ "button",
6247
+ {
6248
+ onClick: () => walkNavigate(notePath),
6249
+ className: "qa-inline-flex qa-items-center qa-gap-1 qa-rounded-md qa-px-2 qa-py-1 qa-font-medium qa-tap qa-bg-accent",
6250
+ style: { border: "none", cursor: "pointer" },
6251
+ children: [
6252
+ /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "MapPinned", size: 12 }),
6253
+ t("loc_go_there", { path: notePath })
6254
+ ]
6255
+ }
6256
+ )
6257
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(
6218
6258
  "button",
6219
6259
  {
6220
6260
  onClick: () => flashLocate(target),
@@ -6932,7 +6972,7 @@ function NoteItem({
6932
6972
  /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "MapPin", size: 12, className: "qa-shrink-0" }),
6933
6973
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "qa-truncate qa-dir-ltr", title: note.url, children: note.route })
6934
6974
  ] }),
6935
- note.target && /* @__PURE__ */ jsxRuntime.jsx(LocationReveal, { target: note.target }),
6975
+ note.target && /* @__PURE__ */ jsxRuntime.jsx(LocationReveal, { target: note.target, route: note.route }),
6936
6976
  contextEventCount > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { children: t("context_attached", { n: contextEventCount }) }),
6937
6977
  stepCount > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "qa-flex qa-items-center qa-gap-1", children: [
6938
6978
  /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "ClipboardList", size: 12, className: "qa-shrink-0" }),
@@ -8676,6 +8716,20 @@ var RISK_COLOR = {
8676
8716
  amber: "var(--qa-warn)",
8677
8717
  green: "var(--qa-success)"
8678
8718
  };
8719
+ function useCurrentPath() {
8720
+ const [path, setPath] = React.useState(() => typeof window === "undefined" ? "" : window.location.pathname);
8721
+ React.useEffect(() => {
8722
+ if (typeof window === "undefined") return;
8723
+ const sync = () => setPath(window.location.pathname);
8724
+ window.addEventListener("popstate", sync);
8725
+ window.addEventListener("hashchange", sync);
8726
+ return () => {
8727
+ window.removeEventListener("popstate", sync);
8728
+ window.removeEventListener("hashchange", sync);
8729
+ };
8730
+ }, []);
8731
+ return path;
8732
+ }
8679
8733
  function WalkHud() {
8680
8734
  const {
8681
8735
  dir,
@@ -8695,10 +8749,13 @@ function WalkHud() {
8695
8749
  startCapture,
8696
8750
  updateNote,
8697
8751
  retestNote,
8698
- notes
8752
+ notes,
8753
+ notesLoading
8699
8754
  } = useQa();
8700
8755
  const index = Math.min(walk.index, Math.max(0, walkStops.length - 1));
8701
8756
  const stop = walkStops[index];
8757
+ const currentPath = useCurrentPath();
8758
+ const [going, setGoing] = React.useState(false);
8702
8759
  const backIcon = dir === "rtl" ? "ChevronRight" : "ChevronLeft";
8703
8760
  const nextIcon = dir === "rtl" ? "ChevronLeft" : "ChevronRight";
8704
8761
  React.useEffect(() => {
@@ -8712,8 +8769,9 @@ function WalkHud() {
8712
8769
  if (latest?.target) flashLocate(latest.target);
8713
8770
  }, [index, walk.source]);
8714
8771
  React.useEffect(() => {
8772
+ if (notesLoading) return;
8715
8773
  if (walk.active && walkStops.length === 0) exitWalk();
8716
- }, [walk.active, walkStops.length, exitWalk]);
8774
+ }, [walk.active, walkStops.length, exitWalk, notesLoading]);
8717
8775
  if (!walk.active || !stop) return null;
8718
8776
  const atLast = index >= walkStops.length - 1;
8719
8777
  let title;
@@ -8874,7 +8932,7 @@ function WalkHud() {
8874
8932
  )
8875
8933
  ] });
8876
8934
  }
8877
- const onThisPage = stop.path === ANY_PAGE || typeof window !== "undefined" && stop.path === window.location.pathname;
8935
+ const onThisPage = stop.path === ANY_PAGE || stop.path === currentPath;
8878
8936
  return /* @__PURE__ */ jsxRuntime.jsxs(
8879
8937
  "div",
8880
8938
  {
@@ -8910,12 +8968,24 @@ function WalkHud() {
8910
8968
  "button",
8911
8969
  {
8912
8970
  type: "button",
8913
- onClick: () => walkNavigate(stop.path),
8971
+ disabled: going,
8972
+ onClick: () => {
8973
+ setGoing(true);
8974
+ walkNavigate(stop.path);
8975
+ window.setTimeout(() => setGoing(false), 900);
8976
+ },
8914
8977
  className: "qa-tap qa-inline-flex qa-flex-1 qa-items-center qa-justify-center qa-gap-1.5 qa-rounded-lg qa-bg-accent qa-px-2 qa-py-1.5 qa-text-11 qa-font-semibold",
8915
- style: { border: "none", cursor: "pointer" },
8978
+ style: { border: "none", cursor: going ? "default" : "pointer" },
8916
8979
  children: [
8917
- /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "MapPinned", size: 13 }),
8918
- t("walk_take_me", { path: stop.path })
8980
+ /* @__PURE__ */ jsxRuntime.jsx(
8981
+ Icon,
8982
+ {
8983
+ name: going ? "Loader2" : "MapPinned",
8984
+ size: 13,
8985
+ className: going ? "qa-animate-spin" : void 0
8986
+ }
8987
+ ),
8988
+ going ? t("walk_taking_you") : t("walk_take_me", { path: stop.path })
8919
8989
  ]
8920
8990
  }
8921
8991
  ),
@@ -10328,5 +10398,5 @@ function Qapture({ config }) {
10328
10398
  exports.Qapture = Qapture;
10329
10399
  exports.deleteQaDatabase = deleteQaDatabase;
10330
10400
  exports.initQaStudio = initQaStudio;
10331
- //# sourceMappingURL=chunk-4LMLW73U.cjs.map
10332
- //# sourceMappingURL=chunk-4LMLW73U.cjs.map
10401
+ //# sourceMappingURL=chunk-6UNSUNJS.cjs.map
10402
+ //# sourceMappingURL=chunk-6UNSUNJS.cjs.map
@@ -1734,6 +1734,8 @@ var STR = {
1734
1734
  loc_show: "Show captured location",
1735
1735
  loc_hide: "Hide location",
1736
1736
  loc_locate: "Locate on page",
1737
+ loc_other_page: "This one was filed on {path}, not the page you are on.",
1738
+ loc_go_there: "Go to {path}",
1737
1739
  journey_title: "Testing journey",
1738
1740
  journey_generic: "No test plan was set up for this project, so this is a general one that fits any app. Work through it, or ask whoever set up Qapture to add the real journey to qa.config.",
1739
1741
  export_name_title: "Name your export",
@@ -1889,6 +1891,7 @@ var STR = {
1889
1891
  capture_screen: "Whole screen",
1890
1892
  walk_title: "Walkthrough",
1891
1893
  walk_take_me: "Take me to {path}",
1894
+ walk_taking_you: "Taking you there\u2026",
1892
1895
  walk_reload_hint: "Reload the page instead (use this if the app didn't move)",
1893
1896
  walk_note_title: "Point {n}",
1894
1897
  walk_still_broken: "Still broken",
@@ -1939,6 +1942,8 @@ var STR = {
1939
1942
  loc_show: "\u0625\u0638\u0647\u0627\u0631 \u0627\u0644\u0645\u0648\u0642\u0639 \u0627\u0644\u0645\u064F\u0644\u062A\u0642\u064E\u0637",
1940
1943
  loc_hide: "\u0625\u062E\u0641\u0627\u0621 \u0627\u0644\u0645\u0648\u0642\u0639",
1941
1944
  loc_locate: "\u0625\u0638\u0647\u0627\u0631 \u0639\u0644\u0649 \u0627\u0644\u0635\u0641\u062D\u0629",
1945
+ loc_other_page: "\u0633\u064F\u062C\u0651\u0644\u062A \u0647\u0630\u0647 \u0641\u064A {path}\u060C \u0648\u0644\u064A\u0633\u062A \u0627\u0644\u0635\u0641\u062D\u0629 \u0627\u0644\u062A\u064A \u0623\u0646\u062A \u0641\u064A\u0647\u0627.",
1946
+ loc_go_there: "\u0627\u0630\u0647\u0628 \u0625\u0644\u0649 {path}",
1942
1947
  journey_title: "\u0631\u062D\u0644\u0629 \u0627\u0644\u0627\u062E\u062A\u0628\u0627\u0631",
1943
1948
  journey_generic: "\u0644\u0645 \u064A\u062A\u0645 \u0625\u0639\u062F\u0627\u062F \u062E\u0637\u0629 \u0627\u062E\u062A\u0628\u0627\u0631 \u0644\u0647\u0630\u0627 \u0627\u0644\u0645\u0634\u0631\u0648\u0639\u060C \u0644\u0630\u0644\u0643 \u0647\u0630\u0647 \u062E\u0637\u0629 \u0639\u0627\u0645\u0629 \u062A\u0635\u0644\u062D \u0644\u0623\u064A \u062A\u0637\u0628\u064A\u0642. \u0627\u0639\u0645\u0644 \u0628\u0647\u0627\u060C \u0623\u0648 \u0627\u0637\u0644\u0628 \u0645\u0645\u0646 \u062B\u0628\u0651\u062A Qapture \u0623\u0646 \u064A\u0636\u064A\u0641 \u0631\u062D\u0644\u0629 \u0627\u0644\u0645\u0634\u0631\u0648\u0639 \u0641\u064A qa.config.",
1944
1949
  export_name_title: "\u0633\u0645\u0650\u0651 \u0645\u0644\u0641 \u0627\u0644\u062A\u0635\u062F\u064A\u0631",
@@ -2094,6 +2099,7 @@ var STR = {
2094
2099
  capture_screen: "\u0627\u0644\u0634\u0627\u0634\u0629 \u0643\u0627\u0645\u0644\u0629",
2095
2100
  walk_title: "\u0627\u0644\u062C\u0648\u0644\u0629",
2096
2101
  walk_take_me: "\u062E\u0630\u0646\u064A \u0625\u0644\u0649 {path}",
2102
+ walk_taking_you: "\u062C\u0627\u0631\u064D \u0646\u0642\u0644\u0643\u2026",
2097
2103
  walk_reload_hint: "\u0623\u0639\u062F \u062A\u062D\u0645\u064A\u0644 \u0627\u0644\u0635\u0641\u062D\u0629 \u0628\u062F\u0644\u064B\u0627 \u0645\u0646 \u0630\u0644\u0643 (\u0627\u0633\u062A\u062E\u062F\u0645\u0647 \u0625\u0630\u0627 \u0644\u0645 \u064A\u0646\u062A\u0642\u0644 \u0627\u0644\u062A\u0637\u0628\u064A\u0642)",
2098
2104
  walk_note_title: "\u0627\u0644\u0646\u0642\u0637\u0629 {n}",
2099
2105
  walk_still_broken: "\u0645\u0627 \u0632\u0627\u0644 \u0645\u0639\u0637\u0644\u064B\u0627",
@@ -4211,6 +4217,13 @@ var DENSE_NOTES_KEY = "denseNotes";
4211
4217
  var PANEL_OPEN_KEY = "panelOpen";
4212
4218
  var ACTIVE_TAB_KEY = "activeTab";
4213
4219
  var WALK_KEY = "walk";
4220
+ var SOFT_NAV_PROOF_MS = 700;
4221
+ function pageSignature() {
4222
+ if (typeof document === "undefined" || !document.body) return "";
4223
+ const body = document.body;
4224
+ const text = body.textContent || "";
4225
+ return [document.title, body.childElementCount, text.length, text.slice(0, 200)].join("\0");
4226
+ }
4214
4227
  var GUIDE_SKIPPED_KEY = "guideSkipped";
4215
4228
  var NOTICE_QUEUE_CAP = 3;
4216
4229
  var NOTICE_DURATION_INFO = 4e3;
@@ -5247,16 +5260,23 @@ function QaProvider({
5247
5260
  const walkNavigate = useCallback((path, hard = false) => {
5248
5261
  if (typeof window === "undefined" || !path) return;
5249
5262
  const target = path.startsWith("/") ? path : `/${path}`;
5250
- if (hard) {
5263
+ if (hard || target === window.location.pathname) {
5251
5264
  window.location.assign(target);
5252
5265
  return;
5253
5266
  }
5267
+ const before = pageSignature();
5254
5268
  try {
5255
- window.history.pushState({}, "", target);
5256
- window.dispatchEvent(new PopStateEvent("popstate"));
5269
+ window.history.pushState(window.history.state, "", target);
5270
+ window.dispatchEvent(new PopStateEvent("popstate", { state: window.history.state }));
5257
5271
  } catch {
5258
5272
  window.location.assign(target);
5273
+ return;
5259
5274
  }
5275
+ window.setTimeout(() => {
5276
+ if (window.location.pathname !== target) return;
5277
+ if (pageSignature() !== before) return;
5278
+ window.location.assign(target);
5279
+ }, SOFT_NAV_PROOF_MS);
5260
5280
  }, []);
5261
5281
  useEffect(() => {
5262
5282
  if (typeof window === "undefined") return;
@@ -6139,11 +6159,17 @@ function flashLocate(target) {
6139
6159
  paint(rect);
6140
6160
  }
6141
6161
  }
6142
- function LocationReveal({ target }) {
6143
- const { t } = useQa();
6162
+ function LocationReveal({
6163
+ target,
6164
+ route
6165
+ }) {
6166
+ const { t, walkNavigate } = useQa();
6144
6167
  const [open, setOpen] = useState(false);
6145
6168
  if (!target) return null;
6146
6169
  const r = target.rect;
6170
+ const notePath = (route || "").split("?")[0].split("#")[0];
6171
+ const here = typeof window === "undefined" ? "" : window.location.pathname;
6172
+ const elsewhere = !!notePath && notePath !== here;
6147
6173
  return /* @__PURE__ */ jsxs("div", { className: "qa-rounded-lg qa-border qa-border-subtle qa-bg-2", children: [
6148
6174
  /* @__PURE__ */ jsxs("div", { className: "qa-flex qa-items-center qa-gap-1.5 qa-px-2 qa-py-1.5 qa-text-11", children: [
6149
6175
  /* @__PURE__ */ jsx(Icon, { name: "CheckCircle2", size: 14, className: "qa-text-success" }),
@@ -6207,7 +6233,21 @@ function LocationReveal({ target }) {
6207
6233
  "\xD7",
6208
6234
  Math.round(r.height)
6209
6235
  ] }),
6210
- /* @__PURE__ */ jsxs(
6236
+ elsewhere ? /* @__PURE__ */ jsxs(Fragment, { children: [
6237
+ /* @__PURE__ */ jsx("p", { className: "qa-mt-1 qa-mb-1 qa-m-0 qa-text-lo", children: t("loc_other_page", { path: notePath }) }),
6238
+ /* @__PURE__ */ jsxs(
6239
+ "button",
6240
+ {
6241
+ onClick: () => walkNavigate(notePath),
6242
+ className: "qa-inline-flex qa-items-center qa-gap-1 qa-rounded-md qa-px-2 qa-py-1 qa-font-medium qa-tap qa-bg-accent",
6243
+ style: { border: "none", cursor: "pointer" },
6244
+ children: [
6245
+ /* @__PURE__ */ jsx(Icon, { name: "MapPinned", size: 12 }),
6246
+ t("loc_go_there", { path: notePath })
6247
+ ]
6248
+ }
6249
+ )
6250
+ ] }) : /* @__PURE__ */ jsxs(
6211
6251
  "button",
6212
6252
  {
6213
6253
  onClick: () => flashLocate(target),
@@ -6925,7 +6965,7 @@ function NoteItem({
6925
6965
  /* @__PURE__ */ jsx(Icon, { name: "MapPin", size: 12, className: "qa-shrink-0" }),
6926
6966
  /* @__PURE__ */ jsx("span", { className: "qa-truncate qa-dir-ltr", title: note.url, children: note.route })
6927
6967
  ] }),
6928
- note.target && /* @__PURE__ */ jsx(LocationReveal, { target: note.target }),
6968
+ note.target && /* @__PURE__ */ jsx(LocationReveal, { target: note.target, route: note.route }),
6929
6969
  contextEventCount > 0 && /* @__PURE__ */ jsx("div", { children: t("context_attached", { n: contextEventCount }) }),
6930
6970
  stepCount > 0 && /* @__PURE__ */ jsxs("div", { className: "qa-flex qa-items-center qa-gap-1", children: [
6931
6971
  /* @__PURE__ */ jsx(Icon, { name: "ClipboardList", size: 12, className: "qa-shrink-0" }),
@@ -8669,6 +8709,20 @@ var RISK_COLOR = {
8669
8709
  amber: "var(--qa-warn)",
8670
8710
  green: "var(--qa-success)"
8671
8711
  };
8712
+ function useCurrentPath() {
8713
+ const [path, setPath] = useState(() => typeof window === "undefined" ? "" : window.location.pathname);
8714
+ useEffect(() => {
8715
+ if (typeof window === "undefined") return;
8716
+ const sync = () => setPath(window.location.pathname);
8717
+ window.addEventListener("popstate", sync);
8718
+ window.addEventListener("hashchange", sync);
8719
+ return () => {
8720
+ window.removeEventListener("popstate", sync);
8721
+ window.removeEventListener("hashchange", sync);
8722
+ };
8723
+ }, []);
8724
+ return path;
8725
+ }
8672
8726
  function WalkHud() {
8673
8727
  const {
8674
8728
  dir,
@@ -8688,10 +8742,13 @@ function WalkHud() {
8688
8742
  startCapture,
8689
8743
  updateNote,
8690
8744
  retestNote,
8691
- notes
8745
+ notes,
8746
+ notesLoading
8692
8747
  } = useQa();
8693
8748
  const index = Math.min(walk.index, Math.max(0, walkStops.length - 1));
8694
8749
  const stop = walkStops[index];
8750
+ const currentPath = useCurrentPath();
8751
+ const [going, setGoing] = useState(false);
8695
8752
  const backIcon = dir === "rtl" ? "ChevronRight" : "ChevronLeft";
8696
8753
  const nextIcon = dir === "rtl" ? "ChevronLeft" : "ChevronRight";
8697
8754
  useEffect(() => {
@@ -8705,8 +8762,9 @@ function WalkHud() {
8705
8762
  if (latest?.target) flashLocate(latest.target);
8706
8763
  }, [index, walk.source]);
8707
8764
  useEffect(() => {
8765
+ if (notesLoading) return;
8708
8766
  if (walk.active && walkStops.length === 0) exitWalk();
8709
- }, [walk.active, walkStops.length, exitWalk]);
8767
+ }, [walk.active, walkStops.length, exitWalk, notesLoading]);
8710
8768
  if (!walk.active || !stop) return null;
8711
8769
  const atLast = index >= walkStops.length - 1;
8712
8770
  let title;
@@ -8867,7 +8925,7 @@ function WalkHud() {
8867
8925
  )
8868
8926
  ] });
8869
8927
  }
8870
- const onThisPage = stop.path === ANY_PAGE || typeof window !== "undefined" && stop.path === window.location.pathname;
8928
+ const onThisPage = stop.path === ANY_PAGE || stop.path === currentPath;
8871
8929
  return /* @__PURE__ */ jsxs(
8872
8930
  "div",
8873
8931
  {
@@ -8903,12 +8961,24 @@ function WalkHud() {
8903
8961
  "button",
8904
8962
  {
8905
8963
  type: "button",
8906
- onClick: () => walkNavigate(stop.path),
8964
+ disabled: going,
8965
+ onClick: () => {
8966
+ setGoing(true);
8967
+ walkNavigate(stop.path);
8968
+ window.setTimeout(() => setGoing(false), 900);
8969
+ },
8907
8970
  className: "qa-tap qa-inline-flex qa-flex-1 qa-items-center qa-justify-center qa-gap-1.5 qa-rounded-lg qa-bg-accent qa-px-2 qa-py-1.5 qa-text-11 qa-font-semibold",
8908
- style: { border: "none", cursor: "pointer" },
8971
+ style: { border: "none", cursor: going ? "default" : "pointer" },
8909
8972
  children: [
8910
- /* @__PURE__ */ jsx(Icon, { name: "MapPinned", size: 13 }),
8911
- t("walk_take_me", { path: stop.path })
8973
+ /* @__PURE__ */ jsx(
8974
+ Icon,
8975
+ {
8976
+ name: going ? "Loader2" : "MapPinned",
8977
+ size: 13,
8978
+ className: going ? "qa-animate-spin" : void 0
8979
+ }
8980
+ ),
8981
+ going ? t("walk_taking_you") : t("walk_take_me", { path: stop.path })
8912
8982
  ]
8913
8983
  }
8914
8984
  ),
@@ -10319,5 +10389,5 @@ function Qapture({ config }) {
10319
10389
  }
10320
10390
 
10321
10391
  export { Qapture, deleteQaDatabase, initQaStudio };
10322
- //# sourceMappingURL=chunk-2JX7YU2P.js.map
10323
- //# sourceMappingURL=chunk-2JX7YU2P.js.map
10392
+ //# sourceMappingURL=chunk-G6O4SIEH.js.map
10393
+ //# sourceMappingURL=chunk-G6O4SIEH.js.map
package/dist/index.cjs CHANGED
@@ -1,24 +1,24 @@
1
1
  'use strict';
2
2
 
3
- var chunk4LMLW73U_cjs = require('./chunk-4LMLW73U.cjs');
3
+ var chunk6UNSUNJS_cjs = require('./chunk-6UNSUNJS.cjs');
4
4
 
5
5
 
6
6
 
7
7
  Object.defineProperty(exports, "QaStudio", {
8
8
  enumerable: true,
9
- get: function () { return chunk4LMLW73U_cjs.Qapture; }
9
+ get: function () { return chunk6UNSUNJS_cjs.Qapture; }
10
10
  });
11
11
  Object.defineProperty(exports, "Qapture", {
12
12
  enumerable: true,
13
- get: function () { return chunk4LMLW73U_cjs.Qapture; }
13
+ get: function () { return chunk6UNSUNJS_cjs.Qapture; }
14
14
  });
15
15
  Object.defineProperty(exports, "deleteQaDatabase", {
16
16
  enumerable: true,
17
- get: function () { return chunk4LMLW73U_cjs.deleteQaDatabase; }
17
+ get: function () { return chunk6UNSUNJS_cjs.deleteQaDatabase; }
18
18
  });
19
19
  Object.defineProperty(exports, "initQaStudio", {
20
20
  enumerable: true,
21
- get: function () { return chunk4LMLW73U_cjs.initQaStudio; }
21
+ get: function () { return chunk6UNSUNJS_cjs.initQaStudio; }
22
22
  });
23
23
  //# sourceMappingURL=index.cjs.map
24
24
  //# sourceMappingURL=index.cjs.map
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- export { Qapture as QaStudio, Qapture, deleteQaDatabase, initQaStudio } from './chunk-2JX7YU2P.js';
1
+ export { Qapture as QaStudio, Qapture, deleteQaDatabase, initQaStudio } from './chunk-G6O4SIEH.js';
2
2
  //# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
package/dist/next.cjs CHANGED
@@ -1,21 +1,21 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var chunk4LMLW73U_cjs = require('./chunk-4LMLW73U.cjs');
4
+ var chunk6UNSUNJS_cjs = require('./chunk-6UNSUNJS.cjs');
5
5
 
6
6
 
7
7
 
8
8
  Object.defineProperty(exports, "QaStudio", {
9
9
  enumerable: true,
10
- get: function () { return chunk4LMLW73U_cjs.Qapture; }
10
+ get: function () { return chunk6UNSUNJS_cjs.Qapture; }
11
11
  });
12
12
  Object.defineProperty(exports, "Qapture", {
13
13
  enumerable: true,
14
- get: function () { return chunk4LMLW73U_cjs.Qapture; }
14
+ get: function () { return chunk6UNSUNJS_cjs.Qapture; }
15
15
  });
16
16
  Object.defineProperty(exports, "initQaStudio", {
17
17
  enumerable: true,
18
- get: function () { return chunk4LMLW73U_cjs.initQaStudio; }
18
+ get: function () { return chunk6UNSUNJS_cjs.initQaStudio; }
19
19
  });
20
20
  //# sourceMappingURL=next.cjs.map
21
21
  //# sourceMappingURL=next.cjs.map
package/dist/next.js CHANGED
@@ -1,4 +1,4 @@
1
1
  "use client";
2
- export { Qapture as QaStudio, Qapture, initQaStudio } from './chunk-2JX7YU2P.js';
2
+ export { Qapture as QaStudio, Qapture, initQaStudio } from './chunk-G6O4SIEH.js';
3
3
  //# sourceMappingURL=next.js.map
4
4
  //# sourceMappingURL=next.js.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunk4LMLW73U_cjs = require('./chunk-4LMLW73U.cjs');
3
+ var chunk6UNSUNJS_cjs = require('./chunk-6UNSUNJS.cjs');
4
4
 
5
5
  // src/standalone.ts
6
6
  if (typeof window !== "undefined" && typeof customElements !== "undefined" && !customElements.get("qapture-widget")) {
@@ -38,7 +38,7 @@ if (typeof window !== "undefined" && typeof customElements !== "undefined" && !c
38
38
 
39
39
  Object.defineProperty(exports, "initQaStudio", {
40
40
  enumerable: true,
41
- get: function () { return chunk4LMLW73U_cjs.initQaStudio; }
41
+ get: function () { return chunk6UNSUNJS_cjs.initQaStudio; }
42
42
  });
43
43
  //# sourceMappingURL=standalone.cjs.map
44
44
  //# sourceMappingURL=standalone.cjs.map
@@ -1,4 +1,4 @@
1
- export { initQaStudio } from './chunk-2JX7YU2P.js';
1
+ export { initQaStudio } from './chunk-G6O4SIEH.js';
2
2
 
3
3
  // src/standalone.ts
4
4
  if (typeof window !== "undefined" && typeof customElements !== "undefined" && !customElements.get("qapture-widget")) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qapture2",
3
- "version": "0.7.8",
3
+ "version": "0.7.9",
4
4
  "description": "Drop-in, AI-aware in-browser QA capture widget. A tester annotates the live app (element/region + auto-screenshot + note), tracks a graded testing journey, and exports a ZIP your own coding agent reads. Ships zero AI.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -96,7 +96,8 @@
96
96
  "walk-test": "node scripts/walk-test.mjs",
97
97
  "modern-css-test": "node scripts/modern-css-test.mjs",
98
98
  "verify": "npm run typecheck && npm run typecheck:bin && npm run build && npm run smoke && npm run export-smoke && npm run cli-smoke && npm run cli-detectors-smoke && npm run selector-smoke && npm run capture-timeout-smoke && npm run fs-sync-smoke && npm run frame-calibration-smoke && npm run standalone-smoke",
99
- "play": "npm --prefix playground run dev"
99
+ "play": "npm --prefix playground run dev",
100
+ "walk-navigation-test": "node scripts/walk-navigation-test.mjs"
100
101
  },
101
102
  "engines": {
102
103
  "node": ">=18"