@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.
- package/lib/commonjs/JsModal.js +2 -1
- package/lib/commonjs/clipboard/clipboard-impl.js +28 -2
- package/lib/commonjs/dataViewer/VirtualizedDataExplorer.js +3 -5
- package/lib/commonjs/hooks/safe-area-impl.js +1 -1
- package/lib/commonjs/icons/lucide-icons.js +130 -22
- package/lib/commonjs/index.js +14 -0
- package/lib/commonjs/license/DeviceLimitModal.js +2 -1
- package/lib/commonjs/license/FeatureGate.js +60 -11
- package/lib/commonjs/license/LicenseEntryModal.js +14 -3
- package/lib/commonjs/license/ManageDevicesModal.js +2 -1
- package/lib/commonjs/license/openPricing.js +36 -0
- package/lib/commonjs/storage/devToolsStorageKeys.js +1 -0
- package/lib/commonjs/stores/BaseEventStore.js +72 -2
- package/lib/commonjs/stores/ignoredPatternsStore.js +229 -0
- package/lib/commonjs/stores/index.js +26 -1
- package/lib/commonjs/ui/components/CompactRow.js +73 -66
- package/lib/commonjs/ui/components/EventHistoryViewer/EventPickerModal.js +3 -2
- package/lib/commonjs/ui/components/ExpandableSectionWithModal.js +2 -1
- package/lib/commonjs/ui/components/ExpandedInfoRow.js +13 -3
- package/lib/commonjs/ui/components/WindowControls.js +9 -3
- package/lib/commonjs/ui/console/CyberpunkConsoleSection.js +6 -5
- package/lib/commonjs/ui/console/GalaxyButton.js +2 -1
- package/lib/commonjs/ui/gameUI/components/GameUIStatusHeader.js +2 -1
- package/lib/commonjs/utils/absoluteFill.js +28 -0
- package/lib/commonjs/utils/index.js +13 -0
- package/lib/commonjs/utils/safeExpoRouter.js +59 -4
- package/lib/module/JsModal.js +2 -1
- package/lib/module/clipboard/clipboard-impl.js +28 -2
- package/lib/module/dataViewer/VirtualizedDataExplorer.js +3 -5
- package/lib/module/hooks/safe-area-impl.js +1 -1
- package/lib/module/icons/lucide-icons.js +125 -19
- package/lib/module/index.js +3 -1
- package/lib/module/license/DeviceLimitModal.js +2 -1
- package/lib/module/license/FeatureGate.js +61 -12
- package/lib/module/license/LicenseEntryModal.js +15 -4
- package/lib/module/license/ManageDevicesModal.js +2 -1
- package/lib/module/license/openPricing.js +31 -0
- package/lib/module/storage/devToolsStorageKeys.js +1 -0
- package/lib/module/stores/BaseEventStore.js +72 -2
- package/lib/module/stores/ignoredPatternsStore.js +223 -0
- package/lib/module/stores/index.js +2 -1
- package/lib/module/ui/components/CompactRow.js +73 -66
- package/lib/module/ui/components/EventHistoryViewer/EventPickerModal.js +3 -2
- package/lib/module/ui/components/ExpandableSectionWithModal.js +2 -1
- package/lib/module/ui/components/ExpandedInfoRow.js +13 -3
- package/lib/module/ui/components/WindowControls.js +10 -4
- package/lib/module/ui/console/CyberpunkConsoleSection.js +6 -5
- package/lib/module/ui/console/GalaxyButton.js +2 -1
- package/lib/module/ui/gameUI/components/GameUIStatusHeader.js +2 -1
- package/lib/module/utils/absoluteFill.js +24 -0
- package/lib/module/utils/index.js +2 -1
- package/lib/module/utils/safeExpoRouter.js +58 -4
- package/lib/typescript/commonjs/JsModal.d.ts.map +1 -1
- package/lib/typescript/commonjs/clipboard/clipboard-impl.d.ts +3 -2
- package/lib/typescript/commonjs/clipboard/clipboard-impl.d.ts.map +1 -1
- package/lib/typescript/commonjs/dataViewer/VirtualizedDataExplorer.d.ts.map +1 -1
- package/lib/typescript/commonjs/hooks/safe-area-impl.d.ts +1 -1
- package/lib/typescript/commonjs/icons/lucide-icons.d.ts +5 -2
- package/lib/typescript/commonjs/icons/lucide-icons.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +1 -1
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/license/DeviceLimitModal.d.ts.map +1 -1
- package/lib/typescript/commonjs/license/FeatureGate.d.ts +14 -1
- package/lib/typescript/commonjs/license/FeatureGate.d.ts.map +1 -1
- package/lib/typescript/commonjs/license/LicenseEntryModal.d.ts.map +1 -1
- package/lib/typescript/commonjs/license/ManageDevicesModal.d.ts.map +1 -1
- package/lib/typescript/commonjs/license/openPricing.d.ts +14 -0
- package/lib/typescript/commonjs/license/openPricing.d.ts.map +1 -0
- package/lib/typescript/commonjs/storage/devToolsStorageKeys.d.ts +1 -0
- package/lib/typescript/commonjs/storage/devToolsStorageKeys.d.ts.map +1 -1
- package/lib/typescript/commonjs/stores/BaseEventStore.d.ts +28 -0
- package/lib/typescript/commonjs/stores/BaseEventStore.d.ts.map +1 -1
- package/lib/typescript/commonjs/stores/ignoredPatternsStore.d.ts +84 -0
- package/lib/typescript/commonjs/stores/ignoredPatternsStore.d.ts.map +1 -0
- package/lib/typescript/commonjs/stores/index.d.ts +1 -0
- package/lib/typescript/commonjs/stores/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/CompactRow.d.ts +3 -1
- package/lib/typescript/commonjs/ui/components/CompactRow.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/EventHistoryViewer/EventPickerModal.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/ExpandableSectionWithModal.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/ExpandedInfoRow.d.ts +3 -1
- package/lib/typescript/commonjs/ui/components/ExpandedInfoRow.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/WindowControls.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/console/CyberpunkConsoleSection.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/console/GalaxyButton.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/gameUI/components/GameUIStatusHeader.d.ts.map +1 -1
- package/lib/typescript/commonjs/utils/absoluteFill.d.ts +18 -0
- package/lib/typescript/commonjs/utils/absoluteFill.d.ts.map +1 -0
- package/lib/typescript/commonjs/utils/index.d.ts +2 -1
- package/lib/typescript/commonjs/utils/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/utils/safeExpoRouter.d.ts +9 -0
- package/lib/typescript/commonjs/utils/safeExpoRouter.d.ts.map +1 -1
- package/lib/typescript/module/JsModal.d.ts.map +1 -1
- package/lib/typescript/module/clipboard/clipboard-impl.d.ts +3 -2
- package/lib/typescript/module/clipboard/clipboard-impl.d.ts.map +1 -1
- package/lib/typescript/module/dataViewer/VirtualizedDataExplorer.d.ts.map +1 -1
- package/lib/typescript/module/hooks/safe-area-impl.d.ts +1 -1
- package/lib/typescript/module/icons/lucide-icons.d.ts +5 -2
- package/lib/typescript/module/icons/lucide-icons.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +1 -1
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/license/DeviceLimitModal.d.ts.map +1 -1
- package/lib/typescript/module/license/FeatureGate.d.ts +14 -1
- package/lib/typescript/module/license/FeatureGate.d.ts.map +1 -1
- package/lib/typescript/module/license/LicenseEntryModal.d.ts.map +1 -1
- package/lib/typescript/module/license/ManageDevicesModal.d.ts.map +1 -1
- package/lib/typescript/module/license/openPricing.d.ts +14 -0
- package/lib/typescript/module/license/openPricing.d.ts.map +1 -0
- package/lib/typescript/module/storage/devToolsStorageKeys.d.ts +1 -0
- package/lib/typescript/module/storage/devToolsStorageKeys.d.ts.map +1 -1
- package/lib/typescript/module/stores/BaseEventStore.d.ts +28 -0
- package/lib/typescript/module/stores/BaseEventStore.d.ts.map +1 -1
- package/lib/typescript/module/stores/ignoredPatternsStore.d.ts +84 -0
- package/lib/typescript/module/stores/ignoredPatternsStore.d.ts.map +1 -0
- package/lib/typescript/module/stores/index.d.ts +1 -0
- package/lib/typescript/module/stores/index.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/CompactRow.d.ts +3 -1
- package/lib/typescript/module/ui/components/CompactRow.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/EventHistoryViewer/EventPickerModal.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/ExpandableSectionWithModal.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/ExpandedInfoRow.d.ts +3 -1
- package/lib/typescript/module/ui/components/ExpandedInfoRow.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/WindowControls.d.ts.map +1 -1
- package/lib/typescript/module/ui/console/CyberpunkConsoleSection.d.ts.map +1 -1
- package/lib/typescript/module/ui/console/GalaxyButton.d.ts.map +1 -1
- package/lib/typescript/module/ui/gameUI/components/GameUIStatusHeader.d.ts.map +1 -1
- package/lib/typescript/module/utils/absoluteFill.d.ts +18 -0
- package/lib/typescript/module/utils/absoluteFill.d.ts.map +1 -0
- package/lib/typescript/module/utils/index.d.ts +2 -1
- package/lib/typescript/module/utils/index.d.ts.map +1 -1
- package/lib/typescript/module/utils/safeExpoRouter.d.ts +9 -0
- package/lib/typescript/module/utils/safeExpoRouter.d.ts.map +1 -1
- 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
|
-
|
|
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.
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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.
|
|
64
|
+
style: styles.querySection,
|
|
49
65
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
50
|
-
style:
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
|
-
})
|
|
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
|
-
|
|
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
|
-
...
|
|
86
|
+
..._absoluteFill.absoluteFill,
|
|
86
87
|
zIndex: 20,
|
|
87
88
|
justifyContent: "center",
|
|
88
89
|
alignItems: "center"
|
|
89
90
|
},
|
|
90
91
|
backdrop: {
|
|
91
|
-
...
|
|
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
|
-
...
|
|
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
|
-
|
|
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
|
|
77
|
-
|
|
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, {
|