@buoy-gg/network 7.0.4 → 7.0.6

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 (69) hide show
  1. package/README.md +2 -1
  2. package/lib/commonjs/index.js +85 -0
  3. package/lib/commonjs/network/components/NetworkEventDetailView.js +201 -40
  4. package/lib/commonjs/network/components/NetworkEventItemCompact.js +52 -5
  5. package/lib/commonjs/network/components/NetworkHeaderLive.js +132 -0
  6. package/lib/commonjs/network/components/NetworkListScreen.js +134 -56
  7. package/lib/commonjs/network/components/NetworkModal.js +154 -36
  8. package/lib/commonjs/network/components/NetworkSavedScreen.js +245 -0
  9. package/lib/commonjs/network/components/NetworkUpgradeBanner.js +76 -0
  10. package/lib/commonjs/network/hooks/useLiveNetworkEvent.js +62 -0
  11. package/lib/commonjs/network/hooks/useNetworkSaved.js +38 -0
  12. package/lib/commonjs/network/index.js +84 -0
  13. package/lib/commonjs/network/sync/networkSyncAdapter.js +85 -7
  14. package/lib/commonjs/network/utils/generateCurl.js +71 -0
  15. package/lib/commonjs/network/utils/networkEventStore.js +10 -1
  16. package/lib/commonjs/network/utils/networkListener.js +54 -1
  17. package/lib/commonjs/network/utils/networkSavedStore.js +575 -0
  18. package/lib/commonjs/network/utils/withPinnedFirst.js +32 -0
  19. package/lib/module/index.js +17 -1
  20. package/lib/module/network/components/NetworkEventDetailView.js +204 -41
  21. package/lib/module/network/components/NetworkEventItemCompact.js +53 -6
  22. package/lib/module/network/components/NetworkHeaderLive.js +132 -2
  23. package/lib/module/network/components/NetworkListScreen.js +136 -58
  24. package/lib/module/network/components/NetworkModal.js +156 -39
  25. package/lib/module/network/components/NetworkSavedScreen.js +241 -0
  26. package/lib/module/network/components/NetworkUpgradeBanner.js +72 -0
  27. package/lib/module/network/hooks/useLiveNetworkEvent.js +58 -0
  28. package/lib/module/network/hooks/useNetworkSaved.js +34 -0
  29. package/lib/module/network/index.js +7 -1
  30. package/lib/module/network/sync/networkSyncAdapter.js +85 -7
  31. package/lib/module/network/utils/generateCurl.js +67 -0
  32. package/lib/module/network/utils/networkEventStore.js +10 -1
  33. package/lib/module/network/utils/networkListener.js +54 -1
  34. package/lib/module/network/utils/networkSavedStore.js +569 -0
  35. package/lib/module/network/utils/withPinnedFirst.js +28 -0
  36. package/lib/typescript/index.d.ts +13 -1
  37. package/lib/typescript/index.d.ts.map +1 -1
  38. package/lib/typescript/network/components/NetworkEventDetailView.d.ts.map +1 -1
  39. package/lib/typescript/network/components/NetworkEventItemCompact.d.ts +12 -0
  40. package/lib/typescript/network/components/NetworkEventItemCompact.d.ts.map +1 -1
  41. package/lib/typescript/network/components/NetworkHeaderLive.d.ts +28 -0
  42. package/lib/typescript/network/components/NetworkHeaderLive.d.ts.map +1 -1
  43. package/lib/typescript/network/components/NetworkListScreen.d.ts.map +1 -1
  44. package/lib/typescript/network/components/NetworkModal.d.ts +34 -0
  45. package/lib/typescript/network/components/NetworkModal.d.ts.map +1 -1
  46. package/lib/typescript/network/components/NetworkSavedScreen.d.ts +29 -0
  47. package/lib/typescript/network/components/NetworkSavedScreen.d.ts.map +1 -0
  48. package/lib/typescript/network/components/NetworkUpgradeBanner.d.ts +17 -0
  49. package/lib/typescript/network/components/NetworkUpgradeBanner.d.ts.map +1 -0
  50. package/lib/typescript/network/hooks/useLiveNetworkEvent.d.ts +19 -0
  51. package/lib/typescript/network/hooks/useLiveNetworkEvent.d.ts.map +1 -0
  52. package/lib/typescript/network/hooks/useNetworkSaved.d.ts +21 -0
  53. package/lib/typescript/network/hooks/useNetworkSaved.d.ts.map +1 -0
  54. package/lib/typescript/network/index.d.ts +8 -1
  55. package/lib/typescript/network/index.d.ts.map +1 -1
  56. package/lib/typescript/network/sync/networkSyncAdapter.d.ts +52 -3
  57. package/lib/typescript/network/sync/networkSyncAdapter.d.ts.map +1 -1
  58. package/lib/typescript/network/types/index.d.ts +43 -0
  59. package/lib/typescript/network/types/index.d.ts.map +1 -1
  60. package/lib/typescript/network/utils/generateCurl.d.ts +3 -0
  61. package/lib/typescript/network/utils/generateCurl.d.ts.map +1 -0
  62. package/lib/typescript/network/utils/networkEventStore.d.ts.map +1 -1
  63. package/lib/typescript/network/utils/networkListener.d.ts +4 -0
  64. package/lib/typescript/network/utils/networkListener.d.ts.map +1 -1
  65. package/lib/typescript/network/utils/networkSavedStore.d.ts +186 -0
  66. package/lib/typescript/network/utils/networkSavedStore.d.ts.map +1 -0
  67. package/lib/typescript/network/utils/withPinnedFirst.d.ts +24 -0
  68. package/lib/typescript/network/utils/withPinnedFirst.d.ts.map +1 -0
  69. package/package.json +2 -2
@@ -4,11 +4,15 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.NetworkClearButton = NetworkClearButton;
7
+ exports.NetworkDetailPinActions = NetworkDetailPinActions;
7
8
  exports.NetworkHeaderBadges = NetworkHeaderBadges;
8
9
  exports.NetworkHeaderCopyButton = NetworkHeaderCopyButton;
10
+ exports.NetworkSavedButton = NetworkSavedButton;
9
11
  var _reactNative = require("react-native");
10
12
  var _sharedUi = require("@buoy-gg/shared-ui");
11
13
  var _networkEventStore = require("../utils/networkEventStore");
14
+ var _networkSavedStore = require("../utils/networkSavedStore");
15
+ var _useNetworkSaved = require("../hooks/useNetworkSaved");
12
16
  var _useNetworkBadgeCounts = require("../hooks/useNetworkBadgeCounts");
13
17
  var _useNetworkHasMatches = require("../hooks/useNetworkHasMatches");
14
18
  var _generateNetworkCopyText = require("../utils/generateNetworkCopyText");
@@ -104,6 +108,104 @@ function NetworkClearButton({
104
108
  })
105
109
  });
106
110
  }
111
+ /**
112
+ * Entry point to the Saved screen, with its count. A self-subscribing leaf so
113
+ * the badge tracks the store without the modal header re-rendering.
114
+ */
115
+ function NetworkSavedButton({
116
+ onPress
117
+ }) {
118
+ const {
119
+ savedRecords
120
+ } = (0, _useNetworkSaved.useNetworkSaved)();
121
+ const count = savedRecords.length;
122
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
123
+ "sentry-label": "ignore open saved",
124
+ onPress: onPress,
125
+ accessibilityLabel: "Saved requests",
126
+ style: styles.headerActionButton,
127
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Bookmark, {
128
+ size: 14,
129
+ color: count > 0 ? _sharedUi.macOSColors.semantic.debug : _sharedUi.macOSColors.text.muted
130
+ }), count > 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
131
+ style: styles.savedBadge,
132
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
133
+ style: styles.savedBadgeText,
134
+ children: count > 99 ? "99+" : count
135
+ })
136
+ }) : null]
137
+ });
138
+ }
139
+ /**
140
+ * Pin + Save toggles for the request-detail header.
141
+ *
142
+ * Lives here, as a self-subscribing leaf, for two reasons. First the usual
143
+ * one: the modal root stays free of subscriptions. Second, and the real
144
+ * constraint — these buttons deliberately do NOT go inside
145
+ * `NetworkEventDetailView`, because the Events tool renders that same detail
146
+ * view (UnifiedEventDetail) and has no saved store behind it. The header is
147
+ * the Network tool's own surface, so the feature stays where it belongs.
148
+ *
149
+ * The event object is resolved at PRESS time rather than held as a prop: the
150
+ * live store has the fresh copy while the request is in flight, and the saved
151
+ * store is the only copy once it has been cleared or aged out.
152
+ */
153
+ function NetworkDetailPinActions({
154
+ eventId,
155
+ isPro,
156
+ onUpgradePress
157
+ }) {
158
+ const state = (0, _useNetworkSaved.useNetworkSaved)();
159
+ const {
160
+ pinned,
161
+ saved
162
+ } = (0, _networkSavedStore.flagsForEventId)(state, eventId);
163
+ const savedLimit = isPro ? _networkSavedStore.MAX_SAVED : _networkSavedStore.FREE_TIER_SAVED_LIMIT;
164
+ const atPinCap = !pinned && state.pinnedEvents.length >= _networkSavedStore.MAX_PINNED;
165
+ const atSavedCap = !saved && state.savedRecords.length >= savedLimit;
166
+ const resolveEvent = () => {
167
+ if (!eventId) return null;
168
+ return _networkEventStore.networkEventStore.getEvents().find(event => event.id === eventId) ?? _networkSavedStore.networkSavedStore.getEventById(eventId);
169
+ };
170
+ const handlePin = () => {
171
+ const event = resolveEvent();
172
+ if (event) state.togglePin(event);
173
+ };
174
+ const handleSave = () => {
175
+ // Hitting the free ceiling is an upgrade moment, not a dead button.
176
+ if (atSavedCap && !isPro) {
177
+ onUpgradePress();
178
+ return;
179
+ }
180
+ const event = resolveEvent();
181
+ if (event) state.toggleSave(event);
182
+ };
183
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
184
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
185
+ "sentry-label": "ignore pin request",
186
+ onPress: handlePin,
187
+ disabled: atPinCap,
188
+ accessibilityLabel: pinned ? "Unpin request" : "Pin request",
189
+ accessibilityHint: atPinCap ? `Pin limit reached (${_networkSavedStore.MAX_PINNED})` : undefined,
190
+ style: [styles.headerActionButton, pinned && styles.headerActionButtonActive, atPinCap && styles.headerActionButtonDisabled],
191
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Pin, {
192
+ size: 14,
193
+ color: pinned ? _sharedUi.macOSColors.semantic.info : atPinCap ? _sharedUi.macOSColors.text.disabled : _sharedUi.macOSColors.text.secondary
194
+ })
195
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
196
+ "sentry-label": "ignore save request",
197
+ onPress: handleSave,
198
+ disabled: atSavedCap && isPro,
199
+ accessibilityLabel: saved ? "Remove from saved" : "Save request",
200
+ accessibilityHint: atSavedCap && isPro ? `Saved limit reached (${_networkSavedStore.MAX_SAVED})` : undefined,
201
+ style: [styles.headerActionButton, saved && styles.headerActionButtonSaved, atSavedCap && isPro && styles.headerActionButtonDisabled],
202
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Bookmark, {
203
+ size: 14,
204
+ color: saved ? _sharedUi.macOSColors.semantic.debug : atSavedCap && isPro ? _sharedUi.macOSColors.text.disabled : _sharedUi.macOSColors.text.secondary
205
+ })
206
+ })]
207
+ });
208
+ }
107
209
  /**
108
210
  * Copy-all-requests button. Subscribes to a flip-guarded boolean (its
109
211
  * enabled state); the copy text is generated at PRESS time from a live
@@ -155,6 +257,10 @@ const styles = _reactNative.StyleSheet.create({
155
257
  alignItems: "center",
156
258
  gap: 8
157
259
  },
260
+ /**
261
+ * Counter chips and toolbar buttons carry a permanent outline; the fill marks
262
+ * the active filter.
263
+ */
158
264
  headerChip: {
159
265
  flexDirection: "row",
160
266
  alignItems: "center",
@@ -195,5 +301,31 @@ const styles = _reactNative.StyleSheet.create({
195
301
  },
196
302
  headerActionButtonDisabled: {
197
303
  opacity: 0.55
304
+ },
305
+ headerActionButtonActive: {
306
+ backgroundColor: _sharedUi.macOSColors.semantic.infoBackground,
307
+ borderColor: _sharedUi.macOSColors.semantic.info + "50"
308
+ },
309
+ headerActionButtonSaved: {
310
+ backgroundColor: _sharedUi.macOSColors.semantic.debug + "1A",
311
+ borderColor: _sharedUi.macOSColors.semantic.debug + "50"
312
+ },
313
+ savedBadge: {
314
+ position: "absolute",
315
+ top: -3,
316
+ right: -3,
317
+ minWidth: 14,
318
+ height: 14,
319
+ paddingHorizontal: 3,
320
+ borderRadius: 7,
321
+ backgroundColor: _sharedUi.macOSColors.semantic.debug,
322
+ alignItems: "center",
323
+ justifyContent: "center"
324
+ },
325
+ savedBadgeText: {
326
+ color: "#FFFFFF",
327
+ fontSize: 9,
328
+ fontWeight: "700",
329
+ fontFamily: "monospace"
198
330
  }
199
331
  });
@@ -4,10 +4,14 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.NetworkListScreen = NetworkListScreen;
7
+ var _react = require("react");
7
8
  var _reactNative = require("react-native");
8
9
  var _sharedUi = require("@buoy-gg/shared-ui");
9
10
  var _NetworkEventItemCompact = require("./NetworkEventItemCompact");
11
+ var _NetworkUpgradeBanner = require("./NetworkUpgradeBanner");
10
12
  var _useNetworkEventList = require("../hooks/useNetworkEventList");
13
+ var _useNetworkSaved = require("../hooks/useNetworkSaved");
14
+ var _withPinnedFirst = require("../utils/withPinnedFirst");
11
15
  var _jsxRuntime = require("react/jsx-runtime");
12
16
  /**
13
17
  * The network tool's LIST screen — owns the event-store subscription, the
@@ -39,6 +43,54 @@ function EmptyState({
39
43
  });
40
44
  }
41
45
  const keyExtractor = item => item.id;
46
+
47
+ /**
48
+ * The PINNED strip above the live list.
49
+ *
50
+ * It renders OUTSIDE the FlatList on purpose. The list's window/batch values
51
+ * are a measured configuration (see the FlatList below), and merging pins into
52
+ * `data` would mean sentinel items in `keyExtractor`/`renderItem` and a
53
+ * section boundary that moves as events arrive. Keeping pins in their own
54
+ * bounded strip (capped at MAX_PINNED in the store) leaves that tuning
55
+ * untouched — and makes "pins ignore the filters" fall out for free, because
56
+ * this strip is never handed the filter.
57
+ */
58
+ function PinnedSection({
59
+ events,
60
+ onEventPress,
61
+ onLongPress,
62
+ savedLiveIds,
63
+ onClearPinned
64
+ }) {
65
+ if (events.length === 0) return null;
66
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
67
+ style: styles.pinnedSection,
68
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
69
+ style: styles.pinnedHeader,
70
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Pin, {
71
+ size: 11,
72
+ color: _sharedUi.macOSColors.semantic.info
73
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
74
+ style: styles.pinnedTitle,
75
+ children: ["PINNED \xB7 ", events.length]
76
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
77
+ onPress: onClearPinned,
78
+ "sentry-label": "ignore unpin all",
79
+ style: styles.pinnedClear,
80
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
81
+ style: styles.pinnedClearText,
82
+ children: "Unpin all"
83
+ })
84
+ })]
85
+ }), events.map(event => /*#__PURE__*/(0, _jsxRuntime.jsx)(_NetworkEventItemCompact.NetworkEventItemCompact, {
86
+ event: event,
87
+ onPress: onEventPress,
88
+ onLongPress: onLongPress,
89
+ pinned: true,
90
+ saved: savedLiveIds.has(event.id)
91
+ }, event.id))]
92
+ });
93
+ }
42
94
  function NetworkListScreen({
43
95
  visible,
44
96
  paused,
@@ -59,42 +111,48 @@ function NetworkListScreen({
59
111
  paused: paused || !visible,
60
112
  isPro
61
113
  });
114
+
115
+ // Pins come from the persisted saved store, NOT from the live list — that is
116
+ // what lets a pinned failure survive Clear, the 500-event cap and a reload.
117
+ const {
118
+ pinnedEvents,
119
+ pinnedLiveIds,
120
+ savedLiveIds,
121
+ togglePin,
122
+ clearPinned
123
+ } = (0, _useNetworkSaved.useNetworkSaved)();
124
+ const {
125
+ pinned,
126
+ rest
127
+ } = (0, _withPinnedFirst.splitPinned)(visibleEvents, pinnedEvents, pinnedLiveIds);
128
+
129
+ // Stable identity: handed to memoized rows.
130
+ const handleLongPress = (0, _react.useCallback)(event => {
131
+ togglePin(event);
132
+ }, [togglePin]);
62
133
  if (!visible) return null;
63
134
  const isEnabled = !paused;
64
135
  const renderItem = ({
65
136
  item
66
137
  }) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_NetworkEventItemCompact.NetworkEventItemCompact, {
67
138
  event: item,
68
- onPress: onEventPress
139
+ onPress: onEventPress,
140
+ onLongPress: handleLongPress,
141
+ saved: savedLiveIds.has(item.id)
69
142
  });
70
143
  const renderListFooter = () => {
71
144
  if (!hasLockedEvents) return null;
72
145
  const isSearching = searchText.length > 0;
73
146
  const bannerText = isSearching ? `${lockedEventCount} matching ${lockedEventCount === 1 ? "request" : "requests"} in locked history` : `${lockedEventCount} requests locked`;
74
147
  const subtextMessage = isSearching ? "Upgrade to Pro to search your full request history" : "Upgrade to Pro to unlock full request history";
75
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
76
- style: styles.limitBanner,
77
- onPress: onUpgradePress,
78
- activeOpacity: 0.8,
79
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
80
- style: styles.limitBannerContent,
81
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
82
- style: styles.limitBannerLeft,
83
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Zap, {
84
- size: 16,
85
- color: "#20C997"
86
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
87
- style: styles.limitBannerText,
88
- children: bannerText
89
- })]
90
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ProBadge, {})]
91
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
92
- style: styles.limitBannerSubtext,
93
- children: subtextMessage
94
- })]
148
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_NetworkUpgradeBanner.NetworkUpgradeBanner, {
149
+ title: bannerText,
150
+ subtitle: subtextMessage,
151
+ onPress: onUpgradePress
95
152
  });
96
153
  };
97
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
154
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
155
+ style: styles.root,
98
156
  children: [!isEnabled ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
99
157
  style: styles.disabledBanner,
100
158
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Power, {
@@ -104,8 +162,14 @@ function NetworkListScreen({
104
162
  style: styles.disabledText,
105
163
  children: "Network interception is disabled"
106
164
  })]
107
- }) : null, visibleEvents.length > 0 || hasLockedEvents ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.FlatList, {
108
- data: visibleEvents,
165
+ }) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(PinnedSection, {
166
+ events: pinned,
167
+ onEventPress: onEventPress,
168
+ onLongPress: handleLongPress,
169
+ savedLiveIds: savedLiveIds,
170
+ onClearPinned: clearPinned
171
+ }), rest.length > 0 || hasLockedEvents ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.FlatList, {
172
+ data: rest,
109
173
  renderItem: renderItem,
110
174
  keyExtractor: keyExtractor,
111
175
  contentContainerStyle: styles.listContent,
@@ -125,15 +189,59 @@ function NetworkListScreen({
125
189
  initialNumToRender: 12,
126
190
  maxToRenderPerBatch: 8,
127
191
  windowSize: 5,
128
- updateCellsBatchingPeriod: 50,
192
+ updateCellsBatchingPeriod: 50
193
+ // Saving a request from the detail view changes a row's glyph
194
+ // without changing `data`. VirtualizedList is a PureComponent, so
195
+ // the Set has to be declared as a re-render marker rather than
196
+ // relying on `renderItem` getting a fresh identity.
197
+ ,
198
+ extraData: savedLiveIds,
129
199
  "sentry-label": "ignore network events list",
130
200
  ListFooterComponent: renderListFooter
131
- }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(EmptyState, {
201
+ }) : pinned.length > 0 ? null : /*#__PURE__*/(0, _jsxRuntime.jsx)(EmptyState, {
132
202
  isEnabled: isEnabled
133
203
  })]
134
204
  });
135
205
  }
136
206
  const styles = _reactNative.StyleSheet.create({
207
+ root: {
208
+ flex: 1,
209
+ minHeight: 0
210
+ },
211
+ /**
212
+ * The strip is separated from the live list by a real rule, not just space:
213
+ * these rows do NOT obey the filters, and the boundary is what tells the
214
+ * user why a request they just filtered out is still on screen.
215
+ */
216
+ pinnedSection: {
217
+ borderBottomWidth: 1,
218
+ borderBottomColor: _sharedUi.macOSColors.border.default,
219
+ paddingBottom: 4
220
+ },
221
+ pinnedHeader: {
222
+ flexDirection: "row",
223
+ alignItems: "center",
224
+ gap: 6,
225
+ paddingHorizontal: 20,
226
+ paddingTop: 10,
227
+ paddingBottom: 6
228
+ },
229
+ pinnedTitle: {
230
+ flex: 1,
231
+ color: _sharedUi.macOSColors.semantic.info,
232
+ fontSize: 10,
233
+ fontWeight: "700",
234
+ letterSpacing: 0.6,
235
+ fontFamily: "monospace"
236
+ },
237
+ pinnedClear: {
238
+ paddingHorizontal: 6,
239
+ paddingVertical: 2
240
+ },
241
+ pinnedClearText: {
242
+ color: _sharedUi.macOSColors.text.muted,
243
+ fontSize: 10
244
+ },
137
245
  disabledBanner: {
138
246
  flexDirection: "row",
139
247
  alignItems: "center",
@@ -169,35 +277,5 @@ const styles = _reactNative.StyleSheet.create({
169
277
  color: _sharedUi.macOSColors.text.muted,
170
278
  fontSize: 12,
171
279
  textAlign: "center"
172
- },
173
- limitBanner: {
174
- backgroundColor: "#1A1A1A",
175
- borderRadius: 10,
176
- borderWidth: 1,
177
- borderColor: "#20C997" + "40",
178
- padding: 12,
179
- marginHorizontal: 12,
180
- marginTop: 12,
181
- marginBottom: 34
182
- },
183
- limitBannerContent: {
184
- flexDirection: "row",
185
- alignItems: "center",
186
- justifyContent: "space-between",
187
- marginBottom: 4
188
- },
189
- limitBannerLeft: {
190
- flexDirection: "row",
191
- alignItems: "center",
192
- gap: 8
193
- },
194
- limitBannerText: {
195
- color: "#E0E0E0",
196
- fontSize: 13,
197
- fontWeight: "600"
198
- },
199
- limitBannerSubtext: {
200
- color: "#888888",
201
- fontSize: 11
202
280
  }
203
281
  });