@buoy-gg/core 1.7.7 → 2.1.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/floatingMenu/AppHost.js +3 -3
- package/lib/commonjs/floatingMenu/DevToolsSettingsModal.js +25 -13
- package/lib/commonjs/floatingMenu/DevToolsSettingsModal.web.js +746 -0
- package/lib/commonjs/floatingMenu/FloatingDevTools.js +16 -4
- package/lib/commonjs/floatingMenu/FloatingDevTools.web.js +153 -0
- package/lib/commonjs/floatingMenu/FloatingMenu.js +8 -8
- package/lib/commonjs/floatingMenu/MinimizedToolsContext.js +2 -2
- package/lib/commonjs/floatingMenu/autoDiscoverPresets.js +30 -0
- package/lib/commonjs/floatingMenu/defaultConfig.js +14 -7
- package/lib/commonjs/floatingMenu/dial/DialDevTools.js +12 -6
- package/lib/commonjs/floatingMenu/dial/DialDevTools.web.js +593 -0
- package/lib/commonjs/floatingMenu/floatingTools.js +218 -38
- package/lib/commonjs/floatingMenu/floatingTools.web.js +357 -0
- package/lib/commonjs/index.js +2 -2
- package/lib/commonjs/index.web.js +131 -0
- package/lib/commonjs/utils/autoDiscoverPresets.web.js +181 -0
- package/lib/module/floatingMenu/AppHost.js +4 -4
- package/lib/module/floatingMenu/DevToolsSettingsModal.js +28 -16
- package/lib/module/floatingMenu/DevToolsSettingsModal.web.js +756 -0
- package/lib/module/floatingMenu/FloatingDevTools.js +17 -5
- package/lib/module/floatingMenu/FloatingDevTools.web.js +149 -0
- package/lib/module/floatingMenu/FloatingMenu.js +9 -9
- package/lib/module/floatingMenu/MinimizedToolsContext.js +3 -3
- package/lib/module/floatingMenu/autoDiscoverPresets.js +30 -0
- package/lib/module/floatingMenu/defaultConfig.js +14 -7
- package/lib/module/floatingMenu/dial/DialDevTools.js +13 -7
- package/lib/module/floatingMenu/dial/DialDevTools.web.js +590 -0
- package/lib/module/floatingMenu/floatingTools.js +219 -39
- package/lib/module/floatingMenu/floatingTools.web.js +357 -0
- package/lib/module/index.js +2 -2
- package/lib/module/index.web.js +24 -0
- package/lib/module/utils/autoDiscoverPresets.web.js +174 -0
- package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.web.d.ts +23 -0
- package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.d.ts +1 -1
- package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.web.d.ts +48 -0
- package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/FloatingMenu.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/autoDiscoverPresets.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/defaultConfig.d.ts +8 -7
- 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/DialDevTools.web.d.ts +26 -0
- package/lib/typescript/commonjs/floatingMenu/dial/DialDevTools.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/floatingTools.d.ts +1 -1
- package/lib/typescript/commonjs/floatingMenu/floatingTools.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/floatingTools.web.d.ts +27 -0
- package/lib/typescript/commonjs/floatingMenu/floatingTools.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/index.web.d.ts +20 -0
- package/lib/typescript/commonjs/index.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/utils/autoDiscoverPresets.web.d.ts +58 -0
- package/lib/typescript/commonjs/utils/autoDiscoverPresets.web.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.web.d.ts +23 -0
- package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.web.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/FloatingDevTools.d.ts +1 -1
- package/lib/typescript/module/floatingMenu/FloatingDevTools.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/FloatingDevTools.web.d.ts +48 -0
- package/lib/typescript/module/floatingMenu/FloatingDevTools.web.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/FloatingMenu.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/autoDiscoverPresets.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/defaultConfig.d.ts +8 -7
- 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/DialDevTools.web.d.ts +26 -0
- package/lib/typescript/module/floatingMenu/dial/DialDevTools.web.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/floatingTools.d.ts +1 -1
- package/lib/typescript/module/floatingMenu/floatingTools.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/floatingTools.web.d.ts +27 -0
- package/lib/typescript/module/floatingMenu/floatingTools.web.d.ts.map +1 -0
- package/lib/typescript/module/index.web.d.ts +20 -0
- package/lib/typescript/module/index.web.d.ts.map +1 -0
- package/lib/typescript/module/utils/autoDiscoverPresets.web.d.ts +58 -0
- package/lib/typescript/module/utils/autoDiscoverPresets.web.d.ts.map +1 -0
- package/package.json +5 -4
|
@@ -11,7 +11,7 @@ import { HintsProvider } from "@buoy-gg/shared-ui";
|
|
|
11
11
|
import { MinimizedToolsProvider } from "./MinimizedToolsContext.js";
|
|
12
12
|
import { validateDialConfig } from "./defaultConfig.js";
|
|
13
13
|
import { DefaultConfigProvider } from "./DefaultConfigContext.js";
|
|
14
|
-
import { LicenseManager } from "@buoy-gg/license";
|
|
14
|
+
import { LicenseManager, useIsPro } from "@buoy-gg/license";
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Environment variable configuration
|
|
@@ -104,16 +104,20 @@ export const FloatingDevTools = ({
|
|
|
104
104
|
defaultDialTools,
|
|
105
105
|
...props
|
|
106
106
|
}) => {
|
|
107
|
+
// Check Pro status for production gating
|
|
108
|
+
const isPro = useIsPro();
|
|
109
|
+
|
|
107
110
|
// Initialize license manager on mount
|
|
108
111
|
useEffect(() => {
|
|
109
112
|
LicenseManager.initialize();
|
|
110
113
|
}, []);
|
|
111
114
|
|
|
112
|
-
//
|
|
113
|
-
|
|
115
|
+
// Normalize dial tools configuration (truncates to max 6 with warning if needed)
|
|
116
|
+
const normalizedDialTools = useMemo(() => {
|
|
114
117
|
if (defaultDialTools) {
|
|
115
|
-
validateDialConfig(defaultDialTools);
|
|
118
|
+
return validateDialConfig(defaultDialTools);
|
|
116
119
|
}
|
|
120
|
+
return defaultDialTools;
|
|
117
121
|
}, [defaultDialTools]);
|
|
118
122
|
|
|
119
123
|
// Build config overrides if requiredEnvVars or requiredStorageKeys are provided
|
|
@@ -214,9 +218,17 @@ export const FloatingDevTools = ({
|
|
|
214
218
|
}
|
|
215
219
|
return tool.icon;
|
|
216
220
|
}, [finalApps]);
|
|
221
|
+
|
|
222
|
+
// Gate: Free tier only works in development mode
|
|
223
|
+
// Pro users can use DevTools everywhere (dev + production)
|
|
224
|
+
const isDevelopment = typeof __DEV__ !== "undefined" && __DEV__;
|
|
225
|
+
if (!isDevelopment && !isPro) {
|
|
226
|
+
// Free user in production - don't render DevTools
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
217
229
|
return /*#__PURE__*/_jsx(DefaultConfigProvider, {
|
|
218
230
|
defaultFloatingTools: defaultFloatingTools,
|
|
219
|
-
defaultDialTools:
|
|
231
|
+
defaultDialTools: normalizedDialTools,
|
|
220
232
|
children: /*#__PURE__*/_jsx(HintsProvider, {
|
|
221
233
|
disableHints: disableHints,
|
|
222
234
|
children: /*#__PURE__*/_jsx(View, {
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* FloatingDevTools - Unified dev tools component for React DOM Web.
|
|
5
|
+
*
|
|
6
|
+
* Matches the mobile FloatingDevTools API exactly:
|
|
7
|
+
* - Self-contained (doesn't wrap your app)
|
|
8
|
+
* - Auto-discovers installed tool packages
|
|
9
|
+
* - Manages dial menu and settings modal state internally
|
|
10
|
+
*
|
|
11
|
+
* Usage (same as mobile):
|
|
12
|
+
* ```tsx
|
|
13
|
+
* <>
|
|
14
|
+
* <YourApp />
|
|
15
|
+
* <FloatingDevTools environment="qa" userRole="admin" />
|
|
16
|
+
* </>
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @platform React DOM Web (Vite, CRA, Next.js, Electron)
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { useState, useMemo, useCallback } from 'react';
|
|
23
|
+
import { useSettings, getToolLabel, getToolDescription, getToolColor } from '@buoy-gg/floating-tools-react';
|
|
24
|
+
import { autoDiscoverWithCustom, getToolsBySlot } from "../utils/autoDiscoverPresets.web.js";
|
|
25
|
+
import { FloatingTools, UserStatus } from "./floatingTools.web.js";
|
|
26
|
+
import { DialMenu } from "./dial/DialDevTools.web.js";
|
|
27
|
+
import { SettingsModal } from "./DevToolsSettingsModal.web.js";
|
|
28
|
+
|
|
29
|
+
// =============================
|
|
30
|
+
// Types
|
|
31
|
+
// =============================
|
|
32
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
33
|
+
// =============================
|
|
34
|
+
// Main Component
|
|
35
|
+
// =============================
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Unified FloatingDevTools component - self-contained, no wrapping required.
|
|
39
|
+
*
|
|
40
|
+
* Matches mobile API exactly:
|
|
41
|
+
* ```tsx
|
|
42
|
+
* // Mobile
|
|
43
|
+
* <FloatingDevTools environment="qa" userRole={userRole} />
|
|
44
|
+
*
|
|
45
|
+
* // Web (this component)
|
|
46
|
+
* <FloatingDevTools environment="qa" userRole="admin" />
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export function FloatingDevTools({
|
|
50
|
+
environment: _environment,
|
|
51
|
+
userRole,
|
|
52
|
+
availableEnvironments: _availableEnvironments,
|
|
53
|
+
onEnvironmentSwitch: _onEnvironmentSwitch,
|
|
54
|
+
apps,
|
|
55
|
+
disableHints: _disableHints
|
|
56
|
+
}) {
|
|
57
|
+
// Internal state for dial and settings
|
|
58
|
+
const [isDialOpen, setIsDialOpen] = useState(false);
|
|
59
|
+
const [isSettingsOpen, setIsSettingsOpen] = useState(false);
|
|
60
|
+
|
|
61
|
+
// Auto-discover tools and merge with custom apps
|
|
62
|
+
const tools = useMemo(() => autoDiscoverWithCustom(apps), [apps]);
|
|
63
|
+
|
|
64
|
+
// Convert to available tools config for settings
|
|
65
|
+
const availableToolsConfig = useMemo(() => tools.map(tool => ({
|
|
66
|
+
id: tool.id,
|
|
67
|
+
name: tool.name,
|
|
68
|
+
description: tool.description,
|
|
69
|
+
slot: tool.slot
|
|
70
|
+
})), [tools]);
|
|
71
|
+
|
|
72
|
+
// Use shared settings hook
|
|
73
|
+
const {
|
|
74
|
+
settings
|
|
75
|
+
} = useSettings({
|
|
76
|
+
availableTools: availableToolsConfig
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// Build dial icons from enabled dial tools
|
|
80
|
+
const dialIcons = useMemo(() => {
|
|
81
|
+
const dialTools = getToolsBySlot(tools, 'dial');
|
|
82
|
+
const enabledDialIds = Object.entries(settings.dialTools).filter(([_, enabled]) => enabled).map(([id]) => id);
|
|
83
|
+
return dialTools.filter(tool => enabledDialIds.includes(tool.id)).map(tool => {
|
|
84
|
+
const color = tool.color || getToolColor(tool.id);
|
|
85
|
+
// Handle icon - can be string (emoji) or function (size) => ReactNode
|
|
86
|
+
let icon;
|
|
87
|
+
if (typeof tool.icon === 'string') {
|
|
88
|
+
icon = tool.icon;
|
|
89
|
+
} else if (typeof tool.icon === 'function') {
|
|
90
|
+
// It's a render function - call it with size
|
|
91
|
+
icon = tool.icon(32);
|
|
92
|
+
} else {
|
|
93
|
+
icon = '🔧';
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
id: tool.id,
|
|
97
|
+
name: getToolLabel(tool.id),
|
|
98
|
+
icon,
|
|
99
|
+
color,
|
|
100
|
+
onPress: () => {
|
|
101
|
+
tool.onPress?.();
|
|
102
|
+
setIsDialOpen(false);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
});
|
|
106
|
+
}, [tools, settings.dialTools]);
|
|
107
|
+
|
|
108
|
+
// Build available tools for settings modal
|
|
109
|
+
const availableTools = useMemo(() => tools.map(tool => ({
|
|
110
|
+
id: tool.id,
|
|
111
|
+
name: tool.name || getToolLabel(tool.id),
|
|
112
|
+
description: tool.description || getToolDescription(tool.id),
|
|
113
|
+
slot: tool.slot
|
|
114
|
+
})), [tools]);
|
|
115
|
+
|
|
116
|
+
// Callbacks
|
|
117
|
+
const handleOpenDial = useCallback(() => setIsDialOpen(true), []);
|
|
118
|
+
const handleCloseDial = useCallback(() => setIsDialOpen(false), []);
|
|
119
|
+
const handleOpenSettings = useCallback(() => {
|
|
120
|
+
setIsDialOpen(false);
|
|
121
|
+
setIsSettingsOpen(true);
|
|
122
|
+
}, []);
|
|
123
|
+
const handleCloseSettings = useCallback(() => setIsSettingsOpen(false), []);
|
|
124
|
+
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
125
|
+
children: [/*#__PURE__*/_jsx(FloatingTools, {
|
|
126
|
+
enablePositionPersistence: true,
|
|
127
|
+
children: userRole && /*#__PURE__*/_jsx(UserStatus, {
|
|
128
|
+
userRole: userRole,
|
|
129
|
+
onPress: handleOpenDial
|
|
130
|
+
})
|
|
131
|
+
}), isDialOpen && /*#__PURE__*/_jsx(DialMenu, {
|
|
132
|
+
icons: dialIcons,
|
|
133
|
+
onClose: handleCloseDial,
|
|
134
|
+
centerLabel: "BUOY",
|
|
135
|
+
onCenterPress: handleOpenSettings
|
|
136
|
+
}), /*#__PURE__*/_jsx(SettingsModal, {
|
|
137
|
+
visible: isSettingsOpen,
|
|
138
|
+
onClose: handleCloseSettings,
|
|
139
|
+
availableTools: availableTools,
|
|
140
|
+
onSettingsChange: _newSettings => {
|
|
141
|
+
// Settings are already saved by the hook
|
|
142
|
+
}
|
|
143
|
+
})]
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// =============================
|
|
148
|
+
// Re-exports for convenience
|
|
149
|
+
// =============================
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
import React, { useEffect, useMemo, useRef, useState } from "react";
|
|
4
4
|
import { TouchableOpacity, StyleSheet, View, Dimensions } from "react-native";
|
|
5
|
-
import { FloatingTools, UserStatus } from "./floatingTools
|
|
6
|
-
import { DialDevTools } from "./dial/DialDevTools
|
|
7
|
-
import { EnvironmentIndicator,
|
|
8
|
-
import { useDevToolsSettings } from "./DevToolsSettingsModal
|
|
5
|
+
import { FloatingTools, UserStatus } from "./floatingTools";
|
|
6
|
+
import { DialDevTools } from "./dial/DialDevTools";
|
|
7
|
+
import { EnvironmentIndicator, persistentStorage, useHintsDisabled, devToolsStorageKeys, buoyColors } from "@buoy-gg/shared-ui";
|
|
8
|
+
import { useDevToolsSettings } from "./DevToolsSettingsModal";
|
|
9
9
|
import { useAppHost } from "./AppHost.js";
|
|
10
10
|
import { useDevToolsVisibility } from "./DevToolsVisibilityContext.js";
|
|
11
11
|
import { toggleStateManager } from "./ToggleStateManager.js";
|
|
@@ -48,7 +48,7 @@ export const FloatingMenu = ({
|
|
|
48
48
|
useEffect(() => {
|
|
49
49
|
const loadDialState = async () => {
|
|
50
50
|
try {
|
|
51
|
-
const savedDialOpen = await
|
|
51
|
+
const savedDialOpen = await persistentStorage.getItem(devToolsStorageKeys.dial.isOpen());
|
|
52
52
|
if (savedDialOpen === "true") {
|
|
53
53
|
setShowDial(true);
|
|
54
54
|
}
|
|
@@ -65,7 +65,7 @@ export const FloatingMenu = ({
|
|
|
65
65
|
useEffect(() => {
|
|
66
66
|
// Only persist after initial state is loaded to avoid overwriting with default
|
|
67
67
|
if (!dialStateLoaded) return;
|
|
68
|
-
|
|
68
|
+
persistentStorage.setItem(devToolsStorageKeys.dial.isOpen(), showDial ? "true" : "false").catch(error => {
|
|
69
69
|
// Failed to save dial state - continue without persistence
|
|
70
70
|
console.warn("Failed to save dial state:", error);
|
|
71
71
|
});
|
|
@@ -92,7 +92,7 @@ export const FloatingMenu = ({
|
|
|
92
92
|
}
|
|
93
93
|
const checkOnboarding = async () => {
|
|
94
94
|
try {
|
|
95
|
-
const hasSeenOnboarding = await
|
|
95
|
+
const hasSeenOnboarding = await persistentStorage.getItem(FLOATING_MENU_ONBOARDING_KEY);
|
|
96
96
|
if (!hasSeenOnboarding) {
|
|
97
97
|
// Small delay to let the UI settle before showing tooltip
|
|
98
98
|
setTimeout(() => {
|
|
@@ -159,7 +159,7 @@ export const FloatingMenu = ({
|
|
|
159
159
|
// Filter function for floating tools based on settings
|
|
160
160
|
const isFloatingEnabled = id => {
|
|
161
161
|
if (!devToolsSettings) return false;
|
|
162
|
-
//
|
|
162
|
+
// Floating tools require explicit opt-in (unlike dial tools which auto-enable)
|
|
163
163
|
return devToolsSettings.floatingTools[id] ?? false;
|
|
164
164
|
};
|
|
165
165
|
|
|
@@ -197,7 +197,7 @@ export const FloatingMenu = ({
|
|
|
197
197
|
setOnboardingStep(null);
|
|
198
198
|
|
|
199
199
|
// Save to storage asynchronously in the background
|
|
200
|
-
|
|
200
|
+
persistentStorage.setItem(FLOATING_MENU_ONBOARDING_KEY, "true").catch(error => {
|
|
201
201
|
// Silently fail - user already saw onboarding, just won't persist
|
|
202
202
|
console.warn("Failed to save onboarding state:", error);
|
|
203
203
|
});
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import React, { createContext, useContext, useState, useCallback, useEffect, useRef, useMemo } from "react";
|
|
4
4
|
import { Dimensions } from "react-native";
|
|
5
|
-
import {
|
|
5
|
+
import { persistentStorage, getSafeAreaInsets } from "@buoy-gg/shared-ui";
|
|
6
6
|
|
|
7
7
|
// ============================================================================
|
|
8
8
|
// Types
|
|
@@ -107,7 +107,7 @@ export function MinimizedToolsProvider({
|
|
|
107
107
|
useEffect(() => {
|
|
108
108
|
const restoreMinimizedTools = async () => {
|
|
109
109
|
try {
|
|
110
|
-
const saved = await
|
|
110
|
+
const saved = await persistentStorage.getItem(STORAGE_KEY);
|
|
111
111
|
if (saved) {
|
|
112
112
|
const serialized = JSON.parse(saved);
|
|
113
113
|
// Reconstruct tools with icons
|
|
@@ -137,7 +137,7 @@ export function MinimizedToolsProvider({
|
|
|
137
137
|
icon,
|
|
138
138
|
...rest
|
|
139
139
|
}) => rest);
|
|
140
|
-
|
|
140
|
+
persistentStorage.setItem(STORAGE_KEY, JSON.stringify(serialized));
|
|
141
141
|
}, PERSISTENCE_DELAY);
|
|
142
142
|
return () => {
|
|
143
143
|
if (persistenceTimeoutRef.current) {
|
|
@@ -174,6 +174,36 @@ export function autoDiscoverPresets() {
|
|
|
174
174
|
return null;
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
|
+
},
|
|
178
|
+
// Redux DevTools
|
|
179
|
+
{
|
|
180
|
+
name: "@buoy-gg/redux",
|
|
181
|
+
loader: () => {
|
|
182
|
+
try {
|
|
183
|
+
// @ts-ignore - Dynamic import that may not exist
|
|
184
|
+
const {
|
|
185
|
+
reduxToolPreset
|
|
186
|
+
} = require("@buoy-gg/redux");
|
|
187
|
+
return reduxToolPreset;
|
|
188
|
+
} catch {
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
// Events Timeline
|
|
194
|
+
{
|
|
195
|
+
name: "@buoy-gg/events",
|
|
196
|
+
loader: () => {
|
|
197
|
+
try {
|
|
198
|
+
// @ts-ignore - Dynamic import that may not exist
|
|
199
|
+
const {
|
|
200
|
+
eventsToolPreset
|
|
201
|
+
} = require("@buoy-gg/events");
|
|
202
|
+
return eventsToolPreset;
|
|
203
|
+
} catch {
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
177
207
|
}];
|
|
178
208
|
|
|
179
209
|
// Attempt to load each preset
|
|
@@ -66,27 +66,34 @@ export const MAX_DIAL_TOOLS = 6;
|
|
|
66
66
|
*/
|
|
67
67
|
|
|
68
68
|
/**
|
|
69
|
-
* Validates
|
|
70
|
-
*
|
|
69
|
+
* Validates and normalizes a dial configuration to not exceed the maximum allowed tools.
|
|
70
|
+
* If more than MAX_DIAL_TOOLS are provided, logs a warning and truncates to first 6 tools.
|
|
71
71
|
*
|
|
72
72
|
* @param tools - Array of dial tool IDs to validate
|
|
73
|
-
* @
|
|
73
|
+
* @returns The original array if valid, or truncated array if too many tools
|
|
74
74
|
*
|
|
75
75
|
* @example
|
|
76
76
|
* ```tsx
|
|
77
|
-
* // This is
|
|
77
|
+
* // This returns as-is
|
|
78
78
|
* validateDialConfig(['env', 'network', 'storage']);
|
|
79
|
+
* // Returns: ['env', 'network', 'storage']
|
|
79
80
|
*
|
|
80
|
-
* // This
|
|
81
|
+
* // This truncates and warns
|
|
81
82
|
* validateDialConfig(['env', 'network', 'storage', 'query', 'route-events', 'debug-borders', 'benchmark']);
|
|
82
|
-
* //
|
|
83
|
+
* // Console warning, returns: ['env', 'network', 'storage', 'query', 'route-events', 'debug-borders']
|
|
83
84
|
* ```
|
|
84
85
|
*/
|
|
85
86
|
export function validateDialConfig(tools) {
|
|
86
87
|
if (tools.length > MAX_DIAL_TOOLS) {
|
|
87
88
|
const toolList = tools.map(t => `"${t}"`).join(', ');
|
|
88
|
-
|
|
89
|
+
// console.warn(
|
|
90
|
+
// `[React Buoy] Dial menu configuration has ${tools.length} tools, but maximum is ${MAX_DIAL_TOOLS}. ` +
|
|
91
|
+
// `Tools provided: [${toolList}]. ` +
|
|
92
|
+
// `Only the first ${MAX_DIAL_TOOLS} tools will be shown.`
|
|
93
|
+
// );
|
|
94
|
+
return tools.slice(0, MAX_DIAL_TOOLS);
|
|
89
95
|
}
|
|
96
|
+
return tools;
|
|
90
97
|
}
|
|
91
98
|
|
|
92
99
|
/**
|
|
@@ -4,8 +4,8 @@ import { useEffect, useMemo, useRef, useState } from "react";
|
|
|
4
4
|
import { Pressable, StyleSheet, View, Dimensions, Text, Animated, Easing } from "react-native";
|
|
5
5
|
// Icons are provided by installedApps; no direct icon imports here.
|
|
6
6
|
import { DialIcon } from "./DialIcon.js";
|
|
7
|
-
import {
|
|
8
|
-
import { DevToolsSettingsModal, useDevToolsSettings } from "../DevToolsSettingsModal
|
|
7
|
+
import { persistentStorage, useHintsDisabled, devToolsStorageKeys, buoyColors } from "@buoy-gg/shared-ui";
|
|
8
|
+
import { DevToolsSettingsModal, useDevToolsSettings } from "../DevToolsSettingsModal";
|
|
9
9
|
import { useIsPro } from "@buoy-gg/license";
|
|
10
10
|
import { useAppHost } from "../AppHost.js";
|
|
11
11
|
import { OnboardingTooltip } from "./OnboardingTooltip.js";
|
|
@@ -55,7 +55,7 @@ export const DialDevTools = ({
|
|
|
55
55
|
useEffect(() => {
|
|
56
56
|
const loadSettingsModalState = async () => {
|
|
57
57
|
try {
|
|
58
|
-
const savedModalOpen = await
|
|
58
|
+
const savedModalOpen = await persistentStorage.getItem(devToolsStorageKeys.settings.modalOpen());
|
|
59
59
|
if (savedModalOpen === "true") {
|
|
60
60
|
setIsSettingsModalOpen(true);
|
|
61
61
|
}
|
|
@@ -72,7 +72,7 @@ export const DialDevTools = ({
|
|
|
72
72
|
useEffect(() => {
|
|
73
73
|
// Only persist after initial state is loaded to avoid overwriting with default
|
|
74
74
|
if (!settingsModalStateLoaded) return;
|
|
75
|
-
|
|
75
|
+
persistentStorage.setItem(devToolsStorageKeys.settings.modalOpen(), isSettingsModalOpen ? "true" : "false").catch(error => {
|
|
76
76
|
// Failed to save settings modal state - continue without persistence
|
|
77
77
|
console.warn("Failed to save settings modal state:", error);
|
|
78
78
|
});
|
|
@@ -107,7 +107,7 @@ export const DialDevTools = ({
|
|
|
107
107
|
}
|
|
108
108
|
const checkOnboarding = async () => {
|
|
109
109
|
try {
|
|
110
|
-
const hasSeenTooltip = await
|
|
110
|
+
const hasSeenTooltip = await persistentStorage.getItem(ONBOARDING_STORAGE_KEY);
|
|
111
111
|
if (!hasSeenTooltip) {
|
|
112
112
|
// Small delay to let the entrance animations play first
|
|
113
113
|
setTimeout(() => {
|
|
@@ -153,8 +153,14 @@ export const DialDevTools = ({
|
|
|
153
153
|
|
|
154
154
|
// Map data-driven apps to dial icons, inserting empty slots for disabled items
|
|
155
155
|
const dialApps = apps.filter(a => (a.slot ?? "both") !== "row");
|
|
156
|
+
|
|
157
|
+
// Check if settings are "virgin" (user hasn't customized dial tools yet)
|
|
158
|
+
// If no explicit settings exist, auto-enable all dial tools by default
|
|
159
|
+
const dialToolsKeys = settings?.dialTools ? Object.keys(settings.dialTools) : [];
|
|
160
|
+
const hasDialSettings = dialToolsKeys.length > 0;
|
|
156
161
|
const isDialEnabled = id => {
|
|
157
|
-
|
|
162
|
+
// No settings or empty dialTools = auto-enable all dial tools by default
|
|
163
|
+
if (!settings?.dialTools || !hasDialSettings) return true;
|
|
158
164
|
return settings.dialTools[id] ?? false;
|
|
159
165
|
};
|
|
160
166
|
const createEmptySlot = slotIndex => ({
|
|
@@ -400,7 +406,7 @@ export const DialDevTools = ({
|
|
|
400
406
|
setShowOnboardingTooltip(false);
|
|
401
407
|
|
|
402
408
|
// Save to storage asynchronously in the background
|
|
403
|
-
|
|
409
|
+
persistentStorage.setItem(ONBOARDING_STORAGE_KEY, "true").catch(error => {
|
|
404
410
|
// Silently fail - user already saw onboarding, just won't persist
|
|
405
411
|
console.warn("Failed to save dial onboarding state:", error);
|
|
406
412
|
});
|