@buoy-gg/core 3.0.1 → 3.0.2
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/floatingMenu/DevToolsSettingsModal.js +1 -1
- package/lib/commonjs/floatingMenu/FloatingDevTools.js +6 -1
- package/lib/commonjs/floatingMenu/FloatingMenu.js +3 -7
- package/lib/commonjs/floatingMenu/autoExternalSync.js +215 -0
- package/lib/commonjs/floatingMenu/defaultConfig.js +1 -1
- package/lib/commonjs/floatingMenu/dial/DialDevTools.js +59 -47
- package/lib/commonjs/floatingMenu/dial/DialIcon.js +12 -13
- package/lib/commonjs/floatingMenu/dial/OnboardingTooltip.js +1 -1
- package/lib/module/floatingMenu/DevToolsSettingsModal.js +2 -2
- package/lib/module/floatingMenu/FloatingDevTools.js +6 -1
- package/lib/module/floatingMenu/FloatingMenu.js +4 -7
- package/lib/module/floatingMenu/autoExternalSync.js +209 -0
- package/lib/module/floatingMenu/defaultConfig.js +1 -1
- package/lib/module/floatingMenu/dial/DialDevTools.js +62 -48
- package/lib/module/floatingMenu/dial/DialIcon.js +15 -15
- package/lib/module/floatingMenu/dial/OnboardingTooltip.js +2 -1
- package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.d.ts +19 -1
- package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/FloatingMenu.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/autoExternalSync.d.ts +21 -0
- package/lib/typescript/commonjs/floatingMenu/autoExternalSync.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/defaultConfig.d.ts +1 -1
- package/lib/typescript/commonjs/floatingMenu/defaultConfig.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/dial/DialDevTools.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/dial/DialIcon.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/dial/OnboardingTooltip.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +1 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/FloatingDevTools.d.ts +19 -1
- package/lib/typescript/module/floatingMenu/FloatingDevTools.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/FloatingMenu.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/autoExternalSync.d.ts +21 -0
- package/lib/typescript/module/floatingMenu/autoExternalSync.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/defaultConfig.d.ts +1 -1
- package/lib/typescript/module/floatingMenu/defaultConfig.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/dial/DialDevTools.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/dial/DialIcon.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/dial/OnboardingTooltip.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +1 -0
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/package.json +5 -5
|
@@ -808,7 +808,7 @@ const DevToolsSettingsModal = ({
|
|
|
808
808
|
children: clearSuccess ? "CLEARED" : isClearing ? "CLEARING..." : "CLEAR ALL SETTINGS"
|
|
809
809
|
})]
|
|
810
810
|
})]
|
|
811
|
-
}), renderGlobalSettingCard("enableSharedModalDimensions", "SHARED MODAL SIZE", "MODAL", "Sync dimensions across all tools", "When enabled, all tool modals will share the same size and position. Resizing one modal will affect all others. When disabled, each tool remembers its own size and position independently.", "Keep OFF for the best experience. This allows you to customize each tool's modal size separately. Enable only if you prefer uniform modal sizes across all dev tools."), renderGlobalSettingCard("expandableWindowControls", "EXPAND CONTROLS", "MODAL", "iPad-style expandable window buttons", "When enabled, the window control buttons (minimize, toggle mode, close) start as small dots and expand into larger, easy-to-tap buttons when pressed — similar to iPad window controls. When disabled, buttons are directly tappable at their small size.", "Keep ON for touch devices where the small buttons are hard to press. Turn OFF if you prefer direct single-tap access (e.g. when using a mouse or simulator)."), isDevelopmentMode && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
811
|
+
}), renderGlobalSettingCard("enableSharedModalDimensions", "SHARED MODAL SIZE", "MODAL", "Sync dimensions across all tools", "When enabled, all tool modals will share the same size and position. Resizing one modal will affect all others. When disabled, each tool remembers its own size and position independently.", "Keep OFF for the best experience. This allows you to customize each tool's modal size separately. Enable only if you prefer uniform modal sizes across all dev tools."), _reactNative.Platform.OS !== "web" && renderGlobalSettingCard("expandableWindowControls", "EXPAND CONTROLS", "MODAL", "iPad-style expandable window buttons", "When enabled, the window control buttons (minimize, toggle mode, close) start as small dots and expand into larger, easy-to-tap buttons when pressed — similar to iPad window controls. When disabled, buttons are directly tappable at their small size.", "Keep ON for touch devices where the small buttons are hard to press. Turn OFF if you prefer direct single-tap access (e.g. when using a mouse or simulator)."), isDevelopmentMode && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
812
812
|
style: styles.exportConfigCard,
|
|
813
813
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
814
814
|
activeOpacity: 0.85,
|
|
@@ -15,6 +15,7 @@ var _MinimizedToolsContext = require("./MinimizedToolsContext.js");
|
|
|
15
15
|
var _defaultConfig = require("./defaultConfig.js");
|
|
16
16
|
var _DefaultConfigContext = require("./DefaultConfigContext.js");
|
|
17
17
|
var _license = require("@buoy-gg/license");
|
|
18
|
+
var _autoExternalSync = require("./autoExternalSync.js");
|
|
18
19
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
19
20
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
20
21
|
/**
|
|
@@ -113,6 +114,7 @@ const FloatingDevTools = ({
|
|
|
113
114
|
licenseKey: licenseKeyProp,
|
|
114
115
|
zustandStores,
|
|
115
116
|
environment,
|
|
117
|
+
externalSync = true,
|
|
116
118
|
...props
|
|
117
119
|
}) => {
|
|
118
120
|
const resolvedEnvironment = environment ?? (0, _sharedUi.normalizeEnvironment)(process.env.NODE_ENV ?? "dev");
|
|
@@ -342,7 +344,10 @@ const FloatingDevTools = ({
|
|
|
342
344
|
environment: resolvedEnvironment
|
|
343
345
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_AppHost.AppOverlay, {})]
|
|
344
346
|
})
|
|
345
|
-
}), children, DebugBordersOverlay && /*#__PURE__*/(0, _jsxRuntime.jsx)(DebugBordersOverlay, {}), HighlightUpdatesOverlay && /*#__PURE__*/(0, _jsxRuntime.jsx)(HighlightUpdatesOverlay, {}), ImageOverlayOverlay && /*#__PURE__*/(0, _jsxRuntime.jsx)(ImageOverlayOverlay, {}), PerfMonitorOverlay && /*#__PURE__*/(0, _jsxRuntime.jsx)(PerfMonitorOverlay, {}), ImpersonateOverlay && /*#__PURE__*/(0, _jsxRuntime.jsx)(ImpersonateOverlay, {}), RouteTracker && /*#__PURE__*/(0, _jsxRuntime.jsx)(RouteTracker, {})
|
|
347
|
+
}), children, DebugBordersOverlay && /*#__PURE__*/(0, _jsxRuntime.jsx)(DebugBordersOverlay, {}), HighlightUpdatesOverlay && /*#__PURE__*/(0, _jsxRuntime.jsx)(HighlightUpdatesOverlay, {}), ImageOverlayOverlay && /*#__PURE__*/(0, _jsxRuntime.jsx)(ImageOverlayOverlay, {}), PerfMonitorOverlay && /*#__PURE__*/(0, _jsxRuntime.jsx)(PerfMonitorOverlay, {}), ImpersonateOverlay && /*#__PURE__*/(0, _jsxRuntime.jsx)(ImpersonateOverlay, {}), RouteTracker && /*#__PURE__*/(0, _jsxRuntime.jsx)(RouteTracker, {}), isDevelopment && externalSync !== false && (0, _autoExternalSync.isExternalSyncAvailable)() && /*#__PURE__*/(0, _jsxRuntime.jsx)(_autoExternalSync.AutoExternalSync, {
|
|
348
|
+
options: typeof externalSync === "object" ? externalSync : undefined,
|
|
349
|
+
requiredEnvVars: requiredEnvVars
|
|
350
|
+
})]
|
|
346
351
|
})
|
|
347
352
|
})
|
|
348
353
|
})
|
|
@@ -6,9 +6,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.FloatingMenu = void 0;
|
|
7
7
|
var _react = _interopRequireWildcard(require("react"));
|
|
8
8
|
var _reactNative = require("react-native");
|
|
9
|
+
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
9
10
|
var _floatingTools = require("./floatingTools");
|
|
10
11
|
var _DialDevTools = require("./dial/DialDevTools");
|
|
11
|
-
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
12
12
|
var _DevToolsSettingsModal = require("./DevToolsSettingsModal");
|
|
13
13
|
var _AppHost = require("./AppHost.js");
|
|
14
14
|
var _DevToolsVisibilityContext = require("./DevToolsVisibilityContext.js");
|
|
@@ -27,10 +27,6 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
|
|
|
27
27
|
*/
|
|
28
28
|
const FLOATING_MENU_ONBOARDING_KEY = "@react_buoy_floating_menu_tooltip_shown";
|
|
29
29
|
const ONBOARDING_STEP_KEY = "@react_buoy_onboarding_step";
|
|
30
|
-
const {
|
|
31
|
-
width: SCREEN_WIDTH,
|
|
32
|
-
height: SCREEN_HEIGHT
|
|
33
|
-
} = _reactNative.Dimensions.get("window");
|
|
34
30
|
const FloatingMenu = ({
|
|
35
31
|
apps,
|
|
36
32
|
state,
|
|
@@ -328,11 +324,11 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
328
324
|
fontWeight: "900"
|
|
329
325
|
},
|
|
330
326
|
onboardingContainer: {
|
|
331
|
-
...
|
|
327
|
+
..._sharedUi.absoluteFill,
|
|
332
328
|
zIndex: 10000
|
|
333
329
|
},
|
|
334
330
|
onboardingBackdrop: {
|
|
335
|
-
...
|
|
331
|
+
..._sharedUi.absoluteFill,
|
|
336
332
|
backgroundColor: "rgba(0, 0, 0, 0.85)"
|
|
337
333
|
}
|
|
338
334
|
});
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.AutoExternalSync = AutoExternalSync;
|
|
7
|
+
exports.isExternalSyncAvailable = isExternalSyncAvailable;
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
var _reactNative = require("react-native");
|
|
10
|
+
/**
|
|
11
|
+
* Zero-config device→desktop sync for FloatingDevTools.
|
|
12
|
+
*
|
|
13
|
+
* When @buoy-gg/external-sync is installed, FloatingDevTools renders
|
|
14
|
+
* <AutoExternalSync /> in dev builds: it connects to the Buoy Desktop broker
|
|
15
|
+
* (localhost:42831 — a silent no-op when the desktop app isn't running) and
|
|
16
|
+
* registers a sync adapter for every installed tool package, discovered with
|
|
17
|
+
* the same guarded-require pattern as autoDiscoverPresets. No <DevToolsSync>
|
|
18
|
+
* wiring needed in the app.
|
|
19
|
+
*
|
|
20
|
+
* Identity defaults come from expo-constants when available (app name →
|
|
21
|
+
* "MyApp (ios)" / "myapp-ios"), overridable via the `externalSync` prop.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
25
|
+
|
|
26
|
+
// Module-level guarded requires: presence is constant for the app lifetime,
|
|
27
|
+
// so hooks pulled from these modules keep a stable call order.
|
|
28
|
+
//
|
|
29
|
+
// IMPORTANT: each require() must sit LEXICALLY inside its own try block
|
|
30
|
+
// (same pattern as autoDiscoverPresets) — Metro only marks a dependency as
|
|
31
|
+
// optional when the require is directly inside a try statement. Wrapping it
|
|
32
|
+
// in a helper/arrow makes Metro hard-fail the bundle for apps that don't
|
|
33
|
+
// install that package.
|
|
34
|
+
let externalSyncModule = null;
|
|
35
|
+
let storageModule = null;
|
|
36
|
+
let networkModule = null;
|
|
37
|
+
let reactQueryModule = null;
|
|
38
|
+
let routeEventsModule = null;
|
|
39
|
+
let reduxModule = null;
|
|
40
|
+
let zustandModule = null;
|
|
41
|
+
let jotaiModule = null;
|
|
42
|
+
let eventsModule = null;
|
|
43
|
+
let envModule = null;
|
|
44
|
+
let highlightUpdatesModule = null;
|
|
45
|
+
let debugBordersModule = null;
|
|
46
|
+
let impersonateModule = null;
|
|
47
|
+
let perfMonitorModule = null;
|
|
48
|
+
let expoConstantsModule = null;
|
|
49
|
+
try {
|
|
50
|
+
externalSyncModule = require("@buoy-gg/external-sync");
|
|
51
|
+
} catch {
|
|
52
|
+
// not installed
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
storageModule = require("@buoy-gg/storage");
|
|
56
|
+
} catch {
|
|
57
|
+
// not installed
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
networkModule = require("@buoy-gg/network");
|
|
61
|
+
} catch {
|
|
62
|
+
// not installed
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
reactQueryModule = require("@buoy-gg/react-query");
|
|
66
|
+
} catch {
|
|
67
|
+
// not installed
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
routeEventsModule = require("@buoy-gg/route-events");
|
|
71
|
+
} catch {
|
|
72
|
+
// not installed
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
reduxModule = require("@buoy-gg/redux");
|
|
76
|
+
} catch {
|
|
77
|
+
// not installed
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
zustandModule = require("@buoy-gg/zustand");
|
|
81
|
+
} catch {
|
|
82
|
+
// not installed
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
jotaiModule = require("@buoy-gg/jotai");
|
|
86
|
+
} catch {
|
|
87
|
+
// not installed
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
eventsModule = require("@buoy-gg/events");
|
|
91
|
+
} catch {
|
|
92
|
+
// not installed
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
envModule = require("@buoy-gg/env");
|
|
96
|
+
} catch {
|
|
97
|
+
// not installed
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
highlightUpdatesModule = require("@buoy-gg/highlight-updates");
|
|
101
|
+
} catch {
|
|
102
|
+
// not installed
|
|
103
|
+
}
|
|
104
|
+
try {
|
|
105
|
+
debugBordersModule = require("@buoy-gg/debug-borders");
|
|
106
|
+
} catch {
|
|
107
|
+
// not installed
|
|
108
|
+
}
|
|
109
|
+
try {
|
|
110
|
+
impersonateModule = require("@buoy-gg/impersonate");
|
|
111
|
+
} catch {
|
|
112
|
+
// not installed
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
perfMonitorModule = require("@buoy-gg/perf-monitor");
|
|
116
|
+
} catch {
|
|
117
|
+
// not installed
|
|
118
|
+
}
|
|
119
|
+
try {
|
|
120
|
+
expoConstantsModule = require("expo-constants");
|
|
121
|
+
} catch {
|
|
122
|
+
// not installed (RN CLI apps)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** Whether zero-config sync can run (the external-sync package is installed). */
|
|
126
|
+
function isExternalSyncAvailable() {
|
|
127
|
+
return !!externalSyncModule?.useExternalSyncSocket;
|
|
128
|
+
}
|
|
129
|
+
function getAppName() {
|
|
130
|
+
const constants = expoConstantsModule?.default ?? expoConstantsModule;
|
|
131
|
+
return constants?.expoConfig?.name ?? constants?.manifest2?.extra?.expoClient?.name ?? null;
|
|
132
|
+
}
|
|
133
|
+
function defaultIdentity() {
|
|
134
|
+
const appName = getAppName();
|
|
135
|
+
const slug = (appName ?? "buoy").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
|
|
136
|
+
return {
|
|
137
|
+
deviceName: `${appName ?? "Buoy Device"} (${_reactNative.Platform.OS})`,
|
|
138
|
+
deviceId: `${slug || "buoy"}-${_reactNative.Platform.OS}`
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
function AutoExternalSync({
|
|
142
|
+
options,
|
|
143
|
+
requiredEnvVars
|
|
144
|
+
}) {
|
|
145
|
+
const {
|
|
146
|
+
useExternalSyncSocket,
|
|
147
|
+
useExternalSync
|
|
148
|
+
} = externalSyncModule;
|
|
149
|
+
|
|
150
|
+
// Context-based query adapter; null when there is no QueryClientProvider
|
|
151
|
+
// above FloatingDevTools (or the installed @buoy-gg/react-query predates
|
|
152
|
+
// the hook).
|
|
153
|
+
const queryAdapter = reactQueryModule?.useReactQuerySyncAdapter ? reactQueryModule.useReactQuerySyncAdapter() : null;
|
|
154
|
+
const identity = (0, _react.useMemo)(defaultIdentity, []);
|
|
155
|
+
const deviceId = options?.deviceId ?? identity.deviceId;
|
|
156
|
+
const {
|
|
157
|
+
socket
|
|
158
|
+
} = useExternalSyncSocket({
|
|
159
|
+
deviceName: options?.deviceName ?? identity.deviceName,
|
|
160
|
+
socketURL: options?.socketURL ?? "http://localhost:42831",
|
|
161
|
+
persistentDeviceId: deviceId,
|
|
162
|
+
platform: _reactNative.Platform.OS,
|
|
163
|
+
enableLogs: options?.enableLogs
|
|
164
|
+
});
|
|
165
|
+
const tools = (0, _react.useMemo)(() => {
|
|
166
|
+
const map = {};
|
|
167
|
+
if (storageModule?.storageSyncAdapter) {
|
|
168
|
+
map.storage = storageModule.storageSyncAdapter;
|
|
169
|
+
}
|
|
170
|
+
if (networkModule?.networkSyncAdapter) {
|
|
171
|
+
map.network = networkModule.networkSyncAdapter;
|
|
172
|
+
}
|
|
173
|
+
if (queryAdapter) {
|
|
174
|
+
map.query = queryAdapter;
|
|
175
|
+
}
|
|
176
|
+
if (routeEventsModule?.routeEventsSyncAdapter) {
|
|
177
|
+
map["route-events"] = routeEventsModule.routeEventsSyncAdapter;
|
|
178
|
+
}
|
|
179
|
+
if (reduxModule?.reduxSyncAdapter) {
|
|
180
|
+
map.redux = reduxModule.reduxSyncAdapter;
|
|
181
|
+
}
|
|
182
|
+
if (zustandModule?.zustandSyncAdapter) {
|
|
183
|
+
map.zustand = zustandModule.zustandSyncAdapter;
|
|
184
|
+
}
|
|
185
|
+
if (jotaiModule?.jotaiSyncAdapter) {
|
|
186
|
+
map.jotai = jotaiModule.jotaiSyncAdapter;
|
|
187
|
+
}
|
|
188
|
+
if (eventsModule?.eventsSyncAdapter) {
|
|
189
|
+
map.events = eventsModule.eventsSyncAdapter;
|
|
190
|
+
}
|
|
191
|
+
if (envModule?.createEnvSyncAdapter) {
|
|
192
|
+
map.env = envModule.createEnvSyncAdapter(requiredEnvVars ?? []);
|
|
193
|
+
}
|
|
194
|
+
if (highlightUpdatesModule?.highlightUpdatesSyncAdapter) {
|
|
195
|
+
map["highlight-updates"] = highlightUpdatesModule.highlightUpdatesSyncAdapter;
|
|
196
|
+
}
|
|
197
|
+
if (debugBordersModule?.debugBordersSyncAdapter) {
|
|
198
|
+
map["debug-borders"] = debugBordersModule.debugBordersSyncAdapter;
|
|
199
|
+
}
|
|
200
|
+
if (impersonateModule?.impersonateSyncAdapter) {
|
|
201
|
+
map.impersonate = impersonateModule.impersonateSyncAdapter;
|
|
202
|
+
}
|
|
203
|
+
if (perfMonitorModule?.perfMonitorSyncAdapter) {
|
|
204
|
+
map["perf-monitor"] = perfMonitorModule.perfMonitorSyncAdapter;
|
|
205
|
+
}
|
|
206
|
+
return map;
|
|
207
|
+
}, [queryAdapter, requiredEnvVars]);
|
|
208
|
+
useExternalSync({
|
|
209
|
+
tools,
|
|
210
|
+
socket,
|
|
211
|
+
deviceId,
|
|
212
|
+
enableLogs: options?.enableLogs
|
|
213
|
+
});
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
@@ -32,7 +32,7 @@ exports.validateDialConfig = validateDialConfig;
|
|
|
32
32
|
* This is a union type of all auto-discovered tool IDs.
|
|
33
33
|
*/
|
|
34
34
|
|
|
35
|
-
//
|
|
35
|
+
// Benchmark recording modal (@buoy-gg/perf-monitor)
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
38
|
* Special floating-only tool IDs that only appear in the floating bubble row.
|
|
@@ -6,10 +6,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.DialDevTools = void 0;
|
|
7
7
|
var _react = require("react");
|
|
8
8
|
var _reactNative = require("react-native");
|
|
9
|
+
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
9
10
|
var _DialIcon = require("./DialIcon.js");
|
|
10
11
|
var _DialPagination = require("./DialPagination.js");
|
|
11
12
|
var _dialUsageStore = require("./dialUsageStore.js");
|
|
12
|
-
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
13
13
|
var _DevToolsSettingsModal = require("../DevToolsSettingsModal");
|
|
14
14
|
var _license = require("@buoy-gg/license");
|
|
15
15
|
var _AppHost = require("../AppHost.js");
|
|
@@ -18,17 +18,10 @@ var _floatingToolsCore = require("@buoy-gg/floating-tools-core");
|
|
|
18
18
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
19
19
|
// Icons are provided by installedApps; no direct icon imports here.
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
// Use shared layout calculation from core
|
|
27
|
-
const layout = (0, _floatingToolsCore.getDialLayout)({
|
|
28
|
-
screenWidth: SCREEN_WIDTH
|
|
29
|
-
});
|
|
30
|
-
const CIRCLE_SIZE = layout.circleSize;
|
|
31
|
-
const BUTTON_SIZE = layout.buttonSize;
|
|
21
|
+
// The circle size depends on the live window width, so it's computed inside
|
|
22
|
+
// the component via useWindowDimensions — a module-scope Dimensions.get
|
|
23
|
+
// snapshot goes stale when the window resizes after load (web/desktop).
|
|
24
|
+
const BUTTON_SIZE = _floatingToolsCore.DIAL_BUTTON_SIZE;
|
|
32
25
|
const ONBOARDING_STORAGE_KEY = "@react_buoy_settings_tooltip_shown";
|
|
33
26
|
/** A non-interactive placeholder used to fill out the last dial page. */
|
|
34
27
|
const createEmptySlot = slotIndex => ({
|
|
@@ -60,6 +53,33 @@ const DialDevTools = ({
|
|
|
60
53
|
} = (0, _AppHost.useAppHost)();
|
|
61
54
|
const isPro = (0, _license.useIsPro)();
|
|
62
55
|
|
|
56
|
+
// Live window size — keeps the dial centered and sized correctly when the
|
|
57
|
+
// window resizes (Electron/web) or the device rotates.
|
|
58
|
+
const {
|
|
59
|
+
width: screenWidth,
|
|
60
|
+
height: screenHeight
|
|
61
|
+
} = (0, _reactNative.useWindowDimensions)();
|
|
62
|
+
const circleSize = (0, _floatingToolsCore.getDialLayout)({
|
|
63
|
+
screenWidth
|
|
64
|
+
}).circleSize;
|
|
65
|
+
const sizeStyles = (0, _react.useMemo)(() => ({
|
|
66
|
+
parent: {
|
|
67
|
+
width: circleSize,
|
|
68
|
+
height: circleSize
|
|
69
|
+
},
|
|
70
|
+
circle: {
|
|
71
|
+
width: circleSize,
|
|
72
|
+
height: circleSize,
|
|
73
|
+
borderRadius: circleSize / 2
|
|
74
|
+
},
|
|
75
|
+
rounded: {
|
|
76
|
+
borderRadius: circleSize / 2
|
|
77
|
+
},
|
|
78
|
+
gridLine: {
|
|
79
|
+
width: circleSize
|
|
80
|
+
}
|
|
81
|
+
}), [circleSize]);
|
|
82
|
+
|
|
63
83
|
// Load persisted settings modal state on mount
|
|
64
84
|
(0, _react.useEffect)(() => {
|
|
65
85
|
const loadSettingsModalState = async () => {
|
|
@@ -485,13 +505,13 @@ const DialDevTools = ({
|
|
|
485
505
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
|
|
486
506
|
style: [styles.backdrop, backdropAnimatedStyle],
|
|
487
507
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
|
|
488
|
-
style:
|
|
508
|
+
style: _sharedUi.absoluteFill,
|
|
489
509
|
onPress: handleClose
|
|
490
510
|
})
|
|
491
511
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, {
|
|
492
|
-
style: [styles.parent, {
|
|
512
|
+
style: [styles.parent, sizeStyles.parent, {
|
|
493
513
|
position: "absolute",
|
|
494
|
-
left: (
|
|
514
|
+
left: (screenWidth - circleSize) / 2,
|
|
495
515
|
bottom: 80,
|
|
496
516
|
transform: [{
|
|
497
517
|
scale: dialScale
|
|
@@ -503,21 +523,21 @@ const DialDevTools = ({
|
|
|
503
523
|
}]
|
|
504
524
|
}],
|
|
505
525
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, {
|
|
506
|
-
style: styles.circle,
|
|
526
|
+
style: [styles.circle, sizeStyles.circle],
|
|
507
527
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
508
|
-
style: styles.gradientBackground,
|
|
528
|
+
style: [styles.gradientBackground, sizeStyles.rounded],
|
|
509
529
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
510
|
-
style: styles.gradientLayer1
|
|
530
|
+
style: [styles.gradientLayer1, sizeStyles.rounded]
|
|
511
531
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
512
|
-
style: styles.gradientLayer2
|
|
532
|
+
style: [styles.gradientLayer2, sizeStyles.rounded]
|
|
513
533
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
514
|
-
style: styles.gradientLayer3
|
|
534
|
+
style: [styles.gradientLayer3, sizeStyles.rounded]
|
|
515
535
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
516
536
|
style: styles.gridPattern,
|
|
517
537
|
children: Array.from({
|
|
518
538
|
length: 6
|
|
519
539
|
}).map((_, i) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
520
|
-
style: [styles.gridLine, {
|
|
540
|
+
style: [styles.gridLine, sizeStyles.gridLine, {
|
|
521
541
|
transform: [{
|
|
522
542
|
rotate: `${i * 60}deg`
|
|
523
543
|
}]
|
|
@@ -608,11 +628,11 @@ const DialDevTools = ({
|
|
|
608
628
|
onNext: () => handlePageChange(safePage + 1),
|
|
609
629
|
animatedStyle: {
|
|
610
630
|
position: "absolute",
|
|
611
|
-
left: (
|
|
612
|
-
// Circle's bottom edge sits at bottom: 80 ->
|
|
631
|
+
left: (screenWidth - circleSize) / 2,
|
|
632
|
+
// Circle's bottom edge sits at bottom: 80 -> screenHeight - 80
|
|
613
633
|
// from the top. Place the pager 16px below that edge.
|
|
614
|
-
top:
|
|
615
|
-
width:
|
|
634
|
+
top: screenHeight - 80 + 16,
|
|
635
|
+
width: circleSize,
|
|
616
636
|
opacity: dialScale,
|
|
617
637
|
transform: [{
|
|
618
638
|
scale: dialScale
|
|
@@ -634,23 +654,20 @@ const DialDevTools = ({
|
|
|
634
654
|
exports.DialDevTools = DialDevTools;
|
|
635
655
|
const styles = _reactNative.StyleSheet.create({
|
|
636
656
|
container: {
|
|
637
|
-
...
|
|
657
|
+
..._sharedUi.absoluteFill,
|
|
638
658
|
zIndex: 9999
|
|
639
659
|
},
|
|
640
660
|
backdrop: {
|
|
641
|
-
...
|
|
661
|
+
..._sharedUi.absoluteFill,
|
|
642
662
|
backgroundColor: _floatingToolsCore.dialColors.dialBackdrop
|
|
643
663
|
},
|
|
664
|
+
// width/height/borderRadius for the circle pieces come from sizeStyles —
|
|
665
|
+
// they track the live window width.
|
|
644
666
|
parent: {
|
|
645
|
-
width: CIRCLE_SIZE,
|
|
646
|
-
height: CIRCLE_SIZE,
|
|
647
667
|
alignItems: "center",
|
|
648
668
|
justifyContent: "center"
|
|
649
669
|
},
|
|
650
670
|
circle: {
|
|
651
|
-
width: CIRCLE_SIZE,
|
|
652
|
-
height: CIRCLE_SIZE,
|
|
653
|
-
borderRadius: CIRCLE_SIZE / 2,
|
|
654
671
|
position: "absolute",
|
|
655
672
|
backgroundColor: "transparent",
|
|
656
673
|
borderWidth: 1,
|
|
@@ -667,41 +684,36 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
667
684
|
gradientBackground: {
|
|
668
685
|
width: "100%",
|
|
669
686
|
height: "100%",
|
|
670
|
-
borderRadius: CIRCLE_SIZE / 2,
|
|
671
687
|
position: "relative",
|
|
672
688
|
backgroundColor: _floatingToolsCore.dialColors.dialBackground,
|
|
673
689
|
overflow: "hidden"
|
|
674
690
|
},
|
|
675
691
|
gradientLayer1: {
|
|
676
|
-
...
|
|
692
|
+
..._sharedUi.absoluteFill,
|
|
677
693
|
backgroundColor: _floatingToolsCore.dialColors.dialGradient1,
|
|
678
|
-
opacity: 0.6
|
|
679
|
-
borderRadius: CIRCLE_SIZE / 2
|
|
694
|
+
opacity: 0.6
|
|
680
695
|
},
|
|
681
696
|
gradientLayer2: {
|
|
682
|
-
...
|
|
697
|
+
..._sharedUi.absoluteFill,
|
|
683
698
|
backgroundColor: _floatingToolsCore.dialColors.dialGradient2,
|
|
684
699
|
opacity: 0.4,
|
|
685
700
|
top: "30%",
|
|
686
|
-
left: "30%"
|
|
687
|
-
borderRadius: CIRCLE_SIZE / 2
|
|
701
|
+
left: "30%"
|
|
688
702
|
},
|
|
689
703
|
gradientLayer3: {
|
|
690
|
-
...
|
|
704
|
+
..._sharedUi.absoluteFill,
|
|
691
705
|
backgroundColor: _floatingToolsCore.dialColors.dialGradient3,
|
|
692
706
|
opacity: 0.3,
|
|
693
707
|
top: "50%",
|
|
694
|
-
left: "50%"
|
|
695
|
-
borderRadius: CIRCLE_SIZE / 2
|
|
708
|
+
left: "50%"
|
|
696
709
|
},
|
|
697
710
|
gridPattern: {
|
|
698
|
-
...
|
|
711
|
+
..._sharedUi.absoluteFill,
|
|
699
712
|
alignItems: "center",
|
|
700
713
|
justifyContent: "center"
|
|
701
714
|
},
|
|
702
715
|
gridLine: {
|
|
703
716
|
position: "absolute",
|
|
704
|
-
width: CIRCLE_SIZE,
|
|
705
717
|
height: 1,
|
|
706
718
|
backgroundColor: _floatingToolsCore.dialColors.dialGridLine
|
|
707
719
|
},
|
|
@@ -727,13 +739,13 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
727
739
|
overflow: "hidden"
|
|
728
740
|
},
|
|
729
741
|
buttonGradientLayer1: {
|
|
730
|
-
...
|
|
742
|
+
..._sharedUi.absoluteFill,
|
|
731
743
|
backgroundColor: _floatingToolsCore.dialColors.dialGradient1,
|
|
732
744
|
opacity: 0.5,
|
|
733
745
|
borderRadius: BUTTON_SIZE
|
|
734
746
|
},
|
|
735
747
|
buttonGradientLayer2: {
|
|
736
|
-
...
|
|
748
|
+
..._sharedUi.absoluteFill,
|
|
737
749
|
backgroundColor: _floatingToolsCore.dialColors.dialGradient2,
|
|
738
750
|
opacity: 0.3,
|
|
739
751
|
top: "20%",
|
|
@@ -741,7 +753,7 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
741
753
|
borderRadius: BUTTON_SIZE
|
|
742
754
|
},
|
|
743
755
|
buttonGradientLayer3: {
|
|
744
|
-
...
|
|
756
|
+
..._sharedUi.absoluteFill,
|
|
745
757
|
backgroundColor: _floatingToolsCore.dialColors.dialGradient3,
|
|
746
758
|
opacity: 0.2,
|
|
747
759
|
top: "40%",
|
|
@@ -8,16 +8,9 @@ var _react = require("react");
|
|
|
8
8
|
var _reactNative = require("react-native");
|
|
9
9
|
var _floatingToolsCore = require("@buoy-gg/floating-tools-core");
|
|
10
10
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
// Use shared layout calculation
|
|
16
|
-
const layout = (0, _floatingToolsCore.getDialLayout)({
|
|
17
|
-
screenWidth: SCREEN_WIDTH
|
|
18
|
-
});
|
|
19
|
-
const VIEW_SIZE = layout.iconSize;
|
|
20
|
-
const CIRCLE_RADIUS = layout.circleRadius;
|
|
11
|
+
// The circle radius depends on the live window width and is computed inside
|
|
12
|
+
// the component (must match DialDevTools' circle, which does the same).
|
|
13
|
+
const VIEW_SIZE = _floatingToolsCore.DIAL_ICON_SIZE;
|
|
21
14
|
const DialIcon = ({
|
|
22
15
|
index,
|
|
23
16
|
icon,
|
|
@@ -28,6 +21,12 @@ const DialIcon = ({
|
|
|
28
21
|
}) => {
|
|
29
22
|
// Animation values - using interpolation for better performance
|
|
30
23
|
const scale = (0, _react.useRef)(new _reactNative.Animated.Value(1)).current;
|
|
24
|
+
const {
|
|
25
|
+
width: screenWidth
|
|
26
|
+
} = (0, _reactNative.useWindowDimensions)();
|
|
27
|
+
const layout = (0, _react.useMemo)(() => (0, _floatingToolsCore.getDialLayout)({
|
|
28
|
+
screenWidth
|
|
29
|
+
}), [screenWidth]);
|
|
31
30
|
|
|
32
31
|
// Hover animation on press in/out - using shared config
|
|
33
32
|
// Fallback values in case dialAnimationConfig hasn't loaded yet
|
|
@@ -123,14 +122,14 @@ const DialIcon = ({
|
|
|
123
122
|
itemOpacity,
|
|
124
123
|
progressScale: staggeredProgress
|
|
125
124
|
};
|
|
126
|
-
}, [index, totalIcons, iconsProgress]);
|
|
125
|
+
}, [index, totalIcons, iconsProgress, layout]);
|
|
127
126
|
|
|
128
127
|
// Main animated style for position and appearance
|
|
129
128
|
const animatedStyle = {
|
|
130
129
|
position: "absolute",
|
|
131
|
-
left:
|
|
130
|
+
left: layout.circleRadius - VIEW_SIZE / 2,
|
|
132
131
|
// Center position
|
|
133
|
-
top:
|
|
132
|
+
top: layout.circleRadius - VIEW_SIZE / 2,
|
|
134
133
|
// Center position
|
|
135
134
|
opacity: motion.itemOpacity,
|
|
136
135
|
transform: [{
|
|
@@ -133,7 +133,7 @@ const OnboardingTooltip = ({
|
|
|
133
133
|
exports.OnboardingTooltip = OnboardingTooltip;
|
|
134
134
|
const styles = _reactNative.StyleSheet.create({
|
|
135
135
|
container: {
|
|
136
|
-
...
|
|
136
|
+
..._sharedUi.absoluteFill,
|
|
137
137
|
alignItems: "center",
|
|
138
138
|
justifyContent: "center",
|
|
139
139
|
pointerEvents: "box-none"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import { useState, useEffect, useCallback, useMemo } from "react";
|
|
4
|
-
import { View, Text, StyleSheet, ScrollView, TouchableOpacity, Dimensions } from "react-native";
|
|
4
|
+
import { View, Text, StyleSheet, ScrollView, TouchableOpacity, Dimensions, Platform } from "react-native";
|
|
5
5
|
import { settingsBus } from "./settingsBus.js";
|
|
6
6
|
import { SentryBugIcon, WifiCircuitIcon, ImageOverlayIcon, RenderCountIcon, Info, Layers, ChevronRightIcon, ChevronDown, getStorageBackendType, persistentStorage, Database, Trash2, CheckCircle2, AlertTriangle, Zap, FileText, HardDrive, Copy, FileCode, copyToClipboard, LicenseEntryModal, SectionHeader } from "@buoy-gg/shared-ui";
|
|
7
7
|
import { EnvIcon, StorageIcon, RoutesIcon, NetworkIcon, QueryIcon, HighlighterIcon, ReduxIcon, EventsIcon } from "@buoy-gg/floating-tools-core";
|
|
@@ -809,7 +809,7 @@ export const DevToolsSettingsModal = ({
|
|
|
809
809
|
children: clearSuccess ? "CLEARED" : isClearing ? "CLEARING..." : "CLEAR ALL SETTINGS"
|
|
810
810
|
})]
|
|
811
811
|
})]
|
|
812
|
-
}), renderGlobalSettingCard("enableSharedModalDimensions", "SHARED MODAL SIZE", "MODAL", "Sync dimensions across all tools", "When enabled, all tool modals will share the same size and position. Resizing one modal will affect all others. When disabled, each tool remembers its own size and position independently.", "Keep OFF for the best experience. This allows you to customize each tool's modal size separately. Enable only if you prefer uniform modal sizes across all dev tools."), renderGlobalSettingCard("expandableWindowControls", "EXPAND CONTROLS", "MODAL", "iPad-style expandable window buttons", "When enabled, the window control buttons (minimize, toggle mode, close) start as small dots and expand into larger, easy-to-tap buttons when pressed — similar to iPad window controls. When disabled, buttons are directly tappable at their small size.", "Keep ON for touch devices where the small buttons are hard to press. Turn OFF if you prefer direct single-tap access (e.g. when using a mouse or simulator)."), isDevelopmentMode && /*#__PURE__*/_jsxs(View, {
|
|
812
|
+
}), renderGlobalSettingCard("enableSharedModalDimensions", "SHARED MODAL SIZE", "MODAL", "Sync dimensions across all tools", "When enabled, all tool modals will share the same size and position. Resizing one modal will affect all others. When disabled, each tool remembers its own size and position independently.", "Keep OFF for the best experience. This allows you to customize each tool's modal size separately. Enable only if you prefer uniform modal sizes across all dev tools."), Platform.OS !== "web" && renderGlobalSettingCard("expandableWindowControls", "EXPAND CONTROLS", "MODAL", "iPad-style expandable window buttons", "When enabled, the window control buttons (minimize, toggle mode, close) start as small dots and expand into larger, easy-to-tap buttons when pressed — similar to iPad window controls. When disabled, buttons are directly tappable at their small size.", "Keep ON for touch devices where the small buttons are hard to press. Turn OFF if you prefer direct single-tap access (e.g. when using a mouse or simulator)."), isDevelopmentMode && /*#__PURE__*/_jsxs(View, {
|
|
813
813
|
style: styles.exportConfigCard,
|
|
814
814
|
children: [/*#__PURE__*/_jsxs(TouchableOpacity, {
|
|
815
815
|
activeOpacity: 0.85,
|
|
@@ -12,6 +12,7 @@ import { MinimizedToolsProvider } from "./MinimizedToolsContext.js";
|
|
|
12
12
|
import { validateDialConfig } from "./defaultConfig.js";
|
|
13
13
|
import { DefaultConfigProvider } from "./DefaultConfigContext.js";
|
|
14
14
|
import { LicenseManager, useIsPro, useLicense } from "@buoy-gg/license";
|
|
15
|
+
import { AutoExternalSync, isExternalSyncAvailable } from "./autoExternalSync.js";
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Environment variable configuration
|
|
@@ -109,6 +110,7 @@ export const FloatingDevTools = ({
|
|
|
109
110
|
licenseKey: licenseKeyProp,
|
|
110
111
|
zustandStores,
|
|
111
112
|
environment,
|
|
113
|
+
externalSync = true,
|
|
112
114
|
...props
|
|
113
115
|
}) => {
|
|
114
116
|
const resolvedEnvironment = environment ?? normalizeEnvironment(process.env.NODE_ENV ?? "dev");
|
|
@@ -338,7 +340,10 @@ export const FloatingDevTools = ({
|
|
|
338
340
|
environment: resolvedEnvironment
|
|
339
341
|
}), /*#__PURE__*/_jsx(AppOverlay, {})]
|
|
340
342
|
})
|
|
341
|
-
}), children, DebugBordersOverlay && /*#__PURE__*/_jsx(DebugBordersOverlay, {}), HighlightUpdatesOverlay && /*#__PURE__*/_jsx(HighlightUpdatesOverlay, {}), ImageOverlayOverlay && /*#__PURE__*/_jsx(ImageOverlayOverlay, {}), PerfMonitorOverlay && /*#__PURE__*/_jsx(PerfMonitorOverlay, {}), ImpersonateOverlay && /*#__PURE__*/_jsx(ImpersonateOverlay, {}), RouteTracker && /*#__PURE__*/_jsx(RouteTracker, {})
|
|
343
|
+
}), children, DebugBordersOverlay && /*#__PURE__*/_jsx(DebugBordersOverlay, {}), HighlightUpdatesOverlay && /*#__PURE__*/_jsx(HighlightUpdatesOverlay, {}), ImageOverlayOverlay && /*#__PURE__*/_jsx(ImageOverlayOverlay, {}), PerfMonitorOverlay && /*#__PURE__*/_jsx(PerfMonitorOverlay, {}), ImpersonateOverlay && /*#__PURE__*/_jsx(ImpersonateOverlay, {}), RouteTracker && /*#__PURE__*/_jsx(RouteTracker, {}), isDevelopment && externalSync !== false && isExternalSyncAvailable() && /*#__PURE__*/_jsx(AutoExternalSync, {
|
|
344
|
+
options: typeof externalSync === "object" ? externalSync : undefined,
|
|
345
|
+
requiredEnvVars: requiredEnvVars
|
|
346
|
+
})]
|
|
342
347
|
})
|
|
343
348
|
})
|
|
344
349
|
})
|