@buoy-gg/route-events 7.0.1 → 7.0.3

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.
Files changed (27) hide show
  1. package/lib/commonjs/components/RouteEventDetail.js +90 -0
  2. package/lib/commonjs/components/RouteEventItemCompact.js +3 -19
  3. package/lib/commonjs/components/RouteEventsModalWithTabs.js +49 -3
  4. package/lib/commonjs/components/RouteEventsTimeline.js +10 -9
  5. package/lib/commonjs/index.js +7 -0
  6. package/lib/commonjs/utils/routeTemplate.js +28 -0
  7. package/lib/module/components/RouteEventDetail.js +86 -0
  8. package/lib/module/components/RouteEventItemCompact.js +1 -17
  9. package/lib/module/components/RouteEventsModalWithTabs.js +49 -3
  10. package/lib/module/components/RouteEventsTimeline.js +11 -10
  11. package/lib/module/index.js +1 -0
  12. package/lib/module/utils/routeTemplate.js +24 -0
  13. package/lib/typescript/components/RouteEventDetail.d.ts +18 -0
  14. package/lib/typescript/components/RouteEventDetail.d.ts.map +1 -0
  15. package/lib/typescript/components/RouteEventItemCompact.d.ts.map +1 -1
  16. package/lib/typescript/components/RouteEventsModalWithTabs.d.ts.map +1 -1
  17. package/lib/typescript/components/RouteEventsTimeline.d.ts +4 -2
  18. package/lib/typescript/components/RouteEventsTimeline.d.ts.map +1 -1
  19. package/lib/typescript/index.d.ts +2 -0
  20. package/lib/typescript/index.d.ts.map +1 -1
  21. package/lib/typescript/utils/routeTemplate.d.ts +8 -0
  22. package/lib/typescript/utils/routeTemplate.d.ts.map +1 -0
  23. package/package.json +5 -5
  24. package/lib/commonjs/components/RouteEventDetailContent.js +0 -499
  25. package/lib/module/components/RouteEventDetailContent.js +0 -494
  26. package/lib/typescript/components/RouteEventDetailContent.d.ts +0 -21
  27. package/lib/typescript/components/RouteEventDetailContent.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"RouteEventItemCompact.d.ts","sourceRoot":"","sources":["../../../src/components/RouteEventItemCompact.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGzD,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,gBAAgB,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB;0DACsD;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAgHD,eAAO,MAAM,qBAAqB,kEAmEhC,CAAC"}
1
+ {"version":3,"file":"RouteEventItemCompact.d.ts","sourceRoot":"","sources":["../../../src/components/RouteEventItemCompact.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAIzD,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,gBAAgB,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB;0DACsD;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AA6FD,eAAO,MAAM,qBAAqB,kEAmEhC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"RouteEventsModalWithTabs.d.ts","sourceRoot":"","sources":["../../../src/components/RouteEventsModalWithTabs.tsx"],"names":[],"mappings":"AA6DA,MAAM,WAAW,6BAA6B;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,KAAK,IAAI,CAAC;IACvC,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACvC;AA8CD,wBAAgB,wBAAwB,CAAC,EACvC,OAAO,EACP,OAAO,EACP,MAAM,EACN,UAAU,EACV,2BAAmC,GACpC,EAAE,6BAA6B,sCA8iB/B"}
1
+ {"version":3,"file":"RouteEventsModalWithTabs.d.ts","sourceRoot":"","sources":["../../../src/components/RouteEventsModalWithTabs.tsx"],"names":[],"mappings":"AA0DA,MAAM,WAAW,6BAA6B;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,KAAK,IAAI,CAAC;IACvC,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACvC;AA8CD,wBAAgB,wBAAwB,CAAC,EACvC,OAAO,EACP,OAAO,EACP,MAAM,EACN,UAAU,EACV,2BAAmC,GACpC,EAAE,6BAA6B,sCAwmB/B"}
@@ -4,14 +4,16 @@
4
4
  * Shows events in the order they happened (most recent first),
5
5
  * providing a clear history of navigation actions.
6
6
  *
7
- * Uses two-level expansion pattern matching network/storage components.
7
+ * Tapping a row opens the full-screen detail view (parity with the Events
8
+ * tool) via onSelectEvent — rows no longer expand inline.
8
9
  */
9
10
  import type { RouteChangeEvent } from "../RouteObserver";
10
11
  interface RouteEventsTimelineProps {
11
12
  events: RouteChangeEvent[];
12
13
  visitCounts: Map<number, number>;
13
14
  onNavigate?: (pathname: string) => void;
15
+ onSelectEvent: (event: RouteChangeEvent, visitNumber: number) => void;
14
16
  }
15
- export declare function RouteEventsTimeline({ events, visitCounts, onNavigate, }: RouteEventsTimelineProps): import("react").JSX.Element;
17
+ export declare function RouteEventsTimeline({ events, visitCounts, onNavigate, onSelectEvent, }: RouteEventsTimelineProps): import("react").JSX.Element;
16
18
  export {};
17
19
  //# sourceMappingURL=RouteEventsTimeline.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RouteEventsTimeline.d.ts","sourceRoot":"","sources":["../../../src/components/RouteEventsTimeline.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAaH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGzD,UAAU,wBAAwB;IAChC,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC;AAED,wBAAgB,mBAAmB,CAAC,EAClC,MAAM,EACN,WAAW,EACX,UAAU,GACX,EAAE,wBAAwB,+BAoD1B"}
1
+ {"version":3,"file":"RouteEventsTimeline.d.ts","sourceRoot":"","sources":["../../../src/components/RouteEventsTimeline.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGzD,UAAU,wBAAwB;IAChC,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,aAAa,EAAE,CAAC,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;CACvE;AAED,wBAAgB,mBAAmB,CAAC,EAClC,MAAM,EACN,WAAW,EACX,UAAU,EACV,aAAa,GACd,EAAE,wBAAwB,+BAqD1B"}
@@ -18,6 +18,8 @@ export { RouteEventItemCompact } from "./components/RouteEventItemCompact";
18
18
  export type { RouteEventItemCompactProps } from "./components/RouteEventItemCompact";
19
19
  export { RouteEventExpandedContent } from "./components/RouteEventExpandedContent";
20
20
  export type { RouteEventExpandedContentProps } from "./components/RouteEventExpandedContent";
21
+ export { RouteEventDetail } from "./components/RouteEventDetail";
22
+ export type { RouteEventDetailProps } from "./components/RouteEventDetail";
21
23
  export { useRouteObserver } from "./useRouteObserver";
22
24
  export { useRouteObserverReactNavigation } from "./useRouteObserverReactNavigation";
23
25
  export { useRouteEvents } from "./hooks/useRouteEvents";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAKxE,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AACjF,YAAY,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AAK3F,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAK9C,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,YAAY,EACV,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,YAAY,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AACrF,OAAO,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AACnF,YAAY,EAAE,8BAA8B,EAAE,MAAM,wCAAwC,CAAC;AAK7F,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,+BAA+B,EAAE,MAAM,mCAAmC,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,YAAY,EACV,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC/E,YAAY,EACV,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,YAAY,EACV,wBAAwB,EACxB,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAK9B,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,YAAY,EACV,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,+BAA+B,CAAC;AAKvC,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,YAAY,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,UAAU,GACX,MAAM,eAAe,CAAC;AAKvB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAKhD,qEAAqE;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,qEAAqE;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,YAAY,EACV,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAKxE,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AACjF,YAAY,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AAK3F,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAK9C,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,YAAY,EACV,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,YAAY,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AACrF,OAAO,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AACnF,YAAY,EAAE,8BAA8B,EAAE,MAAM,wCAAwC,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,YAAY,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAK3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,+BAA+B,EAAE,MAAM,mCAAmC,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,YAAY,EACV,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC/E,YAAY,EACV,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,YAAY,EACV,wBAAwB,EACxB,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAK9B,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,YAAY,EACV,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,+BAA+B,CAAC;AAKvC,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,YAAY,EACV,SAAS,EACT,SAAS,EACT,UAAU,EACV,UAAU,GACX,MAAM,eAAe,CAAC;AAKvB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAKhD,qEAAqE;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,qEAAqE;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,YAAY,EACV,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Infer a route template from a concrete pathname and its segments.
3
+ * Dynamic segments (numeric ids, UUIDs) collapse to `[id]`, so
4
+ * `/products/42` becomes `/products/[id]`. Returns null when the template
5
+ * matches the pathname (i.e. the route is fully static).
6
+ */
7
+ export declare function getRouteTemplate(pathname: string, segments: string[]): string | null;
8
+ //# sourceMappingURL=routeTemplate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routeTemplate.d.ts","sourceRoot":"","sources":["../../../src/utils/routeTemplate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAAE,GACjB,MAAM,GAAG,IAAI,CAqBf"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buoy-gg/route-events",
3
- "version": "7.0.1",
3
+ "version": "7.0.3",
4
4
  "description": "Navigation devtool for React Native — live stack, full sitemap, jump to any screen. Expo Router & React Navigation. Part of Buoy devtools.",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
@@ -26,11 +26,11 @@
26
26
  ],
27
27
  "sideEffects": false,
28
28
  "dependencies": {
29
- "@buoy-gg/floating-tools-core": "7.0.1",
30
- "@buoy-gg/shared-ui": "7.0.1"
29
+ "@buoy-gg/floating-tools-core": "7.0.3",
30
+ "@buoy-gg/shared-ui": "7.0.3"
31
31
  },
32
32
  "peerDependencies": {
33
- "@buoy-gg/license": "7.0.1",
33
+ "@buoy-gg/license": "7.0.3",
34
34
  "@react-native-async-storage/async-storage": "^2.0.0 || ^3.1.0",
35
35
  "@react-navigation/native": "*",
36
36
  "expo-router": "*",
@@ -52,7 +52,7 @@
52
52
  "@types/react-native": "^0.73.0",
53
53
  "expo-router": "~5.0.7",
54
54
  "typescript": "~5.8.3",
55
- "@buoy-gg/license": "7.0.1"
55
+ "@buoy-gg/license": "7.0.3"
56
56
  },
57
57
  "react-native-builder-bob": {
58
58
  "source": "src",
@@ -1,499 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.RouteEventDetailContent = RouteEventDetailContent;
7
- exports.RouteEventDetailFooter = RouteEventDetailFooter;
8
- var _reactNative = require("react-native");
9
- var _react = require("react");
10
- var _sharedUi = require("@buoy-gg/shared-ui");
11
- var _dataViewer = require("@buoy-gg/shared-ui/dataViewer");
12
- var _jsxRuntime = require("react/jsx-runtime");
13
- function RouteEventDetailContent({
14
- conversation,
15
- selectedEventIndex = 0,
16
- onEventIndexChange = () => {},
17
- disableInternalFooter = false
18
- }) {
19
- // Internal view state
20
- const [internalActiveView, setInternalActiveView] = (0, _react.useState)("current");
21
-
22
- // Track if preferences have been loaded
23
- const hasLoadedPreferences = (0, _react.useRef)(false);
24
-
25
- // Load saved preferences on mount
26
- (0, _react.useEffect)(() => {
27
- if (hasLoadedPreferences.current) return;
28
- const loadPreferences = async () => {
29
- try {
30
- // Load detail view preference (current/diff)
31
- const savedDetailView = await _sharedUi.persistentStorage.getItem(_sharedUi.devToolsStorageKeys.routeEvents.detailView());
32
- if (savedDetailView === "current" || savedDetailView === "diff") {
33
- setInternalActiveView(savedDetailView);
34
- }
35
- hasLoadedPreferences.current = true;
36
- } catch (error) {
37
- // Failed to load view preferences
38
- }
39
- };
40
- loadPreferences();
41
- }, []);
42
-
43
- // Save detail view preference when changed
44
- const handleViewChange = (0, _react.useCallback)(async view => {
45
- setInternalActiveView(view);
46
- try {
47
- await _sharedUi.persistentStorage.setItem(_sharedUi.devToolsStorageKeys.routeEvents.detailView(), view);
48
- } catch (error) {
49
- // Failed to save detail view preference
50
- }
51
- }, []);
52
- const renderRouteContent = (event, label) => {
53
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
54
- style: styles.valueContent,
55
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
56
- style: styles.valueHeader,
57
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
58
- style: styles.valueLabel,
59
- children: label
60
- })
61
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
62
- style: styles.dataViewerContainer,
63
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_dataViewer.DataViewer, {
64
- title: "",
65
- data: {
66
- pathname: event.pathname,
67
- segments: event.segments,
68
- params: event.params,
69
- timestamp: new Date(event.timestamp).toISOString()
70
- },
71
- showTypeFilter: true,
72
- rawMode: true,
73
- initialExpanded: true
74
- })
75
- })]
76
- });
77
- };
78
-
79
- // Get all events sorted by time
80
- const navigationItems = conversation.events.sort((a, b) => a.timestamp - b.timestamp);
81
- const totalEvents = navigationItems.length;
82
-
83
- // Precise time HH:MM:SS.mmm
84
- const formatTimeWithMs = (0, _react.useCallback)(timestamp => {
85
- const date = new Date(timestamp);
86
- const h = String(date.getHours()).padStart(2, "0");
87
- const m = String(date.getMinutes()).padStart(2, "0");
88
- const s = String(date.getSeconds()).padStart(2, "0");
89
- const ms = String(date.getMilliseconds()).padStart(3, "0");
90
- return `${h}:${m}:${s}.${ms}`;
91
- }, []);
92
-
93
- // Render current value tab
94
- const renderCurrentValue = () => {
95
- const selectedEvent = navigationItems[selectedEventIndex];
96
- const eventToShow = selectedEvent ?? conversation.lastEvent;
97
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
98
- style: styles.fullPageSection,
99
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
100
- style: styles.contentCard,
101
- children: renderRouteContent(eventToShow, "CURRENT ROUTE STATE")
102
- })
103
- });
104
- };
105
-
106
- // Render diff tab
107
- const renderDiff = () => {
108
- if (navigationItems.length === 0) {
109
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
110
- style: styles.emptyState,
111
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.AlertCircle, {
112
- size: 32,
113
- color: _sharedUi.buoyColors.textMuted
114
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
115
- style: styles.emptyText,
116
- children: "No changes to display"
117
- })]
118
- });
119
- }
120
- const prevIndex = Math.max(0, selectedEventIndex - 1);
121
- const currentIndex = selectedEventIndex;
122
- const previousEvent = navigationItems[prevIndex];
123
- const currentEvent = navigationItems[currentIndex];
124
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
125
- style: styles.fullPageSection,
126
- children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
127
- style: styles.diffContainer,
128
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
129
- style: styles.diffSection,
130
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
131
- style: styles.diffSectionTitle,
132
- children: "PREVIOUS"
133
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
134
- style: styles.contentCard,
135
- children: renderRouteContent(previousEvent, `Event #${prevIndex + 1}`)
136
- })]
137
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
138
- style: styles.diffDivider
139
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
140
- style: styles.diffSection,
141
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
142
- style: styles.diffSectionTitle,
143
- children: "CURRENT"
144
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
145
- style: styles.contentCard,
146
- children: renderRouteContent(currentEvent, `Event #${currentIndex + 1}`)
147
- })]
148
- })]
149
- })
150
- });
151
- };
152
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
153
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
154
- style: [styles.contentOnly, {
155
- flex: 1,
156
- paddingBottom: !disableInternalFooter && totalEvents > 1 ? 80 : 0
157
- }],
158
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
159
- style: styles.viewToggleContainer,
160
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
161
- style: [styles.viewToggleCard, internalActiveView === "current" && styles.viewToggleCardActive],
162
- onPress: () => handleViewChange("current"),
163
- activeOpacity: 0.8,
164
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
165
- style: styles.viewToggleContent,
166
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Navigation, {
167
- size: 16,
168
- color: internalActiveView === "current" ? _sharedUi.buoyColors.primary : _sharedUi.buoyColors.textSecondary
169
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
170
- style: [styles.viewToggleLabel, internalActiveView === "current" && styles.viewToggleLabelActive],
171
- children: "CURRENT STATE"
172
- })]
173
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
174
- style: [styles.viewToggleDescription, internalActiveView === "current" && {
175
- color: _sharedUi.buoyColors.text
176
- }],
177
- children: "View the current route state"
178
- })]
179
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
180
- style: [styles.viewToggleCard, internalActiveView === "diff" && styles.viewToggleCardActive],
181
- onPress: () => handleViewChange("diff"),
182
- activeOpacity: 0.8,
183
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
184
- style: styles.viewToggleContent,
185
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.GitBranch, {
186
- size: 16,
187
- color: internalActiveView === "diff" ? _sharedUi.buoyColors.success : _sharedUi.buoyColors.textSecondary
188
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
189
- style: [styles.viewToggleLabel, internalActiveView === "diff" && styles.viewToggleLabelActive],
190
- children: "DIFF VIEW"
191
- })]
192
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
193
- style: [styles.viewToggleDescription, internalActiveView === "diff" && {
194
- color: _sharedUi.buoyColors.text
195
- }],
196
- children: "Compare changes between events"
197
- })]
198
- })]
199
- }), internalActiveView === "current" && renderCurrentValue(), internalActiveView === "diff" && renderDiff()]
200
- }), totalEvents > 1 && !disableInternalFooter && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
201
- style: styles.stickyFooter,
202
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
203
- onPress: () => onEventIndexChange(Math.max(0, selectedEventIndex - 1)),
204
- disabled: selectedEventIndex === 0,
205
- style: [styles.navButton, selectedEventIndex === 0 && styles.navButtonDisabled],
206
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronLeft, {
207
- size: 20,
208
- color: selectedEventIndex === 0 ? _sharedUi.buoyColors.textMuted : _sharedUi.buoyColors.text
209
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
210
- style: [styles.navButtonText, selectedEventIndex === 0 && styles.navButtonTextDisabled],
211
- children: "Previous"
212
- })]
213
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
214
- style: styles.eventCounterContainer,
215
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
216
- style: styles.eventCounter,
217
- children: ["Event ", selectedEventIndex + 1, " of ", totalEvents]
218
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
219
- style: styles.eventTimestamp,
220
- children: (0, _sharedUi.formatRelativeTime)(new Date(navigationItems[selectedEventIndex]?.timestamp))
221
- })]
222
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
223
- onPress: () => onEventIndexChange(Math.min(totalEvents - 1, selectedEventIndex + 1)),
224
- disabled: selectedEventIndex === totalEvents - 1,
225
- style: [styles.navButton, selectedEventIndex === totalEvents - 1 && styles.navButtonDisabled],
226
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
227
- style: [styles.navButtonText, selectedEventIndex === totalEvents - 1 && styles.navButtonTextDisabled],
228
- children: "Next"
229
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronRight, {
230
- size: 20,
231
- color: selectedEventIndex === totalEvents - 1 ? _sharedUi.buoyColors.textMuted : _sharedUi.buoyColors.text
232
- })]
233
- })]
234
- })]
235
- });
236
- }
237
-
238
- // External footer component to be rendered by the modal outside the ScrollView
239
- function RouteEventDetailFooter({
240
- conversation,
241
- selectedEventIndex = 0,
242
- onEventIndexChange = () => {}
243
- }) {
244
- const navigationItems = conversation.events.sort((a, b) => a.timestamp - b.timestamp);
245
- const totalEvents = navigationItems.length;
246
- if (totalEvents <= 1) return null;
247
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
248
- style: styles.externalFooterBar,
249
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
250
- onPress: () => onEventIndexChange(Math.max(0, selectedEventIndex - 1)),
251
- disabled: selectedEventIndex === 0,
252
- style: [styles.navButton, selectedEventIndex === 0 && styles.navButtonDisabled],
253
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronLeft, {
254
- size: 20,
255
- color: selectedEventIndex === 0 ? _sharedUi.buoyColors.textMuted : _sharedUi.buoyColors.text
256
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
257
- style: [styles.navButtonText, selectedEventIndex === 0 && styles.navButtonTextDisabled],
258
- children: "Previous"
259
- })]
260
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
261
- style: styles.eventCounterContainer,
262
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
263
- style: styles.eventCounter,
264
- children: ["Event ", selectedEventIndex + 1, " of ", totalEvents]
265
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
266
- style: styles.eventTimestamp,
267
- children: (0, _sharedUi.formatRelativeTime)(new Date(navigationItems[selectedEventIndex]?.timestamp))
268
- })]
269
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
270
- onPress: () => onEventIndexChange(Math.min(totalEvents - 1, selectedEventIndex + 1)),
271
- disabled: selectedEventIndex === totalEvents - 1,
272
- style: [styles.navButton, selectedEventIndex === totalEvents - 1 && styles.navButtonDisabled],
273
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
274
- style: [styles.navButtonText, selectedEventIndex === totalEvents - 1 && styles.navButtonTextDisabled],
275
- children: "Next"
276
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronRight, {
277
- size: 20,
278
- color: selectedEventIndex === totalEvents - 1 ? _sharedUi.buoyColors.textMuted : _sharedUi.buoyColors.text
279
- })]
280
- })]
281
- });
282
- }
283
- const styles = _reactNative.StyleSheet.create({
284
- contentOnly: {
285
- flex: 1,
286
- backgroundColor: _sharedUi.buoyColors.base
287
- },
288
- stickyFooter: {
289
- position: "absolute",
290
- bottom: 0,
291
- left: 0,
292
- right: 0,
293
- flexDirection: "row",
294
- alignItems: "center",
295
- justifyContent: "space-between",
296
- paddingHorizontal: 16,
297
- paddingVertical: 12,
298
- backgroundColor: _sharedUi.buoyColors.base,
299
- borderTopWidth: 1,
300
- borderTopColor: _sharedUi.buoyColors.border,
301
- shadowColor: "#000",
302
- shadowOffset: {
303
- width: 0,
304
- height: -2
305
- },
306
- shadowOpacity: 0.1,
307
- shadowRadius: 4,
308
- elevation: 5
309
- },
310
- externalFooterBar: {
311
- flexDirection: "row",
312
- alignItems: "center",
313
- justifyContent: "space-between",
314
- paddingHorizontal: 16,
315
- paddingVertical: 12,
316
- backgroundColor: _sharedUi.buoyColors.base,
317
- borderTopWidth: 1,
318
- borderTopColor: _sharedUi.buoyColors.border,
319
- shadowColor: "#000",
320
- shadowOffset: {
321
- width: 0,
322
- height: -2
323
- },
324
- shadowOpacity: 0.1,
325
- shadowRadius: 4,
326
- elevation: 5
327
- },
328
- fullPageSection: {
329
- flex: 1,
330
- paddingHorizontal: 14,
331
- paddingVertical: 10
332
- },
333
- emptyState: {
334
- flex: 1,
335
- alignItems: "center",
336
- justifyContent: "center",
337
- paddingVertical: 48
338
- },
339
- emptyText: {
340
- marginTop: 12,
341
- fontSize: 14,
342
- color: _sharedUi.buoyColors.textSecondary,
343
- fontFamily: "monospace"
344
- },
345
- valueContent: {
346
- marginTop: 4
347
- },
348
- valueHeader: {
349
- flexDirection: "row",
350
- alignItems: "center",
351
- justifyContent: "space-between",
352
- marginBottom: 4
353
- },
354
- valueLabel: {
355
- fontSize: 10,
356
- color: _sharedUi.buoyColors.textSecondary,
357
- fontFamily: "monospace",
358
- letterSpacing: 0.5,
359
- fontWeight: "600",
360
- textTransform: "uppercase"
361
- },
362
- valueBox: {
363
- backgroundColor: _sharedUi.buoyColors.card,
364
- borderRadius: 6,
365
- borderWidth: 1,
366
- borderColor: _sharedUi.buoyColors.border,
367
- padding: 8
368
- },
369
- navButton: {
370
- flexDirection: "row",
371
- alignItems: "center",
372
- gap: 6,
373
- paddingHorizontal: 12,
374
- paddingVertical: 8,
375
- borderRadius: 6,
376
- backgroundColor: _sharedUi.buoyColors.card,
377
- minWidth: 100,
378
- justifyContent: "center"
379
- },
380
- navButtonDisabled: {
381
- opacity: 0.3
382
- },
383
- navButtonText: {
384
- fontSize: 12,
385
- fontWeight: "600",
386
- color: _sharedUi.buoyColors.text,
387
- fontFamily: "monospace",
388
- textTransform: "uppercase"
389
- },
390
- navButtonTextDisabled: {
391
- color: _sharedUi.buoyColors.textMuted
392
- },
393
- eventCounterContainer: {
394
- alignItems: "center"
395
- },
396
- eventCounter: {
397
- fontSize: 14,
398
- fontWeight: "700",
399
- color: _sharedUi.buoyColors.text,
400
- fontFamily: "monospace",
401
- textTransform: "uppercase"
402
- },
403
- eventTimestamp: {
404
- fontSize: 11,
405
- color: _sharedUi.buoyColors.textSecondary,
406
- fontFamily: "monospace",
407
- marginTop: 2
408
- },
409
- contentCard: {
410
- backgroundColor: _sharedUi.buoyColors.card,
411
- borderRadius: 14,
412
- padding: 14,
413
- borderWidth: 1,
414
- borderColor: _sharedUi.buoyColors.border,
415
- shadowColor: "#000",
416
- shadowOffset: {
417
- width: 0,
418
- height: 2
419
- },
420
- shadowOpacity: 0.04,
421
- shadowRadius: 16,
422
- elevation: 2
423
- },
424
- // View Toggle Cards
425
- viewToggleContainer: {
426
- flexDirection: "row",
427
- gap: 12,
428
- padding: 14,
429
- backgroundColor: _sharedUi.buoyColors.base
430
- },
431
- viewToggleCard: {
432
- flex: 1,
433
- backgroundColor: _sharedUi.buoyColors.card,
434
- borderRadius: 14,
435
- borderWidth: 1,
436
- borderColor: _sharedUi.buoyColors.border,
437
- padding: 14,
438
- gap: 8
439
- },
440
- viewToggleCardActive: {
441
- borderWidth: 1.5,
442
- borderColor: _sharedUi.buoyColors.primary,
443
- backgroundColor: _sharedUi.buoyColors.primary + "15",
444
- shadowColor: _sharedUi.buoyColors.primary,
445
- shadowOffset: {
446
- width: 0,
447
- height: 2
448
- },
449
- shadowOpacity: 0.1,
450
- shadowRadius: 8,
451
- elevation: 3
452
- },
453
- viewToggleContent: {
454
- flexDirection: "row",
455
- alignItems: "center",
456
- gap: 8
457
- },
458
- viewToggleLabel: {
459
- fontSize: 12,
460
- fontWeight: "700",
461
- letterSpacing: 0.5,
462
- color: _sharedUi.buoyColors.textSecondary,
463
- textTransform: "uppercase"
464
- },
465
- viewToggleLabelActive: {
466
- color: _sharedUi.buoyColors.text
467
- },
468
- viewToggleDescription: {
469
- fontSize: 11,
470
- color: _sharedUi.buoyColors.textMuted,
471
- lineHeight: 16
472
- },
473
- // Diff view styles
474
- diffContainer: {
475
- gap: 16
476
- },
477
- diffSection: {
478
- gap: 8
479
- },
480
- diffSectionTitle: {
481
- fontSize: 10,
482
- fontWeight: "700",
483
- color: _sharedUi.buoyColors.textSecondary,
484
- fontFamily: "monospace",
485
- letterSpacing: 0.5,
486
- textTransform: "uppercase",
487
- paddingHorizontal: 4
488
- },
489
- diffDivider: {
490
- height: 1,
491
- backgroundColor: _sharedUi.buoyColors.border,
492
- marginVertical: 8
493
- },
494
- dataViewerContainer: {
495
- marginTop: -12,
496
- marginHorizontal: -12,
497
- marginBottom: -12
498
- }
499
- });