@buoy-gg/core 1.7.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/README.md +43 -0
- package/lib/commonjs/floatingMenu/AppHost.js +410 -0
- package/lib/commonjs/floatingMenu/AppHostLogic.js +44 -0
- package/lib/commonjs/floatingMenu/DefaultConfigContext.js +45 -0
- package/lib/commonjs/floatingMenu/DevToolsSettingsModal.js +2274 -0
- package/lib/commonjs/floatingMenu/DevToolsVisibilityContext.js +49 -0
- package/lib/commonjs/floatingMenu/DraggableHeader.js +114 -0
- package/lib/commonjs/floatingMenu/FloatingDevTools.js +254 -0
- package/lib/commonjs/floatingMenu/FloatingMenu.js +364 -0
- package/lib/commonjs/floatingMenu/MinimizedToolsContext.js +247 -0
- package/lib/commonjs/floatingMenu/MinimizedToolsStack.js +206 -0
- package/lib/commonjs/floatingMenu/ToggleStateManager.js +36 -0
- package/lib/commonjs/floatingMenu/autoDiscoverPresets.js +241 -0
- package/lib/commonjs/floatingMenu/defaultConfig.js +160 -0
- package/lib/commonjs/floatingMenu/dial/DialDevTools.js +835 -0
- package/lib/commonjs/floatingMenu/dial/DialIcon.js +246 -0
- package/lib/commonjs/floatingMenu/dial/OnboardingTooltip.js +249 -0
- package/lib/commonjs/floatingMenu/dial/onboardingConstants.js +70 -0
- package/lib/commonjs/floatingMenu/floatingTools.js +771 -0
- package/lib/commonjs/floatingMenu/settingsBus.js +23 -0
- package/lib/commonjs/floatingMenu/types.js +5 -0
- package/lib/commonjs/index.js +240 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/module/floatingMenu/AppHost.js +402 -0
- package/lib/module/floatingMenu/AppHostLogic.js +39 -0
- package/lib/module/floatingMenu/DefaultConfigContext.js +39 -0
- package/lib/module/floatingMenu/DevToolsSettingsModal.js +2273 -0
- package/lib/module/floatingMenu/DevToolsVisibilityContext.js +44 -0
- package/lib/module/floatingMenu/DraggableHeader.js +110 -0
- package/lib/module/floatingMenu/FloatingDevTools.js +249 -0
- package/lib/module/floatingMenu/FloatingMenu.js +358 -0
- package/lib/module/floatingMenu/MinimizedToolsContext.js +239 -0
- package/lib/module/floatingMenu/MinimizedToolsStack.js +202 -0
- package/lib/module/floatingMenu/ToggleStateManager.js +32 -0
- package/lib/module/floatingMenu/autoDiscoverPresets.js +236 -0
- package/lib/module/floatingMenu/defaultConfig.js +151 -0
- package/lib/module/floatingMenu/dial/DialDevTools.js +829 -0
- package/lib/module/floatingMenu/dial/DialIcon.js +241 -0
- package/lib/module/floatingMenu/dial/OnboardingTooltip.js +244 -0
- package/lib/module/floatingMenu/dial/onboardingConstants.js +64 -0
- package/lib/module/floatingMenu/floatingTools.js +767 -0
- package/lib/module/floatingMenu/settingsBus.js +19 -0
- package/lib/module/floatingMenu/types.js +3 -0
- package/lib/module/index.js +29 -0
- package/lib/module/package.json +1 -0
- package/lib/typescript/commonjs/floatingMenu/AppHost.d.ts +39 -0
- package/lib/typescript/commonjs/floatingMenu/AppHost.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/AppHostLogic.d.ts +37 -0
- package/lib/typescript/commonjs/floatingMenu/AppHostLogic.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/DefaultConfigContext.d.ts +27 -0
- package/lib/typescript/commonjs/floatingMenu/DefaultConfigContext.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.d.ts +57 -0
- package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/DevToolsVisibilityContext.d.ts +25 -0
- package/lib/typescript/commonjs/floatingMenu/DevToolsVisibilityContext.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/DraggableHeader.d.ts +30 -0
- package/lib/typescript/commonjs/floatingMenu/DraggableHeader.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.d.ts +226 -0
- package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/FloatingMenu.d.ts +39 -0
- package/lib/typescript/commonjs/floatingMenu/FloatingMenu.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/MinimizedToolsContext.d.ts +95 -0
- package/lib/typescript/commonjs/floatingMenu/MinimizedToolsContext.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/MinimizedToolsStack.d.ts +10 -0
- package/lib/typescript/commonjs/floatingMenu/MinimizedToolsStack.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/ToggleStateManager.d.ts +21 -0
- package/lib/typescript/commonjs/floatingMenu/ToggleStateManager.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/autoDiscoverPresets.d.ts +75 -0
- package/lib/typescript/commonjs/floatingMenu/autoDiscoverPresets.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/defaultConfig.d.ts +120 -0
- package/lib/typescript/commonjs/floatingMenu/defaultConfig.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/dial/DialDevTools.d.ts +35 -0
- package/lib/typescript/commonjs/floatingMenu/dial/DialDevTools.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/dial/DialIcon.d.ts +14 -0
- package/lib/typescript/commonjs/floatingMenu/dial/DialIcon.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/dial/OnboardingTooltip.d.ts +12 -0
- package/lib/typescript/commonjs/floatingMenu/dial/OnboardingTooltip.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/dial/onboardingConstants.d.ts +30 -0
- package/lib/typescript/commonjs/floatingMenu/dial/onboardingConstants.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/floatingTools.d.ts +56 -0
- package/lib/typescript/commonjs/floatingMenu/floatingTools.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/settingsBus.d.ts +10 -0
- package/lib/typescript/commonjs/floatingMenu/settingsBus.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/types.d.ts +56 -0
- package/lib/typescript/commonjs/floatingMenu/types.d.ts.map +1 -0
- package/lib/typescript/commonjs/index.d.ts +18 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/module/floatingMenu/AppHost.d.ts +39 -0
- package/lib/typescript/module/floatingMenu/AppHost.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/AppHostLogic.d.ts +37 -0
- package/lib/typescript/module/floatingMenu/AppHostLogic.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/DefaultConfigContext.d.ts +27 -0
- package/lib/typescript/module/floatingMenu/DefaultConfigContext.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.d.ts +57 -0
- package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/DevToolsVisibilityContext.d.ts +25 -0
- package/lib/typescript/module/floatingMenu/DevToolsVisibilityContext.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/DraggableHeader.d.ts +30 -0
- package/lib/typescript/module/floatingMenu/DraggableHeader.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/FloatingDevTools.d.ts +226 -0
- package/lib/typescript/module/floatingMenu/FloatingDevTools.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/FloatingMenu.d.ts +39 -0
- package/lib/typescript/module/floatingMenu/FloatingMenu.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/MinimizedToolsContext.d.ts +95 -0
- package/lib/typescript/module/floatingMenu/MinimizedToolsContext.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/MinimizedToolsStack.d.ts +10 -0
- package/lib/typescript/module/floatingMenu/MinimizedToolsStack.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/ToggleStateManager.d.ts +21 -0
- package/lib/typescript/module/floatingMenu/ToggleStateManager.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/autoDiscoverPresets.d.ts +75 -0
- package/lib/typescript/module/floatingMenu/autoDiscoverPresets.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/defaultConfig.d.ts +120 -0
- package/lib/typescript/module/floatingMenu/defaultConfig.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/dial/DialDevTools.d.ts +35 -0
- package/lib/typescript/module/floatingMenu/dial/DialDevTools.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/dial/DialIcon.d.ts +14 -0
- package/lib/typescript/module/floatingMenu/dial/DialIcon.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/dial/OnboardingTooltip.d.ts +12 -0
- package/lib/typescript/module/floatingMenu/dial/OnboardingTooltip.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/dial/onboardingConstants.d.ts +30 -0
- package/lib/typescript/module/floatingMenu/dial/onboardingConstants.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/floatingTools.d.ts +56 -0
- package/lib/typescript/module/floatingMenu/floatingTools.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/settingsBus.d.ts +10 -0
- package/lib/typescript/module/floatingMenu/settingsBus.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/types.d.ts +56 -0
- package/lib/typescript/module/floatingMenu/types.d.ts.map +1 -0
- package/lib/typescript/module/index.d.ts +18 -0
- package/lib/typescript/module/index.d.ts.map +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1,835 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.DialDevTools = void 0;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
var _DialIcon = require("./DialIcon.js");
|
|
10
|
+
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
11
|
+
var _DevToolsSettingsModal = require("../DevToolsSettingsModal.js");
|
|
12
|
+
var _license = require("@buoy-gg/license");
|
|
13
|
+
var _AppHost = require("../AppHost.js");
|
|
14
|
+
var _OnboardingTooltip = require("./OnboardingTooltip.js");
|
|
15
|
+
var _floatingToolsCore = require("@buoy-gg/floating-tools-core");
|
|
16
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
17
|
+
// Icons are provided by installedApps; no direct icon imports here.
|
|
18
|
+
|
|
19
|
+
const {
|
|
20
|
+
width: SCREEN_WIDTH
|
|
21
|
+
} = _reactNative.Dimensions.get("window");
|
|
22
|
+
|
|
23
|
+
// Use shared layout calculation from core
|
|
24
|
+
const layout = (0, _floatingToolsCore.getDialLayout)({
|
|
25
|
+
screenWidth: SCREEN_WIDTH
|
|
26
|
+
});
|
|
27
|
+
const CIRCLE_SIZE = layout.circleSize;
|
|
28
|
+
const BUTTON_SIZE = layout.buttonSize;
|
|
29
|
+
const ONBOARDING_STORAGE_KEY = "@react_buoy_settings_tooltip_shown";
|
|
30
|
+
const DialDevTools = ({
|
|
31
|
+
onClose,
|
|
32
|
+
onSettingsPress,
|
|
33
|
+
settings: externalSettings,
|
|
34
|
+
autoOpenSettings = false,
|
|
35
|
+
apps,
|
|
36
|
+
state,
|
|
37
|
+
actions
|
|
38
|
+
}) => {
|
|
39
|
+
const [selectedIcon, setSelectedIcon] = (0, _react.useState)(-1);
|
|
40
|
+
const [isSettingsModalOpen, setIsSettingsModalOpen] = (0, _react.useState)(false);
|
|
41
|
+
const [settingsModalStateLoaded, setSettingsModalStateLoaded] = (0, _react.useState)(false);
|
|
42
|
+
const [showOnboardingTooltip, setShowOnboardingTooltip] = (0, _react.useState)(false);
|
|
43
|
+
const onboardingDismissedRef = (0, _react.useRef)(false); // Track if onboarding was dismissed
|
|
44
|
+
const hintsDisabled = (0, _sharedUi.useHintsDisabled)();
|
|
45
|
+
const {
|
|
46
|
+
settings: hookSettings,
|
|
47
|
+
refreshSettings
|
|
48
|
+
} = (0, _DevToolsSettingsModal.useDevToolsSettings)();
|
|
49
|
+
const {
|
|
50
|
+
open
|
|
51
|
+
} = (0, _AppHost.useAppHost)();
|
|
52
|
+
const isPro = (0, _license.useIsPro)();
|
|
53
|
+
// Initialize with external settings if provided, otherwise use hook settings
|
|
54
|
+
const [localSettings, setLocalSettings] = (0, _react.useState)(externalSettings || hookSettings);
|
|
55
|
+
|
|
56
|
+
// Always use localSettings (which can be updated by the modal)
|
|
57
|
+
const settings = localSettings;
|
|
58
|
+
|
|
59
|
+
// Load persisted settings modal state on mount
|
|
60
|
+
(0, _react.useEffect)(() => {
|
|
61
|
+
const loadSettingsModalState = async () => {
|
|
62
|
+
try {
|
|
63
|
+
const savedModalOpen = await (0, _sharedUi.safeGetItem)(_sharedUi.devToolsStorageKeys.settings.modalOpen());
|
|
64
|
+
if (savedModalOpen === "true") {
|
|
65
|
+
setIsSettingsModalOpen(true);
|
|
66
|
+
}
|
|
67
|
+
} catch (error) {
|
|
68
|
+
// Failed to load settings modal state - use default (closed)
|
|
69
|
+
} finally {
|
|
70
|
+
setSettingsModalStateLoaded(true);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
loadSettingsModalState();
|
|
74
|
+
}, []);
|
|
75
|
+
|
|
76
|
+
// Persist settings modal state when it changes
|
|
77
|
+
(0, _react.useEffect)(() => {
|
|
78
|
+
// Only persist after initial state is loaded to avoid overwriting with default
|
|
79
|
+
if (!settingsModalStateLoaded) return;
|
|
80
|
+
(0, _sharedUi.safeSetItem)(_sharedUi.devToolsStorageKeys.settings.modalOpen(), isSettingsModalOpen ? "true" : "false").catch(error => {
|
|
81
|
+
// Failed to save settings modal state - continue without persistence
|
|
82
|
+
console.warn("Failed to save settings modal state:", error);
|
|
83
|
+
});
|
|
84
|
+
}, [isSettingsModalOpen, settingsModalStateLoaded]);
|
|
85
|
+
|
|
86
|
+
// Update local settings when external settings change
|
|
87
|
+
(0, _react.useEffect)(() => {
|
|
88
|
+
if (externalSettings) {
|
|
89
|
+
setLocalSettings(externalSettings);
|
|
90
|
+
}
|
|
91
|
+
}, [externalSettings]);
|
|
92
|
+
|
|
93
|
+
// Update local settings when hook settings change (if no external settings)
|
|
94
|
+
(0, _react.useEffect)(() => {
|
|
95
|
+
if (!externalSettings) {
|
|
96
|
+
setLocalSettings(hookSettings);
|
|
97
|
+
}
|
|
98
|
+
}, [hookSettings, externalSettings]);
|
|
99
|
+
|
|
100
|
+
// Auto-open settings modal when prop is true
|
|
101
|
+
(0, _react.useEffect)(() => {
|
|
102
|
+
if (autoOpenSettings && !isSettingsModalOpen) {
|
|
103
|
+
setIsSettingsModalOpen(true);
|
|
104
|
+
}
|
|
105
|
+
}, [autoOpenSettings, isSettingsModalOpen]);
|
|
106
|
+
|
|
107
|
+
// Check if we should show the onboarding tooltip
|
|
108
|
+
(0, _react.useEffect)(() => {
|
|
109
|
+
// Skip onboarding if hints are disabled
|
|
110
|
+
if (hintsDisabled) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const checkOnboarding = async () => {
|
|
114
|
+
try {
|
|
115
|
+
const hasSeenTooltip = await (0, _sharedUi.safeGetItem)(ONBOARDING_STORAGE_KEY);
|
|
116
|
+
if (!hasSeenTooltip) {
|
|
117
|
+
// Small delay to let the entrance animations play first
|
|
118
|
+
setTimeout(() => {
|
|
119
|
+
setShowOnboardingTooltip(true);
|
|
120
|
+
}, 1200);
|
|
121
|
+
}
|
|
122
|
+
} catch (error) {
|
|
123
|
+
// If there's an error reading storage, don't show the tooltip
|
|
124
|
+
// to avoid annoying the user repeatedly
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
checkOnboarding();
|
|
128
|
+
}, [hintsDisabled]);
|
|
129
|
+
|
|
130
|
+
// React Native Animated values
|
|
131
|
+
const backdropOpacity = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
|
|
132
|
+
const dialScale = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
|
|
133
|
+
const dialRotation = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
|
|
134
|
+
const centerButtonScale = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
|
|
135
|
+
const iconsProgress = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
|
|
136
|
+
const glitchOffset = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
|
|
137
|
+
const pulseScale = (0, _react.useRef)(new _reactNative.Animated.Value(1)).current;
|
|
138
|
+
const availableApps = (0, _react.useMemo)(() => apps.map(({
|
|
139
|
+
id,
|
|
140
|
+
name,
|
|
141
|
+
slot,
|
|
142
|
+
description
|
|
143
|
+
}) => ({
|
|
144
|
+
id,
|
|
145
|
+
name,
|
|
146
|
+
slot,
|
|
147
|
+
description
|
|
148
|
+
})), [apps]);
|
|
149
|
+
|
|
150
|
+
// Subtle animations
|
|
151
|
+
const floatingAnim = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
|
|
152
|
+
const breathingScale = (0, _react.useRef)(new _reactNative.Animated.Value(1)).current;
|
|
153
|
+
const circuitOpacity = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
|
|
154
|
+
|
|
155
|
+
// Animation tracking refs
|
|
156
|
+
const glitchIntervalRef = (0, _react.useRef)(null);
|
|
157
|
+
const pulseAnimationRef = (0, _react.useRef)(null);
|
|
158
|
+
|
|
159
|
+
// Map data-driven apps to dial icons, inserting empty slots for disabled items
|
|
160
|
+
const dialApps = apps.filter(a => (a.slot ?? "both") !== "row");
|
|
161
|
+
const isDialEnabled = id => {
|
|
162
|
+
if (!settings) return false;
|
|
163
|
+
return settings.dialTools[id] ?? false;
|
|
164
|
+
};
|
|
165
|
+
const createEmptySlot = slotIndex => ({
|
|
166
|
+
id: `empty-${slotIndex}`,
|
|
167
|
+
name: `empty-${slotIndex}`,
|
|
168
|
+
icon: null,
|
|
169
|
+
color: "transparent",
|
|
170
|
+
onPress: () => {}
|
|
171
|
+
});
|
|
172
|
+
const enabledIcons = [];
|
|
173
|
+
for (const app of dialApps) {
|
|
174
|
+
if (!isDialEnabled(app.id)) {
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
if (enabledIcons.length >= _floatingToolsCore.MAX_DIAL_SLOTS) {
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
enabledIcons.push({
|
|
181
|
+
id: app.id,
|
|
182
|
+
name: app.name,
|
|
183
|
+
// Pass both the pre-rendered icon (for non-function icons) and the component (for dynamic rendering)
|
|
184
|
+
icon: typeof app.icon === "function" ? null // Will be rendered dynamically by DialIcon
|
|
185
|
+
: app.icon,
|
|
186
|
+
// Cast to the expected type - the function signature is compatible at runtime
|
|
187
|
+
iconComponent: typeof app.icon === "function" ? app.icon : undefined,
|
|
188
|
+
color: app.color ?? _sharedUi.buoyColors.primary,
|
|
189
|
+
onPress: () => {
|
|
190
|
+
// Call the app's onPress callback if provided, passing actions for toggle tools
|
|
191
|
+
app?.onPress?.(actions);
|
|
192
|
+
|
|
193
|
+
// Only open modal if not a toggle-only tool
|
|
194
|
+
if (app.launchMode !== "toggle-only") {
|
|
195
|
+
const resolvedIcon = typeof app.icon === "function" ? app.icon({
|
|
196
|
+
slot: "dial",
|
|
197
|
+
size: 20
|
|
198
|
+
}) : app.icon;
|
|
199
|
+
open({
|
|
200
|
+
id: app.id,
|
|
201
|
+
title: app.name,
|
|
202
|
+
component: app.component,
|
|
203
|
+
props: app.props,
|
|
204
|
+
launchMode: app.launchMode ?? "self-modal",
|
|
205
|
+
singleton: app.singleton ?? true,
|
|
206
|
+
icon: resolvedIcon,
|
|
207
|
+
color: app.color
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Close the dial
|
|
212
|
+
onClose?.();
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
if (__DEV__) {
|
|
217
|
+
const totalEnabled = dialApps.filter(app => isDialEnabled(app.id)).length;
|
|
218
|
+
if (totalEnabled > _floatingToolsCore.MAX_DIAL_SLOTS) {
|
|
219
|
+
// More tools enabled than can be shown - they will be hidden
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
const icons = [...enabledIcons];
|
|
223
|
+
while (icons.length < _floatingToolsCore.MAX_DIAL_SLOTS) {
|
|
224
|
+
icons.push(createEmptySlot(icons.length));
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Initialize animations on mount - using shared config from core
|
|
228
|
+
(0, _react.useEffect)(() => {
|
|
229
|
+
// Fallback config in case dialAnimationConfig hasn't loaded
|
|
230
|
+
const config = _floatingToolsCore.dialAnimationConfig ?? {
|
|
231
|
+
entrance: {
|
|
232
|
+
backdrop: {
|
|
233
|
+
duration: 400
|
|
234
|
+
},
|
|
235
|
+
dial: {
|
|
236
|
+
scale: {
|
|
237
|
+
damping: 15,
|
|
238
|
+
stiffness: 150,
|
|
239
|
+
mass: 1
|
|
240
|
+
},
|
|
241
|
+
rotation: {
|
|
242
|
+
duration: 800
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
centerButton: {
|
|
246
|
+
delay: 300,
|
|
247
|
+
damping: 10,
|
|
248
|
+
stiffness: 200
|
|
249
|
+
},
|
|
250
|
+
icons: {
|
|
251
|
+
delay: 500,
|
|
252
|
+
duration: 600
|
|
253
|
+
},
|
|
254
|
+
circuitTraces: {
|
|
255
|
+
delay: 600,
|
|
256
|
+
duration: 1000
|
|
257
|
+
}
|
|
258
|
+
},
|
|
259
|
+
continuous: {
|
|
260
|
+
glitch: {
|
|
261
|
+
interval: 3000,
|
|
262
|
+
offset: 2,
|
|
263
|
+
stepDuration: 50
|
|
264
|
+
},
|
|
265
|
+
pulse: {
|
|
266
|
+
maxScale: 1.02,
|
|
267
|
+
minScale: 0.98,
|
|
268
|
+
duration: 1000
|
|
269
|
+
},
|
|
270
|
+
floating: {
|
|
271
|
+
maxY: -8,
|
|
272
|
+
minY: 0,
|
|
273
|
+
duration: 3000
|
|
274
|
+
},
|
|
275
|
+
breathing: {
|
|
276
|
+
maxScale: 1.05,
|
|
277
|
+
minScale: 0.98,
|
|
278
|
+
duration: 2500
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
const {
|
|
283
|
+
entrance,
|
|
284
|
+
continuous
|
|
285
|
+
} = config;
|
|
286
|
+
|
|
287
|
+
// Entrance animation sequence
|
|
288
|
+
_reactNative.Animated.timing(backdropOpacity, {
|
|
289
|
+
toValue: 1,
|
|
290
|
+
duration: entrance.backdrop.duration,
|
|
291
|
+
useNativeDriver: true
|
|
292
|
+
}).start();
|
|
293
|
+
_reactNative.Animated.spring(dialScale, {
|
|
294
|
+
toValue: 1,
|
|
295
|
+
damping: entrance.dial.scale.damping,
|
|
296
|
+
stiffness: entrance.dial.scale.stiffness,
|
|
297
|
+
mass: entrance.dial.scale.mass,
|
|
298
|
+
useNativeDriver: true
|
|
299
|
+
}).start();
|
|
300
|
+
_reactNative.Animated.sequence([_reactNative.Animated.timing(dialRotation, {
|
|
301
|
+
toValue: 1,
|
|
302
|
+
duration: entrance.dial.rotation.duration,
|
|
303
|
+
easing: _reactNative.Easing.out(_reactNative.Easing.cubic),
|
|
304
|
+
useNativeDriver: true
|
|
305
|
+
}), _reactNative.Animated.timing(dialRotation, {
|
|
306
|
+
toValue: 0,
|
|
307
|
+
duration: 0,
|
|
308
|
+
useNativeDriver: true
|
|
309
|
+
})]).start();
|
|
310
|
+
_reactNative.Animated.sequence([_reactNative.Animated.delay(entrance.centerButton.delay), _reactNative.Animated.spring(centerButtonScale, {
|
|
311
|
+
toValue: 1,
|
|
312
|
+
damping: entrance.centerButton.damping,
|
|
313
|
+
stiffness: entrance.centerButton.stiffness,
|
|
314
|
+
useNativeDriver: true
|
|
315
|
+
})]).start();
|
|
316
|
+
_reactNative.Animated.sequence([_reactNative.Animated.delay(entrance.icons.delay), _reactNative.Animated.timing(iconsProgress, {
|
|
317
|
+
toValue: 1,
|
|
318
|
+
duration: entrance.icons.duration,
|
|
319
|
+
easing: _reactNative.Easing.out(_reactNative.Easing.cubic),
|
|
320
|
+
useNativeDriver: true
|
|
321
|
+
})]).start();
|
|
322
|
+
|
|
323
|
+
// Subtle glitch effect - using shared config
|
|
324
|
+
const glitchAnimation = () => {
|
|
325
|
+
_reactNative.Animated.sequence([_reactNative.Animated.timing(glitchOffset, {
|
|
326
|
+
toValue: continuous.glitch.offset,
|
|
327
|
+
duration: continuous.glitch.stepDuration,
|
|
328
|
+
useNativeDriver: true
|
|
329
|
+
}), _reactNative.Animated.timing(glitchOffset, {
|
|
330
|
+
toValue: -continuous.glitch.offset,
|
|
331
|
+
duration: continuous.glitch.stepDuration,
|
|
332
|
+
useNativeDriver: true
|
|
333
|
+
}), _reactNative.Animated.timing(glitchOffset, {
|
|
334
|
+
toValue: 0,
|
|
335
|
+
duration: continuous.glitch.stepDuration,
|
|
336
|
+
useNativeDriver: true
|
|
337
|
+
})]).start();
|
|
338
|
+
};
|
|
339
|
+
glitchIntervalRef.current = setInterval(glitchAnimation, continuous.glitch.interval);
|
|
340
|
+
|
|
341
|
+
// Pulse animation - using shared config
|
|
342
|
+
const startPulse = () => {
|
|
343
|
+
pulseAnimationRef.current = _reactNative.Animated.loop(_reactNative.Animated.sequence([_reactNative.Animated.timing(pulseScale, {
|
|
344
|
+
toValue: continuous.pulse.maxScale,
|
|
345
|
+
duration: continuous.pulse.duration,
|
|
346
|
+
easing: _reactNative.Easing.inOut(_reactNative.Easing.ease),
|
|
347
|
+
useNativeDriver: true
|
|
348
|
+
}), _reactNative.Animated.timing(pulseScale, {
|
|
349
|
+
toValue: continuous.pulse.minScale,
|
|
350
|
+
duration: continuous.pulse.duration,
|
|
351
|
+
easing: _reactNative.Easing.inOut(_reactNative.Easing.ease),
|
|
352
|
+
useNativeDriver: true
|
|
353
|
+
})]));
|
|
354
|
+
pulseAnimationRef.current.start();
|
|
355
|
+
};
|
|
356
|
+
startPulse();
|
|
357
|
+
|
|
358
|
+
// Subtle floating animation for the dial - using shared config
|
|
359
|
+
_reactNative.Animated.loop(_reactNative.Animated.sequence([_reactNative.Animated.timing(floatingAnim, {
|
|
360
|
+
toValue: continuous.floating.maxY,
|
|
361
|
+
duration: continuous.floating.duration,
|
|
362
|
+
easing: _reactNative.Easing.inOut(_reactNative.Easing.ease),
|
|
363
|
+
useNativeDriver: true
|
|
364
|
+
}), _reactNative.Animated.timing(floatingAnim, {
|
|
365
|
+
toValue: continuous.floating.minY,
|
|
366
|
+
duration: continuous.floating.duration,
|
|
367
|
+
easing: _reactNative.Easing.inOut(_reactNative.Easing.ease),
|
|
368
|
+
useNativeDriver: true
|
|
369
|
+
})])).start();
|
|
370
|
+
|
|
371
|
+
// Gentle breathing effect for center button - using shared config
|
|
372
|
+
_reactNative.Animated.loop(_reactNative.Animated.sequence([_reactNative.Animated.timing(breathingScale, {
|
|
373
|
+
toValue: continuous.breathing.maxScale,
|
|
374
|
+
duration: continuous.breathing.duration,
|
|
375
|
+
easing: _reactNative.Easing.inOut(_reactNative.Easing.ease),
|
|
376
|
+
useNativeDriver: true
|
|
377
|
+
}), _reactNative.Animated.timing(breathingScale, {
|
|
378
|
+
toValue: continuous.breathing.minScale,
|
|
379
|
+
duration: continuous.breathing.duration,
|
|
380
|
+
easing: _reactNative.Easing.inOut(_reactNative.Easing.ease),
|
|
381
|
+
useNativeDriver: true
|
|
382
|
+
})])).start();
|
|
383
|
+
|
|
384
|
+
// Circuit traces fade in - using shared config
|
|
385
|
+
_reactNative.Animated.timing(circuitOpacity, {
|
|
386
|
+
toValue: 1,
|
|
387
|
+
duration: entrance.circuitTraces.duration,
|
|
388
|
+
delay: entrance.circuitTraces.delay,
|
|
389
|
+
useNativeDriver: true
|
|
390
|
+
}).start();
|
|
391
|
+
return () => {
|
|
392
|
+
if (glitchIntervalRef.current) {
|
|
393
|
+
clearInterval(glitchIntervalRef.current);
|
|
394
|
+
}
|
|
395
|
+
if (pulseAnimationRef.current) {
|
|
396
|
+
pulseAnimationRef.current.stop();
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
}, []);
|
|
400
|
+
const handleOnboardingDismiss = () => {
|
|
401
|
+
// Mark as dismissed immediately in ref (synchronous, no re-render needed)
|
|
402
|
+
onboardingDismissedRef.current = true;
|
|
403
|
+
|
|
404
|
+
// Hide the tooltip
|
|
405
|
+
setShowOnboardingTooltip(false);
|
|
406
|
+
|
|
407
|
+
// Save to storage asynchronously in the background
|
|
408
|
+
(0, _sharedUi.safeSetItem)(ONBOARDING_STORAGE_KEY, "true").catch(error => {
|
|
409
|
+
// Silently fail - user already saw onboarding, just won't persist
|
|
410
|
+
console.warn("Failed to save dial onboarding state:", error);
|
|
411
|
+
});
|
|
412
|
+
};
|
|
413
|
+
const handleClose = () => {
|
|
414
|
+
// Stop any ongoing animations first
|
|
415
|
+
if (pulseAnimationRef.current) {
|
|
416
|
+
pulseAnimationRef.current.stop();
|
|
417
|
+
}
|
|
418
|
+
const exit = _floatingToolsCore.dialAnimationConfig?.exit ?? {
|
|
419
|
+
icons: {
|
|
420
|
+
duration: 300
|
|
421
|
+
},
|
|
422
|
+
centerButton: {
|
|
423
|
+
duration: 200
|
|
424
|
+
},
|
|
425
|
+
dialScale: {
|
|
426
|
+
duration: 250
|
|
427
|
+
},
|
|
428
|
+
backdrop: {
|
|
429
|
+
duration: 200
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
// Exit animation sequence - reverse order of entrance, using shared config
|
|
434
|
+
_reactNative.Animated.sequence([
|
|
435
|
+
// First animate icons back to center
|
|
436
|
+
_reactNative.Animated.timing(iconsProgress, {
|
|
437
|
+
toValue: 0,
|
|
438
|
+
duration: exit.icons.duration,
|
|
439
|
+
easing: _reactNative.Easing.in(_reactNative.Easing.cubic),
|
|
440
|
+
useNativeDriver: true
|
|
441
|
+
}),
|
|
442
|
+
// Then scale down center button and dial
|
|
443
|
+
_reactNative.Animated.parallel([_reactNative.Animated.timing(centerButtonScale, {
|
|
444
|
+
toValue: 0,
|
|
445
|
+
duration: exit.centerButton.duration,
|
|
446
|
+
easing: _reactNative.Easing.in(_reactNative.Easing.cubic),
|
|
447
|
+
useNativeDriver: true
|
|
448
|
+
}), _reactNative.Animated.timing(dialScale, {
|
|
449
|
+
toValue: 0,
|
|
450
|
+
duration: exit.dialScale.duration,
|
|
451
|
+
easing: _reactNative.Easing.in(_reactNative.Easing.cubic),
|
|
452
|
+
useNativeDriver: true
|
|
453
|
+
})]),
|
|
454
|
+
// Finally fade out backdrop
|
|
455
|
+
_reactNative.Animated.timing(backdropOpacity, {
|
|
456
|
+
toValue: 0,
|
|
457
|
+
duration: exit.backdrop.duration,
|
|
458
|
+
useNativeDriver: true
|
|
459
|
+
})]).start(() => {
|
|
460
|
+
// Use setTimeout to defer the state update to the next tick
|
|
461
|
+
// This avoids the useInsertionEffect warning
|
|
462
|
+
if (onClose) {
|
|
463
|
+
setTimeout(() => {
|
|
464
|
+
onClose();
|
|
465
|
+
}, 0);
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
};
|
|
469
|
+
const handleIconPress = index => {
|
|
470
|
+
setSelectedIcon(index);
|
|
471
|
+
const interaction = _floatingToolsCore.dialAnimationConfig?.interaction ?? {
|
|
472
|
+
iconSelect: {
|
|
473
|
+
pulse: [{
|
|
474
|
+
scale: 0.9,
|
|
475
|
+
damping: 15,
|
|
476
|
+
stiffness: 500
|
|
477
|
+
}, {
|
|
478
|
+
scale: 1,
|
|
479
|
+
damping: 10,
|
|
480
|
+
stiffness: 200
|
|
481
|
+
}],
|
|
482
|
+
actionDelay: 50
|
|
483
|
+
}
|
|
484
|
+
};
|
|
485
|
+
const [pulseIn, pulseOut] = interaction.iconSelect.pulse;
|
|
486
|
+
|
|
487
|
+
// Pulse animation on selection - using shared config
|
|
488
|
+
_reactNative.Animated.sequence([_reactNative.Animated.spring(centerButtonScale, {
|
|
489
|
+
toValue: pulseIn.scale,
|
|
490
|
+
damping: pulseIn.damping,
|
|
491
|
+
stiffness: pulseIn.stiffness,
|
|
492
|
+
useNativeDriver: true
|
|
493
|
+
}), _reactNative.Animated.spring(centerButtonScale, {
|
|
494
|
+
toValue: pulseOut.scale,
|
|
495
|
+
damping: pulseOut.damping,
|
|
496
|
+
stiffness: pulseOut.stiffness,
|
|
497
|
+
useNativeDriver: true
|
|
498
|
+
})]).start();
|
|
499
|
+
|
|
500
|
+
// Trigger action - using shared delay
|
|
501
|
+
setTimeout(() => {
|
|
502
|
+
icons[index].onPress();
|
|
503
|
+
// Only close if it's not the WiFi toggle (by id)
|
|
504
|
+
if (icons[index].id !== "wifi") {
|
|
505
|
+
handleClose();
|
|
506
|
+
}
|
|
507
|
+
}, interaction.iconSelect.actionDelay);
|
|
508
|
+
};
|
|
509
|
+
|
|
510
|
+
// Animated styles
|
|
511
|
+
const backdropAnimatedStyle = {
|
|
512
|
+
opacity: backdropOpacity
|
|
513
|
+
};
|
|
514
|
+
const glitchAnimatedStyle = {
|
|
515
|
+
transform: [{
|
|
516
|
+
translateX: glitchOffset
|
|
517
|
+
}]
|
|
518
|
+
};
|
|
519
|
+
const centerButtonAnimatedStyle = {
|
|
520
|
+
transform: [{
|
|
521
|
+
scale: _reactNative.Animated.multiply(centerButtonScale, breathingScale)
|
|
522
|
+
}]
|
|
523
|
+
};
|
|
524
|
+
const pulseAnimatedStyle = {
|
|
525
|
+
transform: [{
|
|
526
|
+
scale: selectedIcon >= 0 ? 1 : pulseScale
|
|
527
|
+
}]
|
|
528
|
+
};
|
|
529
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
530
|
+
style: styles.container,
|
|
531
|
+
nativeID: "dial-devtools-root",
|
|
532
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
|
|
533
|
+
style: [styles.backdrop, backdropAnimatedStyle],
|
|
534
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
|
|
535
|
+
style: _reactNative.StyleSheet.absoluteFillObject,
|
|
536
|
+
onPress: handleClose
|
|
537
|
+
})
|
|
538
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, {
|
|
539
|
+
style: [styles.parent, {
|
|
540
|
+
position: "absolute",
|
|
541
|
+
left: (SCREEN_WIDTH - CIRCLE_SIZE) / 2,
|
|
542
|
+
bottom: 80,
|
|
543
|
+
transform: [{
|
|
544
|
+
translateY: floatingAnim
|
|
545
|
+
}, {
|
|
546
|
+
scale: dialScale
|
|
547
|
+
}, {
|
|
548
|
+
rotate: dialRotation.interpolate({
|
|
549
|
+
inputRange: [0, 1],
|
|
550
|
+
outputRange: ["0deg", "360deg"]
|
|
551
|
+
})
|
|
552
|
+
}]
|
|
553
|
+
}],
|
|
554
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Animated.View, {
|
|
555
|
+
style: [styles.circle, glitchAnimatedStyle],
|
|
556
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
557
|
+
style: styles.gradientBackground,
|
|
558
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
559
|
+
style: styles.gradientLayer1
|
|
560
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
561
|
+
style: styles.gradientLayer2
|
|
562
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
563
|
+
style: styles.gradientLayer3
|
|
564
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
565
|
+
style: styles.gridPattern,
|
|
566
|
+
children: Array.from({
|
|
567
|
+
length: 6
|
|
568
|
+
}).map((_, i) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
569
|
+
style: [styles.gridLine, {
|
|
570
|
+
transform: [{
|
|
571
|
+
rotate: `${i * 60}deg`
|
|
572
|
+
}]
|
|
573
|
+
}]
|
|
574
|
+
}, i))
|
|
575
|
+
})]
|
|
576
|
+
}), icons.map((icon, i) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_DialIcon.DialIcon, {
|
|
577
|
+
selectedIcon: selectedIcon,
|
|
578
|
+
onPress: handleIconPress,
|
|
579
|
+
iconsProgress: iconsProgress,
|
|
580
|
+
icon: icon,
|
|
581
|
+
index: i,
|
|
582
|
+
totalIcons: icons.length
|
|
583
|
+
}, `${i}-${icon.name}`))]
|
|
584
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
|
|
585
|
+
style: [styles.buttonContainer, centerButtonAnimatedStyle],
|
|
586
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
587
|
+
style: styles.buttonGradient,
|
|
588
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
589
|
+
style: styles.buttonGradientLayer1
|
|
590
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
591
|
+
style: styles.buttonGradientLayer2
|
|
592
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
593
|
+
style: styles.buttonGradientLayer3
|
|
594
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
595
|
+
style: styles.buttonBorder,
|
|
596
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
|
|
597
|
+
style: [styles.button, pulseAnimatedStyle],
|
|
598
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
|
|
599
|
+
accessibilityRole: "button",
|
|
600
|
+
accessibilityLabel: isSettingsModalOpen ? "Close Settings" : "Open Dev Tools Settings",
|
|
601
|
+
onPress: () => {
|
|
602
|
+
if (isSettingsModalOpen) {
|
|
603
|
+
// Close settings modal
|
|
604
|
+
setIsSettingsModalOpen(false);
|
|
605
|
+
} else {
|
|
606
|
+
// Open internal settings modal
|
|
607
|
+
setIsSettingsModalOpen(true);
|
|
608
|
+
// Dismiss onboarding tooltip when user opens settings
|
|
609
|
+
if (showOnboardingTooltip && !onboardingDismissedRef.current) {
|
|
610
|
+
handleOnboardingDismiss();
|
|
611
|
+
}
|
|
612
|
+
// Also call external handler if provided
|
|
613
|
+
if (onSettingsPress) {
|
|
614
|
+
onSettingsPress();
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
},
|
|
618
|
+
style: styles.buttonPressable,
|
|
619
|
+
children: isSettingsModalOpen ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
620
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
621
|
+
style: [styles.centerText, styles.closeTextTop],
|
|
622
|
+
children: "CLOSE"
|
|
623
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
624
|
+
style: [styles.centerText, styles.closeTextBottom],
|
|
625
|
+
children: "SETTINGS"
|
|
626
|
+
})]
|
|
627
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
628
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
629
|
+
style: styles.centerText,
|
|
630
|
+
children: "BUOY"
|
|
631
|
+
}), isPro && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
632
|
+
style: styles.proText,
|
|
633
|
+
children: "PRO"
|
|
634
|
+
})]
|
|
635
|
+
})
|
|
636
|
+
})
|
|
637
|
+
})
|
|
638
|
+
})]
|
|
639
|
+
})
|
|
640
|
+
})]
|
|
641
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_DevToolsSettingsModal.DevToolsSettingsModal, {
|
|
642
|
+
visible: isSettingsModalOpen,
|
|
643
|
+
onClose: () => {
|
|
644
|
+
setIsSettingsModalOpen(false);
|
|
645
|
+
refreshSettings(); // Refresh from storage
|
|
646
|
+
},
|
|
647
|
+
onSettingsChange: newSettings => {
|
|
648
|
+
// Immediately update local settings for instant feedback
|
|
649
|
+
setLocalSettings(newSettings);
|
|
650
|
+
},
|
|
651
|
+
availableApps: availableApps
|
|
652
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_OnboardingTooltip.OnboardingTooltip, {
|
|
653
|
+
visible: showOnboardingTooltip && !isSettingsModalOpen && !onboardingDismissedRef.current,
|
|
654
|
+
onDismiss: handleOnboardingDismiss
|
|
655
|
+
})]
|
|
656
|
+
});
|
|
657
|
+
};
|
|
658
|
+
exports.DialDevTools = DialDevTools;
|
|
659
|
+
const styles = _reactNative.StyleSheet.create({
|
|
660
|
+
container: {
|
|
661
|
+
..._reactNative.StyleSheet.absoluteFillObject,
|
|
662
|
+
zIndex: 9999
|
|
663
|
+
},
|
|
664
|
+
backdrop: {
|
|
665
|
+
..._reactNative.StyleSheet.absoluteFillObject,
|
|
666
|
+
backgroundColor: _floatingToolsCore.dialColors.dialBackdrop
|
|
667
|
+
},
|
|
668
|
+
parent: {
|
|
669
|
+
width: CIRCLE_SIZE,
|
|
670
|
+
height: CIRCLE_SIZE,
|
|
671
|
+
alignItems: "center",
|
|
672
|
+
justifyContent: "center"
|
|
673
|
+
},
|
|
674
|
+
circle: {
|
|
675
|
+
width: CIRCLE_SIZE,
|
|
676
|
+
height: CIRCLE_SIZE,
|
|
677
|
+
borderRadius: CIRCLE_SIZE / 2,
|
|
678
|
+
position: "absolute",
|
|
679
|
+
backgroundColor: "transparent",
|
|
680
|
+
borderWidth: 1,
|
|
681
|
+
borderColor: _floatingToolsCore.dialColors.dialBorder,
|
|
682
|
+
shadowColor: _floatingToolsCore.dialColors.dialShadow,
|
|
683
|
+
shadowOffset: {
|
|
684
|
+
width: 0,
|
|
685
|
+
height: 0
|
|
686
|
+
},
|
|
687
|
+
shadowOpacity: 0.5,
|
|
688
|
+
shadowRadius: 20,
|
|
689
|
+
elevation: 10
|
|
690
|
+
},
|
|
691
|
+
gradientBackground: {
|
|
692
|
+
width: "100%",
|
|
693
|
+
height: "100%",
|
|
694
|
+
borderRadius: CIRCLE_SIZE / 2,
|
|
695
|
+
position: "relative",
|
|
696
|
+
backgroundColor: _floatingToolsCore.dialColors.dialBackground,
|
|
697
|
+
overflow: "hidden"
|
|
698
|
+
},
|
|
699
|
+
gradientLayer1: {
|
|
700
|
+
..._reactNative.StyleSheet.absoluteFillObject,
|
|
701
|
+
backgroundColor: _floatingToolsCore.dialColors.dialGradient1,
|
|
702
|
+
opacity: 0.6,
|
|
703
|
+
borderRadius: CIRCLE_SIZE / 2
|
|
704
|
+
},
|
|
705
|
+
gradientLayer2: {
|
|
706
|
+
..._reactNative.StyleSheet.absoluteFillObject,
|
|
707
|
+
backgroundColor: _floatingToolsCore.dialColors.dialGradient2,
|
|
708
|
+
opacity: 0.4,
|
|
709
|
+
top: "30%",
|
|
710
|
+
left: "30%",
|
|
711
|
+
borderRadius: CIRCLE_SIZE / 2
|
|
712
|
+
},
|
|
713
|
+
gradientLayer3: {
|
|
714
|
+
..._reactNative.StyleSheet.absoluteFillObject,
|
|
715
|
+
backgroundColor: _floatingToolsCore.dialColors.dialGradient3,
|
|
716
|
+
opacity: 0.3,
|
|
717
|
+
top: "50%",
|
|
718
|
+
left: "50%",
|
|
719
|
+
borderRadius: CIRCLE_SIZE / 2
|
|
720
|
+
},
|
|
721
|
+
gridPattern: {
|
|
722
|
+
..._reactNative.StyleSheet.absoluteFillObject,
|
|
723
|
+
alignItems: "center",
|
|
724
|
+
justifyContent: "center"
|
|
725
|
+
},
|
|
726
|
+
gridLine: {
|
|
727
|
+
position: "absolute",
|
|
728
|
+
width: CIRCLE_SIZE,
|
|
729
|
+
height: 1,
|
|
730
|
+
backgroundColor: _floatingToolsCore.dialColors.dialGridLine
|
|
731
|
+
},
|
|
732
|
+
buttonContainer: {
|
|
733
|
+
zIndex: 1,
|
|
734
|
+
backgroundColor: "transparent",
|
|
735
|
+
alignItems: "center",
|
|
736
|
+
justifyContent: "center",
|
|
737
|
+
position: "absolute",
|
|
738
|
+
width: BUTTON_SIZE * 1.5,
|
|
739
|
+
height: BUTTON_SIZE * 1.5,
|
|
740
|
+
borderRadius: BUTTON_SIZE
|
|
741
|
+
},
|
|
742
|
+
buttonGradient: {
|
|
743
|
+
width: "100%",
|
|
744
|
+
height: "100%",
|
|
745
|
+
borderRadius: BUTTON_SIZE,
|
|
746
|
+
alignItems: "center",
|
|
747
|
+
justifyContent: "center",
|
|
748
|
+
padding: 4,
|
|
749
|
+
backgroundColor: _floatingToolsCore.dialColors.dialBackground,
|
|
750
|
+
position: "relative",
|
|
751
|
+
overflow: "hidden"
|
|
752
|
+
},
|
|
753
|
+
buttonGradientLayer1: {
|
|
754
|
+
..._reactNative.StyleSheet.absoluteFillObject,
|
|
755
|
+
backgroundColor: _floatingToolsCore.dialColors.dialGradient1,
|
|
756
|
+
opacity: 0.5,
|
|
757
|
+
borderRadius: BUTTON_SIZE
|
|
758
|
+
},
|
|
759
|
+
buttonGradientLayer2: {
|
|
760
|
+
..._reactNative.StyleSheet.absoluteFillObject,
|
|
761
|
+
backgroundColor: _floatingToolsCore.dialColors.dialGradient2,
|
|
762
|
+
opacity: 0.3,
|
|
763
|
+
top: "20%",
|
|
764
|
+
left: "20%",
|
|
765
|
+
borderRadius: BUTTON_SIZE
|
|
766
|
+
},
|
|
767
|
+
buttonGradientLayer3: {
|
|
768
|
+
..._reactNative.StyleSheet.absoluteFillObject,
|
|
769
|
+
backgroundColor: _floatingToolsCore.dialColors.dialGradient3,
|
|
770
|
+
opacity: 0.2,
|
|
771
|
+
top: "40%",
|
|
772
|
+
left: "40%",
|
|
773
|
+
borderRadius: BUTTON_SIZE
|
|
774
|
+
},
|
|
775
|
+
buttonBorder: {
|
|
776
|
+
backgroundColor: _floatingToolsCore.dialColors.dialGridLine,
|
|
777
|
+
alignItems: "center",
|
|
778
|
+
justifyContent: "center",
|
|
779
|
+
width: BUTTON_SIZE * 1.2,
|
|
780
|
+
height: BUTTON_SIZE * 1.2,
|
|
781
|
+
borderRadius: BUTTON_SIZE * 0.6,
|
|
782
|
+
borderWidth: 2,
|
|
783
|
+
borderColor: _floatingToolsCore.dialColors.dialBorder
|
|
784
|
+
},
|
|
785
|
+
button: {
|
|
786
|
+
width: BUTTON_SIZE,
|
|
787
|
+
height: BUTTON_SIZE,
|
|
788
|
+
borderRadius: BUTTON_SIZE / 2,
|
|
789
|
+
justifyContent: "center",
|
|
790
|
+
alignItems: "center",
|
|
791
|
+
position: "relative",
|
|
792
|
+
overflow: "hidden"
|
|
793
|
+
},
|
|
794
|
+
buttonPressable: {
|
|
795
|
+
width: "100%",
|
|
796
|
+
height: "100%",
|
|
797
|
+
justifyContent: "center",
|
|
798
|
+
alignItems: "center"
|
|
799
|
+
},
|
|
800
|
+
centerText: {
|
|
801
|
+
color: "#FFFFFF",
|
|
802
|
+
fontSize: 10,
|
|
803
|
+
fontWeight: "900",
|
|
804
|
+
fontFamily: "monospace",
|
|
805
|
+
letterSpacing: 1,
|
|
806
|
+
textAlign: "center",
|
|
807
|
+
textTransform: "uppercase",
|
|
808
|
+
textShadowColor: _sharedUi.buoyColors.primary,
|
|
809
|
+
textShadowOffset: {
|
|
810
|
+
width: 0,
|
|
811
|
+
height: 0
|
|
812
|
+
},
|
|
813
|
+
textShadowRadius: 4
|
|
814
|
+
},
|
|
815
|
+
closeTextTop: {
|
|
816
|
+
marginBottom: -2
|
|
817
|
+
},
|
|
818
|
+
closeTextBottom: {
|
|
819
|
+
marginTop: -2
|
|
820
|
+
},
|
|
821
|
+
proText: {
|
|
822
|
+
color: _sharedUi.buoyColors.warning,
|
|
823
|
+
fontSize: 8,
|
|
824
|
+
fontWeight: "900",
|
|
825
|
+
fontFamily: "monospace",
|
|
826
|
+
letterSpacing: 2,
|
|
827
|
+
textAlign: "center",
|
|
828
|
+
textShadowColor: _sharedUi.buoyColors.warning,
|
|
829
|
+
textShadowOffset: {
|
|
830
|
+
width: 0,
|
|
831
|
+
height: 0
|
|
832
|
+
},
|
|
833
|
+
textShadowRadius: 4
|
|
834
|
+
}
|
|
835
|
+
});
|