@buoy-gg/core 2.1.14 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/lib/commonjs/floatingMenu/DevToolsSettingsModal.js +3 -33
  2. package/lib/commonjs/floatingMenu/DevToolsSettingsModal.web.js +3 -25
  3. package/lib/commonjs/floatingMenu/FloatingDevTools.js +14 -1
  4. package/lib/commonjs/floatingMenu/FloatingDevTools.web.js +19 -9
  5. package/lib/commonjs/floatingMenu/FloatingMenu.js +6 -2
  6. package/lib/commonjs/floatingMenu/dial/DialDevTools.js +166 -196
  7. package/lib/commonjs/floatingMenu/dial/DialDevTools.web.js +82 -7
  8. package/lib/commonjs/floatingMenu/dial/DialIcon.js +66 -59
  9. package/lib/commonjs/floatingMenu/dial/DialPagination.js +170 -0
  10. package/lib/commonjs/floatingMenu/dial/dialUsageStore.js +97 -0
  11. package/lib/module/floatingMenu/DevToolsSettingsModal.js +3 -33
  12. package/lib/module/floatingMenu/DevToolsSettingsModal.web.js +4 -28
  13. package/lib/module/floatingMenu/FloatingDevTools.js +14 -1
  14. package/lib/module/floatingMenu/FloatingDevTools.web.js +19 -9
  15. package/lib/module/floatingMenu/FloatingMenu.js +6 -2
  16. package/lib/module/floatingMenu/dial/DialDevTools.js +166 -196
  17. package/lib/module/floatingMenu/dial/DialDevTools.web.js +82 -7
  18. package/lib/module/floatingMenu/dial/DialIcon.js +67 -60
  19. package/lib/module/floatingMenu/dial/DialPagination.js +165 -0
  20. package/lib/module/floatingMenu/dial/dialUsageStore.js +89 -0
  21. package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.d.ts.map +1 -1
  22. package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.web.d.ts.map +1 -1
  23. package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.d.ts.map +1 -1
  24. package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.web.d.ts.map +1 -1
  25. package/lib/typescript/commonjs/floatingMenu/FloatingMenu.d.ts.map +1 -1
  26. package/lib/typescript/commonjs/floatingMenu/dial/DialDevTools.d.ts +0 -2
  27. package/lib/typescript/commonjs/floatingMenu/dial/DialDevTools.d.ts.map +1 -1
  28. package/lib/typescript/commonjs/floatingMenu/dial/DialDevTools.web.d.ts.map +1 -1
  29. package/lib/typescript/commonjs/floatingMenu/dial/DialIcon.d.ts +7 -2
  30. package/lib/typescript/commonjs/floatingMenu/dial/DialIcon.d.ts.map +1 -1
  31. package/lib/typescript/commonjs/floatingMenu/dial/DialPagination.d.ts +22 -0
  32. package/lib/typescript/commonjs/floatingMenu/dial/DialPagination.d.ts.map +1 -0
  33. package/lib/typescript/commonjs/floatingMenu/dial/dialUsageStore.d.ts +34 -0
  34. package/lib/typescript/commonjs/floatingMenu/dial/dialUsageStore.d.ts.map +1 -0
  35. package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.d.ts.map +1 -1
  36. package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.web.d.ts.map +1 -1
  37. package/lib/typescript/module/floatingMenu/FloatingDevTools.d.ts.map +1 -1
  38. package/lib/typescript/module/floatingMenu/FloatingDevTools.web.d.ts.map +1 -1
  39. package/lib/typescript/module/floatingMenu/FloatingMenu.d.ts.map +1 -1
  40. package/lib/typescript/module/floatingMenu/dial/DialDevTools.d.ts +0 -2
  41. package/lib/typescript/module/floatingMenu/dial/DialDevTools.d.ts.map +1 -1
  42. package/lib/typescript/module/floatingMenu/dial/DialDevTools.web.d.ts.map +1 -1
  43. package/lib/typescript/module/floatingMenu/dial/DialIcon.d.ts +7 -2
  44. package/lib/typescript/module/floatingMenu/dial/DialIcon.d.ts.map +1 -1
  45. package/lib/typescript/module/floatingMenu/dial/DialPagination.d.ts +22 -0
  46. package/lib/typescript/module/floatingMenu/dial/DialPagination.d.ts.map +1 -0
  47. package/lib/typescript/module/floatingMenu/dial/dialUsageStore.d.ts +34 -0
  48. package/lib/typescript/module/floatingMenu/dial/dialUsageStore.d.ts.map +1 -0
  49. package/package.json +5 -5
@@ -154,7 +154,7 @@ const DevToolsSettingsModal = ({
154
154
  const allowedDialKeys = (0, _react.useMemo)(() => Object.keys(defaultSettings.dialTools), [defaultSettings]);
155
155
  const allowedFloatingKeys = (0, _react.useMemo)(() => Object.keys(defaultSettings.floatingTools).filter(key => key !== "environment"), [defaultSettings]);
156
156
  const [settings, setSettings] = (0, _react.useState)(initialSettings || defaultSettings);
157
- const [activeTab, setActiveTab] = (0, _react.useState)("dial");
157
+ const [activeTab, setActiveTab] = (0, _react.useState)("floating");
158
158
  const [activeTabLoaded, setActiveTabLoaded] = (0, _react.useState)(false);
159
159
  const [expandedSettings, setExpandedSettings] = (0, _react.useState)(new Set());
160
160
  const [showLicenseModal, setShowLicenseModal] = (0, _react.useState)(false);
@@ -164,7 +164,7 @@ const DevToolsSettingsModal = ({
164
164
  const loadActiveTab = async () => {
165
165
  try {
166
166
  const savedTab = await _sharedUi.persistentStorage.getItem(_sharedUi.devToolsStorageKeys.settings.activeTab());
167
- if (savedTab && ["dial", "floating", "settings", "pro"].includes(savedTab)) {
167
+ if (savedTab && ["floating", "settings", "pro"].includes(savedTab)) {
168
168
  setActiveTab(savedTab);
169
169
  }
170
170
  } catch (error) {
@@ -262,23 +262,6 @@ const DevToolsSettingsModal = ({
262
262
  console.error("Failed to save dev tools settings:", error);
263
263
  }
264
264
  };
265
- const toggleDialTool = tool => {
266
- const currentEnabled = Object.values(settings.dialTools).filter(v => v).length;
267
- const isCurrentlyEnabled = settings.dialTools[tool];
268
-
269
- // If trying to enable and already at 6, don't allow
270
- if (!isCurrentlyEnabled && currentEnabled >= MAX_DIAL_SLOTS) {
271
- return; // Could also show a toast/alert here
272
- }
273
- const newSettings = {
274
- ...settings,
275
- dialTools: {
276
- ...settings.dialTools,
277
- [tool]: !settings.dialTools[tool]
278
- }
279
- };
280
- saveSettings(newSettings);
281
- };
282
265
  const toggleFloatingTool = tool => {
283
266
  const newSettings = {
284
267
  ...settings,
@@ -646,17 +629,7 @@ const DevToolsSettingsModal = ({
646
629
  style: styles.scrollContent,
647
630
  showsVerticalScrollIndicator: false,
648
631
  contentContainerStyle: styles.scrollContainer,
649
- children: [activeTab === "dial" && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
650
- style: styles.section,
651
- children: (() => {
652
- const enabledCount = Object.values(settings.dialTools).filter(v => v).length;
653
- const isAtLimit = enabledCount >= MAX_DIAL_SLOTS;
654
- return Object.entries(settings.dialTools).map(([key, value]) => {
655
- const isDisabled = !value && isAtLimit;
656
- return renderToolCard(key, value, isDisabled, () => toggleDialTool(key));
657
- });
658
- })()
659
- }), activeTab === "floating" && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
632
+ children: [activeTab === "floating" && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
660
633
  style: styles.section,
661
634
  children: Object.entries(settings.floatingTools).map(([key, value]) => renderToolCard(key, value, false, () => toggleFloatingTool(key)))
662
635
  }), activeTab === "settings" && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
@@ -1111,9 +1084,6 @@ const DevToolsSettingsModal = ({
1111
1084
  noMargin: true,
1112
1085
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.TabSelector, {
1113
1086
  tabs: [{
1114
- key: "dial",
1115
- label: "DIAL"
1116
- }, {
1117
1087
  key: "floating",
1118
1088
  label: "FLOATING"
1119
1089
  }, {
@@ -434,15 +434,14 @@ function SettingsModal({
434
434
  storage = webStorageAdapter,
435
435
  onSettingsChange
436
436
  }) {
437
- const [activeTab, setActiveTab] = (0, _react.useState)('dial');
437
+ const [activeTab, setActiveTab] = (0, _react.useState)('floating');
438
438
  const [isExiting, setIsExiting] = (0, _react.useState)(false);
439
439
 
440
440
  // Use the shared settings hook
441
441
  const {
442
442
  settings,
443
443
  isLoading,
444
- actions,
445
- helpers
444
+ actions
446
445
  } = (0, _floatingToolsReact.useSettings)({
447
446
  availableTools,
448
447
  defaultFloatingTools,
@@ -595,28 +594,7 @@ function SettingsModal({
595
594
  },
596
595
  children: "Loading settings..."
597
596
  }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
598
- children: [activeTab === 'dial' && /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
599
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
600
- style: {
601
- fontSize: _floatingToolsReact.settingsStyles.sectionTitle.fontSize,
602
- fontWeight: _floatingToolsReact.settingsStyles.sectionTitle.fontWeight,
603
- letterSpacing: _floatingToolsReact.settingsStyles.sectionTitle.letterSpacing,
604
- textTransform: _floatingToolsReact.settingsStyles.sectionTitle.textTransform,
605
- color: _floatingToolsReact.settingsColors.textMuted,
606
- marginBottom: _floatingToolsReact.settingsStyles.sectionHeader.marginBottom
607
- },
608
- children: ["SELECT UP TO ", _floatingToolsReact.MAX_SETTINGS_DIAL_SLOTS, " TOOLS (", helpers.dialToolCount, "/", _floatingToolsReact.MAX_SETTINGS_DIAL_SLOTS, ")"]
609
- }), Object.entries(settings.dialTools).map(([id, enabled]) => {
610
- const isDisabled = !enabled && helpers.isDialFull;
611
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(ToolCard, {
612
- toolId: id,
613
- enabled: enabled,
614
- disabled: isDisabled,
615
- availableTools: availableTools,
616
- onToggle: () => actions.toggleDialTool(id)
617
- }, id);
618
- })]
619
- }), activeTab === 'floating' && /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
597
+ children: [activeTab === 'floating' && /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
620
598
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
621
599
  style: {
622
600
  fontSize: _floatingToolsReact.settingsStyles.sectionTitle.fontSize,
@@ -277,6 +277,19 @@ const FloatingDevTools = ({
277
277
  }
278
278
  }, []);
279
279
 
280
+ // Check if impersonate is installed and auto-render the floating banner
281
+ const ImpersonateOverlay = (0, _react.useMemo)(() => {
282
+ try {
283
+ // @ts-ignore - Dynamic import that may not exist
284
+ const {
285
+ ImpersonateOverlay: Overlay
286
+ } = require("@buoy-gg/impersonate");
287
+ return Overlay;
288
+ } catch {
289
+ return null;
290
+ }
291
+ }, []);
292
+
280
293
  // Get tool icon helper for the MinimizedToolsProvider
281
294
  const getToolIcon = (0, _react.useCallback)(id => {
282
295
  const tool = finalApps.find(app => app.id === id);
@@ -329,7 +342,7 @@ const FloatingDevTools = ({
329
342
  environment: resolvedEnvironment
330
343
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_AppHost.AppOverlay, {})]
331
344
  })
332
- }), children, DebugBordersOverlay && /*#__PURE__*/(0, _jsxRuntime.jsx)(DebugBordersOverlay, {}), HighlightUpdatesOverlay && /*#__PURE__*/(0, _jsxRuntime.jsx)(HighlightUpdatesOverlay, {}), ImageOverlayOverlay && /*#__PURE__*/(0, _jsxRuntime.jsx)(ImageOverlayOverlay, {}), PerfMonitorOverlay && /*#__PURE__*/(0, _jsxRuntime.jsx)(PerfMonitorOverlay, {}), RouteTracker && /*#__PURE__*/(0, _jsxRuntime.jsx)(RouteTracker, {})]
345
+ }), children, DebugBordersOverlay && /*#__PURE__*/(0, _jsxRuntime.jsx)(DebugBordersOverlay, {}), HighlightUpdatesOverlay && /*#__PURE__*/(0, _jsxRuntime.jsx)(HighlightUpdatesOverlay, {}), ImageOverlayOverlay && /*#__PURE__*/(0, _jsxRuntime.jsx)(ImageOverlayOverlay, {}), PerfMonitorOverlay && /*#__PURE__*/(0, _jsxRuntime.jsx)(PerfMonitorOverlay, {}), ImpersonateOverlay && /*#__PURE__*/(0, _jsxRuntime.jsx)(ImpersonateOverlay, {}), RouteTracker && /*#__PURE__*/(0, _jsxRuntime.jsx)(RouteTracker, {})]
333
346
  })
334
347
  })
335
348
  })
@@ -9,6 +9,7 @@ var _floatingToolsReact = require("@buoy-gg/floating-tools-react");
9
9
  var _autoDiscoverPresetsWeb = require("../utils/autoDiscoverPresets.web.js");
10
10
  var _floatingToolsWeb = require("./floatingTools.web.js");
11
11
  var _DialDevToolsWeb = require("./dial/DialDevTools.web.js");
12
+ var _dialUsageStore = require("./dial/dialUsageStore.js");
12
13
  var _DevToolsSettingsModalWeb = require("./DevToolsSettingsModal.web.js");
13
14
  var _jsxRuntime = require("react/jsx-runtime");
14
15
  /**
@@ -73,18 +74,17 @@ function FloatingDevTools({
73
74
  slot: tool.slot
74
75
  })), [tools]);
75
76
 
76
- // Use shared settings hook
77
- const {
78
- settings
79
- } = (0, _floatingToolsReact.useSettings)({
77
+ // Register available tools with the shared settings hook (used by the
78
+ // settings modal). The dial no longer reads per-tool show/hide state.
79
+ (0, _floatingToolsReact.useSettings)({
80
80
  availableTools: availableToolsConfig
81
81
  });
82
82
 
83
- // Build dial icons from enabled dial tools
83
+ // Build dial icons for every dial-eligible tool. The dial paginates and
84
+ // ranks them by usage, so there is no per-tool show/hide setting.
84
85
  const dialIcons = (0, _react.useMemo)(() => {
85
86
  const dialTools = (0, _autoDiscoverPresetsWeb.getToolsBySlot)(tools, 'dial');
86
- const enabledDialIds = Object.entries(settings.dialTools).filter(([_, enabled]) => enabled).map(([id]) => id);
87
- return dialTools.filter(tool => enabledDialIds.includes(tool.id)).map(tool => {
87
+ return dialTools.map(tool => {
88
88
  const color = tool.color || (0, _floatingToolsReact.getToolColor)(tool.id);
89
89
  // Handle icon - can be string (emoji) or function (size) => ReactNode
90
90
  let icon;
@@ -102,12 +102,22 @@ function FloatingDevTools({
102
102
  icon,
103
103
  color,
104
104
  onPress: () => {
105
+ // Record usage so frequently/recently used tools rank toward page 1.
106
+ void (0, _dialUsageStore.recordToolUsage)(tool.id);
105
107
  tool.onPress?.();
106
108
  setIsDialOpen(false);
107
109
  }
108
110
  };
109
111
  });
110
- }, [tools, settings.dialTools]);
112
+ }, [tools]);
113
+
114
+ // Snapshot the usage-ranked order each time the dial opens. It stays stable
115
+ // while open so icons don't jump positions mid-interaction.
116
+ const rankedDialIcons = (0, _react.useMemo)(() => {
117
+ if (!isDialOpen) return dialIcons;
118
+ const byId = new Map(dialIcons.map(i => [i.id, i]));
119
+ return (0, _dialUsageStore.getRankedToolIds)(dialIcons.map(i => i.id)).map(id => byId.get(id)).filter(i => Boolean(i));
120
+ }, [isDialOpen, dialIcons]);
111
121
 
112
122
  // Build available tools for settings modal
113
123
  const availableTools = (0, _react.useMemo)(() => tools.map(tool => ({
@@ -133,7 +143,7 @@ function FloatingDevTools({
133
143
  onPress: handleOpenDial
134
144
  })
135
145
  }), isDialOpen && /*#__PURE__*/(0, _jsxRuntime.jsx)(_DialDevToolsWeb.DialMenu, {
136
- icons: dialIcons,
146
+ icons: rankedDialIcons,
137
147
  onClose: handleCloseDial,
138
148
  centerLabel: "BUOY",
139
149
  onCenterPress: handleOpenSettings
@@ -232,8 +232,12 @@ const FloatingMenu = ({
232
232
  message: "Grab and position this menu wherever you want, then tap the icon to open your tools."
233
233
  })]
234
234
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
235
- nativeID: "floating-devtools-root",
236
- pointerEvents: isCompletelyHidden ? "none" : "box-none",
235
+ nativeID: "floating-devtools-root"
236
+ // While the dial overlay is open, the floating menu underneath must be
237
+ // inert — otherwise the draggable bubble's gesture handling intercepts
238
+ // touches on dial controls that overlap it (e.g. the pager buttons).
239
+ ,
240
+ pointerEvents: isCompletelyHidden || showDial ? "none" : "box-none",
237
241
  style: {
238
242
  position: "absolute",
239
243
  top: 0,