@buoy-gg/shared-ui 3.0.1 → 4.0.1

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 (133) hide show
  1. package/lib/commonjs/JsModal.js +2 -1
  2. package/lib/commonjs/clipboard/clipboard-impl.js +28 -2
  3. package/lib/commonjs/dataViewer/VirtualizedDataExplorer.js +3 -5
  4. package/lib/commonjs/hooks/safe-area-impl.js +1 -1
  5. package/lib/commonjs/icons/lucide-icons.js +130 -22
  6. package/lib/commonjs/index.js +14 -0
  7. package/lib/commonjs/license/DeviceLimitModal.js +2 -1
  8. package/lib/commonjs/license/FeatureGate.js +60 -11
  9. package/lib/commonjs/license/LicenseEntryModal.js +14 -3
  10. package/lib/commonjs/license/ManageDevicesModal.js +2 -1
  11. package/lib/commonjs/license/openPricing.js +36 -0
  12. package/lib/commonjs/storage/devToolsStorageKeys.js +1 -0
  13. package/lib/commonjs/stores/BaseEventStore.js +72 -2
  14. package/lib/commonjs/stores/ignoredPatternsStore.js +229 -0
  15. package/lib/commonjs/stores/index.js +26 -1
  16. package/lib/commonjs/ui/components/CompactRow.js +73 -66
  17. package/lib/commonjs/ui/components/EventHistoryViewer/EventPickerModal.js +3 -2
  18. package/lib/commonjs/ui/components/ExpandableSectionWithModal.js +2 -1
  19. package/lib/commonjs/ui/components/ExpandedInfoRow.js +13 -3
  20. package/lib/commonjs/ui/components/WindowControls.js +9 -3
  21. package/lib/commonjs/ui/console/CyberpunkConsoleSection.js +6 -5
  22. package/lib/commonjs/ui/console/GalaxyButton.js +2 -1
  23. package/lib/commonjs/ui/gameUI/components/GameUIStatusHeader.js +2 -1
  24. package/lib/commonjs/utils/absoluteFill.js +28 -0
  25. package/lib/commonjs/utils/index.js +13 -0
  26. package/lib/commonjs/utils/safeExpoRouter.js +59 -4
  27. package/lib/module/JsModal.js +2 -1
  28. package/lib/module/clipboard/clipboard-impl.js +28 -2
  29. package/lib/module/dataViewer/VirtualizedDataExplorer.js +3 -5
  30. package/lib/module/hooks/safe-area-impl.js +1 -1
  31. package/lib/module/icons/lucide-icons.js +125 -19
  32. package/lib/module/index.js +3 -1
  33. package/lib/module/license/DeviceLimitModal.js +2 -1
  34. package/lib/module/license/FeatureGate.js +61 -12
  35. package/lib/module/license/LicenseEntryModal.js +15 -4
  36. package/lib/module/license/ManageDevicesModal.js +2 -1
  37. package/lib/module/license/openPricing.js +31 -0
  38. package/lib/module/storage/devToolsStorageKeys.js +1 -0
  39. package/lib/module/stores/BaseEventStore.js +72 -2
  40. package/lib/module/stores/ignoredPatternsStore.js +223 -0
  41. package/lib/module/stores/index.js +2 -1
  42. package/lib/module/ui/components/CompactRow.js +73 -66
  43. package/lib/module/ui/components/EventHistoryViewer/EventPickerModal.js +3 -2
  44. package/lib/module/ui/components/ExpandableSectionWithModal.js +2 -1
  45. package/lib/module/ui/components/ExpandedInfoRow.js +13 -3
  46. package/lib/module/ui/components/WindowControls.js +10 -4
  47. package/lib/module/ui/console/CyberpunkConsoleSection.js +6 -5
  48. package/lib/module/ui/console/GalaxyButton.js +2 -1
  49. package/lib/module/ui/gameUI/components/GameUIStatusHeader.js +2 -1
  50. package/lib/module/utils/absoluteFill.js +24 -0
  51. package/lib/module/utils/index.js +2 -1
  52. package/lib/module/utils/safeExpoRouter.js +58 -4
  53. package/lib/typescript/commonjs/JsModal.d.ts.map +1 -1
  54. package/lib/typescript/commonjs/clipboard/clipboard-impl.d.ts +3 -2
  55. package/lib/typescript/commonjs/clipboard/clipboard-impl.d.ts.map +1 -1
  56. package/lib/typescript/commonjs/dataViewer/VirtualizedDataExplorer.d.ts.map +1 -1
  57. package/lib/typescript/commonjs/hooks/safe-area-impl.d.ts +1 -1
  58. package/lib/typescript/commonjs/icons/lucide-icons.d.ts +5 -2
  59. package/lib/typescript/commonjs/icons/lucide-icons.d.ts.map +1 -1
  60. package/lib/typescript/commonjs/index.d.ts +1 -1
  61. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  62. package/lib/typescript/commonjs/license/DeviceLimitModal.d.ts.map +1 -1
  63. package/lib/typescript/commonjs/license/FeatureGate.d.ts +14 -1
  64. package/lib/typescript/commonjs/license/FeatureGate.d.ts.map +1 -1
  65. package/lib/typescript/commonjs/license/LicenseEntryModal.d.ts.map +1 -1
  66. package/lib/typescript/commonjs/license/ManageDevicesModal.d.ts.map +1 -1
  67. package/lib/typescript/commonjs/license/openPricing.d.ts +14 -0
  68. package/lib/typescript/commonjs/license/openPricing.d.ts.map +1 -0
  69. package/lib/typescript/commonjs/storage/devToolsStorageKeys.d.ts +1 -0
  70. package/lib/typescript/commonjs/storage/devToolsStorageKeys.d.ts.map +1 -1
  71. package/lib/typescript/commonjs/stores/BaseEventStore.d.ts +28 -0
  72. package/lib/typescript/commonjs/stores/BaseEventStore.d.ts.map +1 -1
  73. package/lib/typescript/commonjs/stores/ignoredPatternsStore.d.ts +84 -0
  74. package/lib/typescript/commonjs/stores/ignoredPatternsStore.d.ts.map +1 -0
  75. package/lib/typescript/commonjs/stores/index.d.ts +1 -0
  76. package/lib/typescript/commonjs/stores/index.d.ts.map +1 -1
  77. package/lib/typescript/commonjs/ui/components/CompactRow.d.ts +3 -1
  78. package/lib/typescript/commonjs/ui/components/CompactRow.d.ts.map +1 -1
  79. package/lib/typescript/commonjs/ui/components/EventHistoryViewer/EventPickerModal.d.ts.map +1 -1
  80. package/lib/typescript/commonjs/ui/components/ExpandableSectionWithModal.d.ts.map +1 -1
  81. package/lib/typescript/commonjs/ui/components/ExpandedInfoRow.d.ts +3 -1
  82. package/lib/typescript/commonjs/ui/components/ExpandedInfoRow.d.ts.map +1 -1
  83. package/lib/typescript/commonjs/ui/components/WindowControls.d.ts.map +1 -1
  84. package/lib/typescript/commonjs/ui/console/CyberpunkConsoleSection.d.ts.map +1 -1
  85. package/lib/typescript/commonjs/ui/console/GalaxyButton.d.ts.map +1 -1
  86. package/lib/typescript/commonjs/ui/gameUI/components/GameUIStatusHeader.d.ts.map +1 -1
  87. package/lib/typescript/commonjs/utils/absoluteFill.d.ts +18 -0
  88. package/lib/typescript/commonjs/utils/absoluteFill.d.ts.map +1 -0
  89. package/lib/typescript/commonjs/utils/index.d.ts +2 -1
  90. package/lib/typescript/commonjs/utils/index.d.ts.map +1 -1
  91. package/lib/typescript/commonjs/utils/safeExpoRouter.d.ts +9 -0
  92. package/lib/typescript/commonjs/utils/safeExpoRouter.d.ts.map +1 -1
  93. package/lib/typescript/module/JsModal.d.ts.map +1 -1
  94. package/lib/typescript/module/clipboard/clipboard-impl.d.ts +3 -2
  95. package/lib/typescript/module/clipboard/clipboard-impl.d.ts.map +1 -1
  96. package/lib/typescript/module/dataViewer/VirtualizedDataExplorer.d.ts.map +1 -1
  97. package/lib/typescript/module/hooks/safe-area-impl.d.ts +1 -1
  98. package/lib/typescript/module/icons/lucide-icons.d.ts +5 -2
  99. package/lib/typescript/module/icons/lucide-icons.d.ts.map +1 -1
  100. package/lib/typescript/module/index.d.ts +1 -1
  101. package/lib/typescript/module/index.d.ts.map +1 -1
  102. package/lib/typescript/module/license/DeviceLimitModal.d.ts.map +1 -1
  103. package/lib/typescript/module/license/FeatureGate.d.ts +14 -1
  104. package/lib/typescript/module/license/FeatureGate.d.ts.map +1 -1
  105. package/lib/typescript/module/license/LicenseEntryModal.d.ts.map +1 -1
  106. package/lib/typescript/module/license/ManageDevicesModal.d.ts.map +1 -1
  107. package/lib/typescript/module/license/openPricing.d.ts +14 -0
  108. package/lib/typescript/module/license/openPricing.d.ts.map +1 -0
  109. package/lib/typescript/module/storage/devToolsStorageKeys.d.ts +1 -0
  110. package/lib/typescript/module/storage/devToolsStorageKeys.d.ts.map +1 -1
  111. package/lib/typescript/module/stores/BaseEventStore.d.ts +28 -0
  112. package/lib/typescript/module/stores/BaseEventStore.d.ts.map +1 -1
  113. package/lib/typescript/module/stores/ignoredPatternsStore.d.ts +84 -0
  114. package/lib/typescript/module/stores/ignoredPatternsStore.d.ts.map +1 -0
  115. package/lib/typescript/module/stores/index.d.ts +1 -0
  116. package/lib/typescript/module/stores/index.d.ts.map +1 -1
  117. package/lib/typescript/module/ui/components/CompactRow.d.ts +3 -1
  118. package/lib/typescript/module/ui/components/CompactRow.d.ts.map +1 -1
  119. package/lib/typescript/module/ui/components/EventHistoryViewer/EventPickerModal.d.ts.map +1 -1
  120. package/lib/typescript/module/ui/components/ExpandableSectionWithModal.d.ts.map +1 -1
  121. package/lib/typescript/module/ui/components/ExpandedInfoRow.d.ts +3 -1
  122. package/lib/typescript/module/ui/components/ExpandedInfoRow.d.ts.map +1 -1
  123. package/lib/typescript/module/ui/components/WindowControls.d.ts.map +1 -1
  124. package/lib/typescript/module/ui/console/CyberpunkConsoleSection.d.ts.map +1 -1
  125. package/lib/typescript/module/ui/console/GalaxyButton.d.ts.map +1 -1
  126. package/lib/typescript/module/ui/gameUI/components/GameUIStatusHeader.d.ts.map +1 -1
  127. package/lib/typescript/module/utils/absoluteFill.d.ts +18 -0
  128. package/lib/typescript/module/utils/absoluteFill.d.ts.map +1 -0
  129. package/lib/typescript/module/utils/index.d.ts +2 -1
  130. package/lib/typescript/module/utils/index.d.ts.map +1 -1
  131. package/lib/typescript/module/utils/safeExpoRouter.d.ts +9 -0
  132. package/lib/typescript/module/utils/safeExpoRouter.d.ts.map +1 -1
  133. package/package.json +4 -4
@@ -62,6 +62,8 @@ var _subscriberCountNotifier = require("../utils/subscriberCountNotifier.js");
62
62
  class BaseEventStore extends _subscribable.Subscribable {
63
63
  events = [];
64
64
  arrayListeners = new Set();
65
+ captureSuppressed = false;
66
+ clearListeners = new Set();
65
67
  constructor(options) {
66
68
  super();
67
69
  this.maxEvents = options.maxEvents ?? 500;
@@ -95,7 +97,7 @@ class BaseEventStore extends _subscribable.Subscribable {
95
97
  * Starts capturing if no one was subscribed.
96
98
  */
97
99
  onSubscribe() {
98
- if (this.getTotalSubscriberCount() === 1) {
100
+ if (this.getTotalSubscriberCount() === 1 && !this.captureSuppressed) {
99
101
  this.startCapturing();
100
102
  }
101
103
  (0, _subscriberCountNotifier.notifySubscriberCountChange)(this.storeName);
@@ -135,7 +137,7 @@ class BaseEventStore extends _subscribable.Subscribable {
135
137
  this.arrayListeners.add(listener);
136
138
 
137
139
  // Start capturing if this is the first subscriber
138
- if (wasEmpty) {
140
+ if (wasEmpty && !this.captureSuppressed) {
139
141
  this.startCapturing();
140
142
  }
141
143
 
@@ -226,6 +228,74 @@ class BaseEventStore extends _subscribable.Subscribable {
226
228
  clearEvents() {
227
229
  this.events = [];
228
230
  this.notifyArrayListeners();
231
+ this.clearListeners.forEach(listener => {
232
+ try {
233
+ listener();
234
+ } catch {
235
+ // Ignore listener errors
236
+ }
237
+ });
238
+ }
239
+
240
+ /**
241
+ * Listen for clearEvents() calls. Used in remote mirror mode to forward a
242
+ * clear performed in the dashboard UI to the synced device.
243
+ */
244
+ onClear(listener) {
245
+ this.clearListeners.add(listener);
246
+ return () => {
247
+ this.clearListeners.delete(listener);
248
+ };
249
+ }
250
+
251
+ // ===========================================================================
252
+ // REMOTE MIRROR MODE
253
+ // ===========================================================================
254
+
255
+ /**
256
+ * Suppress the auto start/stop capture lifecycle. Use when this store acts
257
+ * as a mirror of a remote device's events (e.g. the desktop dashboard):
258
+ * events arrive via replaceEvents() and the local interceptors must never
259
+ * start — on the dashboard they would capture the dashboard's own traffic.
260
+ */
261
+ disableCapture() {
262
+ this.captureSuppressed = true;
263
+ if (this.isCapturing()) {
264
+ this.stopCapturing();
265
+ }
266
+ }
267
+
268
+ /**
269
+ * Replace the entire event list and notify array listeners. Used in remote
270
+ * mirror mode where full snapshots arrive from a synced device.
271
+ */
272
+ replaceEvents(events) {
273
+ this.events = this.dedupeById(events).slice(0, this.maxEvents);
274
+ this.notifyArrayListeners();
275
+ }
276
+
277
+ /**
278
+ * Drop events that share an `id` with an earlier event, keeping the first
279
+ * (newest, since events are newest-first) occurrence. Remote snapshots can
280
+ * momentarily carry duplicate ids — e.g. a device's request counter resets
281
+ * on reload while older events with the same id are still in the buffer —
282
+ * which makes React list keys (keyed on `id`) collide. Events without an
283
+ * `id` are passed through untouched.
284
+ */
285
+ dedupeById(events) {
286
+ const seen = new Set();
287
+ const result = [];
288
+ for (const event of events) {
289
+ const id = event?.id;
290
+ if (id == null) {
291
+ result.push(event);
292
+ continue;
293
+ }
294
+ if (seen.has(id)) continue;
295
+ seen.add(id);
296
+ result.push(event);
297
+ }
298
+ return result;
229
299
  }
230
300
 
231
301
  /**
@@ -0,0 +1,229 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.ignoredPatternsStore = void 0;
7
+ exports.isUrlIgnored = isUrlIgnored;
8
+ exports.urlMatchesIgnoredPattern = urlMatchesIgnoredPattern;
9
+ exports.useIgnoredPatterns = useIgnoredPatterns;
10
+ var _react = require("react");
11
+ var _persistentStorage = require("../utils/persistentStorage.js");
12
+ var _devToolsStorageKeys = require("../storage/devToolsStorageKeys.js");
13
+ /**
14
+ * Shared "ignored patterns" store for network-style URL filtering.
15
+ *
16
+ * This is the SINGLE source of truth for the domains/URL patterns that the
17
+ * Network tool (and now the Events tool) hide from their lists. Both tools read
18
+ * and mutate this one singleton, so an ignore toggled in either place is shared
19
+ * everywhere and persisted to the same storage key.
20
+ *
21
+ * Lives in @buoy-gg/shared-ui (a hard dependency of both @buoy-gg/network and
22
+ * @buoy-gg/events) so the filter logic can be shared without @buoy-gg/events
23
+ * having to take a hard dependency on @buoy-gg/network (which is optional).
24
+ */
25
+
26
+ /**
27
+ * How an ignored-pattern entry should be compared against captured URLs.
28
+ *
29
+ * - `contains`: case-insensitive substring match on the full URL (legacy behavior).
30
+ * - `exact`: smart equality — if pattern starts with `/`, matches URL.pathname;
31
+ * if it starts with `http://`/`https://`, matches origin+pathname; otherwise
32
+ * matches URL.host.
33
+ */
34
+
35
+ /** A single exclude pattern with its match mode. */
36
+
37
+ /** Patterns hidden by default — Buoy's own license API traffic. */
38
+ const DEFAULT_PATTERNS = [{
39
+ value: "api.keygen.sh",
40
+ mode: "contains"
41
+ }];
42
+
43
+ /**
44
+ * Returns true when `url` matches the ignored `pattern` according to its mode.
45
+ *
46
+ * `contains` → case-insensitive substring on the full URL (legacy behavior).
47
+ * `exact` → smart equality: pattern starting with `/` compares URL.pathname,
48
+ * full URLs compare origin+pathname (ignoring query/hash), bare
49
+ * values compare URL.host. Falls back to literal equality if URL
50
+ * parsing fails (e.g. relative URLs).
51
+ */
52
+ function urlMatchesIgnoredPattern(url, pattern) {
53
+ const lowerUrl = url.toLowerCase();
54
+ const lowerValue = pattern.value.toLowerCase();
55
+ if (pattern.mode === "contains") {
56
+ return lowerUrl.includes(lowerValue);
57
+ }
58
+ try {
59
+ const parsed = new URL(url);
60
+ if (lowerValue.startsWith("/")) {
61
+ return parsed.pathname.toLowerCase() === lowerValue;
62
+ }
63
+ if (lowerValue.startsWith("http://") || lowerValue.startsWith("https://")) {
64
+ return `${parsed.origin}${parsed.pathname}`.toLowerCase() === lowerValue;
65
+ }
66
+ return parsed.host.toLowerCase() === lowerValue;
67
+ } catch {
68
+ return lowerUrl === lowerValue;
69
+ }
70
+ }
71
+
72
+ /** Convenience: does `url` match ANY of the ignored `patterns`? */
73
+ function isUrlIgnored(url, patterns) {
74
+ if (!url || patterns.length === 0) return false;
75
+ return patterns.some(pattern => urlMatchesIgnoredPattern(url, pattern));
76
+ }
77
+
78
+ /** Tolerate the legacy `string[]` persisted format and stray junk. */
79
+ function migratePatterns(raw) {
80
+ if (!Array.isArray(raw)) return [];
81
+ const migrated = [];
82
+ for (const entry of raw) {
83
+ if (typeof entry === "string" && entry.trim()) {
84
+ migrated.push({
85
+ value: entry,
86
+ mode: "contains"
87
+ });
88
+ } else if (entry && typeof entry === "object" && typeof entry.value === "string") {
89
+ const e = entry;
90
+ migrated.push({
91
+ value: e.value,
92
+ mode: e.mode === "exact" ? "exact" : "contains"
93
+ });
94
+ }
95
+ }
96
+ return migrated;
97
+ }
98
+
99
+ /** Always keep the default patterns present (e.g. Buoy's license API). */
100
+ function ensureDefaults(patterns) {
101
+ const result = [...patterns];
102
+ for (const def of DEFAULT_PATTERNS) {
103
+ if (!result.some(p => p.value === def.value)) {
104
+ result.push({
105
+ ...def
106
+ });
107
+ }
108
+ }
109
+ return result;
110
+ }
111
+ /**
112
+ * Singleton store. One instance per JS runtime, so every consumer (Network tool,
113
+ * Events tool, on mobile or on the desktop dashboard) shares the same patterns.
114
+ */
115
+ class IgnoredPatternsStore {
116
+ patterns = ensureDefaults(DEFAULT_PATTERNS.map(p => ({
117
+ ...p
118
+ })));
119
+ listeners = new Set();
120
+ loaded = false;
121
+ loadPromise = null;
122
+ /** Set once a mutation happens so a slow initial load can't clobber it. */
123
+ dirty = false;
124
+
125
+ /** Current patterns (stable reference until a mutation occurs). */
126
+ getPatterns() {
127
+ return this.patterns;
128
+ }
129
+ subscribe(listener) {
130
+ this.listeners.add(listener);
131
+ // Lazily hydrate from storage the first time anyone cares.
132
+ void this.ensureLoaded();
133
+ return () => {
134
+ this.listeners.delete(listener);
135
+ };
136
+ }
137
+ emit() {
138
+ this.listeners.forEach(l => l());
139
+ }
140
+ ensureLoaded() {
141
+ if (this.loaded) return Promise.resolve();
142
+ if (this.loadPromise) return this.loadPromise;
143
+ this.loadPromise = (async () => {
144
+ try {
145
+ const stored = await _persistentStorage.persistentStorage.getItem(_devToolsStorageKeys.devToolsStorageKeys.network.ignoredDomains());
146
+ // A mutation may have raced this read — never overwrite user intent.
147
+ if (stored && !this.dirty) {
148
+ const migrated = ensureDefaults(migratePatterns(JSON.parse(stored)));
149
+ this.patterns = migrated;
150
+ }
151
+ } catch {
152
+ // Silently fall back to defaults.
153
+ } finally {
154
+ this.loaded = true;
155
+ this.emit();
156
+ }
157
+ })();
158
+ return this.loadPromise;
159
+ }
160
+ persist() {
161
+ _persistentStorage.persistentStorage.setItem(_devToolsStorageKeys.devToolsStorageKeys.network.ignoredDomains(), JSON.stringify(this.patterns)).catch(() => {
162
+ // Silently fail — patterns remain in memory.
163
+ });
164
+ }
165
+ commit(next) {
166
+ this.dirty = true;
167
+ this.patterns = next;
168
+ this.emit();
169
+ this.persist();
170
+ }
171
+
172
+ /** Add a pattern (no-op if its value already exists). */
173
+ add(pattern) {
174
+ const value = pattern.value.trim();
175
+ if (!value) return;
176
+ if (this.patterns.some(p => p.value === value)) return;
177
+ this.commit([...this.patterns, {
178
+ value,
179
+ mode: pattern.mode
180
+ }]);
181
+ }
182
+
183
+ /** Remove a pattern by value. */
184
+ remove(value) {
185
+ if (!this.patterns.some(p => p.value === value)) return;
186
+ this.commit(this.patterns.filter(p => p.value !== value));
187
+ }
188
+
189
+ /** Add as `contains` if absent, otherwise remove (used by detail-view chips). */
190
+ toggle(value) {
191
+ const trimmed = value.trim();
192
+ if (!trimmed) return;
193
+ this.commit(this.patterns.some(p => p.value === trimmed) ? this.patterns.filter(p => p.value !== trimmed) : [...this.patterns, {
194
+ value: trimmed,
195
+ mode: "contains"
196
+ }]);
197
+ }
198
+
199
+ /** Flip an existing pattern between `contains` and `exact`. */
200
+ toggleMode(value) {
201
+ if (!this.patterns.some(p => p.value === value)) return;
202
+ this.commit(this.patterns.map(p => p.value === value ? {
203
+ ...p,
204
+ mode: p.mode === "contains" ? "exact" : "contains"
205
+ } : p));
206
+ }
207
+ }
208
+ const ignoredPatternsStore = exports.ignoredPatternsStore = new IgnoredPatternsStore();
209
+ /**
210
+ * Subscribe to the shared ignored-patterns store. All consumers in a runtime
211
+ * see the same patterns and the same mutations.
212
+ */
213
+ function useIgnoredPatterns() {
214
+ const [patterns, setPatterns] = (0, _react.useState)(() => ignoredPatternsStore.getPatterns());
215
+ (0, _react.useEffect)(() => {
216
+ return ignoredPatternsStore.subscribe(() => {
217
+ setPatterns(ignoredPatternsStore.getPatterns());
218
+ });
219
+ }, []);
220
+ const values = (0, _react.useMemo)(() => new Set(patterns.map(p => p.value)), [patterns]);
221
+ return {
222
+ patterns,
223
+ values,
224
+ add: pattern => ignoredPatternsStore.add(pattern),
225
+ remove: value => ignoredPatternsStore.remove(value),
226
+ toggle: value => ignoredPatternsStore.toggle(value),
227
+ toggleMode: value => ignoredPatternsStore.toggleMode(value)
228
+ };
229
+ }
@@ -9,4 +9,29 @@ Object.defineProperty(exports, "BaseEventStore", {
9
9
  return _BaseEventStore.BaseEventStore;
10
10
  }
11
11
  });
12
- var _BaseEventStore = require("./BaseEventStore.js");
12
+ Object.defineProperty(exports, "ignoredPatternsStore", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _ignoredPatternsStore.ignoredPatternsStore;
16
+ }
17
+ });
18
+ Object.defineProperty(exports, "isUrlIgnored", {
19
+ enumerable: true,
20
+ get: function () {
21
+ return _ignoredPatternsStore.isUrlIgnored;
22
+ }
23
+ });
24
+ Object.defineProperty(exports, "urlMatchesIgnoredPattern", {
25
+ enumerable: true,
26
+ get: function () {
27
+ return _ignoredPatternsStore.urlMatchesIgnoredPattern;
28
+ }
29
+ });
30
+ Object.defineProperty(exports, "useIgnoredPatterns", {
31
+ enumerable: true,
32
+ get: function () {
33
+ return _ignoredPatternsStore.useIgnoredPatterns;
34
+ }
35
+ });
36
+ var _BaseEventStore = require("./BaseEventStore.js");
37
+ var _ignoredPatternsStore = require("./ignoredPatternsStore.js");
@@ -14,6 +14,7 @@ function CompactRow({
14
14
  statusSublabel,
15
15
  primaryText,
16
16
  secondaryText,
17
+ secondaryAccessory,
17
18
  expandedContent,
18
19
  isExpanded,
19
20
  badgeText,
@@ -28,77 +29,80 @@ function CompactRow({
28
29
  }) {
29
30
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
30
31
  style: styles.rowWrapper,
31
- children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
32
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
32
33
  style: [styles.row, isSelected && styles.selectedRow, isExpanded && [styles.expandedRowActive, {
33
34
  borderColor: expandedGlowColor || _gameUIColors.buoyColors.primary,
34
35
  shadowColor: expandedGlowColor || _gameUIColors.buoyColors.primary
35
36
  }]],
36
- onPress: onPress,
37
- activeOpacity: 0.8,
38
- disabled: disabled || !onPress,
39
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
40
- style: styles.rowContent,
41
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
42
- style: styles.statusSection,
43
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
44
- style: [styles.statusDot, {
45
- backgroundColor: statusDotColor
46
- }]
37
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
38
+ onPress: onPress,
39
+ activeOpacity: 0.8,
40
+ disabled: disabled || !onPress,
41
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
42
+ style: styles.rowContent,
43
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
44
+ style: styles.statusSection,
45
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
46
+ style: [styles.statusDot, {
47
+ backgroundColor: statusDotColor
48
+ }]
49
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
50
+ style: styles.statusInfo,
51
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
52
+ style: [styles.statusLabel, {
53
+ color: statusDotColor
54
+ }],
55
+ numberOfLines: 1,
56
+ children: statusLabel
57
+ }), statusSublabel ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
58
+ style: styles.observerText,
59
+ numberOfLines: 1,
60
+ children: statusSublabel
61
+ }) : null]
62
+ })]
47
63
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
48
- style: styles.statusInfo,
64
+ style: styles.querySection,
49
65
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
50
- style: [styles.statusLabel, {
51
- color: statusDotColor
52
- }],
53
- numberOfLines: 1,
54
- children: statusLabel
55
- }), statusSublabel && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
56
- style: styles.observerText,
57
- numberOfLines: 1,
58
- children: statusSublabel
66
+ style: styles.queryHash,
67
+ numberOfLines: isExpanded ? undefined : 2,
68
+ children: primaryText
69
+ }), !isExpanded && (secondaryText || secondaryAccessory) ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
70
+ style: styles.secondaryRow,
71
+ children: [secondaryText ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
72
+ style: styles.secondaryText,
73
+ numberOfLines: 1,
74
+ children: secondaryText
75
+ }) : null, secondaryAccessory]
76
+ }) : null]
77
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
78
+ style: styles.rightSection,
79
+ children: [(customBadge || badgeText !== undefined || !isExpanded && bottomRightText) && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
80
+ style: styles.badgeContainer,
81
+ children: [customBadge ? customBadge : badgeText !== undefined ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
82
+ style: [styles.statusBadge, {
83
+ color: badgeColor || statusDotColor
84
+ }],
85
+ children: badgeText
86
+ }) : null, !isExpanded && bottomRightText ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
87
+ style: styles.bottomRightText,
88
+ numberOfLines: 1,
89
+ children: bottomRightText
90
+ }) : null]
91
+ }), showChevron && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
92
+ style: styles.chevronContainer,
93
+ children: isExpanded ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.ChevronDown, {
94
+ size: 14,
95
+ color: _gameUIColors.buoyColors.textMuted
96
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.ChevronRight, {
97
+ size: 14,
98
+ color: _gameUIColors.buoyColors.textMuted
99
+ })
59
100
  })]
60
101
  })]
61
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
62
- style: styles.querySection,
63
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
64
- style: styles.queryHash,
65
- numberOfLines: isExpanded ? undefined : 2,
66
- children: primaryText
67
- }), !isExpanded && secondaryText && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
68
- style: styles.secondaryText,
69
- numberOfLines: 1,
70
- children: secondaryText
71
- })]
72
- }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
73
- style: styles.rightSection,
74
- children: [(customBadge || badgeText !== undefined) && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
75
- style: styles.badgeContainer,
76
- children: customBadge ? customBadge : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
77
- style: [styles.statusBadge, {
78
- color: badgeColor || statusDotColor
79
- }],
80
- children: badgeText
81
- })
82
- }), showChevron && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
83
- style: styles.chevronContainer,
84
- children: isExpanded ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.ChevronDown, {
85
- size: 14,
86
- color: _gameUIColors.buoyColors.textMuted
87
- }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.ChevronRight, {
88
- size: 14,
89
- color: _gameUIColors.buoyColors.textMuted
90
- })
91
- })]
92
- })]
102
+ })
93
103
  }), isExpanded && expandedContent && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
94
104
  style: styles.expandedContent,
95
105
  children: expandedContent
96
- }), !isExpanded && bottomRightText && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
97
- style: styles.bottomRightContainer,
98
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
99
- style: styles.bottomRightText,
100
- children: bottomRightText
101
- })
102
106
  })]
103
107
  })
104
108
  });
@@ -189,6 +193,12 @@ const styles = _reactNative.StyleSheet.create({
189
193
  color: _gameUIColors.buoyColors.text,
190
194
  lineHeight: 16
191
195
  },
196
+ secondaryRow: {
197
+ flexDirection: "row",
198
+ alignItems: "center",
199
+ gap: 6,
200
+ marginTop: 1
201
+ },
192
202
  secondaryText: {
193
203
  fontSize: 10,
194
204
  color: _gameUIColors.buoyColors.textMuted,
@@ -200,7 +210,9 @@ const styles = _reactNative.StyleSheet.create({
200
210
  gap: 8
201
211
  },
202
212
  badgeContainer: {
203
- alignItems: "flex-end"
213
+ flexDirection: "column",
214
+ alignItems: "flex-end",
215
+ gap: 2
204
216
  },
205
217
  statusBadge: {
206
218
  fontSize: 12,
@@ -217,11 +229,6 @@ const styles = _reactNative.StyleSheet.create({
217
229
  borderTopColor: _gameUIColors.buoyColors.border + "20",
218
230
  marginLeft: 24 // Align with content after status dot
219
231
  },
220
- bottomRightContainer: {
221
- position: "absolute",
222
- bottom: 4,
223
- right: 8
224
- },
225
232
  bottomRightText: {
226
233
  fontSize: 9,
227
234
  color: _gameUIColors.buoyColors.textMuted,
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.EventPickerModal = void 0;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _reactNative = require("react-native");
9
+ var _absoluteFill = require("../../../utils/absoluteFill.js");
9
10
  var _macOSDesignSystemColors = require("../../gameUI/constants/macOSDesignSystemColors.js");
10
11
  var _lucideIcons = require("../../../icons/lucide-icons.js");
11
12
  var _jsxRuntime = require("react/jsx-runtime");
@@ -82,13 +83,13 @@ const EventPickerModal = exports.EventPickerModal = /*#__PURE__*/(0, _react.memo
82
83
  });
83
84
  const styles = _reactNative.StyleSheet.create({
84
85
  overlay: {
85
- ..._reactNative.StyleSheet.absoluteFillObject,
86
+ ..._absoluteFill.absoluteFill,
86
87
  zIndex: 20,
87
88
  justifyContent: "center",
88
89
  alignItems: "center"
89
90
  },
90
91
  backdrop: {
91
- ..._reactNative.StyleSheet.absoluteFillObject,
92
+ ..._absoluteFill.absoluteFill,
92
93
  backgroundColor: "rgba(0,0,0,0.65)"
93
94
  },
94
95
  card: {
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.ExpandableSectionWithModal = ExpandableSectionWithModal;
7
7
  var _react = require("react");
8
8
  var _reactNative = require("react-native");
9
+ var _absoluteFill = require("../../utils/absoluteFill.js");
9
10
  var _useSafeAreaInsets = require("../../hooks/useSafeAreaInsets.js");
10
11
  var _index = require("../../icons/index.js");
11
12
  var _ExpandableSection = require("./ExpandableSection.js");
@@ -125,7 +126,7 @@ const styles = _reactNative.StyleSheet.create({
125
126
  flex: 1
126
127
  },
127
128
  backdrop: {
128
- ..._reactNative.StyleSheet.absoluteFillObject,
129
+ ..._absoluteFill.absoluteFill,
129
130
  backgroundColor: "rgba(0, 0, 0, 0.8)"
130
131
  },
131
132
  backdropTouchable: {
@@ -44,10 +44,12 @@ function ExpandedInfoRow({
44
44
  function PillBadge({
45
45
  color,
46
46
  children,
47
- icon
47
+ icon,
48
+ size = "md"
48
49
  }) {
50
+ const isSm = size === "sm";
49
51
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
50
- style: [styles.pill, {
52
+ style: [styles.pill, isSm && styles.pillSm, {
51
53
  backgroundColor: color + "20",
52
54
  borderColor: color + "40"
53
55
  }],
@@ -55,7 +57,7 @@ function PillBadge({
55
57
  style: styles.pillIcon,
56
58
  children: icon
57
59
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
58
- style: [styles.pillText, {
60
+ style: [styles.pillText, isSm && styles.pillTextSm, {
59
61
  color
60
62
  }],
61
63
  children: children
@@ -83,6 +85,10 @@ const styles = _reactNative.StyleSheet.create({
83
85
  borderRadius: 999,
84
86
  borderWidth: 1
85
87
  },
88
+ pillSm: {
89
+ paddingHorizontal: 5,
90
+ paddingVertical: 1
91
+ },
86
92
  pillIcon: {
87
93
  marginRight: 4
88
94
  },
@@ -91,5 +97,9 @@ const styles = _reactNative.StyleSheet.create({
91
97
  fontWeight: "700",
92
98
  fontFamily: "monospace",
93
99
  letterSpacing: 0.5
100
+ },
101
+ pillTextSm: {
102
+ fontSize: 9,
103
+ letterSpacing: 0.3
94
104
  }
95
105
  });
@@ -13,7 +13,12 @@ var _jsxRuntime = require("react/jsx-runtime");
13
13
  // ============================================================================
14
14
  // Global expandable setting — controlled via setExpandableWindowControls()
15
15
  // ============================================================================
16
- let _expandableEnabled = true; // Default ON
16
+
17
+ // The expandable behavior is a touch affordance (big tap targets). On web a
18
+ // mouse clicks the small dots directly, so it's always off there — the
19
+ // setting only applies to native touch platforms.
20
+ const EXPANDABLE_SUPPORTED = _reactNative.Platform.OS !== "web";
21
+ let _expandableEnabled = true; // Default ON (native touch devices)
17
22
 
18
23
  /**
19
24
  * Set whether window controls use the expandable iPad-style behavior.
@@ -73,8 +78,9 @@ function WindowControls({
73
78
  const ToggleModeIcon = mode === "floating" ? _index.DockBottom : _index.FloatWindow;
74
79
  const toggleModeLabel = mode === "floating" ? "Dock to bottom sheet" : "Make floating window";
75
80
 
76
- // When expandable is disabled, render original directly-tappable buttons
77
- if (!_expandableEnabled) {
81
+ // When expandable is disabled (or unsupported on this platform), render
82
+ // original directly-tappable buttons
83
+ if (!_expandableEnabled || !EXPANDABLE_SUPPORTED) {
78
84
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
79
85
  style: styles.container,
80
86
  children: [onMinimize && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {