@buoy-gg/shared-ui 2.2.0 → 3.0.0
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/clipboard/clipboard-impl.js +28 -2
- package/lib/commonjs/hooks/safe-area-impl.js +1 -1
- package/lib/commonjs/stores/BaseEventStore.js +48 -2
- package/lib/commonjs/ui/components/WindowControls.js +9 -3
- package/lib/module/clipboard/clipboard-impl.js +28 -2
- package/lib/module/hooks/safe-area-impl.js +1 -1
- package/lib/module/stores/BaseEventStore.js +48 -2
- package/lib/module/ui/components/WindowControls.js +10 -4
- 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/hooks/safe-area-impl.d.ts +1 -1
- package/lib/typescript/commonjs/stores/BaseEventStore.d.ts +19 -0
- package/lib/typescript/commonjs/stores/BaseEventStore.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/WindowControls.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/hooks/safe-area-impl.d.ts +1 -1
- package/lib/typescript/module/stores/BaseEventStore.d.ts +19 -0
- package/lib/typescript/module/stores/BaseEventStore.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/WindowControls.d.ts.map +1 -1
- package/package.json +4 -4
|
@@ -20,9 +20,17 @@ exports.isClipboardAvailable = exports.clipboardType = exports.clipboardFunction
|
|
|
20
20
|
* Fallback chain:
|
|
21
21
|
* 1. expo-clipboard
|
|
22
22
|
* 2. @react-native-clipboard/clipboard
|
|
23
|
-
* 3.
|
|
23
|
+
* 3. Web clipboard API (navigator.clipboard)
|
|
24
|
+
* 4. Graceful failure
|
|
24
25
|
*/
|
|
25
26
|
|
|
27
|
+
// navigator.clipboard isn't in React Native's TS lib — narrow it manually
|
|
28
|
+
|
|
29
|
+
function getWebClipboard() {
|
|
30
|
+
if (typeof navigator === "undefined") return null;
|
|
31
|
+
const clipboard = navigator.clipboard;
|
|
32
|
+
return clipboard && typeof clipboard.writeText === "function" ? clipboard : null;
|
|
33
|
+
}
|
|
26
34
|
// Grab module references at load time (top-level try-catch for Metro)
|
|
27
35
|
// Always require both — we decide which actually works at call time
|
|
28
36
|
let _expoClipboard = null;
|
|
@@ -67,6 +75,21 @@ async function detect(text) {
|
|
|
67
75
|
return true;
|
|
68
76
|
} catch {/* rn-clipboard not functional */}
|
|
69
77
|
}
|
|
78
|
+
|
|
79
|
+
// 3. Web fallback (react-native-web / desktop dashboard / browsers)
|
|
80
|
+
const webClipboard = getWebClipboard();
|
|
81
|
+
if (webClipboard) {
|
|
82
|
+
try {
|
|
83
|
+
await webClipboard.writeText(text);
|
|
84
|
+
_detectedType = "web";
|
|
85
|
+
_clipboardFn = async t => {
|
|
86
|
+
await webClipboard.writeText(t);
|
|
87
|
+
return true;
|
|
88
|
+
};
|
|
89
|
+
_detected = true;
|
|
90
|
+
return true;
|
|
91
|
+
} catch {/* clipboard permission denied */}
|
|
92
|
+
}
|
|
70
93
|
_detected = true;
|
|
71
94
|
return false;
|
|
72
95
|
}
|
|
@@ -76,7 +99,10 @@ const clipboardType = () => {
|
|
|
76
99
|
exports.clipboardType = clipboardType;
|
|
77
100
|
const isClipboardAvailable = () => {
|
|
78
101
|
// Before first use, optimistically return true if we have a module ref
|
|
79
|
-
|
|
102
|
+
// or the web clipboard API is present
|
|
103
|
+
if (!_detected) {
|
|
104
|
+
return _expoClipboard != null || _rnClipboard != null || getWebClipboard() != null;
|
|
105
|
+
}
|
|
80
106
|
return _clipboardFn != null;
|
|
81
107
|
};
|
|
82
108
|
exports.isClipboardAvailable = isClipboardAvailable;
|
|
@@ -7,7 +7,7 @@ exports.useNativeSafeAreaInsets = exports.safeAreaType = exports.hasSafeAreaPack
|
|
|
7
7
|
/**
|
|
8
8
|
* Auto-generated safe area implementation
|
|
9
9
|
* Detected: none
|
|
10
|
-
* Generated at: 2026-
|
|
10
|
+
* Generated at: 2026-06-12T23:17:33.323Z
|
|
11
11
|
*
|
|
12
12
|
* DO NOT EDIT - This file is generated by scripts/detect-safe-area.js
|
|
13
13
|
*
|
|
@@ -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,50 @@ 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 = events.slice(0, this.maxEvents);
|
|
274
|
+
this.notifyArrayListeners();
|
|
229
275
|
}
|
|
230
276
|
|
|
231
277
|
/**
|
|
@@ -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, {
|
|
@@ -16,9 +16,17 @@
|
|
|
16
16
|
* Fallback chain:
|
|
17
17
|
* 1. expo-clipboard
|
|
18
18
|
* 2. @react-native-clipboard/clipboard
|
|
19
|
-
* 3.
|
|
19
|
+
* 3. Web clipboard API (navigator.clipboard)
|
|
20
|
+
* 4. Graceful failure
|
|
20
21
|
*/
|
|
21
22
|
|
|
23
|
+
// navigator.clipboard isn't in React Native's TS lib — narrow it manually
|
|
24
|
+
|
|
25
|
+
function getWebClipboard() {
|
|
26
|
+
if (typeof navigator === "undefined") return null;
|
|
27
|
+
const clipboard = navigator.clipboard;
|
|
28
|
+
return clipboard && typeof clipboard.writeText === "function" ? clipboard : null;
|
|
29
|
+
}
|
|
22
30
|
// Grab module references at load time (top-level try-catch for Metro)
|
|
23
31
|
// Always require both — we decide which actually works at call time
|
|
24
32
|
let _expoClipboard = null;
|
|
@@ -63,6 +71,21 @@ async function detect(text) {
|
|
|
63
71
|
return true;
|
|
64
72
|
} catch {/* rn-clipboard not functional */}
|
|
65
73
|
}
|
|
74
|
+
|
|
75
|
+
// 3. Web fallback (react-native-web / desktop dashboard / browsers)
|
|
76
|
+
const webClipboard = getWebClipboard();
|
|
77
|
+
if (webClipboard) {
|
|
78
|
+
try {
|
|
79
|
+
await webClipboard.writeText(text);
|
|
80
|
+
_detectedType = "web";
|
|
81
|
+
_clipboardFn = async t => {
|
|
82
|
+
await webClipboard.writeText(t);
|
|
83
|
+
return true;
|
|
84
|
+
};
|
|
85
|
+
_detected = true;
|
|
86
|
+
return true;
|
|
87
|
+
} catch {/* clipboard permission denied */}
|
|
88
|
+
}
|
|
66
89
|
_detected = true;
|
|
67
90
|
return false;
|
|
68
91
|
}
|
|
@@ -71,7 +94,10 @@ export const clipboardType = () => {
|
|
|
71
94
|
};
|
|
72
95
|
export const isClipboardAvailable = () => {
|
|
73
96
|
// Before first use, optimistically return true if we have a module ref
|
|
74
|
-
|
|
97
|
+
// or the web clipboard API is present
|
|
98
|
+
if (!_detected) {
|
|
99
|
+
return _expoClipboard != null || _rnClipboard != null || getWebClipboard() != null;
|
|
100
|
+
}
|
|
75
101
|
return _clipboardFn != null;
|
|
76
102
|
};
|
|
77
103
|
export const clipboardFunction = async text => {
|
|
@@ -59,6 +59,8 @@ import { notifySubscriberCountChange } from "../utils/subscriberCountNotifier.js
|
|
|
59
59
|
export class BaseEventStore extends Subscribable {
|
|
60
60
|
events = [];
|
|
61
61
|
arrayListeners = new Set();
|
|
62
|
+
captureSuppressed = false;
|
|
63
|
+
clearListeners = new Set();
|
|
62
64
|
constructor(options) {
|
|
63
65
|
super();
|
|
64
66
|
this.maxEvents = options.maxEvents ?? 500;
|
|
@@ -92,7 +94,7 @@ export class BaseEventStore extends Subscribable {
|
|
|
92
94
|
* Starts capturing if no one was subscribed.
|
|
93
95
|
*/
|
|
94
96
|
onSubscribe() {
|
|
95
|
-
if (this.getTotalSubscriberCount() === 1) {
|
|
97
|
+
if (this.getTotalSubscriberCount() === 1 && !this.captureSuppressed) {
|
|
96
98
|
this.startCapturing();
|
|
97
99
|
}
|
|
98
100
|
notifySubscriberCountChange(this.storeName);
|
|
@@ -132,7 +134,7 @@ export class BaseEventStore extends Subscribable {
|
|
|
132
134
|
this.arrayListeners.add(listener);
|
|
133
135
|
|
|
134
136
|
// Start capturing if this is the first subscriber
|
|
135
|
-
if (wasEmpty) {
|
|
137
|
+
if (wasEmpty && !this.captureSuppressed) {
|
|
136
138
|
this.startCapturing();
|
|
137
139
|
}
|
|
138
140
|
|
|
@@ -223,6 +225,50 @@ export class BaseEventStore extends Subscribable {
|
|
|
223
225
|
clearEvents() {
|
|
224
226
|
this.events = [];
|
|
225
227
|
this.notifyArrayListeners();
|
|
228
|
+
this.clearListeners.forEach(listener => {
|
|
229
|
+
try {
|
|
230
|
+
listener();
|
|
231
|
+
} catch {
|
|
232
|
+
// Ignore listener errors
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Listen for clearEvents() calls. Used in remote mirror mode to forward a
|
|
239
|
+
* clear performed in the dashboard UI to the synced device.
|
|
240
|
+
*/
|
|
241
|
+
onClear(listener) {
|
|
242
|
+
this.clearListeners.add(listener);
|
|
243
|
+
return () => {
|
|
244
|
+
this.clearListeners.delete(listener);
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// ===========================================================================
|
|
249
|
+
// REMOTE MIRROR MODE
|
|
250
|
+
// ===========================================================================
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Suppress the auto start/stop capture lifecycle. Use when this store acts
|
|
254
|
+
* as a mirror of a remote device's events (e.g. the desktop dashboard):
|
|
255
|
+
* events arrive via replaceEvents() and the local interceptors must never
|
|
256
|
+
* start — on the dashboard they would capture the dashboard's own traffic.
|
|
257
|
+
*/
|
|
258
|
+
disableCapture() {
|
|
259
|
+
this.captureSuppressed = true;
|
|
260
|
+
if (this.isCapturing()) {
|
|
261
|
+
this.stopCapturing();
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Replace the entire event list and notify array listeners. Used in remote
|
|
267
|
+
* mirror mode where full snapshots arrive from a synced device.
|
|
268
|
+
*/
|
|
269
|
+
replaceEvents(events) {
|
|
270
|
+
this.events = events.slice(0, this.maxEvents);
|
|
271
|
+
this.notifyArrayListeners();
|
|
226
272
|
}
|
|
227
273
|
|
|
228
274
|
/**
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import { useState, useRef, useCallback, useEffect } from "react";
|
|
4
|
-
import { View, TouchableOpacity, TouchableWithoutFeedback, StyleSheet, Animated, Modal } from "react-native";
|
|
4
|
+
import { View, TouchableOpacity, TouchableWithoutFeedback, StyleSheet, Animated, Modal, Platform } from "react-native";
|
|
5
5
|
import { X, Minus, DockBottom, FloatWindow } from "../../icons/index.js";
|
|
6
6
|
import { buoyColors } from "../gameUI/constants/gameUIColors.js";
|
|
7
7
|
|
|
8
8
|
// ============================================================================
|
|
9
9
|
// Global expandable setting — controlled via setExpandableWindowControls()
|
|
10
10
|
// ============================================================================
|
|
11
|
+
|
|
12
|
+
// The expandable behavior is a touch affordance (big tap targets). On web a
|
|
13
|
+
// mouse clicks the small dots directly, so it's always off there — the
|
|
14
|
+
// setting only applies to native touch platforms.
|
|
11
15
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
12
|
-
|
|
16
|
+
const EXPANDABLE_SUPPORTED = Platform.OS !== "web";
|
|
17
|
+
let _expandableEnabled = true; // Default ON (native touch devices)
|
|
13
18
|
|
|
14
19
|
/**
|
|
15
20
|
* Set whether window controls use the expandable iPad-style behavior.
|
|
@@ -69,8 +74,9 @@ export function WindowControls({
|
|
|
69
74
|
const ToggleModeIcon = mode === "floating" ? DockBottom : FloatWindow;
|
|
70
75
|
const toggleModeLabel = mode === "floating" ? "Dock to bottom sheet" : "Make floating window";
|
|
71
76
|
|
|
72
|
-
// When expandable is disabled
|
|
73
|
-
|
|
77
|
+
// When expandable is disabled (or unsupported on this platform), render
|
|
78
|
+
// original directly-tappable buttons
|
|
79
|
+
if (!_expandableEnabled || !EXPANDABLE_SUPPORTED) {
|
|
74
80
|
return /*#__PURE__*/_jsxs(View, {
|
|
75
81
|
style: styles.container,
|
|
76
82
|
children: [onMinimize && /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
@@ -14,10 +14,11 @@
|
|
|
14
14
|
* Fallback chain:
|
|
15
15
|
* 1. expo-clipboard
|
|
16
16
|
* 2. @react-native-clipboard/clipboard
|
|
17
|
-
* 3.
|
|
17
|
+
* 3. Web clipboard API (navigator.clipboard)
|
|
18
|
+
* 4. Graceful failure
|
|
18
19
|
*/
|
|
19
20
|
export type ClipboardFunction = (text: string) => Promise<boolean>;
|
|
20
|
-
export declare const clipboardType: () => "expo" | "react-native" | null;
|
|
21
|
+
export declare const clipboardType: () => "expo" | "react-native" | "web" | null;
|
|
21
22
|
export declare const isClipboardAvailable: () => boolean;
|
|
22
23
|
export declare const clipboardFunction: ClipboardFunction;
|
|
23
24
|
//# sourceMappingURL=clipboard-impl.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clipboard-impl.d.ts","sourceRoot":"","sources":["../../../../src/clipboard/clipboard-impl.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"clipboard-impl.d.ts","sourceRoot":"","sources":["../../../../src/clipboard/clipboard-impl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAYH,MAAM,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAoEnE,eAAO,MAAM,aAAa,QAAO,MAAM,GAAG,cAAc,GAAG,KAAK,GAAG,IAElE,CAAC;AAEF,eAAO,MAAM,oBAAoB,QAAO,OASvC,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,iBAmB/B,CAAC"}
|
|
@@ -61,6 +61,8 @@ export declare abstract class BaseEventStore<TEvent> extends Subscribable<EventC
|
|
|
61
61
|
protected arrayListeners: Set<ArrayListener<TEvent>>;
|
|
62
62
|
protected maxEvents: number;
|
|
63
63
|
protected storeName: string;
|
|
64
|
+
private captureSuppressed;
|
|
65
|
+
private clearListeners;
|
|
64
66
|
constructor(options: BaseEventStoreOptions);
|
|
65
67
|
/**
|
|
66
68
|
* Start capturing events from the underlying source.
|
|
@@ -129,6 +131,23 @@ export declare abstract class BaseEventStore<TEvent> extends Subscribable<EventC
|
|
|
129
131
|
* Clear all events
|
|
130
132
|
*/
|
|
131
133
|
clearEvents(): void;
|
|
134
|
+
/**
|
|
135
|
+
* Listen for clearEvents() calls. Used in remote mirror mode to forward a
|
|
136
|
+
* clear performed in the dashboard UI to the synced device.
|
|
137
|
+
*/
|
|
138
|
+
onClear(listener: () => void): () => void;
|
|
139
|
+
/**
|
|
140
|
+
* Suppress the auto start/stop capture lifecycle. Use when this store acts
|
|
141
|
+
* as a mirror of a remote device's events (e.g. the desktop dashboard):
|
|
142
|
+
* events arrive via replaceEvents() and the local interceptors must never
|
|
143
|
+
* start — on the dashboard they would capture the dashboard's own traffic.
|
|
144
|
+
*/
|
|
145
|
+
disableCapture(): void;
|
|
146
|
+
/**
|
|
147
|
+
* Replace the entire event list and notify array listeners. Used in remote
|
|
148
|
+
* mirror mode where full snapshots arrive from a synced device.
|
|
149
|
+
*/
|
|
150
|
+
replaceEvents(events: TEvent[]): void;
|
|
132
151
|
/**
|
|
133
152
|
* Set maximum number of events to keep
|
|
134
153
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseEventStore.d.ts","sourceRoot":"","sources":["../../../../src/stores/BaseEventStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGrD;;GAEG;AACH,MAAM,MAAM,aAAa,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;AAE/D;;GAEG;AACH,MAAM,MAAM,aAAa,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,8BAAsB,cAAc,CAAC,MAAM,CAAE,SAAQ,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IACtF,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,CAAM;IAChC,SAAS,CAAC,cAAc,EAAE,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAa;IACjE,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC;IAC5B,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"BaseEventStore.d.ts","sourceRoot":"","sources":["../../../../src/stores/BaseEventStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGrD;;GAEG;AACH,MAAM,MAAM,aAAa,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;AAE/D;;GAEG;AACH,MAAM,MAAM,aAAa,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,8BAAsB,cAAc,CAAC,MAAM,CAAE,SAAQ,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IACtF,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,CAAM;IAChC,SAAS,CAAC,cAAc,EAAE,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAa;IACjE,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC;IAC5B,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,cAAc,CAA8B;gBAExC,OAAO,EAAE,qBAAqB;IAU1C;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,cAAc,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAEzD;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,aAAa,IAAI,IAAI;IAExC;;OAEG;IACH,QAAQ,CAAC,WAAW,IAAI,OAAO;IAM/B;;;OAGG;IACH,SAAS,CAAC,WAAW,IAAI,IAAI;IAO7B;;;OAGG;IACH,SAAS,CAAC,aAAa,IAAI,IAAI;IAW/B;;OAEG;IACH,SAAS,CAAC,uBAAuB,IAAI,MAAM;IAI3C;;;;;;OAMG;IACH,iBAAiB,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,MAAM,IAAI;IA8B9D;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,MAAM,IAAI;IASpD;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAWvC;;OAEG;IACH,SAAS,CAAC,oBAAoB,IAAI,IAAI;IAWtC;;OAEG;IACH,SAAS,IAAI,MAAM,EAAE;IAIrB;;OAEG;IACH,aAAa,IAAI,MAAM;IAIvB;;OAEG;IACH,WAAW,IAAI,IAAI;IAYnB;;;OAGG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAWzC;;;;;OAKG;IACH,cAAc,IAAI,IAAI;IAOtB;;;OAGG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI;IAKrC;;OAEG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAY/B;;OAEG;IACH,mBAAmB,IAAI;QACrB,cAAc,EAAE,MAAM,CAAC;QACvB,cAAc,EAAE,MAAM,CAAC;QACvB,KAAK,EAAE,MAAM,CAAC;KACf;CAOF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WindowControls.d.ts","sourceRoot":"","sources":["../../../../../src/ui/components/WindowControls.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"WindowControls.d.ts","sourceRoot":"","sources":["../../../../../src/ui/components/WindowControls.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAc/C;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,QAE3D;AAMD,UAAU,mBAAmB;IAC3B,+BAA+B;IAC/B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,sFAAsF;IACtF,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,2EAA2E;IAC3E,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AA+BD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,UAAU,EACV,YAAY,EACZ,IAAI,GACL,EAAE,mBAAmB,+BAqDrB"}
|
|
@@ -14,10 +14,11 @@
|
|
|
14
14
|
* Fallback chain:
|
|
15
15
|
* 1. expo-clipboard
|
|
16
16
|
* 2. @react-native-clipboard/clipboard
|
|
17
|
-
* 3.
|
|
17
|
+
* 3. Web clipboard API (navigator.clipboard)
|
|
18
|
+
* 4. Graceful failure
|
|
18
19
|
*/
|
|
19
20
|
export type ClipboardFunction = (text: string) => Promise<boolean>;
|
|
20
|
-
export declare const clipboardType: () => "expo" | "react-native" | null;
|
|
21
|
+
export declare const clipboardType: () => "expo" | "react-native" | "web" | null;
|
|
21
22
|
export declare const isClipboardAvailable: () => boolean;
|
|
22
23
|
export declare const clipboardFunction: ClipboardFunction;
|
|
23
24
|
//# sourceMappingURL=clipboard-impl.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clipboard-impl.d.ts","sourceRoot":"","sources":["../../../../src/clipboard/clipboard-impl.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"clipboard-impl.d.ts","sourceRoot":"","sources":["../../../../src/clipboard/clipboard-impl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAYH,MAAM,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAoEnE,eAAO,MAAM,aAAa,QAAO,MAAM,GAAG,cAAc,GAAG,KAAK,GAAG,IAElE,CAAC;AAEF,eAAO,MAAM,oBAAoB,QAAO,OASvC,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,iBAmB/B,CAAC"}
|
|
@@ -61,6 +61,8 @@ export declare abstract class BaseEventStore<TEvent> extends Subscribable<EventC
|
|
|
61
61
|
protected arrayListeners: Set<ArrayListener<TEvent>>;
|
|
62
62
|
protected maxEvents: number;
|
|
63
63
|
protected storeName: string;
|
|
64
|
+
private captureSuppressed;
|
|
65
|
+
private clearListeners;
|
|
64
66
|
constructor(options: BaseEventStoreOptions);
|
|
65
67
|
/**
|
|
66
68
|
* Start capturing events from the underlying source.
|
|
@@ -129,6 +131,23 @@ export declare abstract class BaseEventStore<TEvent> extends Subscribable<EventC
|
|
|
129
131
|
* Clear all events
|
|
130
132
|
*/
|
|
131
133
|
clearEvents(): void;
|
|
134
|
+
/**
|
|
135
|
+
* Listen for clearEvents() calls. Used in remote mirror mode to forward a
|
|
136
|
+
* clear performed in the dashboard UI to the synced device.
|
|
137
|
+
*/
|
|
138
|
+
onClear(listener: () => void): () => void;
|
|
139
|
+
/**
|
|
140
|
+
* Suppress the auto start/stop capture lifecycle. Use when this store acts
|
|
141
|
+
* as a mirror of a remote device's events (e.g. the desktop dashboard):
|
|
142
|
+
* events arrive via replaceEvents() and the local interceptors must never
|
|
143
|
+
* start — on the dashboard they would capture the dashboard's own traffic.
|
|
144
|
+
*/
|
|
145
|
+
disableCapture(): void;
|
|
146
|
+
/**
|
|
147
|
+
* Replace the entire event list and notify array listeners. Used in remote
|
|
148
|
+
* mirror mode where full snapshots arrive from a synced device.
|
|
149
|
+
*/
|
|
150
|
+
replaceEvents(events: TEvent[]): void;
|
|
132
151
|
/**
|
|
133
152
|
* Set maximum number of events to keep
|
|
134
153
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseEventStore.d.ts","sourceRoot":"","sources":["../../../../src/stores/BaseEventStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGrD;;GAEG;AACH,MAAM,MAAM,aAAa,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;AAE/D;;GAEG;AACH,MAAM,MAAM,aAAa,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,8BAAsB,cAAc,CAAC,MAAM,CAAE,SAAQ,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IACtF,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,CAAM;IAChC,SAAS,CAAC,cAAc,EAAE,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAa;IACjE,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC;IAC5B,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"BaseEventStore.d.ts","sourceRoot":"","sources":["../../../../src/stores/BaseEventStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGrD;;GAEG;AACH,MAAM,MAAM,aAAa,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;AAE/D;;GAEG;AACH,MAAM,MAAM,aAAa,CAAC,MAAM,IAAI,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;AAE5D;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,8BAAsB,cAAc,CAAC,MAAM,CAAE,SAAQ,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IACtF,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,CAAM;IAChC,SAAS,CAAC,cAAc,EAAE,GAAG,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAa;IACjE,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC;IAC5B,SAAS,CAAC,SAAS,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,cAAc,CAA8B;gBAExC,OAAO,EAAE,qBAAqB;IAU1C;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,cAAc,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAEzD;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,aAAa,IAAI,IAAI;IAExC;;OAEG;IACH,QAAQ,CAAC,WAAW,IAAI,OAAO;IAM/B;;;OAGG;IACH,SAAS,CAAC,WAAW,IAAI,IAAI;IAO7B;;;OAGG;IACH,SAAS,CAAC,aAAa,IAAI,IAAI;IAW/B;;OAEG;IACH,SAAS,CAAC,uBAAuB,IAAI,MAAM;IAI3C;;;;;;OAMG;IACH,iBAAiB,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,MAAM,IAAI;IA8B9D;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,MAAM,IAAI;IASpD;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAWvC;;OAEG;IACH,SAAS,CAAC,oBAAoB,IAAI,IAAI;IAWtC;;OAEG;IACH,SAAS,IAAI,MAAM,EAAE;IAIrB;;OAEG;IACH,aAAa,IAAI,MAAM;IAIvB;;OAEG;IACH,WAAW,IAAI,IAAI;IAYnB;;;OAGG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAWzC;;;;;OAKG;IACH,cAAc,IAAI,IAAI;IAOtB;;;OAGG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI;IAKrC;;OAEG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAY/B;;OAEG;IACH,mBAAmB,IAAI;QACrB,cAAc,EAAE,MAAM,CAAC;QACvB,cAAc,EAAE,MAAM,CAAC;QACvB,KAAK,EAAE,MAAM,CAAC;KACf;CAOF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WindowControls.d.ts","sourceRoot":"","sources":["../../../../../src/ui/components/WindowControls.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"WindowControls.d.ts","sourceRoot":"","sources":["../../../../../src/ui/components/WindowControls.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAc/C;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,QAE3D;AAMD,UAAU,mBAAmB;IAC3B,+BAA+B;IAC/B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,sFAAsF;IACtF,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,2EAA2E;IAC3E,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AA+BD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,UAAU,EACV,YAAY,EACZ,IAAI,GACL,EAAE,mBAAmB,+BAqDrB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@buoy-gg/shared-ui",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Shared UI components, hooks, and utilities",
|
|
5
5
|
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
@@ -115,10 +115,10 @@
|
|
|
115
115
|
],
|
|
116
116
|
"sideEffects": false,
|
|
117
117
|
"dependencies": {
|
|
118
|
-
"@buoy-gg/floating-tools-core": "
|
|
118
|
+
"@buoy-gg/floating-tools-core": "3.0.0"
|
|
119
119
|
},
|
|
120
120
|
"peerDependencies": {
|
|
121
|
-
"@buoy-gg/license": "
|
|
121
|
+
"@buoy-gg/license": "3.0.0",
|
|
122
122
|
"@react-native-clipboard/clipboard": "*",
|
|
123
123
|
"expo-clipboard": "*",
|
|
124
124
|
"expo-file-system": "*",
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
"expo-clipboard": "~7.1.5",
|
|
147
147
|
"react-native-safe-area-context": "^5.6.2",
|
|
148
148
|
"typescript": "~5.8.3",
|
|
149
|
-
"@buoy-gg/license": "
|
|
149
|
+
"@buoy-gg/license": "3.0.0"
|
|
150
150
|
},
|
|
151
151
|
"react-native-builder-bob": {
|
|
152
152
|
"source": "src",
|