@buoy-gg/core 7.0.35 → 7.0.38
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 +57 -66
- package/bin/buoy.js +71 -20
- package/lib/commonjs/Buoy.js +3 -16
- package/lib/commonjs/floatingMenu/AppHost.js +1 -1
- package/lib/commonjs/floatingMenu/AppHost.web.js +1 -1
- package/lib/commonjs/floatingMenu/AppIcon.web.js +53 -0
- package/lib/commonjs/floatingMenu/DevToolsSettingsModal.js +12 -5
- package/lib/commonjs/floatingMenu/DevToolsSettingsModal.web.js +14 -34
- package/lib/commonjs/floatingMenu/FloatingDevTools.js +32 -48
- package/lib/commonjs/floatingMenu/FloatingDevTools.web.js +24 -4
- package/lib/commonjs/floatingMenu/FloatingMenu.js +1 -1
- package/lib/commonjs/floatingMenu/MinimizedToolsStack.js +83 -4
- package/lib/commonjs/floatingMenu/MinimizedToolsStack.web.js +90 -6
- package/lib/commonjs/floatingMenu/ToolHost.js +1 -0
- package/lib/commonjs/floatingMenu/autoExternalSync.js +3 -2
- package/lib/commonjs/floatingMenu/dial/DialDevTools.js +43 -10
- package/lib/commonjs/floatingMenu/dial/DialDevTools.web.js +18 -5
- package/lib/commonjs/floatingMenu/dial/dialUsageStore.js +13 -17
- package/lib/commonjs/floatingMenu/dial/onboardingConstants.js +37 -65
- package/lib/commonjs/floatingMenu/dial/onboardingConstants.web.js +37 -29
- package/lib/commonjs/floatingMenu/floatingTools.js +23 -889
- package/lib/commonjs/floatingMenu/floatingTools.web.js +24 -514
- package/lib/commonjs/floatingMenu/optionalRequire.js +4 -0
- package/lib/commonjs/telemetry/installPing.js +7 -0
- package/lib/commonjs/version.js +1 -1
- package/lib/module/Buoy.js +3 -16
- package/lib/module/floatingMenu/AppHost.js +1 -1
- package/lib/module/floatingMenu/AppHost.web.js +1 -1
- package/lib/module/floatingMenu/AppIcon.web.js +47 -0
- package/lib/module/floatingMenu/DevToolsSettingsModal.js +13 -6
- package/lib/module/floatingMenu/DevToolsSettingsModal.web.js +15 -35
- package/lib/module/floatingMenu/FloatingDevTools.js +35 -49
- package/lib/module/floatingMenu/FloatingDevTools.web.js +24 -3
- package/lib/module/floatingMenu/FloatingMenu.js +1 -1
- package/lib/module/floatingMenu/MinimizedToolsStack.js +88 -8
- package/lib/module/floatingMenu/MinimizedToolsStack.web.js +92 -8
- package/lib/module/floatingMenu/ToolHost.js +1 -0
- package/lib/module/floatingMenu/autoExternalSync.js +3 -2
- package/lib/module/floatingMenu/dial/DialDevTools.js +43 -10
- package/lib/module/floatingMenu/dial/DialDevTools.web.js +18 -5
- package/lib/module/floatingMenu/dial/dialUsageStore.js +14 -18
- package/lib/module/floatingMenu/dial/onboardingConstants.js +1 -62
- package/lib/module/floatingMenu/dial/onboardingConstants.web.js +1 -25
- package/lib/module/floatingMenu/floatingTools.js +15 -890
- package/lib/module/floatingMenu/floatingTools.web.js +1 -517
- package/lib/module/floatingMenu/optionalRequire.js +4 -0
- package/lib/module/telemetry/installPing.js +7 -0
- package/lib/module/version.js +1 -1
- package/lib/typescript/commonjs/Buoy.d.ts +14 -3
- package/lib/typescript/commonjs/Buoy.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/AppIcon.web.d.ts +14 -0
- package/lib/typescript/commonjs/floatingMenu/AppIcon.web.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.d.ts +4 -14
- package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.web.d.ts +4 -19
- package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/MinimizedToolsStack.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/MinimizedToolsStack.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/ToolHost.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/autoExternalSync.d.ts +3 -4
- package/lib/typescript/commonjs/floatingMenu/autoExternalSync.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.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/dial/dialUsageStore.d.ts +3 -15
- package/lib/typescript/commonjs/floatingMenu/dial/dialUsageStore.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/dial/onboardingConstants.d.ts +1 -29
- package/lib/typescript/commonjs/floatingMenu/dial/onboardingConstants.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/dial/onboardingConstants.web.d.ts +1 -12
- package/lib/typescript/commonjs/floatingMenu/dial/onboardingConstants.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/floatingTools.d.ts +6 -55
- package/lib/typescript/commonjs/floatingMenu/floatingTools.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/floatingTools.web.d.ts +3 -53
- package/lib/typescript/commonjs/floatingMenu/floatingTools.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/optionalRequire.d.ts.map +1 -1
- package/lib/typescript/commonjs/telemetry/installPing.d.ts +8 -1
- package/lib/typescript/commonjs/telemetry/installPing.d.ts.map +1 -1
- package/lib/typescript/commonjs/version.d.ts +1 -1
- package/lib/typescript/module/Buoy.d.ts +14 -3
- package/lib/typescript/module/Buoy.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/AppIcon.web.d.ts +14 -0
- package/lib/typescript/module/floatingMenu/AppIcon.web.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.web.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/FloatingDevTools.d.ts +4 -14
- package/lib/typescript/module/floatingMenu/FloatingDevTools.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/FloatingDevTools.web.d.ts +4 -19
- package/lib/typescript/module/floatingMenu/FloatingDevTools.web.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/MinimizedToolsStack.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/MinimizedToolsStack.web.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/ToolHost.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/autoExternalSync.d.ts +3 -4
- package/lib/typescript/module/floatingMenu/autoExternalSync.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.map +1 -1
- package/lib/typescript/module/floatingMenu/dial/dialUsageStore.d.ts +3 -15
- package/lib/typescript/module/floatingMenu/dial/dialUsageStore.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/dial/onboardingConstants.d.ts +1 -29
- package/lib/typescript/module/floatingMenu/dial/onboardingConstants.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/dial/onboardingConstants.web.d.ts +1 -12
- package/lib/typescript/module/floatingMenu/dial/onboardingConstants.web.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/floatingTools.d.ts +6 -55
- package/lib/typescript/module/floatingMenu/floatingTools.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/floatingTools.web.d.ts +3 -53
- package/lib/typescript/module/floatingMenu/floatingTools.web.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/optionalRequire.d.ts.map +1 -1
- package/lib/typescript/module/telemetry/installPing.d.ts +8 -1
- package/lib/typescript/module/telemetry/installPing.d.ts.map +1 -1
- package/lib/typescript/module/version.d.ts +1 -1
- package/package.json +6 -6
|
@@ -54,6 +54,9 @@ const night = {
|
|
|
54
54
|
surfaceElevated: '#161618',
|
|
55
55
|
border: '#1A1A1C',
|
|
56
56
|
separator: 'rgba(255, 255, 255, 0.08)',
|
|
57
|
+
glass: 'rgba(5, 5, 5, 0.50)',
|
|
58
|
+
glassElevated: 'rgba(255, 255, 255, 0.06)',
|
|
59
|
+
glassBorder: 'rgba(255, 255, 255, 0.07)',
|
|
57
60
|
fillTertiary: 'rgba(255, 255, 255, 0.12)',
|
|
58
61
|
buttonSurface: 'rgba(8, 10, 14, 0.85)',
|
|
59
62
|
button: '#1C1C1C',
|
|
@@ -140,28 +143,6 @@ const Sparkles = ({
|
|
|
140
143
|
})]
|
|
141
144
|
});
|
|
142
145
|
|
|
143
|
-
/** Fallback for shared-ui SentryBugIcon (native sentry row icon, red). */
|
|
144
|
-
const AlertTriangle = ({
|
|
145
|
-
size = 24,
|
|
146
|
-
color = 'currentColor'
|
|
147
|
-
}) => /*#__PURE__*/(0, _jsxRuntime.jsxs)("svg", {
|
|
148
|
-
width: size,
|
|
149
|
-
height: size,
|
|
150
|
-
viewBox: "0 0 24 24",
|
|
151
|
-
fill: "none",
|
|
152
|
-
stroke: color,
|
|
153
|
-
strokeWidth: "2",
|
|
154
|
-
strokeLinecap: "round",
|
|
155
|
-
strokeLinejoin: "round",
|
|
156
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
|
|
157
|
-
d: "m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"
|
|
158
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
|
|
159
|
-
d: "M12 9v4"
|
|
160
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("path", {
|
|
161
|
-
d: "M12 17h.01"
|
|
162
|
-
})]
|
|
163
|
-
});
|
|
164
|
-
|
|
165
146
|
/** shared-ui Info icon (native default tool icon). */
|
|
166
147
|
const Info = ({
|
|
167
148
|
size = 24,
|
|
@@ -298,10 +279,9 @@ function ToolIcon({
|
|
|
298
279
|
size: size
|
|
299
280
|
});
|
|
300
281
|
case 'sentry':
|
|
301
|
-
|
|
302
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsx)(AlertTriangle, {
|
|
282
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_floatingToolsCore.SentryIcon, {
|
|
303
283
|
size: size,
|
|
304
|
-
color:
|
|
284
|
+
color: "#9945FF"
|
|
305
285
|
});
|
|
306
286
|
case 'storage':
|
|
307
287
|
// native passes bgColor=night surface for the BIF knock-out parts
|
|
@@ -437,11 +417,11 @@ function Footnote({
|
|
|
437
417
|
});
|
|
438
418
|
}
|
|
439
419
|
|
|
440
|
-
/** native NightCard:
|
|
420
|
+
/** native NightCard glass: 50% black, radius 14, 1px white-alpha hairline, clipped */
|
|
441
421
|
const cardStyle = {
|
|
442
|
-
backgroundColor: night.
|
|
422
|
+
backgroundColor: night.glass,
|
|
443
423
|
borderRadius: 14,
|
|
444
|
-
border: `1px solid ${night.
|
|
424
|
+
border: `1px solid ${night.glassBorder}`,
|
|
445
425
|
overflow: 'hidden'
|
|
446
426
|
};
|
|
447
427
|
|
|
@@ -786,8 +766,8 @@ function SettingsModal({
|
|
|
786
766
|
const displayTabs = _floatingToolsReact.settingsTabs.filter(tab => tab.key !== 'pro');
|
|
787
767
|
|
|
788
768
|
// Segmented control rendered inside the JsModal header — native passes a
|
|
789
|
-
// NightSegmented as header.customContent the same way. Track =
|
|
790
|
-
// radius 10 / padding 3; active thumb =
|
|
769
|
+
// NightSegmented glass as header.customContent the same way. Track = glass
|
|
770
|
+
// at radius 10 / padding 3; active thumb = glassElevated at radius 8 with
|
|
791
771
|
// the accent underline glow (the Everlights All/Day tabs).
|
|
792
772
|
const tabHeader = /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
793
773
|
style: {
|
|
@@ -802,9 +782,9 @@ function SettingsModal({
|
|
|
802
782
|
style: {
|
|
803
783
|
flex: 1,
|
|
804
784
|
display: 'flex',
|
|
805
|
-
backgroundColor: night.
|
|
785
|
+
backgroundColor: night.glass,
|
|
806
786
|
borderRadius: 10,
|
|
807
|
-
border: `1px solid ${night.
|
|
787
|
+
border: `1px solid ${night.glassBorder}`,
|
|
808
788
|
padding: 3,
|
|
809
789
|
boxSizing: 'border-box'
|
|
810
790
|
},
|
|
@@ -822,7 +802,7 @@ function SettingsModal({
|
|
|
822
802
|
padding: '8px 0',
|
|
823
803
|
borderRadius: 8,
|
|
824
804
|
border: 'none',
|
|
825
|
-
backgroundColor: isActive ? night.
|
|
805
|
+
backgroundColor: isActive ? night.glassElevated : 'transparent',
|
|
826
806
|
color: isActive ? night.text : night.textSecondary,
|
|
827
807
|
fontSize: 13,
|
|
828
808
|
fontWeight: isActive ? 600 : 500,
|
|
@@ -1007,7 +987,7 @@ function SettingsModal({
|
|
|
1007
987
|
},
|
|
1008
988
|
children: savedKeys.map(key => /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
1009
989
|
style: {
|
|
1010
|
-
backgroundColor: night.
|
|
990
|
+
backgroundColor: night.glassElevated,
|
|
1011
991
|
borderRadius: 8,
|
|
1012
992
|
padding: '7px 10px',
|
|
1013
993
|
marginBottom: 4
|
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.FloatingDevTools = void 0;
|
|
7
|
+
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
7
8
|
var _react = _interopRequireWildcard(require("react"));
|
|
8
9
|
var _reactNative = require("react-native");
|
|
9
10
|
var _AppHost = require("./AppHost");
|
|
@@ -12,10 +13,9 @@ var _ToolOpenerBridge = require("./ToolOpenerBridge.js");
|
|
|
12
13
|
var _autoDiscoverPresets = require("./autoDiscoverPresets.js");
|
|
13
14
|
var _installPing = require("../telemetry/installPing.js");
|
|
14
15
|
var _Buoy = require("../Buoy.js");
|
|
15
|
-
var _AppIcon = require("./AppIcon
|
|
16
|
+
var _AppIcon = require("./AppIcon");
|
|
16
17
|
var _DevToolsVisibilityContext = require("./DevToolsVisibilityContext.js");
|
|
17
18
|
var _optionalRequire = require("./optionalRequire.js");
|
|
18
|
-
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
19
19
|
var _MinimizedToolsContext = require("./MinimizedToolsContext.js");
|
|
20
20
|
var _defaultConfig = require("./defaultConfig.js");
|
|
21
21
|
var _DefaultConfigContext = require("./DefaultConfigContext.js");
|
|
@@ -124,7 +124,7 @@ const FloatingDevTools = ({
|
|
|
124
124
|
disableHints = false,
|
|
125
125
|
defaultFloatingTools,
|
|
126
126
|
defaultDialTools,
|
|
127
|
-
requireLicense
|
|
127
|
+
requireLicense: _requireLicense,
|
|
128
128
|
licenseKey: licenseKeyProp,
|
|
129
129
|
zustandStores,
|
|
130
130
|
environment,
|
|
@@ -142,24 +142,27 @@ const FloatingDevTools = ({
|
|
|
142
142
|
isLicensed
|
|
143
143
|
} = (0, _license.useProAccess)();
|
|
144
144
|
|
|
145
|
-
//
|
|
145
|
+
// Account admission is mandatory; paid feature gates remain separate.
|
|
146
146
|
const {
|
|
147
147
|
licenseKey,
|
|
148
148
|
isInitialized,
|
|
149
|
-
tier
|
|
149
|
+
tier,
|
|
150
|
+
access
|
|
150
151
|
} = (0, _license.useLicense)();
|
|
152
|
+
const configuredMatches = licenseKeyProp === undefined || licenseKeyProp.trim().toUpperCase() === (licenseKey ?? "");
|
|
153
|
+
const accountAdmitted = configuredMatches && access.status === "admitted";
|
|
151
154
|
|
|
152
155
|
// Anonymous install ping — dev-only, once a day, no project or tool data.
|
|
153
|
-
// Deliberately waits for
|
|
154
|
-
//
|
|
156
|
+
// Deliberately waits for admission to resolve so what it reports is the
|
|
157
|
+
// real outcome (the account's tier, or "locked") rather than the manager's
|
|
158
|
+
// starting state.
|
|
155
159
|
(0, _react.useEffect)(() => {
|
|
156
|
-
if (!isInitialized) return;
|
|
160
|
+
if (!isInitialized || access.status === "initializing") return;
|
|
157
161
|
void (0, _installPing.sendInstallPing)({
|
|
158
|
-
tier,
|
|
162
|
+
tier: access.status === "admitted" ? tier : "locked",
|
|
159
163
|
enabled: (0, _Buoy.isTelemetryEnabled)()
|
|
160
164
|
});
|
|
161
|
-
}, [isInitialized, tier]);
|
|
162
|
-
const [showLicenseModal, setShowLicenseModal] = (0, _react.useState)(false);
|
|
165
|
+
}, [isInitialized, access.status, tier]);
|
|
163
166
|
|
|
164
167
|
// Initialize license manager on mount, and set/clear license key when prop changes.
|
|
165
168
|
// The `licenseKey` prop is the source of truth WHEN PROVIDED:
|
|
@@ -167,28 +170,12 @@ const FloatingDevTools = ({
|
|
|
167
170
|
// - "" (blank) → EXPLICITLY clear the cached license (key was removed)
|
|
168
171
|
// - undefined → don't touch it (the app may set a key via Buoy.init())
|
|
169
172
|
(0, _react.useEffect)(() => {
|
|
170
|
-
|
|
171
|
-
_license.LicenseManager.initialize().then(() => _license.LicenseManager.setLicenseKey(licenseKeyProp)).catch(() => {});
|
|
172
|
-
} else if (licenseKeyProp === "") {
|
|
173
|
-
// Explicit removal: wipe the 30-day cache so Pro actually turns off.
|
|
174
|
-
_license.LicenseManager.initialize().then(() => _license.LicenseManager.clearLicense()).catch(() => {});
|
|
175
|
-
} else {
|
|
176
|
-
_license.LicenseManager.initialize();
|
|
177
|
-
}
|
|
173
|
+
void _license.LicenseManager.configure(licenseKeyProp).catch(() => {});
|
|
178
174
|
}, [licenseKeyProp]);
|
|
179
175
|
|
|
180
|
-
// Show license modal if requireLicense is enabled and no valid license
|
|
181
|
-
(0, _react.useEffect)(() => {
|
|
182
|
-
if (requireLicense && isInitialized && !licenseKey) {
|
|
183
|
-
setShowLicenseModal(true);
|
|
184
|
-
} else if (licenseKey) {
|
|
185
|
-
setShowLicenseModal(false);
|
|
186
|
-
}
|
|
187
|
-
}, [requireLicense, isInitialized, licenseKey]);
|
|
188
|
-
|
|
189
176
|
// Register zustand stores once on mount if provided
|
|
190
177
|
(0, _react.useEffect)(() => {
|
|
191
|
-
if (!zustandStores) return;
|
|
178
|
+
if (!zustandStores || access.status === "locked") return;
|
|
192
179
|
try {
|
|
193
180
|
const {
|
|
194
181
|
watchStores
|
|
@@ -197,7 +184,7 @@ const FloatingDevTools = ({
|
|
|
197
184
|
} catch (e) {
|
|
198
185
|
(0, _optionalRequire.reportOptionalRequireError)("@buoy-gg/zustand", e);
|
|
199
186
|
}
|
|
200
|
-
}, []);
|
|
187
|
+
}, [zustandStores, access.status]);
|
|
201
188
|
|
|
202
189
|
// Normalize dial tools configuration (truncates to max 6 with warning if needed)
|
|
203
190
|
const normalizedDialTools = (0, _react.useMemo)(() => {
|
|
@@ -454,17 +441,16 @@ const FloatingDevTools = ({
|
|
|
454
441
|
|
|
455
442
|
// Gate: only a PAID license works outside development.
|
|
456
443
|
//
|
|
457
|
-
//
|
|
458
|
-
//
|
|
459
|
-
//
|
|
460
|
-
// here even though it validates perfectly well.
|
|
444
|
+
// A free key (and, of course, no key at all) stays dev-only. `isLicensed` is
|
|
445
|
+
// safe to gate on because `isPro` is a strict mirror of `tier === "pro"`, so
|
|
446
|
+
// a free key reports false here even though it validates perfectly well.
|
|
461
447
|
//
|
|
462
448
|
// When Business on-device login lands, this becomes the boundary that a
|
|
463
449
|
// logged-in QA/support seat crosses WITHOUT a key in the build — i.e.
|
|
464
450
|
// `isLicensed || tierSource === "session"`. Nothing else should.
|
|
465
451
|
const isDevelopment = typeof __DEV__ !== "undefined" && __DEV__;
|
|
466
452
|
if (!isDevelopment && !isLicensed) {
|
|
467
|
-
//
|
|
453
|
+
// Free or unadmitted user in production - don't render DevTools.
|
|
468
454
|
// NOTE for whoever relaxes this for the free tier: desktop sync does NOT
|
|
469
455
|
// ride on this check. It re-tests `isLicensed` itself (externalSyncGate),
|
|
470
456
|
// so opening this door does not open a broker socket. Keep it that way.
|
|
@@ -491,10 +477,16 @@ const FloatingDevTools = ({
|
|
|
491
477
|
requiredEnvVars: requiredEnvVars,
|
|
492
478
|
customApps: syncApps
|
|
493
479
|
});
|
|
480
|
+
if (!accountAdmitted) {
|
|
481
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
482
|
+
children: [access.status === "initializing" && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
483
|
+
children: [ReduxAutoInstrument && /*#__PURE__*/(0, _jsxRuntime.jsx)(ReduxAutoInstrument, {}), ConsoleRoot && /*#__PURE__*/(0, _jsxRuntime.jsx)(ConsoleRoot, {}), RouteTracker && /*#__PURE__*/(0, _jsxRuntime.jsx)(RouteTracker, {}), ReactQueryTracker && /*#__PURE__*/(0, _jsxRuntime.jsx)(ReactQueryTracker, {})]
|
|
484
|
+
}), !headless && /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.AccountSetup, {})]
|
|
485
|
+
});
|
|
486
|
+
}
|
|
494
487
|
|
|
495
488
|
// Headless (sync-only): tool adapters + route tracking + desktop sync, no
|
|
496
|
-
// on-device UI.
|
|
497
|
-
// to gate. All hooks above already ran, so hook order is preserved, and
|
|
489
|
+
// on-device UI. Account admission above applies to this path too. All hooks above already ran, so hook order is preserved, and
|
|
498
490
|
// AutoExternalSync still obeys `syncEnabled` (the broker must never be
|
|
499
491
|
// contacted from a shipped build that didn't ask for it).
|
|
500
492
|
if (headless) {
|
|
@@ -510,16 +502,6 @@ const FloatingDevTools = ({
|
|
|
510
502
|
});
|
|
511
503
|
}
|
|
512
504
|
|
|
513
|
-
// Gate: If requireLicense is enabled and no license, show only the license modal
|
|
514
|
-
if (requireLicense && isInitialized && !licenseKey) {
|
|
515
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.LicenseEntryModal, {
|
|
516
|
-
visible: showLicenseModal,
|
|
517
|
-
onClose: () => {} // Can't close without entering a license
|
|
518
|
-
,
|
|
519
|
-
onSuccess: () => setShowLicenseModal(false)
|
|
520
|
-
});
|
|
521
|
-
}
|
|
522
|
-
|
|
523
505
|
// Session blocking is handled inline by JsModal's SessionBlockedOverlay
|
|
524
506
|
// No need to replace the entire UI - tools still render, but content is blocked
|
|
525
507
|
|
|
@@ -542,7 +524,9 @@ const FloatingDevTools = ({
|
|
|
542
524
|
...props,
|
|
543
525
|
apps: finalApps,
|
|
544
526
|
environment: resolvedEnvironment
|
|
545
|
-
}), props.hidden ? null : /*#__PURE__*/(0, _jsxRuntime.
|
|
527
|
+
}), props.hidden ? null : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
528
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_AppHost.AppOverlay, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.FloatingToolHost, {})]
|
|
529
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_ToolOpenerBridge.ToolOpenerBridge, {})]
|
|
546
530
|
})
|
|
547
531
|
}), 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, {}), JsTopOverlay && /*#__PURE__*/(0, _jsxRuntime.jsx)(JsTopOverlay, {}), ImpersonateOverlay && /*#__PURE__*/(0, _jsxRuntime.jsx)(ImpersonateOverlay, {}), ScenariosOverlay && /*#__PURE__*/(0, _jsxRuntime.jsx)(ScenariosOverlay, {}), ReduxAutoInstrument && /*#__PURE__*/(0, _jsxRuntime.jsx)(ReduxAutoInstrument, {}), ConsoleRoot && /*#__PURE__*/(0, _jsxRuntime.jsx)(ConsoleRoot, {}), RouteTracker && /*#__PURE__*/(0, _jsxRuntime.jsx)(RouteTracker, {}), ReactQueryTracker && /*#__PURE__*/(0, _jsxRuntime.jsx)(ReactQueryTracker, {}), toolRegistry, syncEnabled && /*#__PURE__*/(0, _jsxRuntime.jsx)(_autoExternalSync.AutoExternalSync, {
|
|
548
532
|
options: (0, _externalSyncGate.externalSyncOptions)(externalSync),
|
|
@@ -4,9 +4,11 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.FloatingDevTools = FloatingDevTools;
|
|
7
|
+
var _floating = require("@buoy-gg/shared-ui/floating");
|
|
8
|
+
var _license = require("@buoy-gg/license");
|
|
9
|
+
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
7
10
|
var _react = require("react");
|
|
8
11
|
var _floatingToolsReact = require("@buoy-gg/floating-tools-react");
|
|
9
|
-
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
10
12
|
var _autoDiscoverPresetsWeb = require("../utils/autoDiscoverPresets.web.js");
|
|
11
13
|
var _floatingToolsWeb = require("./floatingTools.web.js");
|
|
12
14
|
var _DialDevToolsWeb = require("./dial/DialDevTools.web.js");
|
|
@@ -87,7 +89,7 @@ function MenuLauncherIcon({
|
|
|
87
89
|
// Main Component
|
|
88
90
|
// =============================
|
|
89
91
|
|
|
90
|
-
function
|
|
92
|
+
function AdmittedFloatingDevTools(props) {
|
|
91
93
|
// The tool host wraps everything so dial presses can open tool components
|
|
92
94
|
// into the AppOverlay (web twin of the native AppHostProvider/AppOverlay).
|
|
93
95
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_AppHostWeb.AppHostProvider, {
|
|
@@ -372,10 +374,28 @@ function FloatingDevToolsInner({
|
|
|
372
374
|
onSettingsChange: _newSettings => {
|
|
373
375
|
// Settings are already saved by the hook
|
|
374
376
|
}
|
|
375
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_AppHostWeb.AppOverlay, {})]
|
|
377
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_AppHostWeb.AppOverlay, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_floating.FloatingToolHost, {})]
|
|
376
378
|
});
|
|
377
379
|
}
|
|
378
380
|
|
|
379
381
|
// =============================
|
|
380
382
|
// Re-exports for convenience
|
|
381
|
-
// =============================
|
|
383
|
+
// =============================
|
|
384
|
+
|
|
385
|
+
function FloatingDevTools(props) {
|
|
386
|
+
const {
|
|
387
|
+
access,
|
|
388
|
+
isPro,
|
|
389
|
+
licenseKey
|
|
390
|
+
} = (0, _license.useLicense)();
|
|
391
|
+
(0, _react.useEffect)(() => {
|
|
392
|
+
void _license.LicenseManager.configure(props.licenseKey);
|
|
393
|
+
}, [props.licenseKey]);
|
|
394
|
+
const matches = props.licenseKey === undefined || props.licenseKey.trim().toUpperCase() === (licenseKey ?? "");
|
|
395
|
+
const dev = typeof __DEV__ !== "undefined" ? __DEV__ : process.env.NODE_ENV !== "production";
|
|
396
|
+
if (!dev && !isPro) return null;
|
|
397
|
+
if (!matches || access.status !== "admitted") return props.headless ? null : /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.AccountSetup, {});
|
|
398
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(AdmittedFloatingDevTools, {
|
|
399
|
+
...props
|
|
400
|
+
});
|
|
401
|
+
}
|
|
@@ -8,7 +8,7 @@ var _react = _interopRequireWildcard(require("react"));
|
|
|
8
8
|
var _reactNative = require("react-native");
|
|
9
9
|
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
10
10
|
var _floatingTools = require("./floatingTools");
|
|
11
|
-
var _AppIcon = require("./AppIcon
|
|
11
|
+
var _AppIcon = require("./AppIcon");
|
|
12
12
|
var _DialDevTools = require("./dial/DialDevTools");
|
|
13
13
|
var _DevToolsSettingsModal = require("./DevToolsSettingsModal");
|
|
14
14
|
var _AppHost = require("./AppHost");
|
|
@@ -10,9 +10,50 @@ var _sharedUi = require("@buoy-gg/shared-ui");
|
|
|
10
10
|
var _MinimizedToolsContext = require("./MinimizedToolsContext.js");
|
|
11
11
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
12
12
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
13
|
+
/**
|
|
14
|
+
* A hidden tool's "I need you". See `setToolAttention` in shared-ui — the tool
|
|
15
|
+
* publishes, the rail draws. Read through useSyncExternalStore so a badge set
|
|
16
|
+
* from inside a minimized sheet lands on the chip without the rail polling.
|
|
17
|
+
*/function useToolAttention(toolId) {
|
|
18
|
+
return (0, _react.useSyncExternalStore)(_sharedUi.subscribeToolAttention, () => (0, _sharedUi.getToolAttention)(toolId), () => (0, _sharedUi.getToolAttention)(toolId));
|
|
19
|
+
}
|
|
20
|
+
const ATTENTION_COLORS = {
|
|
21
|
+
needsInput: "#FF8329",
|
|
22
|
+
done: "#20C997",
|
|
23
|
+
failed: "#FF3B30"
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
/** needsInput outranks failed outranks done — the peek shows the one that matters most. */
|
|
27
|
+
const ATTENTION_RANK = {
|
|
28
|
+
needsInput: 3,
|
|
29
|
+
failed: 2,
|
|
30
|
+
done: 1
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/** The strongest attention across every minimized tool, for the folded peek. */
|
|
34
|
+
function useStrongestAttention(toolIds) {
|
|
35
|
+
const key = toolIds.join("|");
|
|
36
|
+
return (0, _react.useSyncExternalStore)(_sharedUi.subscribeToolAttention, () => strongest(key), () => strongest(key));
|
|
37
|
+
}
|
|
38
|
+
const strongestCache = new Map();
|
|
39
|
+
function strongest(key) {
|
|
40
|
+
let best = null;
|
|
41
|
+
for (const id of key ? key.split("|") : []) {
|
|
42
|
+
const a = (0, _sharedUi.getToolAttention)(id);
|
|
43
|
+
if (a && (!best || ATTENTION_RANK[a.kind] > ATTENTION_RANK[best.kind])) best = a;
|
|
44
|
+
}
|
|
45
|
+
// Same value → same object, or useSyncExternalStore re-renders forever.
|
|
46
|
+
const prev = strongestCache.get(key);
|
|
47
|
+
if (prev && best && prev.kind === best.kind && prev.label === best.label) return prev;
|
|
48
|
+
if (!prev && !best) return null;
|
|
49
|
+
strongestCache.set(key, best);
|
|
50
|
+
return best;
|
|
51
|
+
}
|
|
52
|
+
|
|
13
53
|
// ============================================================================
|
|
14
54
|
// Constants
|
|
15
55
|
// ============================================================================
|
|
56
|
+
|
|
16
57
|
const PEEK_HEIGHT = 28;
|
|
17
58
|
const TOOLBAR_WIDTH = 44;
|
|
18
59
|
const TOOL_ITEM_SIZE = 32;
|
|
@@ -35,6 +76,7 @@ function GlitchToolButton({
|
|
|
35
76
|
onSelect,
|
|
36
77
|
index
|
|
37
78
|
}) {
|
|
79
|
+
const attention = useToolAttention(tool.id);
|
|
38
80
|
const glitchX = (0, _react.useRef)(new _reactNative.Animated.Value(0)).current;
|
|
39
81
|
const glitchOpacity = (0, _react.useRef)(new _reactNative.Animated.Value(1)).current;
|
|
40
82
|
const glitchScale = (0, _react.useRef)(new _reactNative.Animated.Value(1)).current;
|
|
@@ -126,14 +168,14 @@ function GlitchToolButton({
|
|
|
126
168
|
clearTimeout(timeoutId);
|
|
127
169
|
};
|
|
128
170
|
}, [glitchX, glitchOpacity, glitchScale, index]);
|
|
129
|
-
return /*#__PURE__*/(0, _jsxRuntime.
|
|
171
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
130
172
|
onPress: () => onSelect(tool),
|
|
131
173
|
activeOpacity: 0.7,
|
|
132
174
|
style: styles.toolButton,
|
|
133
|
-
accessibilityLabel: `Restore ${tool.title}`,
|
|
175
|
+
accessibilityLabel: attention ? `${tool.title} — ${attention.label}. Restore` : `Restore ${tool.title}`,
|
|
134
176
|
accessibilityRole: "button",
|
|
135
177
|
testID: `buoy-dock-restore-${tool.id}`,
|
|
136
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
|
|
178
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
|
|
137
179
|
style: {
|
|
138
180
|
opacity: glitchOpacity,
|
|
139
181
|
transform: [{
|
|
@@ -143,7 +185,17 @@ function GlitchToolButton({
|
|
|
143
185
|
}]
|
|
144
186
|
},
|
|
145
187
|
children: tool.icon
|
|
146
|
-
})
|
|
188
|
+
}), attention ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
189
|
+
style: [styles.badge, {
|
|
190
|
+
backgroundColor: ATTENTION_COLORS[attention.kind]
|
|
191
|
+
}],
|
|
192
|
+
testID: `buoy-dock-badge-${tool.id}-${attention.kind}`,
|
|
193
|
+
pointerEvents: "none",
|
|
194
|
+
children: attention.kind === "needsInput" ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
195
|
+
style: styles.badgeText,
|
|
196
|
+
children: "!"
|
|
197
|
+
}) : null
|
|
198
|
+
}) : null]
|
|
147
199
|
});
|
|
148
200
|
}
|
|
149
201
|
|
|
@@ -163,6 +215,7 @@ function MinimizedToolsStack({
|
|
|
163
215
|
minimizedTools,
|
|
164
216
|
restore
|
|
165
217
|
} = (0, _MinimizedToolsContext.useMinimizedTools)();
|
|
218
|
+
const peekAttention = useStrongestAttention(minimizedTools.map(t => t.id));
|
|
166
219
|
|
|
167
220
|
// Calculate expanded height based on number of tools
|
|
168
221
|
const expandedHeight = TOOLBAR_PADDING + minimizedTools.length * TOOL_ITEM_SIZE + (minimizedTools.length - 1) * ICON_GAP + ICON_GAP + COLLAPSE_BUTTON_SIZE + 4;
|
|
@@ -186,6 +239,11 @@ function MinimizedToolsStack({
|
|
|
186
239
|
collapsedLabel: `Show ${minimizedTools.length} minimized tools`,
|
|
187
240
|
testID: "buoy-dock-peek",
|
|
188
241
|
collapseTestID: "buoy-dock-collapse",
|
|
242
|
+
attention: peekAttention ? {
|
|
243
|
+
color: ATTENTION_COLORS[peekAttention.kind],
|
|
244
|
+
glyph: peekAttention.kind === "needsInput" ? "!" : undefined,
|
|
245
|
+
label: peekAttention.label
|
|
246
|
+
} : null,
|
|
189
247
|
children: [...minimizedTools].reverse().map((tool, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(GlitchToolButton, {
|
|
190
248
|
tool: tool,
|
|
191
249
|
onSelect: handleToolPress,
|
|
@@ -205,5 +263,26 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
205
263
|
alignItems: "center",
|
|
206
264
|
justifyContent: "center",
|
|
207
265
|
backgroundColor: "transparent"
|
|
266
|
+
},
|
|
267
|
+
// Top-right of the chip. Needs-input carries a glyph; done/failed are a dot —
|
|
268
|
+
// the colour says which, the glyph says "act".
|
|
269
|
+
badge: {
|
|
270
|
+
position: "absolute",
|
|
271
|
+
top: 0,
|
|
272
|
+
right: 0,
|
|
273
|
+
minWidth: 12,
|
|
274
|
+
height: 12,
|
|
275
|
+
borderRadius: 6,
|
|
276
|
+
paddingHorizontal: 2,
|
|
277
|
+
alignItems: "center",
|
|
278
|
+
justifyContent: "center",
|
|
279
|
+
borderWidth: 1.5,
|
|
280
|
+
borderColor: "#0C0C0C"
|
|
281
|
+
},
|
|
282
|
+
badgeText: {
|
|
283
|
+
color: "#000",
|
|
284
|
+
fontSize: 8,
|
|
285
|
+
fontWeight: "800",
|
|
286
|
+
lineHeight: 9
|
|
208
287
|
}
|
|
209
288
|
});
|
|
@@ -24,6 +24,39 @@ var _jsxRuntime = require("react/jsx-runtime");
|
|
|
24
24
|
* used before this replaced it.
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
+
/** Twin of the native hook — see MinimizedToolsStack.tsx. */
|
|
28
|
+
function useToolAttention(toolId) {
|
|
29
|
+
return (0, _react.useSyncExternalStore)(_sharedUi.subscribeToolAttention, () => (0, _sharedUi.getToolAttention)(toolId), () => (0, _sharedUi.getToolAttention)(toolId));
|
|
30
|
+
}
|
|
31
|
+
const ATTENTION_COLORS = {
|
|
32
|
+
needsInput: '#FF8329',
|
|
33
|
+
done: '#20C997',
|
|
34
|
+
failed: '#FF3B30'
|
|
35
|
+
};
|
|
36
|
+
const ATTENTION_RANK = {
|
|
37
|
+
needsInput: 3,
|
|
38
|
+
failed: 2,
|
|
39
|
+
done: 1
|
|
40
|
+
};
|
|
41
|
+
const strongestCache = new Map();
|
|
42
|
+
function strongest(key) {
|
|
43
|
+
let best = null;
|
|
44
|
+
for (const id of key ? key.split('|') : []) {
|
|
45
|
+
const a = (0, _sharedUi.getToolAttention)(id);
|
|
46
|
+
if (a && (!best || ATTENTION_RANK[a.kind] > ATTENTION_RANK[best.kind])) best = a;
|
|
47
|
+
}
|
|
48
|
+
const prev = strongestCache.get(key);
|
|
49
|
+
if (prev && best && prev.kind === best.kind && prev.label === best.label) return prev;
|
|
50
|
+
if (!prev && !best) return null;
|
|
51
|
+
strongestCache.set(key, best);
|
|
52
|
+
return best;
|
|
53
|
+
}
|
|
54
|
+
/** Twin of the native hook: the strongest attention across the folded dock. */
|
|
55
|
+
function useStrongestAttention(toolIds) {
|
|
56
|
+
const key = toolIds.join('|');
|
|
57
|
+
return (0, _react.useSyncExternalStore)(_sharedUi.subscribeToolAttention, () => strongest(key), () => strongest(key));
|
|
58
|
+
}
|
|
59
|
+
|
|
27
60
|
// native MinimizedToolsStack.tsx constants
|
|
28
61
|
const PEEK_HEIGHT = 28;
|
|
29
62
|
const TOOL_ITEM_SIZE = 32;
|
|
@@ -61,11 +94,13 @@ function ChevronGlyph({
|
|
|
61
94
|
});
|
|
62
95
|
}
|
|
63
96
|
function GlitchToolButton({
|
|
97
|
+
id,
|
|
64
98
|
title,
|
|
65
99
|
icon,
|
|
66
100
|
index,
|
|
67
101
|
onPress
|
|
68
102
|
}) {
|
|
103
|
+
const attention = useToolAttention(id);
|
|
69
104
|
const innerRef = (0, _react.useRef)(null);
|
|
70
105
|
(0, _react.useEffect)(() => {
|
|
71
106
|
let mounted = true;
|
|
@@ -116,9 +151,9 @@ function GlitchToolButton({
|
|
|
116
151
|
clearTimeout(timer);
|
|
117
152
|
};
|
|
118
153
|
}, [index]);
|
|
119
|
-
return /*#__PURE__*/(0, _jsxRuntime.
|
|
154
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)("button", {
|
|
120
155
|
type: "button",
|
|
121
|
-
"aria-label": `Restore ${title}`,
|
|
156
|
+
"aria-label": attention ? `${title} — ${attention.label}. Restore` : `Restore ${title}`,
|
|
122
157
|
onClick: onPress,
|
|
123
158
|
style: {
|
|
124
159
|
width: TOOL_ITEM_SIZE,
|
|
@@ -129,9 +164,10 @@ function GlitchToolButton({
|
|
|
129
164
|
background: 'none',
|
|
130
165
|
border: 'none',
|
|
131
166
|
padding: 0,
|
|
132
|
-
cursor: 'pointer'
|
|
167
|
+
cursor: 'pointer',
|
|
168
|
+
position: 'relative'
|
|
133
169
|
},
|
|
134
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
170
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
135
171
|
ref: innerRef,
|
|
136
172
|
style: {
|
|
137
173
|
display: 'flex',
|
|
@@ -139,7 +175,30 @@ function GlitchToolButton({
|
|
|
139
175
|
justifyContent: 'center'
|
|
140
176
|
},
|
|
141
177
|
children: icon
|
|
142
|
-
})
|
|
178
|
+
}), attention ? /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
|
|
179
|
+
"aria-hidden": true,
|
|
180
|
+
"data-testid": `buoy-dock-badge-${id}-${attention.kind}`,
|
|
181
|
+
style: {
|
|
182
|
+
position: 'absolute',
|
|
183
|
+
top: 0,
|
|
184
|
+
right: 0,
|
|
185
|
+
minWidth: 12,
|
|
186
|
+
height: 12,
|
|
187
|
+
borderRadius: 6,
|
|
188
|
+
padding: '0 2px',
|
|
189
|
+
boxSizing: 'border-box',
|
|
190
|
+
background: ATTENTION_COLORS[attention.kind],
|
|
191
|
+
border: '1.5px solid #0C0C0C',
|
|
192
|
+
color: '#000',
|
|
193
|
+
fontSize: 8,
|
|
194
|
+
fontWeight: 800,
|
|
195
|
+
lineHeight: '9px',
|
|
196
|
+
display: 'flex',
|
|
197
|
+
alignItems: 'center',
|
|
198
|
+
justifyContent: 'center'
|
|
199
|
+
},
|
|
200
|
+
children: attention.kind === 'needsInput' ? '!' : ''
|
|
201
|
+
}) : null]
|
|
143
202
|
});
|
|
144
203
|
}
|
|
145
204
|
function MinimizedToolsStack({
|
|
@@ -152,6 +211,7 @@ function MinimizedToolsStack({
|
|
|
152
211
|
const minimized = openApps.filter(app => app.minimized && app.launchMode !== 'toggle-only');
|
|
153
212
|
const [isExpanded, setIsExpanded] = (0, _react.useState)(false);
|
|
154
213
|
const [isStateRestored, setIsStateRestored] = (0, _react.useState)(false);
|
|
214
|
+
const peekAttention = useStrongestAttention(minimized.map(app => app.id));
|
|
155
215
|
|
|
156
216
|
// Restore + persist the expanded flag (native ExpandablePopover persistState).
|
|
157
217
|
(0, _react.useEffect)(() => {
|
|
@@ -219,6 +279,7 @@ function MinimizedToolsStack({
|
|
|
219
279
|
boxSizing: 'border-box'
|
|
220
280
|
},
|
|
221
281
|
children: [[...minimized].reverse().map((app, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(GlitchToolButton, {
|
|
282
|
+
id: app.id,
|
|
222
283
|
title: app.title || app.id,
|
|
223
284
|
icon: app.icon ?? /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
|
|
224
285
|
style: {
|
|
@@ -273,7 +334,30 @@ function MinimizedToolsStack({
|
|
|
273
334
|
pointerEvents: isExpanded ? 'none' : 'auto',
|
|
274
335
|
...frame
|
|
275
336
|
},
|
|
276
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(ChevronGlyph, {}),
|
|
337
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(ChevronGlyph, {}), peekAttention ? /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
|
|
338
|
+
"aria-hidden": true,
|
|
339
|
+
"data-testid": `buoy-dock-peek-attention`,
|
|
340
|
+
style: {
|
|
341
|
+
position: 'absolute',
|
|
342
|
+
top: 2,
|
|
343
|
+
right: 2,
|
|
344
|
+
minWidth: 11,
|
|
345
|
+
height: 11,
|
|
346
|
+
borderRadius: 6,
|
|
347
|
+
padding: '0 2px',
|
|
348
|
+
boxSizing: 'border-box',
|
|
349
|
+
background: ATTENTION_COLORS[peekAttention.kind],
|
|
350
|
+
border: '1.5px solid #0C0C0C',
|
|
351
|
+
color: '#000',
|
|
352
|
+
fontSize: 8,
|
|
353
|
+
fontWeight: 800,
|
|
354
|
+
lineHeight: '9px',
|
|
355
|
+
display: 'flex',
|
|
356
|
+
alignItems: 'center',
|
|
357
|
+
justifyContent: 'center'
|
|
358
|
+
},
|
|
359
|
+
children: peekAttention.kind === 'needsInput' ? '!' : ''
|
|
360
|
+
}) : null, minimized.length > 1 && /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
|
|
277
361
|
style: {
|
|
278
362
|
fontSize: 9,
|
|
279
363
|
fontWeight: 600,
|
|
@@ -197,6 +197,7 @@ function ToolModalShell({
|
|
|
197
197
|
subtitle: subtitle
|
|
198
198
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_sharedUi.ModalHeader.Actions, {
|
|
199
199
|
children: [!isSearchActive && actions, searchable && !isSearchActive && /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.HeaderSearchButton, {
|
|
200
|
+
variant: "chip",
|
|
200
201
|
testID: `tool-search-${app.id}`,
|
|
201
202
|
onPress: () => setIsSearchActive(true)
|
|
202
203
|
})]
|
|
@@ -9,6 +9,7 @@ exports.isExternalSyncAvailable = isExternalSyncAvailable;
|
|
|
9
9
|
exports.useToolAdapterMap = useToolAdapterMap;
|
|
10
10
|
var _react = require("react");
|
|
11
11
|
var _reactNative = require("react-native");
|
|
12
|
+
var _license = require("@buoy-gg/license");
|
|
12
13
|
var _optionalRequire = require("./optionalRequire.js");
|
|
13
14
|
var _appSyncAdapter = require("./sync/appSyncAdapter.js");
|
|
14
15
|
var _deviceIdentity = require("./deviceIdentity.js");
|
|
@@ -292,11 +293,11 @@ function AutoExternalSync({
|
|
|
292
293
|
(0, _react.useEffect)(() => {
|
|
293
294
|
if (!socket) return;
|
|
294
295
|
const emitLicense = () => {
|
|
296
|
+
if (!_license.LicenseManager.hasAccountAccess() || !socket.connected) return;
|
|
295
297
|
socket.emit("device-license", {
|
|
296
298
|
isPro: licenseRef.current.isPro ? "1" : "0",
|
|
297
299
|
// Brokers older than the tier split ignore this; newer ones prefer it.
|
|
298
|
-
tier: licenseRef.current.tier ?? (licenseRef.current.isPro ? "pro" : "
|
|
299
|
-
licenseKey: licenseRef.current.licenseKey ?? ""
|
|
300
|
+
tier: licenseRef.current.tier ?? (licenseRef.current.isPro ? "pro" : "free")
|
|
300
301
|
});
|
|
301
302
|
};
|
|
302
303
|
if (socket.connected) emitLicense();
|