@buoy-gg/core 7.0.15 → 7.0.17
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 +18 -0
- package/lib/commonjs/floatingMenu/AppHost.web.js +359 -0
- package/lib/commonjs/floatingMenu/AppHostLogic.js +6 -0
- package/lib/commonjs/floatingMenu/DevToolsSettingsModal.web.js +787 -418
- package/lib/commonjs/floatingMenu/FloatingDevTools.js +1 -1
- package/lib/commonjs/floatingMenu/FloatingDevTools.web.js +244 -36
- package/lib/commonjs/floatingMenu/FloatingMenu.js +4 -3
- package/lib/commonjs/floatingMenu/MinimizedToolsContext.js +2 -3
- package/lib/commonjs/floatingMenu/MinimizedToolsStack.web.js +287 -0
- package/lib/commonjs/floatingMenu/ToolHost.js +264 -0
- package/lib/commonjs/floatingMenu/allToolsRegistry.js +7 -0
- package/lib/commonjs/floatingMenu/autoDiscoverPresets.js +32 -0
- package/lib/commonjs/floatingMenu/autoExternalSync.js +18 -0
- package/lib/commonjs/floatingMenu/dial/DialDevTools.js +9 -5
- package/lib/commonjs/floatingMenu/dial/DialDevTools.web.js +373 -231
- package/lib/commonjs/floatingMenu/dial/DialIcon.js +25 -3
- package/lib/commonjs/floatingMenu/dial/OnboardingTooltip.js +1 -1
- package/lib/commonjs/floatingMenu/dial/OnboardingTooltip.web.js +154 -0
- package/lib/commonjs/floatingMenu/dial/onboardingConstants.web.js +34 -0
- package/lib/commonjs/floatingMenu/floatingTools.js +3 -3
- package/lib/commonjs/floatingMenu/floatingTools.web.js +191 -28
- package/lib/commonjs/index.js +29 -2
- package/lib/commonjs/index.web.js +19 -0
- package/lib/commonjs/toolkit.js +427 -0
- package/lib/commonjs/utils/autoDiscoverPresets.web.js +50 -5
- package/lib/module/floatingMenu/AppHost.js +18 -0
- package/lib/module/floatingMenu/AppHost.web.js +351 -0
- package/lib/module/floatingMenu/AppHostLogic.js +6 -0
- package/lib/module/floatingMenu/DevToolsSettingsModal.web.js +792 -422
- package/lib/module/floatingMenu/FloatingDevTools.js +2 -2
- package/lib/module/floatingMenu/FloatingDevTools.web.js +247 -38
- package/lib/module/floatingMenu/FloatingMenu.js +4 -3
- package/lib/module/floatingMenu/MinimizedToolsContext.js +2 -3
- package/lib/module/floatingMenu/MinimizedToolsStack.web.js +284 -0
- package/lib/module/floatingMenu/ToolHost.js +256 -0
- package/lib/module/floatingMenu/allToolsRegistry.js +8 -1
- package/lib/module/floatingMenu/autoDiscoverPresets.js +32 -0
- package/lib/module/floatingMenu/autoExternalSync.js +18 -0
- package/lib/module/floatingMenu/dial/DialDevTools.js +10 -6
- package/lib/module/floatingMenu/dial/DialDevTools.web.js +375 -233
- package/lib/module/floatingMenu/dial/DialIcon.js +26 -4
- package/lib/module/floatingMenu/dial/OnboardingTooltip.js +1 -1
- package/lib/module/floatingMenu/dial/OnboardingTooltip.web.js +149 -0
- package/lib/module/floatingMenu/dial/onboardingConstants.web.js +27 -0
- package/lib/module/floatingMenu/floatingTools.js +3 -3
- package/lib/module/floatingMenu/floatingTools.web.js +190 -28
- package/lib/module/index.js +8 -2
- package/lib/module/index.web.js +5 -0
- package/lib/module/toolkit.js +45 -0
- package/lib/module/utils/autoDiscoverPresets.web.js +53 -7
- package/lib/typescript/commonjs/floatingMenu/AppHost.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/AppHost.web.d.ts +38 -0
- package/lib/typescript/commonjs/floatingMenu/AppHost.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/AppHostLogic.d.ts +24 -1
- package/lib/typescript/commonjs/floatingMenu/AppHostLogic.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.web.d.ts +5 -2
- package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.web.d.ts +2 -14
- package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/FloatingMenu.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/MinimizedToolsContext.d.ts +2 -20
- package/lib/typescript/commonjs/floatingMenu/MinimizedToolsContext.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/MinimizedToolsStack.web.d.ts +21 -0
- package/lib/typescript/commonjs/floatingMenu/MinimizedToolsStack.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/ToolHost.d.ts +72 -0
- package/lib/typescript/commonjs/floatingMenu/ToolHost.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/allToolsRegistry.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/autoDiscoverPresets.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/autoExternalSync.d.ts.map +1 -1
- 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/DialDevTools.web.d.ts +16 -2
- package/lib/typescript/commonjs/floatingMenu/dial/DialDevTools.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/dial/DialIcon.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/dial/OnboardingTooltip.web.d.ts +9 -0
- package/lib/typescript/commonjs/floatingMenu/dial/OnboardingTooltip.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/dial/onboardingConstants.web.d.ts +13 -0
- package/lib/typescript/commonjs/floatingMenu/dial/onboardingConstants.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/floatingTools.web.d.ts +29 -2
- package/lib/typescript/commonjs/floatingMenu/floatingTools.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/types.d.ts +30 -1
- package/lib/typescript/commonjs/floatingMenu/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +2 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.web.d.ts +1 -0
- package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/toolkit.d.ts +22 -0
- package/lib/typescript/commonjs/toolkit.d.ts.map +1 -0
- package/lib/typescript/commonjs/utils/autoDiscoverPresets.web.d.ts +2 -0
- package/lib/typescript/commonjs/utils/autoDiscoverPresets.web.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/AppHost.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/AppHost.web.d.ts +38 -0
- package/lib/typescript/module/floatingMenu/AppHost.web.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/AppHostLogic.d.ts +24 -1
- package/lib/typescript/module/floatingMenu/AppHostLogic.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.web.d.ts +5 -2
- package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.web.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/FloatingDevTools.web.d.ts +2 -14
- package/lib/typescript/module/floatingMenu/FloatingDevTools.web.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/FloatingMenu.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/MinimizedToolsContext.d.ts +2 -20
- package/lib/typescript/module/floatingMenu/MinimizedToolsContext.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/MinimizedToolsStack.web.d.ts +21 -0
- package/lib/typescript/module/floatingMenu/MinimizedToolsStack.web.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/ToolHost.d.ts +72 -0
- package/lib/typescript/module/floatingMenu/ToolHost.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/allToolsRegistry.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/autoDiscoverPresets.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/autoExternalSync.d.ts.map +1 -1
- 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/DialDevTools.web.d.ts +16 -2
- package/lib/typescript/module/floatingMenu/dial/DialDevTools.web.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/dial/DialIcon.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/dial/OnboardingTooltip.web.d.ts +9 -0
- package/lib/typescript/module/floatingMenu/dial/OnboardingTooltip.web.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/dial/onboardingConstants.web.d.ts +13 -0
- package/lib/typescript/module/floatingMenu/dial/onboardingConstants.web.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/floatingTools.web.d.ts +29 -2
- package/lib/typescript/module/floatingMenu/floatingTools.web.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/types.d.ts +30 -1
- package/lib/typescript/module/floatingMenu/types.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +2 -0
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/index.web.d.ts +1 -0
- package/lib/typescript/module/index.web.d.ts.map +1 -1
- package/lib/typescript/module/toolkit.d.ts +22 -0
- package/lib/typescript/module/toolkit.d.ts.map +1 -0
- package/lib/typescript/module/utils/autoDiscoverPresets.web.d.ts +2 -0
- package/lib/typescript/module/utils/autoDiscoverPresets.web.d.ts.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* MinimizedToolsStack — Web twin of MinimizedToolsStack.tsx +
|
|
5
|
+
* shared-ui's ExpandablePopover (inlined: the popover is only used here on
|
|
6
|
+
* web). A vertical stack of minimized-tool icons fused to the top of the
|
|
7
|
+
* floating bubble's drag handle:
|
|
8
|
+
* - collapsed: a 28px "peek" tab (chevron-up + count) with top corners only
|
|
9
|
+
* - expanded: animated-height panel, icons newest-first, collapse chevron
|
|
10
|
+
* - expanded state persists under "@react_buoy_minimized_stack_expanded"
|
|
11
|
+
* - each icon runs the native randomized glitch loop (translateX shake +
|
|
12
|
+
* opacity flicker + scale pulse, 80ms), scheduled every 2-6s + index*300ms
|
|
13
|
+
*
|
|
14
|
+
* Data comes from the web AppHost (openApps with minimized === true) instead
|
|
15
|
+
* of the native MinimizedToolsContext — same derivation the MinimizedDock
|
|
16
|
+
* used before this replaced it.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
20
|
+
import { persistentStorage } from '@buoy-gg/shared-ui';
|
|
21
|
+
import { useAppHost } from "./AppHost.web.js";
|
|
22
|
+
|
|
23
|
+
// native MinimizedToolsStack.tsx constants
|
|
24
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
25
|
+
const PEEK_HEIGHT = 28;
|
|
26
|
+
const TOOL_ITEM_SIZE = 32;
|
|
27
|
+
const ICON_GAP = 6;
|
|
28
|
+
const TOOLBAR_PADDING = 8;
|
|
29
|
+
const COLLAPSE_BUTTON_SIZE = 24;
|
|
30
|
+
const STORAGE_KEY_EXPANDED = '@react_buoy_minimized_stack_expanded';
|
|
31
|
+
const GLITCH_DURATION_MS = 80;
|
|
32
|
+
const MIN_GLITCH_DELAY = 2000;
|
|
33
|
+
const MAX_GLITCH_DELAY = 6000;
|
|
34
|
+
|
|
35
|
+
// native shared-ui buoyColors (gameUIColors.ts) — card + textMuted
|
|
36
|
+
const CARD = '#1A1A1A';
|
|
37
|
+
const TEXT_MUTED = '#888888';
|
|
38
|
+
function ChevronGlyph({
|
|
39
|
+
down = false
|
|
40
|
+
}) {
|
|
41
|
+
// native: ChevronUp size 12, strokeWidth 2, buoyColors.textMuted
|
|
42
|
+
return /*#__PURE__*/_jsx("svg", {
|
|
43
|
+
width: 12,
|
|
44
|
+
height: 12,
|
|
45
|
+
viewBox: "0 0 24 24",
|
|
46
|
+
"aria-hidden": "true",
|
|
47
|
+
style: {
|
|
48
|
+
transform: down ? 'rotate(180deg)' : undefined
|
|
49
|
+
},
|
|
50
|
+
children: /*#__PURE__*/_jsx("path", {
|
|
51
|
+
d: "M18 15l-6-6-6 6",
|
|
52
|
+
fill: "none",
|
|
53
|
+
stroke: TEXT_MUTED,
|
|
54
|
+
strokeWidth: "2",
|
|
55
|
+
strokeLinecap: "round",
|
|
56
|
+
strokeLinejoin: "round"
|
|
57
|
+
})
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
function GlitchToolButton({
|
|
61
|
+
title,
|
|
62
|
+
icon,
|
|
63
|
+
index,
|
|
64
|
+
onPress
|
|
65
|
+
}) {
|
|
66
|
+
const innerRef = useRef(null);
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
let mounted = true;
|
|
69
|
+
let timer;
|
|
70
|
+
const runGlitch = () => {
|
|
71
|
+
// native: parallel translateX shake / opacity flicker / scale pulse,
|
|
72
|
+
// all inside GLITCH_DURATION_MS — one WAAPI animation with offsets.
|
|
73
|
+
innerRef.current?.animate([{
|
|
74
|
+
transform: 'translateX(0) scale(1)',
|
|
75
|
+
opacity: 1,
|
|
76
|
+
offset: 0
|
|
77
|
+
}, {
|
|
78
|
+
transform: 'translateX(3px) scale(1.05)',
|
|
79
|
+
opacity: 0.4,
|
|
80
|
+
offset: 0.2
|
|
81
|
+
}, {
|
|
82
|
+
transform: 'translateX(-3px) scale(1.1)',
|
|
83
|
+
opacity: 1,
|
|
84
|
+
offset: 0.4
|
|
85
|
+
}, {
|
|
86
|
+
transform: 'translateX(2px) scale(1.0)',
|
|
87
|
+
opacity: 0.6,
|
|
88
|
+
offset: 0.6
|
|
89
|
+
}, {
|
|
90
|
+
transform: 'translateX(-1px) scale(0.95)',
|
|
91
|
+
opacity: 1,
|
|
92
|
+
offset: 0.8
|
|
93
|
+
}, {
|
|
94
|
+
transform: 'translateX(0) scale(1)',
|
|
95
|
+
opacity: 1,
|
|
96
|
+
offset: 1
|
|
97
|
+
}], {
|
|
98
|
+
duration: GLITCH_DURATION_MS,
|
|
99
|
+
easing: 'linear'
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
const schedule = initial => {
|
|
103
|
+
const delay = initial ? 500 + Math.random() * 1500 + index * 200 : MIN_GLITCH_DELAY + Math.random() * (MAX_GLITCH_DELAY - MIN_GLITCH_DELAY) + index * 300;
|
|
104
|
+
timer = setTimeout(() => {
|
|
105
|
+
if (!mounted) return;
|
|
106
|
+
runGlitch();
|
|
107
|
+
schedule(false);
|
|
108
|
+
}, delay);
|
|
109
|
+
};
|
|
110
|
+
schedule(true);
|
|
111
|
+
return () => {
|
|
112
|
+
mounted = false;
|
|
113
|
+
clearTimeout(timer);
|
|
114
|
+
};
|
|
115
|
+
}, [index]);
|
|
116
|
+
return /*#__PURE__*/_jsx("button", {
|
|
117
|
+
type: "button",
|
|
118
|
+
"aria-label": `Restore ${title}`,
|
|
119
|
+
onClick: onPress,
|
|
120
|
+
style: {
|
|
121
|
+
width: TOOL_ITEM_SIZE,
|
|
122
|
+
height: TOOL_ITEM_SIZE,
|
|
123
|
+
display: 'flex',
|
|
124
|
+
alignItems: 'center',
|
|
125
|
+
justifyContent: 'center',
|
|
126
|
+
background: 'none',
|
|
127
|
+
border: 'none',
|
|
128
|
+
padding: 0,
|
|
129
|
+
cursor: 'pointer'
|
|
130
|
+
},
|
|
131
|
+
children: /*#__PURE__*/_jsx("div", {
|
|
132
|
+
ref: innerRef,
|
|
133
|
+
style: {
|
|
134
|
+
display: 'flex',
|
|
135
|
+
alignItems: 'center',
|
|
136
|
+
justifyContent: 'center'
|
|
137
|
+
},
|
|
138
|
+
children: icon
|
|
139
|
+
})
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
export function MinimizedToolsStack({
|
|
143
|
+
containerWidth = 32
|
|
144
|
+
}) {
|
|
145
|
+
const {
|
|
146
|
+
openApps,
|
|
147
|
+
restore
|
|
148
|
+
} = useAppHost();
|
|
149
|
+
const minimized = openApps.filter(app => app.minimized && app.launchMode !== 'toggle-only');
|
|
150
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
151
|
+
const [isStateRestored, setIsStateRestored] = useState(false);
|
|
152
|
+
|
|
153
|
+
// Restore + persist the expanded flag (native ExpandablePopover persistState).
|
|
154
|
+
useEffect(() => {
|
|
155
|
+
let cancelled = false;
|
|
156
|
+
const load = async () => {
|
|
157
|
+
const saved = await persistentStorage.getItem(STORAGE_KEY_EXPANDED);
|
|
158
|
+
if (!cancelled && saved === 'true') setIsExpanded(true);
|
|
159
|
+
if (!cancelled) setIsStateRestored(true);
|
|
160
|
+
};
|
|
161
|
+
void load();
|
|
162
|
+
return () => {
|
|
163
|
+
cancelled = true;
|
|
164
|
+
};
|
|
165
|
+
}, []);
|
|
166
|
+
useEffect(() => {
|
|
167
|
+
if (!isStateRestored) return;
|
|
168
|
+
void persistentStorage.setItem(STORAGE_KEY_EXPANDED, isExpanded ? 'true' : 'false');
|
|
169
|
+
}, [isExpanded, isStateRestored]);
|
|
170
|
+
const handleRestore = useCallback(instanceId => {
|
|
171
|
+
restore(instanceId);
|
|
172
|
+
}, [restore]);
|
|
173
|
+
if (minimized.length === 0) return null;
|
|
174
|
+
|
|
175
|
+
// native: expandedHeight = padding + n*item + (n-1)*gap + gap + collapse + 4
|
|
176
|
+
const expandedHeight = TOOLBAR_PADDING + minimized.length * TOOL_ITEM_SIZE + (minimized.length - 1) * ICON_GAP + ICON_GAP + COLLAPSE_BUTTON_SIZE + 4;
|
|
177
|
+
const frame = {
|
|
178
|
+
// native peekButton/expandedContainer: card bg, top corners 6, 1px border
|
|
179
|
+
// on top/left/right only (fuses with the bubble below)
|
|
180
|
+
backgroundColor: CARD,
|
|
181
|
+
borderTopLeftRadius: 6,
|
|
182
|
+
borderTopRightRadius: 6,
|
|
183
|
+
borderTop: `1px solid ${TEXT_MUTED}66`,
|
|
184
|
+
borderLeft: `1px solid ${TEXT_MUTED}66`,
|
|
185
|
+
borderRight: `1px solid ${TEXT_MUTED}66`,
|
|
186
|
+
borderBottom: 'none',
|
|
187
|
+
boxSizing: 'border-box'
|
|
188
|
+
};
|
|
189
|
+
return /*#__PURE__*/_jsxs("div", {
|
|
190
|
+
style: {
|
|
191
|
+
height: PEEK_HEIGHT,
|
|
192
|
+
overflow: 'visible',
|
|
193
|
+
position: 'relative'
|
|
194
|
+
},
|
|
195
|
+
children: [/*#__PURE__*/_jsx("div", {
|
|
196
|
+
style: {
|
|
197
|
+
position: 'absolute',
|
|
198
|
+
bottom: 0,
|
|
199
|
+
left: 0,
|
|
200
|
+
width: containerWidth,
|
|
201
|
+
height: isExpanded ? expandedHeight : 0,
|
|
202
|
+
opacity: isExpanded ? 1 : 0,
|
|
203
|
+
overflow: 'hidden',
|
|
204
|
+
transition: 'height 200ms ease, opacity 200ms ease',
|
|
205
|
+
pointerEvents: isExpanded ? 'auto' : 'none',
|
|
206
|
+
...frame
|
|
207
|
+
},
|
|
208
|
+
children: /*#__PURE__*/_jsxs("div", {
|
|
209
|
+
style: {
|
|
210
|
+
height: expandedHeight,
|
|
211
|
+
display: 'flex',
|
|
212
|
+
flexDirection: 'column',
|
|
213
|
+
alignItems: 'center',
|
|
214
|
+
paddingTop: TOOLBAR_PADDING,
|
|
215
|
+
gap: ICON_GAP,
|
|
216
|
+
boxSizing: 'border-box'
|
|
217
|
+
},
|
|
218
|
+
children: [[...minimized].reverse().map((app, index) => /*#__PURE__*/_jsx(GlitchToolButton, {
|
|
219
|
+
title: app.title || app.id,
|
|
220
|
+
icon: app.icon ?? /*#__PURE__*/_jsx("span", {
|
|
221
|
+
style: {
|
|
222
|
+
color: '#fff',
|
|
223
|
+
fontSize: 13
|
|
224
|
+
},
|
|
225
|
+
children: (app.title || app.id).slice(0, 1).toUpperCase()
|
|
226
|
+
}),
|
|
227
|
+
index: index,
|
|
228
|
+
onPress: () => handleRestore(app.instanceId)
|
|
229
|
+
}, app.instanceId)), /*#__PURE__*/_jsx("button", {
|
|
230
|
+
type: "button",
|
|
231
|
+
"aria-label": "Collapse",
|
|
232
|
+
onClick: () => setIsExpanded(false),
|
|
233
|
+
style: {
|
|
234
|
+
width: '100%',
|
|
235
|
+
height: COLLAPSE_BUTTON_SIZE,
|
|
236
|
+
marginTop: 3,
|
|
237
|
+
display: 'flex',
|
|
238
|
+
alignItems: 'center',
|
|
239
|
+
justifyContent: 'center',
|
|
240
|
+
background: 'none',
|
|
241
|
+
border: 'none',
|
|
242
|
+
cursor: 'pointer',
|
|
243
|
+
padding: 0
|
|
244
|
+
},
|
|
245
|
+
children: /*#__PURE__*/_jsx(ChevronGlyph, {
|
|
246
|
+
down: true
|
|
247
|
+
})
|
|
248
|
+
})]
|
|
249
|
+
})
|
|
250
|
+
}), /*#__PURE__*/_jsxs("button", {
|
|
251
|
+
type: "button",
|
|
252
|
+
"aria-label": `Show ${minimized.length} minimized tools`,
|
|
253
|
+
onClick: () => setIsExpanded(true),
|
|
254
|
+
style: {
|
|
255
|
+
position: 'absolute',
|
|
256
|
+
bottom: 0,
|
|
257
|
+
left: 0,
|
|
258
|
+
width: containerWidth,
|
|
259
|
+
height: PEEK_HEIGHT,
|
|
260
|
+
display: 'flex',
|
|
261
|
+
flexDirection: 'row',
|
|
262
|
+
alignItems: 'center',
|
|
263
|
+
justifyContent: 'center',
|
|
264
|
+
gap: 2,
|
|
265
|
+
cursor: 'pointer',
|
|
266
|
+
padding: 0,
|
|
267
|
+
opacity: isExpanded ? 0 : 1,
|
|
268
|
+
transform: isExpanded ? 'scale(0.9)' : 'scale(1)',
|
|
269
|
+
transition: 'opacity 200ms ease, transform 200ms ease',
|
|
270
|
+
pointerEvents: isExpanded ? 'none' : 'auto',
|
|
271
|
+
...frame
|
|
272
|
+
},
|
|
273
|
+
children: [/*#__PURE__*/_jsx(ChevronGlyph, {}), minimized.length > 1 && /*#__PURE__*/_jsx("span", {
|
|
274
|
+
style: {
|
|
275
|
+
fontSize: 9,
|
|
276
|
+
fontWeight: 600,
|
|
277
|
+
color: TEXT_MUTED,
|
|
278
|
+
marginLeft: 1
|
|
279
|
+
},
|
|
280
|
+
children: minimized.length
|
|
281
|
+
})]
|
|
282
|
+
})]
|
|
283
|
+
});
|
|
284
|
+
}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ToolHost — the declarative chrome layer for custom tools.
|
|
5
|
+
*
|
|
6
|
+
* When an `InstalledApp` declares `modal: {...}`, the AppHost renders its
|
|
7
|
+
* component inside `ToolModalShell` instead of raw: the shared JsModal
|
|
8
|
+
* (drag/resize, floating⇄bottom-sheet, minimize, dimension persistence) plus
|
|
9
|
+
* a managed header (title/subtitle, back navigation, search, actions) and a
|
|
10
|
+
* lightweight toast layer. The tool body talks back to the shell through
|
|
11
|
+
* `useToolHost()` / `useToolHeader()`.
|
|
12
|
+
*/
|
|
13
|
+
import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
14
|
+
import { Animated, StyleSheet, Text, View } from "react-native";
|
|
15
|
+
import { JsModal, ModalHeader, HeaderSearchButton, devToolsStorageKeys, buoyColors, gameUIColors } from "@buoy-gg/shared-ui";
|
|
16
|
+
|
|
17
|
+
/** Per-screen header overrides a tool body can apply (see `useToolHeader`). */
|
|
18
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
19
|
+
const noop = () => {};
|
|
20
|
+
const FALLBACK_CONTEXT = {
|
|
21
|
+
search: "",
|
|
22
|
+
isSearchActive: false,
|
|
23
|
+
clearSearch: noop,
|
|
24
|
+
close: noop,
|
|
25
|
+
showToast: noop,
|
|
26
|
+
setHeaderOverride: noop
|
|
27
|
+
};
|
|
28
|
+
const ToolHostContext = /*#__PURE__*/createContext(null);
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Access the hosting shell from a custom tool body: search query, toasts,
|
|
32
|
+
* close. Safe to call outside the shell (returns inert no-ops) so tool
|
|
33
|
+
* components can also be mounted standalone.
|
|
34
|
+
*/
|
|
35
|
+
export function useToolHost() {
|
|
36
|
+
return useContext(ToolHostContext) ?? FALLBACK_CONTEXT;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Declare per-screen header state (title/subtitle/actions/back) from inside a
|
|
41
|
+
* tool body. Applies while the calling component is mounted and reverts to
|
|
42
|
+
* the preset's static config on unmount — so a detail screen simply mounts
|
|
43
|
+
* with its own header and the list header returns when it unmounts.
|
|
44
|
+
*
|
|
45
|
+
* ```tsx
|
|
46
|
+
* useToolHeader(
|
|
47
|
+
* { title: flag.key, onBack: () => setScreen("list"), actions: <CopyButton value={flag} /> },
|
|
48
|
+
* [flag.key]
|
|
49
|
+
* );
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export function useToolHeader(override, deps) {
|
|
53
|
+
const {
|
|
54
|
+
setHeaderOverride
|
|
55
|
+
} = useToolHost();
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
setHeaderOverride(override);
|
|
58
|
+
return () => setHeaderOverride(null);
|
|
59
|
+
// Caller-provided deps intentionally control when the override refreshes.
|
|
60
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
61
|
+
}, deps);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
// Toast layer
|
|
66
|
+
// ---------------------------------------------------------------------------
|
|
67
|
+
|
|
68
|
+
const TOAST_DURATION_MS = 2200;
|
|
69
|
+
const TOAST_COLORS = {
|
|
70
|
+
success: gameUIColors.success,
|
|
71
|
+
error: gameUIColors.error,
|
|
72
|
+
info: gameUIColors.info
|
|
73
|
+
};
|
|
74
|
+
function ToastView({
|
|
75
|
+
message,
|
|
76
|
+
type,
|
|
77
|
+
nonce
|
|
78
|
+
}) {
|
|
79
|
+
const opacity = useRef(new Animated.Value(0)).current;
|
|
80
|
+
useEffect(() => {
|
|
81
|
+
opacity.setValue(0);
|
|
82
|
+
Animated.sequence([Animated.timing(opacity, {
|
|
83
|
+
toValue: 1,
|
|
84
|
+
duration: 150,
|
|
85
|
+
useNativeDriver: true
|
|
86
|
+
}), Animated.delay(TOAST_DURATION_MS - 450), Animated.timing(opacity, {
|
|
87
|
+
toValue: 0,
|
|
88
|
+
duration: 300,
|
|
89
|
+
useNativeDriver: true
|
|
90
|
+
})]).start();
|
|
91
|
+
}, [nonce, opacity]);
|
|
92
|
+
const color = TOAST_COLORS[type];
|
|
93
|
+
return /*#__PURE__*/_jsxs(Animated.View, {
|
|
94
|
+
pointerEvents: "none",
|
|
95
|
+
style: [styles.toast, {
|
|
96
|
+
opacity,
|
|
97
|
+
borderColor: color + "60"
|
|
98
|
+
}],
|
|
99
|
+
children: [/*#__PURE__*/_jsx(View, {
|
|
100
|
+
style: [styles.toastDot, {
|
|
101
|
+
backgroundColor: color
|
|
102
|
+
}]
|
|
103
|
+
}), /*#__PURE__*/_jsx(Text, {
|
|
104
|
+
style: styles.toastText,
|
|
105
|
+
numberOfLines: 2,
|
|
106
|
+
children: message
|
|
107
|
+
})]
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
// Shell
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
|
|
115
|
+
export function ToolModalShell({
|
|
116
|
+
app,
|
|
117
|
+
config,
|
|
118
|
+
visible,
|
|
119
|
+
zIndex,
|
|
120
|
+
onClose,
|
|
121
|
+
onMinimize,
|
|
122
|
+
initialModalState,
|
|
123
|
+
enableSharedModalDimensions,
|
|
124
|
+
bodyProps
|
|
125
|
+
}) {
|
|
126
|
+
const Body = app.component;
|
|
127
|
+
const [isSearchActive, setIsSearchActive] = useState(false);
|
|
128
|
+
const [search, setSearch] = useState("");
|
|
129
|
+
const [headerOverride, setHeaderOverride] = useState(null);
|
|
130
|
+
const [toast, setToast] = useState(null);
|
|
131
|
+
const toastTimeoutRef = useRef(null);
|
|
132
|
+
const clearSearch = useCallback(() => {
|
|
133
|
+
setIsSearchActive(false);
|
|
134
|
+
setSearch("");
|
|
135
|
+
}, []);
|
|
136
|
+
const showToast = useCallback((message, type = "info") => {
|
|
137
|
+
if (toastTimeoutRef.current) clearTimeout(toastTimeoutRef.current);
|
|
138
|
+
setToast(prev => ({
|
|
139
|
+
message,
|
|
140
|
+
type,
|
|
141
|
+
nonce: (prev?.nonce ?? 0) + 1
|
|
142
|
+
}));
|
|
143
|
+
toastTimeoutRef.current = setTimeout(() => setToast(null), TOAST_DURATION_MS);
|
|
144
|
+
}, []);
|
|
145
|
+
useEffect(() => {
|
|
146
|
+
return () => {
|
|
147
|
+
if (toastTimeoutRef.current) clearTimeout(toastTimeoutRef.current);
|
|
148
|
+
};
|
|
149
|
+
}, []);
|
|
150
|
+
const contextValue = useMemo(() => ({
|
|
151
|
+
search: isSearchActive ? search : "",
|
|
152
|
+
isSearchActive,
|
|
153
|
+
clearSearch,
|
|
154
|
+
close: onClose,
|
|
155
|
+
showToast,
|
|
156
|
+
setHeaderOverride,
|
|
157
|
+
instanceId: app.instanceId
|
|
158
|
+
}), [search, isSearchActive, clearSearch, onClose, showToast, app.instanceId]);
|
|
159
|
+
const title = headerOverride?.title ?? config.title ?? app.title ?? app.id;
|
|
160
|
+
const subtitle = headerOverride?.subtitle ?? config.subtitle;
|
|
161
|
+
const onBack = headerOverride?.onBack;
|
|
162
|
+
const actions = headerOverride?.actions ?? config.headerActions;
|
|
163
|
+
|
|
164
|
+
// Tool-scoped persistence via the custom namespace unless the user has the
|
|
165
|
+
// shared-dimensions global setting on (all tools share one window size).
|
|
166
|
+
const persistenceKey = enableSharedModalDimensions ? devToolsStorageKeys.modal.root() : devToolsStorageKeys.custom(app.id).modal();
|
|
167
|
+
const header = /*#__PURE__*/_jsxs(ModalHeader, {
|
|
168
|
+
children: [onBack && !isSearchActive && /*#__PURE__*/_jsx(ModalHeader.Navigation, {
|
|
169
|
+
onBack: onBack
|
|
170
|
+
}), isSearchActive ? /*#__PURE__*/_jsx(ModalHeader.Search, {
|
|
171
|
+
value: search,
|
|
172
|
+
onChangeText: setSearch,
|
|
173
|
+
onCancel: clearSearch,
|
|
174
|
+
placeholder: config.searchPlaceholder
|
|
175
|
+
}) : /*#__PURE__*/_jsx(ModalHeader.Content, {
|
|
176
|
+
title: title,
|
|
177
|
+
subtitle: subtitle
|
|
178
|
+
}), /*#__PURE__*/_jsxs(ModalHeader.Actions, {
|
|
179
|
+
children: [!isSearchActive && actions, config.searchable && !isSearchActive && /*#__PURE__*/_jsx(HeaderSearchButton, {
|
|
180
|
+
onPress: () => setIsSearchActive(true)
|
|
181
|
+
})]
|
|
182
|
+
})]
|
|
183
|
+
});
|
|
184
|
+
return /*#__PURE__*/_jsx(ToolHostContext.Provider, {
|
|
185
|
+
value: contextValue,
|
|
186
|
+
children: /*#__PURE__*/_jsx(JsModal, {
|
|
187
|
+
visible: visible,
|
|
188
|
+
onClose: onClose,
|
|
189
|
+
onBack: onBack,
|
|
190
|
+
onMinimize: onMinimize,
|
|
191
|
+
initialModalState: initialModalState,
|
|
192
|
+
zIndex: zIndex,
|
|
193
|
+
persistenceKey: persistenceKey,
|
|
194
|
+
enablePersistence: true,
|
|
195
|
+
initialMode: config.initialMode ?? "bottomSheet",
|
|
196
|
+
header: {
|
|
197
|
+
customContent: header,
|
|
198
|
+
showToggleButton: true
|
|
199
|
+
}
|
|
200
|
+
// Tool bodies own their scrolling (ScrollView/FlatList) — the shell
|
|
201
|
+
// must not add a competing wrapper.
|
|
202
|
+
,
|
|
203
|
+
disableScrollWrapper: true,
|
|
204
|
+
styles: {},
|
|
205
|
+
children: /*#__PURE__*/_jsxs(View, {
|
|
206
|
+
style: styles.bodyRoot,
|
|
207
|
+
children: [/*#__PURE__*/_jsx(Body, {
|
|
208
|
+
...bodyProps
|
|
209
|
+
}), toast && /*#__PURE__*/_jsx(ToastView, {
|
|
210
|
+
message: toast.message,
|
|
211
|
+
type: toast.type,
|
|
212
|
+
nonce: toast.nonce
|
|
213
|
+
})]
|
|
214
|
+
})
|
|
215
|
+
})
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
const styles = StyleSheet.create({
|
|
219
|
+
bodyRoot: {
|
|
220
|
+
flex: 1,
|
|
221
|
+
minHeight: 0,
|
|
222
|
+
backgroundColor: buoyColors.base
|
|
223
|
+
},
|
|
224
|
+
toast: {
|
|
225
|
+
position: "absolute",
|
|
226
|
+
bottom: 16,
|
|
227
|
+
alignSelf: "center",
|
|
228
|
+
flexDirection: "row",
|
|
229
|
+
alignItems: "center",
|
|
230
|
+
gap: 8,
|
|
231
|
+
maxWidth: "86%",
|
|
232
|
+
backgroundColor: buoyColors.card,
|
|
233
|
+
borderWidth: 1,
|
|
234
|
+
borderRadius: 8,
|
|
235
|
+
paddingHorizontal: 12,
|
|
236
|
+
paddingVertical: 8,
|
|
237
|
+
shadowColor: "#000",
|
|
238
|
+
shadowOpacity: 0.4,
|
|
239
|
+
shadowRadius: 8,
|
|
240
|
+
shadowOffset: {
|
|
241
|
+
width: 0,
|
|
242
|
+
height: 2
|
|
243
|
+
},
|
|
244
|
+
elevation: 6
|
|
245
|
+
},
|
|
246
|
+
toastDot: {
|
|
247
|
+
width: 6,
|
|
248
|
+
height: 6,
|
|
249
|
+
borderRadius: 3
|
|
250
|
+
},
|
|
251
|
+
toastText: {
|
|
252
|
+
flex: 1,
|
|
253
|
+
fontSize: 12,
|
|
254
|
+
color: buoyColors.text
|
|
255
|
+
}
|
|
256
|
+
});
|
|
@@ -27,7 +27,7 @@ import { ImageOverlayIcon } from "@buoy-gg/shared-ui";
|
|
|
27
27
|
// in shared/icons/*.json and generated into @buoy-gg/floating-tools-core, which
|
|
28
28
|
// IS a required dependency. Unavailable items therefore render the ACTUAL tool
|
|
29
29
|
// icon (just dimmed by DialIcon), and it can no longer drift from the real one.
|
|
30
|
-
import { ZustandIcon, ZUSTAND_ICON_COLOR, JotaiIcon, JOTAI_ICON_COLOR, IMAGE_OVERLAY_ICON_COLOR } from "@buoy-gg/floating-tools-core";
|
|
30
|
+
import { ZustandIcon, ZUSTAND_ICON_COLOR, JotaiIcon, JOTAI_ICON_COLOR, IMAGE_OVERLAY_ICON_COLOR, TimeMachineIcon, TIME_MACHINE_ICON_COLOR } from "@buoy-gg/floating-tools-core";
|
|
31
31
|
|
|
32
32
|
// ─── Registry entry type ──────────────────────────────────────────────────────
|
|
33
33
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
@@ -109,6 +109,13 @@ export const ALL_TOOLS_REGISTRY = [{
|
|
|
109
109
|
renderIcon: size => /*#__PURE__*/_jsx(EventsIcon, {
|
|
110
110
|
size: size
|
|
111
111
|
})
|
|
112
|
+
}, {
|
|
113
|
+
id: "time-machine",
|
|
114
|
+
name: "TIME MACHINE",
|
|
115
|
+
color: TIME_MACHINE_ICON_COLOR,
|
|
116
|
+
renderIcon: size => /*#__PURE__*/_jsx(TimeMachineIcon, {
|
|
117
|
+
size: size
|
|
118
|
+
})
|
|
112
119
|
}, {
|
|
113
120
|
id: "jotai",
|
|
114
121
|
name: "JOTAI",
|
|
@@ -185,6 +185,22 @@ export function autoDiscoverPresets() {
|
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
},
|
|
188
|
+
// Time Machine
|
|
189
|
+
{
|
|
190
|
+
name: "@buoy-gg/time-machine",
|
|
191
|
+
loader: () => {
|
|
192
|
+
try {
|
|
193
|
+
// @ts-ignore - Dynamic import that may not exist
|
|
194
|
+
const {
|
|
195
|
+
timeMachineToolPreset
|
|
196
|
+
} = require("@buoy-gg/time-machine");
|
|
197
|
+
return timeMachineToolPreset;
|
|
198
|
+
} catch (e) {
|
|
199
|
+
reportOptionalRequireError("@buoy-gg/time-machine", e);
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
},
|
|
188
204
|
// Redux DevTools
|
|
189
205
|
{
|
|
190
206
|
name: "@buoy-gg/redux",
|
|
@@ -314,6 +330,22 @@ export function autoDiscoverPresets() {
|
|
|
314
330
|
return null;
|
|
315
331
|
}
|
|
316
332
|
}
|
|
333
|
+
},
|
|
334
|
+
// ASSETS — bundled-asset inventory (sizes / scale coverage / unused)
|
|
335
|
+
{
|
|
336
|
+
name: "@buoy-gg/assets",
|
|
337
|
+
loader: () => {
|
|
338
|
+
try {
|
|
339
|
+
// @ts-ignore - Dynamic import that may not exist
|
|
340
|
+
const {
|
|
341
|
+
assetsToolPreset
|
|
342
|
+
} = require("@buoy-gg/assets");
|
|
343
|
+
return assetsToolPreset;
|
|
344
|
+
} catch (e) {
|
|
345
|
+
reportOptionalRequireError("@buoy-gg/assets", e);
|
|
346
|
+
return null;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
317
349
|
}];
|
|
318
350
|
|
|
319
351
|
// Attempt to load each preset
|
|
@@ -39,6 +39,7 @@ let zustandModule = null;
|
|
|
39
39
|
let jotaiModule = null;
|
|
40
40
|
let eventsModule = null;
|
|
41
41
|
let consoleModule = null;
|
|
42
|
+
let timeMachineModule = null;
|
|
42
43
|
let envModule = null;
|
|
43
44
|
let highlightUpdatesModule = null;
|
|
44
45
|
let debugBordersModule = null;
|
|
@@ -46,6 +47,7 @@ let impersonateModule = null;
|
|
|
46
47
|
let perfMonitorModule = null;
|
|
47
48
|
let jsTopModule = null;
|
|
48
49
|
let imagesModule = null;
|
|
50
|
+
let assetsModule = null;
|
|
49
51
|
let expoConstantsModule = null;
|
|
50
52
|
|
|
51
53
|
// Catch bodies report through reportOptionalRequireError: silent for a
|
|
@@ -101,6 +103,11 @@ try {
|
|
|
101
103
|
} catch (e) {
|
|
102
104
|
reportOptionalRequireError("@buoy-gg/console", e);
|
|
103
105
|
}
|
|
106
|
+
try {
|
|
107
|
+
timeMachineModule = require("@buoy-gg/time-machine");
|
|
108
|
+
} catch (e) {
|
|
109
|
+
reportOptionalRequireError("@buoy-gg/time-machine", e);
|
|
110
|
+
}
|
|
104
111
|
try {
|
|
105
112
|
envModule = require("@buoy-gg/env");
|
|
106
113
|
} catch (e) {
|
|
@@ -136,6 +143,11 @@ try {
|
|
|
136
143
|
} catch (e) {
|
|
137
144
|
reportOptionalRequireError("@buoy-gg/images", e);
|
|
138
145
|
}
|
|
146
|
+
try {
|
|
147
|
+
assetsModule = require("@buoy-gg/assets");
|
|
148
|
+
} catch (e) {
|
|
149
|
+
reportOptionalRequireError("@buoy-gg/assets", e);
|
|
150
|
+
}
|
|
139
151
|
try {
|
|
140
152
|
expoConstantsModule = require("expo-constants");
|
|
141
153
|
} catch (e) {
|
|
@@ -249,6 +261,9 @@ export function AutoExternalSync({
|
|
|
249
261
|
if (consoleModule?.consoleSyncAdapter) {
|
|
250
262
|
map.console = consoleModule.consoleSyncAdapter;
|
|
251
263
|
}
|
|
264
|
+
if (timeMachineModule?.timeMachineSyncAdapter) {
|
|
265
|
+
map["time-machine"] = timeMachineModule.timeMachineSyncAdapter;
|
|
266
|
+
}
|
|
252
267
|
if (envModule?.createEnvSyncAdapter) {
|
|
253
268
|
map.env = envModule.createEnvSyncAdapter(requiredEnvVars ?? []);
|
|
254
269
|
}
|
|
@@ -270,6 +285,9 @@ export function AutoExternalSync({
|
|
|
270
285
|
if (imagesModule?.imagesSyncAdapter) {
|
|
271
286
|
map.images = imagesModule.imagesSyncAdapter;
|
|
272
287
|
}
|
|
288
|
+
if (assetsModule?.assetsSyncAdapter) {
|
|
289
|
+
map.assets = assetsModule.assetsSyncAdapter;
|
|
290
|
+
}
|
|
273
291
|
return map;
|
|
274
292
|
}, [queryAdapter, requiredEnvVars]);
|
|
275
293
|
useExternalSync({
|
|
@@ -11,9 +11,9 @@ import { getRankedToolIds, isDialUsageLoaded, loadDialUsage, recordToolUsage } f
|
|
|
11
11
|
import { persistentStorage, useHintsDisabled, devToolsStorageKeys, buoyColors } from "@buoy-gg/shared-ui";
|
|
12
12
|
import { DevToolsSettingsModal, useDevToolsSettings } from "../DevToolsSettingsModal";
|
|
13
13
|
import { useProAccess } from "@buoy-gg/license";
|
|
14
|
-
import { useAppHost } from "../AppHost
|
|
15
|
-
import { OnboardingTooltip } from "./OnboardingTooltip
|
|
16
|
-
import { getDialLayout, MAX_DIAL_SLOTS, DIAL_BUTTON_SIZE,
|
|
14
|
+
import { useAppHost } from "../AppHost";
|
|
15
|
+
import { OnboardingTooltip } from "./OnboardingTooltip";
|
|
16
|
+
import { getDialLayout, MAX_DIAL_SLOTS, DIAL_BUTTON_SIZE, DIAL_ICON_GLYPH_SIZE, dialAnimationConfig, dialColors } from "@buoy-gg/floating-tools-core";
|
|
17
17
|
|
|
18
18
|
// The circle size depends on the live window width, so it's computed inside
|
|
19
19
|
// the component via useWindowDimensions — a module-scope Dimensions.get
|
|
@@ -200,7 +200,8 @@ export const DialDevTools = ({
|
|
|
200
200
|
launchMode: app.launchMode ?? "self-modal",
|
|
201
201
|
singleton: app.singleton ?? true,
|
|
202
202
|
icon: resolvedIcon,
|
|
203
|
-
color: app.color
|
|
203
|
+
color: app.color,
|
|
204
|
+
modal: app.modal
|
|
204
205
|
});
|
|
205
206
|
}
|
|
206
207
|
|
|
@@ -227,8 +228,11 @@ export const DialDevTools = ({
|
|
|
227
228
|
map.set(tool.id, {
|
|
228
229
|
id: tool.id,
|
|
229
230
|
name: tool.name,
|
|
230
|
-
// Pre-render the icon at the standard
|
|
231
|
-
|
|
231
|
+
// Pre-render the icon at the standard GLYPH size (not the slot size —
|
|
232
|
+
// the slot also holds the label + "Unavailable" caption, so a glyph
|
|
233
|
+
// rendered at DIAL_ICON_SIZE overflows the slot and looks ~2x bigger
|
|
234
|
+
// than installed tools' icons).
|
|
235
|
+
icon: tool.renderIcon(DIAL_ICON_GLYPH_SIZE),
|
|
232
236
|
iconComponent: undefined,
|
|
233
237
|
color: tool.color,
|
|
234
238
|
unavailable: true,
|