@buoy-gg/core 7.0.26 → 7.0.28
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/bin/buoy.js +6 -0
- package/lib/commonjs/floatingMenu/DevToolsSettingsModal.js +532 -1520
- package/lib/commonjs/floatingMenu/DevToolsSettingsModal.web.js +541 -566
- package/lib/commonjs/floatingMenu/FloatingDevTools.web.js +5 -1
- package/lib/commonjs/floatingMenu/ToolHost.js +2 -1
- package/lib/commonjs/floatingMenu/autoExternalSync.js +11 -8
- package/lib/commonjs/floatingMenu/dial/DialDevTools.js +50 -21
- package/lib/commonjs/floatingMenu/dial/DialHyperspace.js +177 -0
- package/lib/commonjs/floatingMenu/dial/DialIcon.js +31 -0
- package/lib/commonjs/floatingMenu/dial/DialSnow.js +92 -0
- package/lib/commonjs/version.js +1 -1
- package/lib/module/floatingMenu/DevToolsSettingsModal.js +533 -1524
- package/lib/module/floatingMenu/DevToolsSettingsModal.web.js +542 -569
- package/lib/module/floatingMenu/FloatingDevTools.web.js +5 -1
- package/lib/module/floatingMenu/ToolHost.js +2 -1
- package/lib/module/floatingMenu/autoExternalSync.js +11 -8
- package/lib/module/floatingMenu/dial/DialDevTools.js +52 -23
- package/lib/module/floatingMenu/dial/DialHyperspace.js +173 -0
- package/lib/module/floatingMenu/dial/DialIcon.js +33 -1
- package/lib/module/floatingMenu/dial/DialSnow.js +90 -0
- package/lib/module/version.js +1 -1
- package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.d.ts +19 -13
- package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.web.d.ts +3 -3
- package/lib/typescript/commonjs/floatingMenu/DevToolsSettingsModal.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/FloatingDevTools.web.d.ts.map +1 -1
- 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/DialHyperspace.d.ts +24 -0
- package/lib/typescript/commonjs/floatingMenu/dial/DialHyperspace.d.ts.map +1 -0
- package/lib/typescript/commonjs/floatingMenu/dial/DialIcon.d.ts.map +1 -1
- package/lib/typescript/commonjs/floatingMenu/dial/DialSnow.d.ts +23 -0
- package/lib/typescript/commonjs/floatingMenu/dial/DialSnow.d.ts.map +1 -0
- package/lib/typescript/commonjs/version.d.ts +1 -1
- package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.d.ts +19 -13
- package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.web.d.ts +3 -3
- package/lib/typescript/module/floatingMenu/DevToolsSettingsModal.web.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/FloatingDevTools.web.d.ts.map +1 -1
- 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/DialHyperspace.d.ts +24 -0
- package/lib/typescript/module/floatingMenu/dial/DialHyperspace.d.ts.map +1 -0
- package/lib/typescript/module/floatingMenu/dial/DialIcon.d.ts.map +1 -1
- package/lib/typescript/module/floatingMenu/dial/DialSnow.d.ts +23 -0
- package/lib/typescript/module/floatingMenu/dial/DialSnow.d.ts.map +1 -0
- package/lib/typescript/module/version.d.ts +1 -1
- package/package.json +5 -5
|
@@ -11,6 +11,7 @@ var _useDesktopSyncStatus = require("./useDesktopSyncStatus.js");
|
|
|
11
11
|
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
12
12
|
var _floatingToolsCore = require("@buoy-gg/floating-tools-core");
|
|
13
13
|
var _DefaultConfigContext = require("./DefaultConfigContext.js");
|
|
14
|
+
var _AppIcon = require("./AppIcon.js");
|
|
14
15
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
15
16
|
const STORAGE_KEY = "@react_buoy_dev_tools_settings";
|
|
16
17
|
const MAX_DIAL_SLOTS = 6;
|
|
@@ -87,6 +88,12 @@ const mergeWithDefaults = (defaults, stored, options) => {
|
|
|
87
88
|
* via AsyncStorage so teams can tailor which tools appear in the dial or floating row.
|
|
88
89
|
*/
|
|
89
90
|
|
|
91
|
+
/**
|
|
92
|
+
* The subset of InstalledApp the settings modal needs per tool. `icon`/`color`
|
|
93
|
+
* let rows fall back to the tool's own glyph when getToolIcon() has no
|
|
94
|
+
* night-tuned override for it.
|
|
95
|
+
*/
|
|
96
|
+
|
|
90
97
|
/**
|
|
91
98
|
* Generate default settings based on available apps and optional team default configuration.
|
|
92
99
|
*
|
|
@@ -138,6 +145,10 @@ const generateDefaultSettings = (availableApps = [], defaultFloatingTools, defau
|
|
|
138
145
|
/**
|
|
139
146
|
* Configurable modal surface that lets engineers pick which dev tools appear in the dial and
|
|
140
147
|
* floating row. Persists preferences and enforces slot limits for a consistent UX.
|
|
148
|
+
*
|
|
149
|
+
* Styled in the "night" language (Everlights port — see shared-ui's
|
|
150
|
+
* ui/night): section labels outside near-black cards, hairline-separated
|
|
151
|
+
* rows, real switches, and a transparent header the star field runs through.
|
|
141
152
|
*/
|
|
142
153
|
const DevToolsSettingsModal = ({
|
|
143
154
|
visible,
|
|
@@ -154,11 +165,27 @@ const DevToolsSettingsModal = ({
|
|
|
154
165
|
const defaultSettings = (0, _react.useMemo)(() => generateDefaultSettings(availableApps, defaultFloatingTools, defaultDialTools), [availableApps, defaultFloatingTools, defaultDialTools]);
|
|
155
166
|
const allowedDialKeys = (0, _react.useMemo)(() => Object.keys(defaultSettings.dialTools), [defaultSettings]);
|
|
156
167
|
const allowedFloatingKeys = (0, _react.useMemo)(() => Object.keys(defaultSettings.floatingTools).filter(key => key !== "environment"), [defaultSettings]);
|
|
157
|
-
const [settings, setSettings] = (0, _react.useState)(initialSettings || defaultSettings);
|
|
158
|
-
const [activeTab, setActiveTab] = (0, _react.useState)("floating");
|
|
159
|
-
const [activeTabLoaded, setActiveTabLoaded] = (0, _react.useState)(
|
|
168
|
+
const [settings, setSettings] = (0, _react.useState)(initialSettings || cachedSettings || defaultSettings);
|
|
169
|
+
const [activeTab, setActiveTab] = (0, _react.useState)(cachedActiveTab ?? "floating");
|
|
170
|
+
const [activeTabLoaded, setActiveTabLoaded] = (0, _react.useState)(cachedActiveTab !== null);
|
|
160
171
|
const [expandedSettings, setExpandedSettings] = (0, _react.useState)(new Set());
|
|
161
172
|
const [showLicenseModal, setShowLicenseModal] = (0, _react.useState)(false);
|
|
173
|
+
/**
|
|
174
|
+
* Tool icons are the expensive half of this modal: ~20 of them, each a
|
|
175
|
+
* data-driven glyph that mounts one view per shape. Rendering them in the
|
|
176
|
+
* first pass pushed the modal's first paint out to ~240ms, so the tap felt
|
|
177
|
+
* dead. Holding them back a single frame lets the chrome and the tool rows
|
|
178
|
+
* paint at ~100ms and the glyphs land during the entrance fade.
|
|
179
|
+
*
|
|
180
|
+
* There is no layout shift: `styles.toolIconSlot` is a fixed box, so it
|
|
181
|
+
* reads as the icon's placeholder until filled.
|
|
182
|
+
*/
|
|
183
|
+
const [iconsReady, setIconsReady] = (0, _react.useState)(false);
|
|
184
|
+
(0, _react.useEffect)(() => {
|
|
185
|
+
const frame = requestAnimationFrame(() => setIconsReady(true));
|
|
186
|
+
return () => cancelAnimationFrame(frame);
|
|
187
|
+
}, []);
|
|
188
|
+
|
|
162
189
|
// null when external-sync isn't installed (or predates the status store);
|
|
163
190
|
// "idle" until AutoExternalSync initializes — the row hides in both cases.
|
|
164
191
|
const desktopSyncStatus = (0, _useDesktopSyncStatus.useDesktopSyncStatus)();
|
|
@@ -169,7 +196,9 @@ const DevToolsSettingsModal = ({
|
|
|
169
196
|
try {
|
|
170
197
|
const savedTab = await _sharedUi.persistentStorage.getItem(_sharedUi.devToolsStorageKeys.settings.activeTab());
|
|
171
198
|
if (savedTab && ["floating", "settings", "pro"].includes(savedTab)) {
|
|
172
|
-
|
|
199
|
+
const tab = savedTab;
|
|
200
|
+
cachedActiveTab = tab;
|
|
201
|
+
setActiveTab(prev => prev === tab ? prev : tab);
|
|
173
202
|
}
|
|
174
203
|
} catch (error) {
|
|
175
204
|
// Failed to load active tab - use default
|
|
@@ -194,18 +223,21 @@ const DevToolsSettingsModal = ({
|
|
|
194
223
|
const useLicenseHook = getUseLicense();
|
|
195
224
|
const license = useLicenseHook?.();
|
|
196
225
|
const isPro = license?.isPro ?? false;
|
|
197
|
-
|
|
226
|
+
// A key is set but validation is failing. Without this the tab renders a bare
|
|
227
|
+
// "Free" badge, which reads as "your key was rejected" when what actually
|
|
228
|
+
// happened is that we never reached the license server. `errorKind` decides
|
|
229
|
+
// which story to tell: only a transport failure gets the VPN/proxy advice — a
|
|
230
|
+
// real verdict (suspended, expired) with that advice would send the user off
|
|
231
|
+
// to fight their network over a key that was genuinely rejected.
|
|
232
|
+
const licenseError = !isPro && license?.licenseKey ? license.error : null;
|
|
233
|
+
const licenseErrorIsTransport = license?.errorKind === "transport";
|
|
234
|
+
const [storageBackend, setStorageBackend] = (0, _react.useState)(cachedStorageBackend);
|
|
198
235
|
const [isClearing, setIsClearing] = (0, _react.useState)(false);
|
|
199
236
|
const [clearSuccess, setClearSuccess] = (0, _react.useState)(false);
|
|
200
237
|
const [isStorageExpanded, setIsStorageExpanded] = (0, _react.useState)(false);
|
|
201
238
|
const [savedKeys, setSavedKeys] = (0, _react.useState)([]);
|
|
202
239
|
const [savedKeysLoading, setSavedKeysLoading] = (0, _react.useState)(false);
|
|
203
|
-
const [copySuccess, setCopySuccess] = (0, _react.useState)(false);
|
|
204
|
-
const [isExportExpanded, setIsExportExpanded] = (0, _react.useState)(false);
|
|
205
240
|
const insets = (0, _sharedUi.useSafeAreaInsets)();
|
|
206
|
-
|
|
207
|
-
// Check if in development mode - used to show dev-only features like Export Config
|
|
208
|
-
const isDevelopmentMode = typeof __DEV__ !== "undefined" && __DEV__;
|
|
209
241
|
const screenHeight = _reactNative.Dimensions.get("window").height;
|
|
210
242
|
const screenWidth = _reactNative.Dimensions.get("window").width;
|
|
211
243
|
const modalHeight = Math.floor(screenHeight * 0.33); // 1/3 of screen height
|
|
@@ -220,10 +252,12 @@ const DevToolsSettingsModal = ({
|
|
|
220
252
|
allowedDialKeys,
|
|
221
253
|
allowedFloatingKeys
|
|
222
254
|
});
|
|
223
|
-
|
|
255
|
+
cachedSettings = merged;
|
|
256
|
+
setSettings(prev => sameSettings(prev, merged) ? prev : merged);
|
|
224
257
|
return;
|
|
225
258
|
}
|
|
226
|
-
|
|
259
|
+
cachedSettings = defaultSettings;
|
|
260
|
+
setSettings(prev => sameSettings(prev, defaultSettings) ? prev : defaultSettings);
|
|
227
261
|
} catch (error) {
|
|
228
262
|
console.error("Failed to load dev tools settings:", error);
|
|
229
263
|
setSettings(defaultSettings);
|
|
@@ -235,7 +269,10 @@ const DevToolsSettingsModal = ({
|
|
|
235
269
|
|
|
236
270
|
// Load storage backend type
|
|
237
271
|
(0, _react.useEffect)(() => {
|
|
238
|
-
(0, _sharedUi.getStorageBackendType)().then(
|
|
272
|
+
(0, _sharedUi.getStorageBackendType)().then(backend => {
|
|
273
|
+
cachedStorageBackend = backend;
|
|
274
|
+
setStorageBackend(prev => prev === backend ? prev : backend);
|
|
275
|
+
});
|
|
239
276
|
}, []);
|
|
240
277
|
|
|
241
278
|
// Load saved keys when storage card is expanded
|
|
@@ -258,6 +295,7 @@ const DevToolsSettingsModal = ({
|
|
|
258
295
|
dialTools: enforceDialLimit(newSettings.dialTools)
|
|
259
296
|
};
|
|
260
297
|
await _sharedUi.persistentStorage.setItem(STORAGE_KEY, JSON.stringify(limitedSettings));
|
|
298
|
+
cachedSettings = limitedSettings;
|
|
261
299
|
setSettings(limitedSettings);
|
|
262
300
|
onSettingsChange?.(limitedSettings);
|
|
263
301
|
// Notify listeners (e.g., floating bubble) to refresh immediately
|
|
@@ -304,49 +342,6 @@ const DevToolsSettingsModal = ({
|
|
|
304
342
|
}
|
|
305
343
|
};
|
|
306
344
|
|
|
307
|
-
// Get the enabled tools as arrays for display and copy
|
|
308
|
-
const enabledConfig = (0, _react.useMemo)(() => {
|
|
309
|
-
const enabledFloating = Object.entries(settings.floatingTools).filter(([_, enabled]) => enabled).map(([id]) => id);
|
|
310
|
-
const enabledDial = Object.entries(settings.dialTools).filter(([_, enabled]) => enabled).map(([id]) => id);
|
|
311
|
-
return {
|
|
312
|
-
floating: enabledFloating,
|
|
313
|
-
dial: enabledDial
|
|
314
|
-
};
|
|
315
|
-
}, [settings]);
|
|
316
|
-
|
|
317
|
-
// Generate exportable code snippet from current settings
|
|
318
|
-
// Only outputs the defaultFloatingTools and defaultDialTools props
|
|
319
|
-
// so users can add them to their existing FloatingDevTools config
|
|
320
|
-
const generateConfigCode = (0, _react.useCallback)(() => {
|
|
321
|
-
const {
|
|
322
|
-
floating,
|
|
323
|
-
dial
|
|
324
|
-
} = enabledConfig;
|
|
325
|
-
|
|
326
|
-
// Build only the default config props (not the full component)
|
|
327
|
-
const props = [];
|
|
328
|
-
if (floating.length > 0) {
|
|
329
|
-
const floatingStr = floating.map(id => `'${id}'`).join(', ');
|
|
330
|
-
props.push(`defaultFloatingTools={[${floatingStr}]}`);
|
|
331
|
-
}
|
|
332
|
-
if (dial.length > 0) {
|
|
333
|
-
const dialStr = dial.map(id => `'${id}'`).join(', ');
|
|
334
|
-
props.push(`defaultDialTools={[${dialStr}]}`);
|
|
335
|
-
}
|
|
336
|
-
if (props.length === 0) {
|
|
337
|
-
return `// No tools enabled`;
|
|
338
|
-
}
|
|
339
|
-
return props.join('\n');
|
|
340
|
-
}, [enabledConfig]);
|
|
341
|
-
const handleCopyConfig = async () => {
|
|
342
|
-
const code = generateConfigCode();
|
|
343
|
-
const success = await (0, _sharedUi.copyToClipboard)(code);
|
|
344
|
-
if (success) {
|
|
345
|
-
setCopySuccess(true);
|
|
346
|
-
setTimeout(() => setCopySuccess(false), 2000);
|
|
347
|
-
}
|
|
348
|
-
};
|
|
349
|
-
|
|
350
345
|
// Modal is fixed to bottom sheet mode
|
|
351
346
|
const handleModeChange = (0, _react.useCallback)(_mode => {
|
|
352
347
|
// Mode changes handled by JsModal
|
|
@@ -364,153 +359,161 @@ const DevToolsSettingsModal = ({
|
|
|
364
359
|
};
|
|
365
360
|
const getToolLabel = tool => {
|
|
366
361
|
if (tool === "environment") {
|
|
367
|
-
return "
|
|
362
|
+
return "Env Badge";
|
|
368
363
|
}
|
|
369
364
|
const app = availableApps.find(a => a.id === tool);
|
|
370
365
|
return app?.name ?? tool.toUpperCase().replace(/_/g, " ");
|
|
371
366
|
};
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
367
|
+
const getToolIcon = tool => {
|
|
368
|
+
if (!iconsReady) return null;
|
|
369
|
+
switch (tool) {
|
|
370
|
+
case "query":
|
|
371
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_floatingToolsCore.QueryIcon, {
|
|
372
|
+
size: 18
|
|
373
|
+
});
|
|
374
|
+
case "env":
|
|
375
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_floatingToolsCore.EnvIcon, {
|
|
376
|
+
size: 18
|
|
377
|
+
});
|
|
378
|
+
case "sentry":
|
|
379
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.SentryBugIcon, {
|
|
380
|
+
size: 18,
|
|
381
|
+
colorPreset: "red",
|
|
382
|
+
noBackground: true
|
|
383
|
+
});
|
|
384
|
+
case "storage":
|
|
385
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_floatingToolsCore.StorageIcon, {
|
|
386
|
+
size: 18,
|
|
387
|
+
bgColor: _sharedUi.night.color.surface
|
|
388
|
+
});
|
|
389
|
+
case "wifi":
|
|
390
|
+
case "query-wifi-toggle":
|
|
391
|
+
// Support both IDs for wifi toggle
|
|
392
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.WifiCircuitIcon, {
|
|
393
|
+
size: 18,
|
|
394
|
+
colorPreset: "green",
|
|
395
|
+
strength: 4,
|
|
396
|
+
noBackground: true
|
|
397
|
+
});
|
|
398
|
+
case "route-events":
|
|
399
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_floatingToolsCore.RoutesIcon, {
|
|
400
|
+
size: 18,
|
|
401
|
+
bgColor: _sharedUi.night.color.surface
|
|
402
|
+
});
|
|
403
|
+
case "network":
|
|
404
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_floatingToolsCore.NetworkIcon, {
|
|
405
|
+
size: 18
|
|
406
|
+
});
|
|
407
|
+
case "environment":
|
|
408
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_floatingToolsCore.EnvIcon, {
|
|
409
|
+
size: 18
|
|
410
|
+
});
|
|
411
|
+
case "debug-borders":
|
|
412
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Layers, {
|
|
413
|
+
size: 18,
|
|
414
|
+
color: _sharedUi.night.color.accent
|
|
415
|
+
});
|
|
416
|
+
case "highlight-updates":
|
|
417
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.RenderCountIcon, {
|
|
418
|
+
size: 18,
|
|
419
|
+
color: _sharedUi.night.color.accent
|
|
420
|
+
});
|
|
421
|
+
case "highlight-updates-modal":
|
|
422
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_floatingToolsCore.HighlighterIcon, {
|
|
423
|
+
size: 18
|
|
424
|
+
});
|
|
425
|
+
case "redux":
|
|
426
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_floatingToolsCore.ReduxIcon, {
|
|
427
|
+
size: 18
|
|
428
|
+
});
|
|
429
|
+
case "image-overlay":
|
|
430
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ImageOverlayIcon, {
|
|
431
|
+
size: 18
|
|
432
|
+
});
|
|
433
|
+
case "events":
|
|
434
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_floatingToolsCore.EventsIcon, {
|
|
435
|
+
size: 18
|
|
436
|
+
});
|
|
437
|
+
case "zustand":
|
|
438
|
+
try {
|
|
439
|
+
// @ts-ignore - Optional package
|
|
440
|
+
const {
|
|
441
|
+
ZustandIcon
|
|
442
|
+
} = require("@buoy-gg/zustand");
|
|
443
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(ZustandIcon, {
|
|
444
|
+
size: 18
|
|
429
445
|
});
|
|
430
|
-
|
|
431
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
432
|
-
size:
|
|
446
|
+
} catch {
|
|
447
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Info, {
|
|
448
|
+
size: 18,
|
|
449
|
+
color: _sharedUi.night.color.textSecondary
|
|
433
450
|
});
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
451
|
+
}
|
|
452
|
+
case "jotai":
|
|
453
|
+
try {
|
|
454
|
+
// @ts-ignore - Optional package
|
|
455
|
+
const {
|
|
456
|
+
JotaiIcon
|
|
457
|
+
} = require("@buoy-gg/jotai");
|
|
458
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(JotaiIcon, {
|
|
459
|
+
size: 18
|
|
437
460
|
});
|
|
438
|
-
|
|
439
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
440
|
-
size:
|
|
461
|
+
} catch {
|
|
462
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Info, {
|
|
463
|
+
size: 18,
|
|
464
|
+
color: _sharedUi.night.color.textSecondary
|
|
441
465
|
});
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
color: _sharedUi.buoyColors.textSecondary
|
|
455
|
-
});
|
|
456
|
-
}
|
|
457
|
-
case "jotai":
|
|
458
|
-
try {
|
|
459
|
-
// @ts-ignore - Optional package
|
|
460
|
-
const {
|
|
461
|
-
JotaiIcon
|
|
462
|
-
} = require("@buoy-gg/jotai");
|
|
463
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsx)(JotaiIcon, {
|
|
464
|
-
size: 16
|
|
465
|
-
});
|
|
466
|
-
} catch {
|
|
467
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Info, {
|
|
468
|
-
size: 16,
|
|
469
|
-
color: _sharedUi.buoyColors.textSecondary
|
|
466
|
+
}
|
|
467
|
+
default:
|
|
468
|
+
{
|
|
469
|
+
// Tools without a night-tuned override (console, images, time
|
|
470
|
+
// machine, perf monitor, custom toolkit tools, …) render their own
|
|
471
|
+
// app icon — the same artwork the dial shows.
|
|
472
|
+
const app = availableApps.find(a => a.id === tool);
|
|
473
|
+
if (app?.icon != null) {
|
|
474
|
+
return (0, _AppIcon.renderAppIcon)(app.icon, {
|
|
475
|
+
slot: "row",
|
|
476
|
+
size: 18,
|
|
477
|
+
color: app.color
|
|
470
478
|
});
|
|
471
479
|
}
|
|
472
|
-
default:
|
|
473
480
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Info, {
|
|
474
|
-
size:
|
|
475
|
-
color: _sharedUi.
|
|
481
|
+
size: 18,
|
|
482
|
+
color: _sharedUi.night.color.textSecondary
|
|
476
483
|
});
|
|
477
|
-
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
};
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* One tool row: glyph, name + one-line description, switch. Lives inside a
|
|
490
|
+
* NightCard's hairline-separated rows.
|
|
491
|
+
*/
|
|
492
|
+
const renderToolRow = (keyName, value, disabled, onToggle) => {
|
|
493
|
+
const description = getToolDescription(keyName);
|
|
494
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
495
|
+
activeOpacity: disabled ? 1 : 0.7,
|
|
481
496
|
onPress: () => !disabled && onToggle(),
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
})]
|
|
503
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
504
|
-
style: [styles.pillToggle, value ? styles.pillToggleOn : styles.pillToggleOff, disabled && {
|
|
505
|
-
opacity: 0.5
|
|
506
|
-
}],
|
|
507
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
508
|
-
style: [styles.pillToggleText, value ? styles.pillToggleTextOn : styles.pillToggleTextOff],
|
|
509
|
-
children: value ? "ON" : "OFF"
|
|
510
|
-
})
|
|
511
|
-
})]
|
|
512
|
-
})
|
|
513
|
-
})
|
|
497
|
+
accessibilityLabel: getToolLabel(keyName),
|
|
498
|
+
style: [styles.toolRow, disabled && styles.rowDisabled],
|
|
499
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
500
|
+
style: styles.toolIconSlot,
|
|
501
|
+
children: getToolIcon(keyName)
|
|
502
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
503
|
+
style: styles.rowInfo,
|
|
504
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
505
|
+
style: styles.rowLabel,
|
|
506
|
+
children: [getToolLabel(keyName), disabled ? " · max 6" : ""]
|
|
507
|
+
}), description ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
508
|
+
style: styles.rowCaption,
|
|
509
|
+
numberOfLines: 1,
|
|
510
|
+
children: description
|
|
511
|
+
}) : null]
|
|
512
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightSwitch, {
|
|
513
|
+
value: value,
|
|
514
|
+
disabled: disabled,
|
|
515
|
+
onValueChange: () => onToggle()
|
|
516
|
+
})]
|
|
514
517
|
}, keyName);
|
|
515
518
|
};
|
|
516
519
|
|
|
@@ -527,609 +530,252 @@ const DevToolsSettingsModal = ({
|
|
|
527
530
|
});
|
|
528
531
|
};
|
|
529
532
|
|
|
530
|
-
|
|
531
|
-
|
|
533
|
+
/**
|
|
534
|
+
* One global-setting row: name + one-line hint, switch, and a tap-to-expand
|
|
535
|
+
* body holding the full description and recommendation.
|
|
536
|
+
*/
|
|
537
|
+
const renderGlobalSettingRow = (settingKey, label, shortDescription, fullDescription, recommendation) => {
|
|
532
538
|
const value = settings.globalSettings?.[settingKey] ?? false;
|
|
533
539
|
const isExpanded = expandedSettings.has(settingKey);
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
marginBottom: 10
|
|
538
|
-
},
|
|
539
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
540
|
-
activeOpacity: 0.85,
|
|
540
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
541
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
542
|
+
activeOpacity: 0.7,
|
|
541
543
|
onPress: () => toggleSettingExpanded(settingKey),
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
borderWidth: 2,
|
|
545
|
-
shadowColor: color,
|
|
546
|
-
shadowOpacity: 0.8,
|
|
547
|
-
shadowRadius: 20,
|
|
548
|
-
shadowOffset: {
|
|
549
|
-
width: 0,
|
|
550
|
-
height: 0
|
|
551
|
-
},
|
|
552
|
-
elevation: 10,
|
|
553
|
-
transform: [{
|
|
554
|
-
scale: 1.01
|
|
555
|
-
}]
|
|
556
|
-
}],
|
|
544
|
+
accessibilityLabel: label,
|
|
545
|
+
style: styles.settingRow,
|
|
557
546
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
558
|
-
style: styles.
|
|
559
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.
|
|
560
|
-
style: styles.
|
|
561
|
-
children:
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
style: styles.expandableCardTitle,
|
|
567
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
568
|
-
style: styles.expandableCardTitleText,
|
|
569
|
-
children: label
|
|
570
|
-
}), !isExpanded && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
571
|
-
style: styles.expandableCardSubtitle,
|
|
572
|
-
numberOfLines: 1,
|
|
573
|
-
children: shortDescription
|
|
574
|
-
})]
|
|
575
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
576
|
-
style: styles.expandableCardActions,
|
|
577
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
578
|
-
onPress: () => toggleGlobalSetting(settingKey),
|
|
579
|
-
activeOpacity: 0.8,
|
|
580
|
-
style: [styles.pillToggle, {
|
|
581
|
-
backgroundColor: value ? `${_sharedUi.buoyColors.success}33` : _sharedUi.buoyColors.hover,
|
|
582
|
-
borderColor: value ? `${_sharedUi.buoyColors.success}88` : _sharedUi.buoyColors.border,
|
|
583
|
-
shadowColor: value ? _sharedUi.buoyColors.success : "transparent",
|
|
584
|
-
shadowOffset: {
|
|
585
|
-
width: 0,
|
|
586
|
-
height: 0
|
|
587
|
-
},
|
|
588
|
-
shadowOpacity: value ? 0.4 : 0,
|
|
589
|
-
shadowRadius: value ? 8 : 0
|
|
590
|
-
}],
|
|
591
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
592
|
-
style: [styles.pillToggleText, {
|
|
593
|
-
color: value ? _sharedUi.buoyColors.success : _sharedUi.buoyColors.textMuted
|
|
594
|
-
}],
|
|
595
|
-
children: value ? "ON" : "OFF"
|
|
596
|
-
})
|
|
597
|
-
}), isExpanded ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronDown, {
|
|
598
|
-
size: 18,
|
|
599
|
-
color: "#7F91B2"
|
|
600
|
-
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronRightIcon, {
|
|
601
|
-
size: 18,
|
|
602
|
-
color: "#7F91B2"
|
|
603
|
-
})]
|
|
604
|
-
})]
|
|
605
|
-
}), isExpanded && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
606
|
-
style: styles.expandableCardBody,
|
|
607
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
608
|
-
style: styles.expandableCardSection,
|
|
609
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
610
|
-
style: styles.expandableCardSectionTitle,
|
|
611
|
-
children: "DESCRIPTION"
|
|
612
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
613
|
-
style: styles.expandableCardSectionText,
|
|
614
|
-
children: fullDescription
|
|
615
|
-
})]
|
|
616
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
617
|
-
style: styles.expandableCardSection,
|
|
618
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
619
|
-
style: styles.expandableCardSectionTitle,
|
|
620
|
-
children: "RECOMMENDATION"
|
|
621
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
622
|
-
style: styles.expandableCardSectionText,
|
|
623
|
-
children: recommendation
|
|
624
|
-
})]
|
|
547
|
+
style: styles.rowInfo,
|
|
548
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
549
|
+
style: styles.rowLabel,
|
|
550
|
+
children: label
|
|
551
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
552
|
+
style: styles.rowCaption,
|
|
553
|
+
numberOfLines: isExpanded ? 0 : 1,
|
|
554
|
+
children: shortDescription
|
|
625
555
|
})]
|
|
556
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightSwitch, {
|
|
557
|
+
value: value,
|
|
558
|
+
onValueChange: () => toggleGlobalSetting(settingKey)
|
|
626
559
|
})]
|
|
627
|
-
})
|
|
560
|
+
}), isExpanded && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
561
|
+
style: styles.settingRowBody,
|
|
562
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
563
|
+
style: styles.settingRowBodyText,
|
|
564
|
+
children: fullDescription
|
|
565
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
566
|
+
style: styles.settingRowBodyHint,
|
|
567
|
+
children: recommendation
|
|
568
|
+
})]
|
|
569
|
+
})]
|
|
628
570
|
}, settingKey);
|
|
629
571
|
};
|
|
572
|
+
|
|
573
|
+
/** Section = uppercase label, card, optional footnote(s) under it. */
|
|
574
|
+
const renderSection = (label, card, footnotes) => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
575
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightSectionLabel, {
|
|
576
|
+
children: label
|
|
577
|
+
}), card, footnotes]
|
|
578
|
+
});
|
|
579
|
+
const storageBadge = storageBackend === "filesystem" ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightBadge, {
|
|
580
|
+
label: "File System",
|
|
581
|
+
tone: "accent"
|
|
582
|
+
}) : storageBackend === "asyncstorage" ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightBadge, {
|
|
583
|
+
label: "Async Storage",
|
|
584
|
+
tone: "warning"
|
|
585
|
+
}) : storageBackend === "memory" ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightBadge, {
|
|
586
|
+
label: "Memory",
|
|
587
|
+
tone: "danger"
|
|
588
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightBadge, {
|
|
589
|
+
label: "Loading\u2026",
|
|
590
|
+
tone: "neutral"
|
|
591
|
+
});
|
|
630
592
|
const renderContent = () => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
631
593
|
style: styles.container,
|
|
632
594
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.ScrollView, {
|
|
633
595
|
style: styles.scrollContent,
|
|
634
596
|
showsVerticalScrollIndicator: false,
|
|
635
597
|
contentContainerStyle: styles.scrollContainer,
|
|
636
|
-
children: [activeTab === "floating" && /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
598
|
+
children: [activeTab === "floating" && /*#__PURE__*/(0, _jsxRuntime.jsx)(_jsxRuntime.Fragment, {
|
|
599
|
+
children: renderSection("Floating Tools", /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightCard, {
|
|
600
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightRows, {
|
|
601
|
+
children: Object.entries(settings.floatingTools).map(([key, value]) => renderToolRow(key, value, false, () => toggleFloatingTool(key)))
|
|
602
|
+
})
|
|
603
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightFootnote, {
|
|
604
|
+
children: "Tools switched on here appear in the floating bubble row."
|
|
605
|
+
}))
|
|
606
|
+
}), activeTab === "settings" && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
607
|
+
children: [renderSection("Background", /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightCard, {
|
|
608
|
+
padded: true,
|
|
609
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.BackgroundSwitcher, {
|
|
610
|
+
embedded: true
|
|
611
|
+
})
|
|
612
|
+
})), renderSection("Storage", /*#__PURE__*/(0, _jsxRuntime.jsxs)(_sharedUi.NightCard, {
|
|
613
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
614
|
+
activeOpacity: 0.7,
|
|
647
615
|
onPress: () => setIsStorageExpanded(!isStorageExpanded),
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
children:
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
children: "STORAGE TYPE"
|
|
663
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
664
|
-
style: styles.storageStatusBadgeContainer,
|
|
665
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
666
|
-
style: [styles.storageStatusBadge, {
|
|
667
|
-
backgroundColor: storageBackend === "filesystem" ? _sharedUi.buoyColors.success + "20" : storageBackend === "asyncstorage" ? _sharedUi.buoyColors.warning + "20" : _sharedUi.buoyColors.error + "20",
|
|
668
|
-
borderColor: storageBackend === "filesystem" ? _sharedUi.buoyColors.success + "60" : storageBackend === "asyncstorage" ? _sharedUi.buoyColors.warning + "60" : _sharedUi.buoyColors.error + "60"
|
|
669
|
-
}],
|
|
670
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
671
|
-
style: [styles.storageStatusBadgeText, {
|
|
672
|
-
color: storageBackend === "filesystem" ? _sharedUi.buoyColors.success : storageBackend === "asyncstorage" ? _sharedUi.buoyColors.warning : _sharedUi.buoyColors.error
|
|
673
|
-
}],
|
|
674
|
-
children: storageBackend === "filesystem" ? "FILE SYSTEM" : storageBackend === "asyncstorage" ? "ASYNC STORAGE" : storageBackend === "memory" ? "MEMORY" : "LOADING..."
|
|
675
|
-
})
|
|
676
|
-
}), storageBackend === "filesystem" && /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CheckCircle2, {
|
|
677
|
-
size: 14,
|
|
678
|
-
color: _sharedUi.buoyColors.success
|
|
679
|
-
}), storageBackend === "asyncstorage" && /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.AlertTriangle, {
|
|
680
|
-
size: 14,
|
|
681
|
-
color: _sharedUi.buoyColors.warning
|
|
682
|
-
}), storageBackend === "memory" && /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.AlertTriangle, {
|
|
683
|
-
size: 14,
|
|
684
|
-
color: _sharedUi.buoyColors.error
|
|
685
|
-
})]
|
|
686
|
-
})]
|
|
687
|
-
}), isStorageExpanded ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronDown, {
|
|
688
|
-
size: 18,
|
|
689
|
-
color: _sharedUi.buoyColors.textMuted
|
|
690
|
-
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronRightIcon, {
|
|
691
|
-
size: 18,
|
|
692
|
-
color: _sharedUi.buoyColors.textMuted
|
|
693
|
-
})]
|
|
694
|
-
})
|
|
695
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
696
|
-
style: styles.storageStatusDescription,
|
|
697
|
-
children: storageBackend === "filesystem" ? "Settings persist independently and survive AsyncStorage.clear() calls during logout." : storageBackend === "asyncstorage" ? "Settings may be lost if AsyncStorage is cleared during logout." : storageBackend === "memory" ? "Settings are stored in memory only and will be lost on app restart." : "Checking storage backend..."
|
|
698
|
-
}), storageBackend === "asyncstorage" && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
699
|
-
style: styles.adviceHint,
|
|
700
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Zap, {
|
|
701
|
-
size: 14,
|
|
702
|
-
color: _sharedUi.buoyColors.warning
|
|
703
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
704
|
-
style: styles.adviceHintText,
|
|
705
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
706
|
-
style: styles.adviceHintBold,
|
|
707
|
-
children: "Tip:"
|
|
708
|
-
}), " Install", " ", /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
709
|
-
style: styles.adviceHintCode,
|
|
710
|
-
children: "expo-file-system"
|
|
711
|
-
}), " to persist settings through logout flows."]
|
|
616
|
+
accessibilityLabel: "Storage Type",
|
|
617
|
+
style: styles.settingRow,
|
|
618
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
619
|
+
style: styles.rowInfo,
|
|
620
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
621
|
+
style: styles.rowLabel,
|
|
622
|
+
children: "Storage Type"
|
|
623
|
+
})
|
|
624
|
+
}), storageBadge, isStorageExpanded ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronDown, {
|
|
625
|
+
size: 16,
|
|
626
|
+
color: _sharedUi.night.color.textTertiary
|
|
627
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronRightIcon, {
|
|
628
|
+
size: 16,
|
|
629
|
+
color: _sharedUi.night.color.textTertiary
|
|
712
630
|
})]
|
|
713
|
-
}),
|
|
714
|
-
style: styles.adviceHintsContainer,
|
|
631
|
+
}), isStorageExpanded && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
715
632
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
716
|
-
style:
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
727
|
-
style: styles.adviceHintBold,
|
|
728
|
-
children: "No persistent storage available!"
|
|
729
|
-
}), " Settings will reset on every app restart."]
|
|
730
|
-
})]
|
|
731
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
732
|
-
style: styles.adviceHint,
|
|
733
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Zap, {
|
|
734
|
-
size: 14,
|
|
735
|
-
color: _sharedUi.buoyColors.primary
|
|
736
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
737
|
-
style: styles.adviceHintText,
|
|
738
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
739
|
-
style: styles.adviceHintBold,
|
|
740
|
-
children: "Best:"
|
|
741
|
-
}), " Install", " ", /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
742
|
-
style: styles.adviceHintCode,
|
|
743
|
-
children: "expo-file-system"
|
|
744
|
-
}), " for logout-safe persistence."]
|
|
633
|
+
style: styles.settingRowBody,
|
|
634
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
635
|
+
style: styles.settingRowBodyText,
|
|
636
|
+
children: storageBackend === "filesystem" ? "Settings persist independently and survive AsyncStorage.clear() calls during logout." : storageBackend === "asyncstorage" ? "Settings may be lost if AsyncStorage is cleared during logout." : storageBackend === "memory" ? "Settings are stored in memory only and will be lost on app restart." : "Checking storage backend…"
|
|
637
|
+
}), storageBackend === "asyncstorage" && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
638
|
+
style: [styles.settingRowBodyText, styles.bodyWarning],
|
|
639
|
+
children: "Install expo-file-system to persist settings through logout flows."
|
|
640
|
+
}), storageBackend === "memory" && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
641
|
+
style: [styles.settingRowBodyText, styles.bodyDanger],
|
|
642
|
+
children: "No persistent storage available \u2014 install expo-file-system (best) or @react-native-async-storage/async-storage."
|
|
745
643
|
})]
|
|
746
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
747
|
-
style: styles.
|
|
748
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.
|
|
749
|
-
|
|
750
|
-
color: _sharedUi.buoyColors.textMuted
|
|
751
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
752
|
-
style: styles.adviceHintText,
|
|
644
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightSeparator, {}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
645
|
+
style: styles.storageExpanded,
|
|
646
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
647
|
+
style: styles.storageExpandedHeader,
|
|
753
648
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
754
|
-
style: styles.
|
|
755
|
-
children: "
|
|
756
|
-
}),
|
|
757
|
-
style: styles.
|
|
758
|
-
children: "
|
|
759
|
-
})
|
|
760
|
-
})
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
773
|
-
style: styles.storageExpandedCount,
|
|
774
|
-
children: savedKeysLoading ? "..." : `${savedKeys.length} keys`
|
|
775
|
-
})]
|
|
776
|
-
}), savedKeysLoading ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
777
|
-
style: styles.storageKeyItem,
|
|
778
|
-
children: "Loading..."
|
|
779
|
-
}) : savedKeys.length === 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
780
|
-
style: styles.storageKeyItemEmpty,
|
|
781
|
-
children: "No settings saved yet"
|
|
782
|
-
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
|
|
783
|
-
style: styles.storageKeysList,
|
|
784
|
-
nestedScrollEnabled: true,
|
|
785
|
-
showsVerticalScrollIndicator: true,
|
|
786
|
-
children: savedKeys.map(key => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
787
|
-
style: styles.storageKeyItem,
|
|
788
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
789
|
-
style: styles.storageKeyText,
|
|
790
|
-
numberOfLines: 1,
|
|
791
|
-
children: key.replace("@react_buoy_", "")
|
|
792
|
-
})
|
|
793
|
-
}, key))
|
|
794
|
-
})]
|
|
795
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
796
|
-
style: [styles.clearStorageButton, isClearing && styles.clearStorageButtonDisabled, clearSuccess && styles.clearStorageButtonSuccess],
|
|
797
|
-
onPress: handleClearStorage,
|
|
798
|
-
disabled: isClearing,
|
|
799
|
-
activeOpacity: 0.7,
|
|
800
|
-
children: [clearSuccess ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CheckCircle2, {
|
|
801
|
-
size: 14,
|
|
802
|
-
color: _sharedUi.buoyColors.success
|
|
803
|
-
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Trash2, {
|
|
804
|
-
size: 14,
|
|
805
|
-
color: isClearing ? _sharedUi.buoyColors.textMuted : _sharedUi.buoyColors.error
|
|
806
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
807
|
-
style: [styles.clearStorageButtonText, clearSuccess && {
|
|
808
|
-
color: _sharedUi.buoyColors.success
|
|
809
|
-
}, isClearing && {
|
|
810
|
-
color: _sharedUi.buoyColors.textMuted
|
|
811
|
-
}],
|
|
812
|
-
children: clearSuccess ? "CLEARED" : isClearing ? "CLEARING..." : "CLEAR ALL SETTINGS"
|
|
813
|
-
})]
|
|
814
|
-
})]
|
|
815
|
-
}), desktopSyncStatus && desktopSyncStatus.state !== "idle" && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
816
|
-
style: [styles.storageStatusCard, {
|
|
817
|
-
borderColor: desktopSyncStatus.state === "connected" ? _sharedUi.buoyColors.success + "60" : _sharedUi.buoyColors.warning + "60"
|
|
818
|
-
}],
|
|
819
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
820
|
-
style: styles.storageStatusHeader,
|
|
821
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
822
|
-
style: [styles.storageStatusIcon, {
|
|
823
|
-
backgroundColor: desktopSyncStatus.state === "connected" ? _sharedUi.buoyColors.success + "15" : _sharedUi.buoyColors.warning + "15"
|
|
824
|
-
}],
|
|
825
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Globe, {
|
|
826
|
-
size: 18,
|
|
827
|
-
color: desktopSyncStatus.state === "connected" ? _sharedUi.buoyColors.success : _sharedUi.buoyColors.warning
|
|
828
|
-
})
|
|
829
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
830
|
-
style: styles.storageStatusInfo,
|
|
831
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
832
|
-
style: styles.storageStatusLabel,
|
|
833
|
-
children: "DESKTOP SYNC"
|
|
834
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
835
|
-
style: styles.storageStatusBadgeContainer,
|
|
836
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
837
|
-
style: [styles.storageStatusBadge, {
|
|
838
|
-
backgroundColor: desktopSyncStatus.state === "connected" ? _sharedUi.buoyColors.success + "20" : _sharedUi.buoyColors.warning + "20",
|
|
839
|
-
borderColor: desktopSyncStatus.state === "connected" ? _sharedUi.buoyColors.success + "60" : _sharedUi.buoyColors.warning + "60"
|
|
840
|
-
}],
|
|
649
|
+
style: styles.storageExpandedTitle,
|
|
650
|
+
children: "SAVED SETTINGS"
|
|
651
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
652
|
+
style: styles.storageExpandedCount,
|
|
653
|
+
children: savedKeysLoading ? "…" : `${savedKeys.length} keys`
|
|
654
|
+
})]
|
|
655
|
+
}), savedKeysLoading ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
656
|
+
style: styles.storageKeyEmpty,
|
|
657
|
+
children: "Loading\u2026"
|
|
658
|
+
}) : savedKeys.length === 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
659
|
+
style: styles.storageKeyEmpty,
|
|
660
|
+
children: "No settings saved yet"
|
|
661
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
|
|
662
|
+
style: styles.storageKeysList,
|
|
663
|
+
nestedScrollEnabled: true,
|
|
664
|
+
showsVerticalScrollIndicator: true,
|
|
665
|
+
children: savedKeys.map(key => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
666
|
+
style: styles.storageKeyItem,
|
|
841
667
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
842
|
-
style:
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
children: desktopSyncStatus.state === "connected" ? "CONNECTED" : desktopSyncStatus.state === "connecting" ? "CONNECTING..." : "RETRYING"
|
|
668
|
+
style: styles.storageKeyText,
|
|
669
|
+
numberOfLines: 1,
|
|
670
|
+
children: key.replace("@react_buoy_", "")
|
|
846
671
|
})
|
|
847
|
-
}
|
|
848
|
-
size: 14,
|
|
849
|
-
color: _sharedUi.buoyColors.success
|
|
850
|
-
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.AlertTriangle, {
|
|
851
|
-
size: 14,
|
|
852
|
-
color: _sharedUi.buoyColors.warning
|
|
853
|
-
})]
|
|
854
|
-
})]
|
|
855
|
-
})]
|
|
856
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
857
|
-
style: styles.storageStatusDescription,
|
|
858
|
-
children: [desktopSyncStatus.state === "connected" ? "Streaming tool data to Buoy Desktop at " : "Trying to reach Buoy Desktop at ", /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
859
|
-
style: styles.adviceHintCode,
|
|
860
|
-
children: desktopSyncStatus.targetURL ?? "(unknown URL)"
|
|
861
|
-
}), desktopSyncStatus.state !== "connected" && " — is the desktop app running? Override with the externalSync socketURL option if it runs elsewhere."]
|
|
862
|
-
}), desktopSyncStatus.state === "retrying" && desktopSyncStatus.lastError && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
863
|
-
style: styles.adviceHint,
|
|
864
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.AlertTriangle, {
|
|
865
|
-
size: 14,
|
|
866
|
-
color: _sharedUi.buoyColors.warning
|
|
867
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
868
|
-
style: styles.adviceHintText,
|
|
869
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
870
|
-
style: styles.adviceHintBold,
|
|
871
|
-
children: "Last error:"
|
|
872
|
-
}), " ", desktopSyncStatus.lastError]
|
|
873
|
-
})]
|
|
874
|
-
})]
|
|
875
|
-
}), renderGlobalSettingCard("enableSharedModalDimensions", "SHARED MODAL SIZE", "MODAL", "Sync dimensions across all tools", "When enabled, all tool modals will share the same size and position. Resizing one modal will affect all others. When disabled, each tool remembers its own size and position independently.", "Keep OFF for the best experience. This allows you to customize each tool's modal size separately. Enable only if you prefer uniform modal sizes across all dev tools."), _reactNative.Platform.OS !== "web" && renderGlobalSettingCard("expandableWindowControls", "EXPAND CONTROLS", "MODAL", "iPad-style expandable window buttons", "When enabled, the window control buttons (minimize, toggle mode, close) start as small dots and expand into larger, easy-to-tap buttons when pressed — similar to iPad window controls. When disabled, buttons are directly tappable at their small size.", "Keep ON for touch devices where the small buttons are hard to press. Turn OFF if you prefer direct single-tap access (e.g. when using a mouse or simulator)."), isDevelopmentMode && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
876
|
-
style: styles.exportConfigCard,
|
|
877
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
878
|
-
activeOpacity: 0.85,
|
|
879
|
-
onPress: () => setIsExportExpanded(!isExportExpanded),
|
|
880
|
-
style: styles.exportConfigHeader,
|
|
881
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
882
|
-
style: styles.exportConfigIconContainer,
|
|
883
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.FileCode, {
|
|
884
|
-
size: 18,
|
|
885
|
-
color: _sharedUi.buoyColors.success
|
|
886
|
-
})
|
|
887
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
888
|
-
style: styles.exportConfigInfo,
|
|
889
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
890
|
-
style: styles.exportConfigLabel,
|
|
891
|
-
children: "EXPORT CONFIG"
|
|
892
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
893
|
-
style: styles.exportConfigHint,
|
|
894
|
-
children: "Save your settings to code"
|
|
672
|
+
}, key))
|
|
895
673
|
})]
|
|
896
674
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
897
|
-
style: styles.
|
|
898
|
-
children:
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
675
|
+
style: styles.cardButtonWrap,
|
|
676
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightButton, {
|
|
677
|
+
label: clearSuccess ? "Cleared" : isClearing ? "Clearing…" : "Clear All Settings",
|
|
678
|
+
variant: clearSuccess ? "secondary" : "destructive",
|
|
679
|
+
size: "md",
|
|
680
|
+
disabled: isClearing,
|
|
681
|
+
onPress: handleClearStorage,
|
|
682
|
+
icon: clearSuccess ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CheckCircle2, {
|
|
683
|
+
size: 15,
|
|
684
|
+
color: _sharedUi.night.color.accent
|
|
685
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Trash2, {
|
|
686
|
+
size: 15,
|
|
687
|
+
color: isClearing ? _sharedUi.night.color.textTertiary : _sharedUi.night.color.danger
|
|
688
|
+
})
|
|
904
689
|
})
|
|
905
690
|
})]
|
|
906
|
-
})
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
children: "Configure tools, then export as props for your team."
|
|
914
|
-
})]
|
|
915
|
-
}), isExportExpanded && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
916
|
-
style: styles.exportCodeContainer,
|
|
691
|
+
})]
|
|
692
|
+
})), desktopSyncStatus && desktopSyncStatus.state !== "idle" && renderSection("Desktop Sync", /*#__PURE__*/(0, _jsxRuntime.jsxs)(_sharedUi.NightCard, {
|
|
693
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
694
|
+
activeOpacity: 0.7,
|
|
695
|
+
onPress: () => toggleSettingExpanded("desktopSync"),
|
|
696
|
+
accessibilityLabel: "Buoy Desktop",
|
|
697
|
+
style: styles.settingRow,
|
|
917
698
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
918
|
-
style: styles.
|
|
919
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
920
|
-
style: styles.exportCodeTitle,
|
|
921
|
-
children: "PROPS TO ADD"
|
|
922
|
-
})
|
|
923
|
-
}), enabledConfig.floating.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
924
|
-
style: styles.exportJsonBlock,
|
|
925
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
926
|
-
style: styles.exportJsonProp,
|
|
927
|
-
children: "defaultFloatingTools"
|
|
928
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
929
|
-
style: styles.exportJsonEquals,
|
|
930
|
-
children: "="
|
|
931
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
932
|
-
style: styles.exportJsonBracket,
|
|
933
|
-
children: "{"
|
|
934
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
935
|
-
style: styles.exportJsonArrayBracket,
|
|
936
|
-
children: "["
|
|
937
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
938
|
-
style: styles.exportJsonArrayContent,
|
|
939
|
-
children: enabledConfig.floating.map((id, index) => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
940
|
-
style: styles.exportJsonArrayItem,
|
|
941
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
942
|
-
style: styles.exportJsonString,
|
|
943
|
-
children: ["'", id, "'"]
|
|
944
|
-
}), index < enabledConfig.floating.length - 1 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
945
|
-
style: styles.exportJsonComma,
|
|
946
|
-
children: ","
|
|
947
|
-
})]
|
|
948
|
-
}, id))
|
|
949
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
950
|
-
style: styles.exportJsonArrayBracket,
|
|
951
|
-
children: "]"
|
|
952
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
953
|
-
style: styles.exportJsonBracket,
|
|
954
|
-
children: "}"
|
|
955
|
-
})]
|
|
956
|
-
}), enabledConfig.dial.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
957
|
-
style: [styles.exportJsonBlock, enabledConfig.floating.length > 0 && {
|
|
958
|
-
marginTop: 8
|
|
959
|
-
}],
|
|
960
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
961
|
-
style: styles.exportJsonProp,
|
|
962
|
-
children: "defaultDialTools"
|
|
963
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
964
|
-
style: styles.exportJsonEquals,
|
|
965
|
-
children: "="
|
|
966
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
967
|
-
style: styles.exportJsonBracket,
|
|
968
|
-
children: "{"
|
|
969
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
970
|
-
style: styles.exportJsonArrayBracket,
|
|
971
|
-
children: "["
|
|
972
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
973
|
-
style: styles.exportJsonArrayContent,
|
|
974
|
-
children: enabledConfig.dial.map((id, index) => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
975
|
-
style: styles.exportJsonArrayItem,
|
|
976
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
977
|
-
style: styles.exportJsonString,
|
|
978
|
-
children: ["'", id, "'"]
|
|
979
|
-
}), index < enabledConfig.dial.length - 1 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
980
|
-
style: styles.exportJsonComma,
|
|
981
|
-
children: ","
|
|
982
|
-
})]
|
|
983
|
-
}, id))
|
|
984
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
985
|
-
style: styles.exportJsonArrayBracket,
|
|
986
|
-
children: "]"
|
|
987
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
988
|
-
style: styles.exportJsonBracket,
|
|
989
|
-
children: "}"
|
|
990
|
-
})]
|
|
991
|
-
}), enabledConfig.floating.length === 0 && enabledConfig.dial.length === 0 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
992
|
-
style: styles.exportJsonBlock,
|
|
699
|
+
style: styles.rowInfo,
|
|
993
700
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
994
|
-
style: styles.
|
|
995
|
-
children: "
|
|
701
|
+
style: styles.rowLabel,
|
|
702
|
+
children: "Buoy Desktop"
|
|
996
703
|
})
|
|
997
|
-
}), /*#__PURE__*/(0, _jsxRuntime.
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
704
|
+
}), desktopSyncStatus.state === "connected" ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightBadge, {
|
|
705
|
+
label: "Connected",
|
|
706
|
+
tone: "accent"
|
|
707
|
+
}) : desktopSyncStatus.state === "connecting" ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightBadge, {
|
|
708
|
+
label: "Connecting\u2026",
|
|
709
|
+
tone: "neutral"
|
|
710
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightBadge, {
|
|
711
|
+
label: "Retrying",
|
|
712
|
+
tone: "warning"
|
|
713
|
+
}), expandedSettings.has("desktopSync") ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronDown, {
|
|
714
|
+
size: 16,
|
|
715
|
+
color: _sharedUi.night.color.textTertiary
|
|
716
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ChevronRightIcon, {
|
|
717
|
+
size: 16,
|
|
718
|
+
color: _sharedUi.night.color.textTertiary
|
|
1003
719
|
})]
|
|
1004
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.
|
|
1005
|
-
style:
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
style: [styles.exportCopyButtonText, copySuccess && {
|
|
1016
|
-
color: _sharedUi.buoyColors.success
|
|
1017
|
-
}],
|
|
1018
|
-
children: copySuccess ? "COPIED!" : "COPY CONFIG TO CLIPBOARD"
|
|
720
|
+
}), expandedSettings.has("desktopSync") && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
721
|
+
style: styles.settingRowBody,
|
|
722
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
723
|
+
style: styles.settingRowBodyText,
|
|
724
|
+
children: [desktopSyncStatus.state === "connected" ? "Streaming tool data to Buoy Desktop at " : "Trying to reach Buoy Desktop at ", /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
725
|
+
style: styles.footnoteMono,
|
|
726
|
+
children: desktopSyncStatus.targetURL ?? "(unknown URL)"
|
|
727
|
+
}), desktopSyncStatus.state !== "connected" && " — is the desktop app running? Override with the externalSync socketURL option if it runs elsewhere."]
|
|
728
|
+
}), desktopSyncStatus.state === "retrying" && desktopSyncStatus.lastError && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
729
|
+
style: [styles.settingRowBodyText, styles.bodyWarning],
|
|
730
|
+
children: ["Last error: ", desktopSyncStatus.lastError]
|
|
1019
731
|
})]
|
|
1020
732
|
})]
|
|
1021
|
-
})
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
733
|
+
})), renderSection("Modal Behavior", /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightCard, {
|
|
734
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_sharedUi.NightRows, {
|
|
735
|
+
children: [renderGlobalSettingRow("enableSharedModalDimensions", "Shared Modal Size", "Sync dimensions across all tools", "When enabled, all tool modals will share the same size and position. Resizing one modal will affect all others. When disabled, each tool remembers its own size and position independently.", "Keep OFF for the best experience. This allows you to customize each tool's modal size separately."), _reactNative.Platform.OS !== "web" ? renderGlobalSettingRow("expandableWindowControls", "Expand Controls", "iPad-style expandable window buttons", "When enabled, the window control buttons (minimize, toggle mode, close) start as small dots and expand into larger, easy-to-tap buttons when pressed. When disabled, buttons are directly tappable at their small size.", "Keep ON for touch devices where the small buttons are hard to press. Turn OFF if you prefer direct single-tap access.") : null]
|
|
736
|
+
})
|
|
737
|
+
}))]
|
|
738
|
+
}), activeTab === "pro" && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
739
|
+
children: [renderSection("License", /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightCard, {
|
|
1025
740
|
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1026
|
-
style: styles.
|
|
1027
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.
|
|
1028
|
-
|
|
1029
|
-
icon: _sharedUi.Zap,
|
|
1030
|
-
color: _sharedUi.buoyColors.primary,
|
|
1031
|
-
size: 12
|
|
1032
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.SectionHeader.Title, {
|
|
1033
|
-
children: "LICENSE STATUS"
|
|
1034
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.SectionHeader.Badge, {
|
|
1035
|
-
count: "Active",
|
|
1036
|
-
color: _sharedUi.buoyColors.success
|
|
1037
|
-
})]
|
|
1038
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
1039
|
-
style: styles.proSectionContent,
|
|
741
|
+
style: styles.settingRow,
|
|
742
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
743
|
+
style: styles.rowInfo,
|
|
1040
744
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
1041
|
-
style: styles.
|
|
1042
|
-
children: "
|
|
745
|
+
style: styles.rowLabel,
|
|
746
|
+
children: "License Status"
|
|
1043
747
|
})
|
|
748
|
+
}), isPro ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightBadge, {
|
|
749
|
+
label: "Active",
|
|
750
|
+
tone: "accent"
|
|
751
|
+
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightBadge, {
|
|
752
|
+
label: "Free",
|
|
753
|
+
tone: "neutral"
|
|
1044
754
|
})]
|
|
1045
755
|
})
|
|
1046
|
-
})
|
|
1047
|
-
children:
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
})]
|
|
1060
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
1061
|
-
style: styles.proSectionContent,
|
|
1062
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
1063
|
-
style: styles.proFreeDescription,
|
|
1064
|
-
children: "Upgrade to Pro to unlock all features and support development."
|
|
1065
|
-
})
|
|
1066
|
-
})]
|
|
1067
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1068
|
-
style: styles.proSection,
|
|
1069
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_sharedUi.SectionHeader, {
|
|
1070
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.SectionHeader.Icon, {
|
|
1071
|
-
icon: _sharedUi.CheckCircle2,
|
|
1072
|
-
color: _sharedUi.buoyColors.primary,
|
|
1073
|
-
size: 12
|
|
1074
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.SectionHeader.Title, {
|
|
1075
|
-
children: "PRO FEATURES"
|
|
1076
|
-
})]
|
|
1077
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
1078
|
-
style: styles.proSectionContent,
|
|
1079
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1080
|
-
style: styles.proFeaturesList,
|
|
1081
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1082
|
-
style: styles.proFeatureItem,
|
|
1083
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CheckCircle2, {
|
|
1084
|
-
size: 14,
|
|
1085
|
-
color: _sharedUi.buoyColors.primary
|
|
1086
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
1087
|
-
style: styles.proFeatureText,
|
|
1088
|
-
children: "Advanced Settings"
|
|
1089
|
-
})]
|
|
1090
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1091
|
-
style: styles.proFeatureItem,
|
|
1092
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CheckCircle2, {
|
|
1093
|
-
size: 14,
|
|
1094
|
-
color: _sharedUi.buoyColors.primary
|
|
1095
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
1096
|
-
style: styles.proFeatureText,
|
|
1097
|
-
children: "Export Configuration"
|
|
1098
|
-
})]
|
|
1099
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1100
|
-
style: styles.proFeatureItem,
|
|
1101
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CheckCircle2, {
|
|
1102
|
-
size: 14,
|
|
1103
|
-
color: _sharedUi.buoyColors.primary
|
|
1104
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
1105
|
-
style: styles.proFeatureText,
|
|
1106
|
-
children: "Team Defaults"
|
|
1107
|
-
})]
|
|
1108
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
1109
|
-
style: styles.proFeatureItem,
|
|
1110
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CheckCircle2, {
|
|
1111
|
-
size: 14,
|
|
1112
|
-
color: _sharedUi.buoyColors.primary
|
|
1113
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
1114
|
-
style: styles.proFeatureText,
|
|
1115
|
-
children: "Priority Support"
|
|
1116
|
-
})]
|
|
756
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightFootnote, {
|
|
757
|
+
children: isPro ? "You have full access to all Buoy DevTools features." : licenseError ? licenseErrorIsTransport ? `Couldn't reach the license server (${licenseError}). A VPN or corporate proxy can block api.keygen.sh — turn it off and reload. Your key hasn't been rejected.` : `License check failed: ${licenseError}.` : "Upgrade to Pro to unlock all features and support development."
|
|
758
|
+
})), !isPro && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
759
|
+
children: [renderSection("Pro Features", /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightCard, {
|
|
760
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightRows, {
|
|
761
|
+
children: ["Advanced Settings", "Priority Support"].map(feature => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
762
|
+
style: styles.featureRow,
|
|
763
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CheckCircle2, {
|
|
764
|
+
size: 16,
|
|
765
|
+
color: _sharedUi.night.color.accent
|
|
766
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
767
|
+
style: styles.rowLabel,
|
|
768
|
+
children: feature
|
|
1117
769
|
})]
|
|
1118
|
-
})
|
|
1119
|
-
})
|
|
1120
|
-
}), /*#__PURE__*/(0, _jsxRuntime.
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
size: 16,
|
|
1126
|
-
color: _sharedUi.buoyColors.base
|
|
1127
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
1128
|
-
style: styles.proUpgradeBtnText,
|
|
1129
|
-
children: "Upgrade to Pro"
|
|
1130
|
-
})]
|
|
770
|
+
}, feature))
|
|
771
|
+
})
|
|
772
|
+
})), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightButton, {
|
|
773
|
+
label: "Upgrade to Pro",
|
|
774
|
+
variant: "primary",
|
|
775
|
+
size: "lg",
|
|
776
|
+
onPress: () => setShowLicenseModal(true)
|
|
1131
777
|
})]
|
|
1132
|
-
})
|
|
778
|
+
})]
|
|
1133
779
|
})]
|
|
1134
780
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.LicenseEntryModal, {
|
|
1135
781
|
visible: showLicenseModal,
|
|
@@ -1140,27 +786,25 @@ const DevToolsSettingsModal = ({
|
|
|
1140
786
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.JsModal, {
|
|
1141
787
|
visible: visible,
|
|
1142
788
|
onClose: onClose,
|
|
789
|
+
variant: "night",
|
|
1143
790
|
header: {
|
|
1144
791
|
showToggleButton: false,
|
|
1145
|
-
customContent: /*#__PURE__*/(0, _jsxRuntime.
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
onTabChange: tab => setActiveTab(tab)
|
|
1162
|
-
})
|
|
1163
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.ModalHeader.Actions, {})]
|
|
792
|
+
customContent: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
793
|
+
style: styles.headerRow,
|
|
794
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.NightSegmented, {
|
|
795
|
+
tabs: [{
|
|
796
|
+
key: "floating",
|
|
797
|
+
label: "Floating"
|
|
798
|
+
}, {
|
|
799
|
+
key: "settings",
|
|
800
|
+
label: "Settings"
|
|
801
|
+
}, {
|
|
802
|
+
key: "pro",
|
|
803
|
+
label: "Pro"
|
|
804
|
+
}],
|
|
805
|
+
activeKey: activeTab,
|
|
806
|
+
onChange: tab => setActiveTab(tab)
|
|
807
|
+
})
|
|
1164
808
|
})
|
|
1165
809
|
},
|
|
1166
810
|
initialMode: "bottomSheet",
|
|
@@ -1236,6 +880,30 @@ const createDefaultsFromConfig = (defaultFloatingTools, defaultDialTools) => {
|
|
|
1236
880
|
* When no saved settings exist, the hook uses the default configuration from
|
|
1237
881
|
* the DefaultConfigProvider (if available) to determine initial tool states.
|
|
1238
882
|
*/
|
|
883
|
+
/**
|
|
884
|
+
* Session cache for the values the settings modal loads asynchronously on mount.
|
|
885
|
+
*
|
|
886
|
+
* Without it every open renders three times: once with defaults, then again as
|
|
887
|
+
* each of the persisted reads (settings, active tab, storage backend) resolves —
|
|
888
|
+
* and each of those re-renders rebuilds the whole tool list. The values cannot
|
|
889
|
+
* change behind our back (writes go through this module, and settingsBus
|
|
890
|
+
* broadcasts them), so after the first open we can render the real values
|
|
891
|
+
* immediately and only re-render if a read actually came back different.
|
|
892
|
+
*/
|
|
893
|
+
let cachedSettings = null;
|
|
894
|
+
let cachedActiveTab = null;
|
|
895
|
+
let cachedStorageBackend = null;
|
|
896
|
+
|
|
897
|
+
/** Cheap structural equality — these objects are small and JSON-safe. */
|
|
898
|
+
const sameSettings = (a, b) => JSON.stringify(a) === JSON.stringify(b);
|
|
899
|
+
|
|
900
|
+
// Every surface that changes settings broadcasts on the bus, so listening here
|
|
901
|
+
// keeps the cache authoritative rather than merely last-seen — otherwise a
|
|
902
|
+
// change made while the modal was unmounted would show stale for one frame.
|
|
903
|
+
// Registered for the app's lifetime on purpose; there is nothing to unsubscribe.
|
|
904
|
+
_settingsBus.settingsBus.addListener(payload => {
|
|
905
|
+
if (payload) cachedSettings = payload;
|
|
906
|
+
});
|
|
1239
907
|
const useDevToolsSettings = () => {
|
|
1240
908
|
// Get team default configuration from context
|
|
1241
909
|
const {
|
|
@@ -1297,800 +965,144 @@ exports.useDevToolsSettings = useDevToolsSettings;
|
|
|
1297
965
|
const styles = _reactNative.StyleSheet.create({
|
|
1298
966
|
container: {
|
|
1299
967
|
flex: 1,
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
// Header styles matching React Query modal exactly
|
|
1303
|
-
headerContainer: {
|
|
1304
|
-
flex: 1,
|
|
1305
|
-
flexDirection: "row",
|
|
1306
|
-
alignItems: "center",
|
|
1307
|
-
justifyContent: "space-between",
|
|
1308
|
-
paddingHorizontal: 12
|
|
968
|
+
// Transparent so JsModal's night star field shows through everything.
|
|
969
|
+
backgroundColor: "transparent"
|
|
1309
970
|
},
|
|
1310
|
-
|
|
1311
|
-
|
|
971
|
+
// Header — the segmented control, inset so it clears the absolutely
|
|
972
|
+
// positioned window controls on the right.
|
|
973
|
+
headerRow: {
|
|
1312
974
|
flexDirection: "row",
|
|
1313
|
-
backgroundColor: _sharedUi.buoyColors.hover,
|
|
1314
|
-
borderRadius: 6,
|
|
1315
|
-
padding: 2,
|
|
1316
|
-
borderWidth: 1,
|
|
1317
|
-
borderColor: _sharedUi.buoyColors.border,
|
|
1318
|
-
justifyContent: "space-evenly"
|
|
1319
|
-
},
|
|
1320
|
-
tabButton: {
|
|
1321
|
-
paddingHorizontal: 8,
|
|
1322
|
-
paddingVertical: 5,
|
|
1323
|
-
borderRadius: 4,
|
|
1324
975
|
alignItems: "center",
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
},
|
|
1329
|
-
tabButtonActive: {
|
|
1330
|
-
backgroundColor: _sharedUi.buoyColors.primary + "20",
|
|
1331
|
-
borderWidth: 1,
|
|
1332
|
-
borderColor: _sharedUi.buoyColors.primary
|
|
976
|
+
paddingLeft: _sharedUi.night.gutter,
|
|
977
|
+
paddingRight: 64,
|
|
978
|
+
paddingBottom: 8
|
|
1333
979
|
},
|
|
1334
|
-
|
|
1335
|
-
backgroundColor: "transparent"
|
|
1336
|
-
},
|
|
1337
|
-
tabButtonText: {
|
|
1338
|
-
fontSize: 12,
|
|
1339
|
-
fontWeight: "600",
|
|
1340
|
-
letterSpacing: 0.5,
|
|
1341
|
-
fontFamily: "monospace",
|
|
1342
|
-
textTransform: "uppercase"
|
|
1343
|
-
},
|
|
1344
|
-
tabButtonTextActive: {
|
|
1345
|
-
color: _sharedUi.buoyColors.primary
|
|
1346
|
-
},
|
|
1347
|
-
tabButtonTextInactive: {
|
|
1348
|
-
color: _sharedUi.buoyColors.textMuted
|
|
1349
|
-
},
|
|
1350
|
-
// Scroll content
|
|
980
|
+
// Scroll content — labeled groups on a 24pt rhythm (Everlights create screen)
|
|
1351
981
|
scrollContent: {
|
|
1352
982
|
flex: 1
|
|
1353
983
|
},
|
|
1354
984
|
scrollContainer: {
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
section: {
|
|
1360
|
-
marginHorizontal: 16,
|
|
1361
|
-
marginBottom: 24
|
|
985
|
+
paddingHorizontal: _sharedUi.night.gutter,
|
|
986
|
+
paddingTop: 8,
|
|
987
|
+
paddingBottom: 24,
|
|
988
|
+
gap: _sharedUi.night.groupGap
|
|
1362
989
|
},
|
|
1363
|
-
|
|
990
|
+
// Rows
|
|
991
|
+
toolRow: {
|
|
1364
992
|
flexDirection: "row",
|
|
1365
993
|
alignItems: "center",
|
|
1366
|
-
|
|
1367
|
-
paddingHorizontal:
|
|
1368
|
-
|
|
1369
|
-
sectionIndicator: {
|
|
1370
|
-
width: 3,
|
|
1371
|
-
height: 16,
|
|
1372
|
-
borderRadius: 2,
|
|
1373
|
-
backgroundColor: _sharedUi.buoyColors.primary,
|
|
1374
|
-
marginRight: 8,
|
|
1375
|
-
shadowColor: _sharedUi.buoyColors.primary,
|
|
1376
|
-
shadowOffset: {
|
|
1377
|
-
width: 0,
|
|
1378
|
-
height: 0
|
|
1379
|
-
},
|
|
1380
|
-
shadowOpacity: 0.6,
|
|
1381
|
-
shadowRadius: 4
|
|
1382
|
-
},
|
|
1383
|
-
sectionTitle: {
|
|
1384
|
-
flex: 1,
|
|
1385
|
-
color: _sharedUi.buoyColors.primary,
|
|
1386
|
-
fontSize: 13,
|
|
1387
|
-
fontWeight: "700",
|
|
1388
|
-
letterSpacing: 1.2
|
|
1389
|
-
},
|
|
1390
|
-
sectionCount: {
|
|
1391
|
-
color: _sharedUi.buoyColors.textSecondary,
|
|
1392
|
-
fontSize: 11,
|
|
1393
|
-
opacity: 0.7
|
|
1394
|
-
},
|
|
1395
|
-
// Tool Cards - Clean unified Buoy theme
|
|
1396
|
-
glassCard: {
|
|
1397
|
-
borderRadius: 12,
|
|
1398
|
-
paddingVertical: 12,
|
|
1399
|
-
paddingHorizontal: 14,
|
|
1400
|
-
backgroundColor: _sharedUi.buoyColors.card,
|
|
1401
|
-
borderWidth: 1,
|
|
1402
|
-
borderColor: _sharedUi.buoyColors.border
|
|
1403
|
-
},
|
|
1404
|
-
glassCardActive: {
|
|
1405
|
-
borderColor: _sharedUi.buoyColors.primary + "50",
|
|
1406
|
-
backgroundColor: _sharedUi.buoyColors.primary + "08"
|
|
994
|
+
gap: 12,
|
|
995
|
+
paddingHorizontal: _sharedUi.night.rowPadH,
|
|
996
|
+
paddingVertical: 12
|
|
1407
997
|
},
|
|
1408
|
-
|
|
998
|
+
settingRow: {
|
|
1409
999
|
flexDirection: "row",
|
|
1410
1000
|
alignItems: "center",
|
|
1411
|
-
gap:
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
height: 32,
|
|
1416
|
-
borderRadius: 8,
|
|
1417
|
-
backgroundColor: _sharedUi.buoyColors.hover,
|
|
1418
|
-
alignItems: "center",
|
|
1419
|
-
justifyContent: "center"
|
|
1420
|
-
},
|
|
1421
|
-
iconContainerActive: {
|
|
1422
|
-
backgroundColor: _sharedUi.buoyColors.primary + "20"
|
|
1423
|
-
},
|
|
1424
|
-
toolInfo: {
|
|
1425
|
-
flex: 1
|
|
1426
|
-
},
|
|
1427
|
-
toolName: {
|
|
1428
|
-
color: _sharedUi.buoyColors.text,
|
|
1429
|
-
fontWeight: "600",
|
|
1430
|
-
fontSize: 13
|
|
1431
|
-
},
|
|
1432
|
-
toolNameActive: {
|
|
1433
|
-
color: _sharedUi.buoyColors.text
|
|
1001
|
+
gap: 10,
|
|
1002
|
+
paddingHorizontal: _sharedUi.night.rowPadH,
|
|
1003
|
+
paddingVertical: _sharedUi.night.rowPadV,
|
|
1004
|
+
minHeight: 52
|
|
1434
1005
|
},
|
|
1435
|
-
|
|
1436
|
-
color: _sharedUi.buoyColors.textMuted,
|
|
1437
|
-
fontSize: 11,
|
|
1438
|
-
marginTop: 2
|
|
1439
|
-
},
|
|
1440
|
-
pillToggle: {
|
|
1441
|
-
paddingHorizontal: 14,
|
|
1442
|
-
paddingVertical: 6,
|
|
1443
|
-
borderRadius: 6,
|
|
1444
|
-
borderWidth: 1,
|
|
1445
|
-
minWidth: 48,
|
|
1446
|
-
alignItems: "center"
|
|
1447
|
-
},
|
|
1448
|
-
pillToggleOn: {
|
|
1449
|
-
backgroundColor: _sharedUi.buoyColors.primary + "20",
|
|
1450
|
-
borderColor: _sharedUi.buoyColors.primary
|
|
1451
|
-
},
|
|
1452
|
-
pillToggleOff: {
|
|
1453
|
-
backgroundColor: _sharedUi.buoyColors.hover,
|
|
1454
|
-
borderColor: _sharedUi.buoyColors.border
|
|
1455
|
-
},
|
|
1456
|
-
pillToggleText: {
|
|
1457
|
-
fontWeight: "600",
|
|
1458
|
-
fontSize: 11,
|
|
1459
|
-
letterSpacing: 0.5
|
|
1460
|
-
},
|
|
1461
|
-
pillToggleTextOn: {
|
|
1462
|
-
color: _sharedUi.buoyColors.primary
|
|
1463
|
-
},
|
|
1464
|
-
pillToggleTextOff: {
|
|
1465
|
-
color: _sharedUi.buoyColors.textMuted
|
|
1466
|
-
},
|
|
1467
|
-
closeButton: {
|
|
1468
|
-
marginLeft: 8,
|
|
1469
|
-
paddingHorizontal: 10,
|
|
1470
|
-
paddingVertical: 6,
|
|
1471
|
-
borderRadius: 6,
|
|
1472
|
-
backgroundColor: _sharedUi.buoyColors.error + "1A",
|
|
1473
|
-
borderWidth: 1,
|
|
1474
|
-
borderColor: _sharedUi.buoyColors.error + "33"
|
|
1475
|
-
},
|
|
1476
|
-
closeButtonText: {
|
|
1477
|
-
color: _sharedUi.buoyColors.error,
|
|
1478
|
-
fontSize: 14,
|
|
1479
|
-
fontWeight: "700",
|
|
1480
|
-
letterSpacing: 0.5
|
|
1481
|
-
},
|
|
1482
|
-
// Expandable Settings Card styles
|
|
1483
|
-
expandableCard: {
|
|
1484
|
-
backgroundColor: _sharedUi.buoyColors.card,
|
|
1485
|
-
borderRadius: 8,
|
|
1486
|
-
borderWidth: 1,
|
|
1487
|
-
borderColor: _sharedUi.buoyColors.border,
|
|
1488
|
-
padding: 12
|
|
1489
|
-
},
|
|
1490
|
-
expandableCardHeader: {
|
|
1006
|
+
featureRow: {
|
|
1491
1007
|
flexDirection: "row",
|
|
1492
1008
|
alignItems: "center",
|
|
1493
|
-
gap:
|
|
1009
|
+
gap: 10,
|
|
1010
|
+
paddingHorizontal: _sharedUi.night.rowPadH,
|
|
1011
|
+
paddingVertical: 12
|
|
1494
1012
|
},
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
borderWidth: 1,
|
|
1498
|
-
borderColor: _sharedUi.buoyColors.primary + "40",
|
|
1499
|
-
borderRadius: 4,
|
|
1500
|
-
paddingHorizontal: 8,
|
|
1501
|
-
paddingVertical: 4
|
|
1013
|
+
rowDisabled: {
|
|
1014
|
+
opacity: 0.4
|
|
1502
1015
|
},
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
color: _sharedUi.buoyColors.primary,
|
|
1507
|
-
letterSpacing: 0.5
|
|
1016
|
+
toolIconSlot: {
|
|
1017
|
+
width: 24,
|
|
1018
|
+
alignItems: "center"
|
|
1508
1019
|
},
|
|
1509
|
-
|
|
1020
|
+
rowInfo: {
|
|
1510
1021
|
flex: 1,
|
|
1511
|
-
|
|
1512
|
-
},
|
|
1513
|
-
expandableCardTitleText: {
|
|
1514
|
-
fontFamily: "monospace",
|
|
1515
|
-
fontSize: 12,
|
|
1516
|
-
fontWeight: "700",
|
|
1517
|
-
color: _sharedUi.buoyColors.text
|
|
1518
|
-
},
|
|
1519
|
-
expandableCardSubtitle: {
|
|
1520
|
-
fontSize: 10,
|
|
1521
|
-
color: _sharedUi.buoyColors.textMuted,
|
|
1522
|
-
marginTop: 2
|
|
1523
|
-
},
|
|
1524
|
-
expandableCardActions: {
|
|
1525
|
-
flexDirection: "row",
|
|
1526
|
-
alignItems: "center",
|
|
1527
|
-
gap: 8
|
|
1528
|
-
},
|
|
1529
|
-
expandableCardBody: {
|
|
1530
|
-
marginTop: 12,
|
|
1531
|
-
paddingTop: 12,
|
|
1532
|
-
borderTopWidth: 1,
|
|
1533
|
-
borderTopColor: _sharedUi.buoyColors.border + "50"
|
|
1534
|
-
},
|
|
1535
|
-
expandableCardSection: {
|
|
1536
|
-
marginBottom: 12
|
|
1537
|
-
},
|
|
1538
|
-
expandableCardSectionTitle: {
|
|
1539
|
-
fontSize: 10,
|
|
1540
|
-
fontWeight: "700",
|
|
1541
|
-
color: _sharedUi.buoyColors.primary,
|
|
1542
|
-
letterSpacing: 1,
|
|
1543
|
-
marginBottom: 6
|
|
1544
|
-
},
|
|
1545
|
-
expandableCardSectionText: {
|
|
1546
|
-
fontSize: 12,
|
|
1547
|
-
color: _sharedUi.buoyColors.textSecondary,
|
|
1548
|
-
lineHeight: 18
|
|
1549
|
-
},
|
|
1550
|
-
// Storage Status Card styles
|
|
1551
|
-
storageStatusCard: {
|
|
1552
|
-
backgroundColor: _sharedUi.buoyColors.card,
|
|
1553
|
-
borderRadius: 8,
|
|
1554
|
-
borderWidth: 1,
|
|
1555
|
-
borderColor: _sharedUi.buoyColors.border,
|
|
1556
|
-
padding: 12,
|
|
1557
|
-
marginBottom: 10
|
|
1558
|
-
},
|
|
1559
|
-
storageStatusHeader: {
|
|
1560
|
-
flexDirection: "row",
|
|
1561
|
-
alignItems: "center",
|
|
1562
|
-
gap: 12,
|
|
1563
|
-
marginBottom: 8
|
|
1564
|
-
},
|
|
1565
|
-
storageStatusIcon: {
|
|
1566
|
-
width: 36,
|
|
1567
|
-
height: 36,
|
|
1568
|
-
borderRadius: 8,
|
|
1569
|
-
backgroundColor: _sharedUi.buoyColors.hover,
|
|
1570
|
-
alignItems: "center",
|
|
1571
|
-
justifyContent: "center"
|
|
1022
|
+
gap: 2
|
|
1572
1023
|
},
|
|
1573
|
-
|
|
1574
|
-
|
|
1024
|
+
rowLabel: {
|
|
1025
|
+
color: _sharedUi.night.color.text,
|
|
1026
|
+
fontSize: _sharedUi.night.font.row,
|
|
1027
|
+
fontWeight: "500"
|
|
1575
1028
|
},
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
color: _sharedUi.buoyColors.textMuted,
|
|
1580
|
-
letterSpacing: 1,
|
|
1581
|
-
marginBottom: 4
|
|
1029
|
+
rowCaption: {
|
|
1030
|
+
color: _sharedUi.night.color.textTertiary,
|
|
1031
|
+
fontSize: _sharedUi.night.font.label
|
|
1582
1032
|
},
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1033
|
+
// Expanded body under a global-setting row
|
|
1034
|
+
settingRowBody: {
|
|
1035
|
+
paddingHorizontal: _sharedUi.night.rowPadH,
|
|
1036
|
+
paddingBottom: _sharedUi.night.rowPadV,
|
|
1586
1037
|
gap: 6
|
|
1587
1038
|
},
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
borderWidth: 1
|
|
1593
|
-
},
|
|
1594
|
-
storageStatusBadgeText: {
|
|
1595
|
-
fontSize: 11,
|
|
1596
|
-
fontWeight: "700",
|
|
1597
|
-
letterSpacing: 0.5
|
|
1039
|
+
settingRowBodyText: {
|
|
1040
|
+
color: _sharedUi.night.color.textSecondary,
|
|
1041
|
+
fontSize: _sharedUi.night.font.caption,
|
|
1042
|
+
lineHeight: _sharedUi.night.font.caption * 1.45
|
|
1598
1043
|
},
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
lineHeight:
|
|
1603
|
-
marginBottom: 12
|
|
1604
|
-
},
|
|
1605
|
-
clearStorageButton: {
|
|
1606
|
-
flexDirection: "row",
|
|
1607
|
-
alignItems: "center",
|
|
1608
|
-
justifyContent: "center",
|
|
1609
|
-
gap: 8,
|
|
1610
|
-
paddingVertical: 10,
|
|
1611
|
-
paddingHorizontal: 16,
|
|
1612
|
-
borderRadius: 6,
|
|
1613
|
-
backgroundColor: _sharedUi.buoyColors.error + "15",
|
|
1614
|
-
borderWidth: 1,
|
|
1615
|
-
borderColor: _sharedUi.buoyColors.error + "40"
|
|
1044
|
+
settingRowBodyHint: {
|
|
1045
|
+
color: _sharedUi.night.color.textTertiary,
|
|
1046
|
+
fontSize: _sharedUi.night.font.caption,
|
|
1047
|
+
lineHeight: _sharedUi.night.font.caption * 1.45
|
|
1616
1048
|
},
|
|
1617
|
-
|
|
1618
|
-
|
|
1049
|
+
bodyWarning: {
|
|
1050
|
+
color: _sharedUi.night.color.warning
|
|
1619
1051
|
},
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
borderColor: _sharedUi.buoyColors.success + "40"
|
|
1052
|
+
bodyDanger: {
|
|
1053
|
+
color: _sharedUi.night.color.danger
|
|
1623
1054
|
},
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
},
|
|
1630
|
-
// Advice hints
|
|
1631
|
-
adviceHintsContainer: {
|
|
1632
|
-
gap: 8,
|
|
1633
|
-
marginBottom: 12
|
|
1634
|
-
},
|
|
1635
|
-
adviceHint: {
|
|
1636
|
-
flexDirection: "row",
|
|
1637
|
-
alignItems: "flex-start",
|
|
1638
|
-
gap: 8,
|
|
1639
|
-
backgroundColor: _sharedUi.buoyColors.warning + "10",
|
|
1640
|
-
borderRadius: 6,
|
|
1641
|
-
padding: 10,
|
|
1642
|
-
marginBottom: 8
|
|
1643
|
-
},
|
|
1644
|
-
adviceHintText: {
|
|
1645
|
-
flex: 1,
|
|
1646
|
-
fontSize: 11,
|
|
1647
|
-
color: _sharedUi.buoyColors.textSecondary,
|
|
1648
|
-
lineHeight: 16
|
|
1055
|
+
// Buttons that live inside a card
|
|
1056
|
+
cardButtonWrap: {
|
|
1057
|
+
paddingHorizontal: _sharedUi.night.cardPad,
|
|
1058
|
+
paddingTop: 10,
|
|
1059
|
+
paddingBottom: _sharedUi.night.cardPad
|
|
1649
1060
|
},
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
fontFamily: "monospace",
|
|
1656
|
-
fontSize: 10,
|
|
1657
|
-
color: _sharedUi.buoyColors.info,
|
|
1658
|
-
backgroundColor: _sharedUi.buoyColors.info + "15",
|
|
1659
|
-
paddingHorizontal: 4,
|
|
1660
|
-
borderRadius: 3
|
|
1661
|
-
},
|
|
1662
|
-
// Expanded storage content
|
|
1663
|
-
storageExpandedContent: {
|
|
1664
|
-
marginTop: 12,
|
|
1665
|
-
paddingTop: 12,
|
|
1666
|
-
borderTopWidth: 1,
|
|
1667
|
-
borderTopColor: _sharedUi.buoyColors.border + "50"
|
|
1061
|
+
// Storage expanded key list
|
|
1062
|
+
storageExpanded: {
|
|
1063
|
+
paddingHorizontal: _sharedUi.night.rowPadH,
|
|
1064
|
+
paddingVertical: 12,
|
|
1065
|
+
gap: 8
|
|
1668
1066
|
},
|
|
1669
1067
|
storageExpandedHeader: {
|
|
1670
1068
|
flexDirection: "row",
|
|
1671
|
-
alignItems: "center"
|
|
1672
|
-
gap: 8,
|
|
1673
|
-
marginBottom: 10
|
|
1069
|
+
alignItems: "center"
|
|
1674
1070
|
},
|
|
1675
1071
|
storageExpandedTitle: {
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1072
|
+
flex: 1,
|
|
1073
|
+
color: _sharedUi.night.color.textSecondary,
|
|
1074
|
+
fontSize: _sharedUi.night.font.micro,
|
|
1075
|
+
fontWeight: "600",
|
|
1076
|
+
letterSpacing: 0.5
|
|
1681
1077
|
},
|
|
1682
1078
|
storageExpandedCount: {
|
|
1683
|
-
|
|
1684
|
-
|
|
1079
|
+
color: _sharedUi.night.color.textTertiary,
|
|
1080
|
+
fontSize: _sharedUi.night.font.micro
|
|
1685
1081
|
},
|
|
1686
1082
|
storageKeysList: {
|
|
1687
|
-
gap: 4,
|
|
1688
1083
|
maxHeight: 150
|
|
1689
1084
|
},
|
|
1690
1085
|
storageKeyItem: {
|
|
1691
|
-
backgroundColor: _sharedUi.
|
|
1692
|
-
borderRadius:
|
|
1693
|
-
paddingHorizontal:
|
|
1694
|
-
paddingVertical:
|
|
1695
|
-
|
|
1696
|
-
borderColor: _sharedUi.buoyColors.border + "50"
|
|
1697
|
-
},
|
|
1698
|
-
storageKeyItemEmpty: {
|
|
1699
|
-
fontSize: 11,
|
|
1700
|
-
color: _sharedUi.buoyColors.textMuted,
|
|
1701
|
-
fontStyle: "italic",
|
|
1702
|
-
paddingVertical: 8
|
|
1086
|
+
backgroundColor: _sharedUi.night.color.surfaceElevated,
|
|
1087
|
+
borderRadius: _sharedUi.night.radius.segment,
|
|
1088
|
+
paddingHorizontal: 10,
|
|
1089
|
+
paddingVertical: 7,
|
|
1090
|
+
marginBottom: 4
|
|
1703
1091
|
},
|
|
1704
1092
|
storageKeyText: {
|
|
1705
|
-
|
|
1706
|
-
|
|
1093
|
+
color: _sharedUi.night.color.textSecondary,
|
|
1094
|
+
fontSize: _sharedUi.night.font.micro,
|
|
1707
1095
|
fontFamily: "monospace"
|
|
1708
1096
|
},
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
borderRadius: 8,
|
|
1713
|
-
borderWidth: 1,
|
|
1714
|
-
borderColor: _sharedUi.buoyColors.success + "40",
|
|
1715
|
-
padding: 12,
|
|
1716
|
-
marginTop: 10
|
|
1717
|
-
},
|
|
1718
|
-
exportConfigHeader: {
|
|
1719
|
-
flexDirection: "row",
|
|
1720
|
-
alignItems: "center",
|
|
1721
|
-
gap: 12
|
|
1722
|
-
},
|
|
1723
|
-
exportConfigIconContainer: {
|
|
1724
|
-
width: 36,
|
|
1725
|
-
height: 36,
|
|
1726
|
-
borderRadius: 8,
|
|
1727
|
-
backgroundColor: _sharedUi.buoyColors.success + "15",
|
|
1728
|
-
alignItems: "center",
|
|
1729
|
-
justifyContent: "center"
|
|
1730
|
-
},
|
|
1731
|
-
exportConfigInfo: {
|
|
1732
|
-
flex: 1
|
|
1733
|
-
},
|
|
1734
|
-
exportConfigLabel: {
|
|
1735
|
-
fontSize: 12,
|
|
1736
|
-
fontWeight: "700",
|
|
1737
|
-
color: _sharedUi.buoyColors.success,
|
|
1738
|
-
letterSpacing: 0.5
|
|
1739
|
-
},
|
|
1740
|
-
exportConfigHint: {
|
|
1741
|
-
fontSize: 10,
|
|
1742
|
-
color: _sharedUi.buoyColors.textMuted,
|
|
1743
|
-
marginTop: 2
|
|
1744
|
-
},
|
|
1745
|
-
exportConfigActions: {
|
|
1746
|
-
flexDirection: "row",
|
|
1747
|
-
alignItems: "center"
|
|
1748
|
-
},
|
|
1749
|
-
exportHintBanner: {
|
|
1750
|
-
flexDirection: "row",
|
|
1751
|
-
alignItems: "flex-start",
|
|
1752
|
-
gap: 8,
|
|
1753
|
-
backgroundColor: _sharedUi.buoyColors.warning + "10",
|
|
1754
|
-
borderRadius: 6,
|
|
1755
|
-
padding: 10,
|
|
1756
|
-
marginTop: 12
|
|
1757
|
-
},
|
|
1758
|
-
exportHintText: {
|
|
1759
|
-
flex: 1,
|
|
1760
|
-
fontSize: 11,
|
|
1761
|
-
color: _sharedUi.buoyColors.textSecondary,
|
|
1762
|
-
lineHeight: 16
|
|
1763
|
-
},
|
|
1764
|
-
exportHintBold: {
|
|
1765
|
-
fontWeight: "700",
|
|
1766
|
-
color: _sharedUi.buoyColors.warning
|
|
1767
|
-
},
|
|
1768
|
-
exportCodeContainer: {
|
|
1769
|
-
marginTop: 12,
|
|
1770
|
-
paddingTop: 12,
|
|
1771
|
-
borderTopWidth: 1,
|
|
1772
|
-
borderTopColor: _sharedUi.buoyColors.border + "50"
|
|
1773
|
-
},
|
|
1774
|
-
exportCodeHeader: {
|
|
1775
|
-
flexDirection: "row",
|
|
1776
|
-
alignItems: "center",
|
|
1777
|
-
gap: 8,
|
|
1778
|
-
marginBottom: 8
|
|
1779
|
-
},
|
|
1780
|
-
exportCodeTitle: {
|
|
1781
|
-
fontSize: 10,
|
|
1782
|
-
fontWeight: "700",
|
|
1783
|
-
color: _sharedUi.buoyColors.success,
|
|
1784
|
-
letterSpacing: 1
|
|
1785
|
-
},
|
|
1786
|
-
exportCodeBlock: {
|
|
1787
|
-
backgroundColor: _sharedUi.buoyColors.hover,
|
|
1788
|
-
borderRadius: 6,
|
|
1789
|
-
padding: 12,
|
|
1790
|
-
borderWidth: 1,
|
|
1791
|
-
borderColor: _sharedUi.buoyColors.border + "50"
|
|
1792
|
-
},
|
|
1793
|
-
exportCodeText: {
|
|
1794
|
-
fontSize: 11,
|
|
1795
|
-
color: _sharedUi.buoyColors.text,
|
|
1796
|
-
fontFamily: "monospace",
|
|
1797
|
-
lineHeight: 18
|
|
1798
|
-
},
|
|
1799
|
-
exportCodeDescription: {
|
|
1800
|
-
fontSize: 10,
|
|
1801
|
-
color: _sharedUi.buoyColors.textMuted,
|
|
1802
|
-
marginTop: 8,
|
|
1803
|
-
lineHeight: 14
|
|
1804
|
-
},
|
|
1805
|
-
exportCodeInline: {
|
|
1806
|
-
fontFamily: "monospace",
|
|
1807
|
-
fontSize: 10,
|
|
1808
|
-
color: _sharedUi.buoyColors.info,
|
|
1809
|
-
backgroundColor: _sharedUi.buoyColors.info + "15",
|
|
1810
|
-
paddingHorizontal: 4,
|
|
1811
|
-
borderRadius: 3
|
|
1812
|
-
},
|
|
1813
|
-
exportCopyButton: {
|
|
1814
|
-
flexDirection: "row",
|
|
1815
|
-
alignItems: "center",
|
|
1816
|
-
justifyContent: "center",
|
|
1817
|
-
gap: 8,
|
|
1818
|
-
paddingVertical: 10,
|
|
1819
|
-
paddingHorizontal: 16,
|
|
1820
|
-
borderRadius: 6,
|
|
1821
|
-
backgroundColor: _sharedUi.buoyColors.success + "15",
|
|
1822
|
-
borderWidth: 1,
|
|
1823
|
-
borderColor: _sharedUi.buoyColors.success + "40",
|
|
1824
|
-
marginTop: 12
|
|
1825
|
-
},
|
|
1826
|
-
exportCopyButtonSuccess: {
|
|
1827
|
-
backgroundColor: _sharedUi.buoyColors.success + "25",
|
|
1828
|
-
borderColor: _sharedUi.buoyColors.success + "60"
|
|
1829
|
-
},
|
|
1830
|
-
exportCopyButtonText: {
|
|
1831
|
-
fontSize: 12,
|
|
1832
|
-
fontWeight: "700",
|
|
1833
|
-
color: _sharedUi.buoyColors.success,
|
|
1834
|
-
letterSpacing: 0.5
|
|
1835
|
-
},
|
|
1836
|
-
// JSON-like viewer styles (syntax highlighting)
|
|
1837
|
-
exportJsonBlock: {
|
|
1838
|
-
backgroundColor: _sharedUi.buoyColors.hover,
|
|
1839
|
-
borderRadius: 6,
|
|
1840
|
-
padding: 12,
|
|
1841
|
-
borderWidth: 1,
|
|
1842
|
-
borderColor: _sharedUi.buoyColors.border + "50",
|
|
1843
|
-
flexDirection: "row",
|
|
1844
|
-
flexWrap: "wrap",
|
|
1845
|
-
alignItems: "center",
|
|
1846
|
-
gap: 4
|
|
1847
|
-
},
|
|
1848
|
-
exportJsonProp: {
|
|
1849
|
-
fontSize: 12,
|
|
1850
|
-
fontFamily: "monospace",
|
|
1851
|
-
color: _sharedUi.buoyColors.info,
|
|
1852
|
-
// Cyan for prop names
|
|
1853
|
-
fontWeight: "600"
|
|
1854
|
-
},
|
|
1855
|
-
exportJsonEquals: {
|
|
1856
|
-
fontSize: 12,
|
|
1857
|
-
fontFamily: "monospace",
|
|
1858
|
-
color: _sharedUi.buoyColors.textMuted
|
|
1859
|
-
},
|
|
1860
|
-
exportJsonBracket: {
|
|
1861
|
-
fontSize: 12,
|
|
1862
|
-
fontFamily: "monospace",
|
|
1863
|
-
color: _sharedUi.buoyColors.warning // Yellow for JSX brackets
|
|
1864
|
-
},
|
|
1865
|
-
exportJsonArrayBracket: {
|
|
1866
|
-
fontSize: 12,
|
|
1867
|
-
fontFamily: "monospace",
|
|
1868
|
-
color: _sharedUi.buoyColors.text
|
|
1869
|
-
},
|
|
1870
|
-
exportJsonArrayContent: {
|
|
1871
|
-
flexDirection: "row",
|
|
1872
|
-
flexWrap: "wrap",
|
|
1873
|
-
alignItems: "center",
|
|
1874
|
-
gap: 2
|
|
1875
|
-
},
|
|
1876
|
-
exportJsonArrayItem: {
|
|
1877
|
-
flexDirection: "row",
|
|
1878
|
-
alignItems: "center"
|
|
1879
|
-
},
|
|
1880
|
-
exportJsonString: {
|
|
1881
|
-
fontSize: 12,
|
|
1882
|
-
fontFamily: "monospace",
|
|
1883
|
-
color: _sharedUi.buoyColors.success // Green for strings
|
|
1884
|
-
},
|
|
1885
|
-
exportJsonComma: {
|
|
1886
|
-
fontSize: 12,
|
|
1887
|
-
fontFamily: "monospace",
|
|
1888
|
-
color: _sharedUi.buoyColors.textMuted,
|
|
1889
|
-
marginRight: 4
|
|
1890
|
-
},
|
|
1891
|
-
exportJsonComment: {
|
|
1892
|
-
fontSize: 12,
|
|
1893
|
-
fontFamily: "monospace",
|
|
1894
|
-
color: _sharedUi.buoyColors.textMuted,
|
|
1895
|
-
fontStyle: "italic"
|
|
1896
|
-
},
|
|
1897
|
-
// Pro tab styles - using buoyColors for consistency with other modals
|
|
1898
|
-
proContainer: {
|
|
1899
|
-
paddingHorizontal: 16,
|
|
1900
|
-
paddingTop: 16,
|
|
1901
|
-
paddingBottom: 24
|
|
1902
|
-
},
|
|
1903
|
-
proSection: {
|
|
1904
|
-
backgroundColor: _sharedUi.buoyColors.card,
|
|
1905
|
-
borderRadius: 8,
|
|
1906
|
-
borderWidth: 1,
|
|
1907
|
-
borderColor: _sharedUi.buoyColors.border,
|
|
1908
|
-
marginBottom: 12,
|
|
1909
|
-
overflow: "hidden"
|
|
1910
|
-
},
|
|
1911
|
-
proSectionContent: {
|
|
1912
|
-
paddingHorizontal: 16,
|
|
1913
|
-
paddingTop: 8,
|
|
1914
|
-
paddingBottom: 16
|
|
1915
|
-
},
|
|
1916
|
-
proStatsRow: {
|
|
1917
|
-
flexDirection: "row",
|
|
1918
|
-
justifyContent: "center",
|
|
1919
|
-
alignItems: "center",
|
|
1920
|
-
paddingVertical: 8
|
|
1921
|
-
},
|
|
1922
|
-
proStatItem: {
|
|
1923
|
-
alignItems: "center",
|
|
1924
|
-
paddingHorizontal: 20
|
|
1925
|
-
},
|
|
1926
|
-
proStatValue: {
|
|
1927
|
-
fontSize: 20,
|
|
1928
|
-
fontWeight: "700",
|
|
1929
|
-
color: _sharedUi.buoyColors.text
|
|
1930
|
-
},
|
|
1931
|
-
proStatValueDanger: {
|
|
1932
|
-
color: _sharedUi.buoyColors.error
|
|
1933
|
-
},
|
|
1934
|
-
proStatLabel: {
|
|
1935
|
-
fontSize: 10,
|
|
1936
|
-
color: _sharedUi.buoyColors.textMuted,
|
|
1937
|
-
letterSpacing: 0.5,
|
|
1938
|
-
marginTop: 2
|
|
1939
|
-
},
|
|
1940
|
-
proStatDivider: {
|
|
1941
|
-
width: 1,
|
|
1942
|
-
height: 24,
|
|
1943
|
-
backgroundColor: _sharedUi.buoyColors.border
|
|
1944
|
-
},
|
|
1945
|
-
proEmptyState: {
|
|
1946
|
-
alignItems: "center",
|
|
1947
|
-
paddingVertical: 20,
|
|
1948
|
-
gap: 8
|
|
1949
|
-
},
|
|
1950
|
-
proEmptyStateText: {
|
|
1951
|
-
fontSize: 11,
|
|
1952
|
-
color: _sharedUi.buoyColors.textMuted,
|
|
1097
|
+
storageKeyEmpty: {
|
|
1098
|
+
color: _sharedUi.night.color.textTertiary,
|
|
1099
|
+
fontSize: _sharedUi.night.font.caption,
|
|
1953
1100
|
fontStyle: "italic"
|
|
1954
1101
|
},
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
paddingHorizontal: 12,
|
|
1961
|
-
backgroundColor: _sharedUi.buoyColors.error + "15",
|
|
1962
|
-
borderRadius: 6
|
|
1963
|
-
},
|
|
1964
|
-
proErrorStateText: {
|
|
1965
|
-
fontSize: 11,
|
|
1966
|
-
color: _sharedUi.buoyColors.error,
|
|
1967
|
-
flex: 1
|
|
1968
|
-
},
|
|
1969
|
-
proDevicesList: {
|
|
1970
|
-
gap: 6
|
|
1971
|
-
},
|
|
1972
|
-
proDeviceRow: {
|
|
1973
|
-
flexDirection: "row",
|
|
1974
|
-
alignItems: "center",
|
|
1975
|
-
paddingVertical: 8,
|
|
1976
|
-
paddingHorizontal: 10,
|
|
1977
|
-
backgroundColor: _sharedUi.buoyColors.input,
|
|
1978
|
-
borderRadius: 6,
|
|
1979
|
-
borderWidth: 1,
|
|
1980
|
-
borderColor: _sharedUi.buoyColors.border
|
|
1981
|
-
},
|
|
1982
|
-
proDeviceRowCurrent: {
|
|
1983
|
-
borderColor: _sharedUi.buoyColors.success + "50",
|
|
1984
|
-
backgroundColor: _sharedUi.buoyColors.success + "08"
|
|
1985
|
-
},
|
|
1986
|
-
proDeviceIcon: {
|
|
1987
|
-
width: 28,
|
|
1988
|
-
height: 28,
|
|
1989
|
-
borderRadius: 14,
|
|
1990
|
-
backgroundColor: _sharedUi.buoyColors.hover,
|
|
1991
|
-
alignItems: "center",
|
|
1992
|
-
justifyContent: "center"
|
|
1993
|
-
},
|
|
1994
|
-
proDeviceInfo: {
|
|
1995
|
-
flex: 1,
|
|
1996
|
-
marginLeft: 10
|
|
1997
|
-
},
|
|
1998
|
-
proDeviceNameRow: {
|
|
1999
|
-
flexDirection: "row",
|
|
2000
|
-
alignItems: "center",
|
|
2001
|
-
gap: 6
|
|
2002
|
-
},
|
|
2003
|
-
proDeviceName: {
|
|
2004
|
-
fontSize: 12,
|
|
2005
|
-
fontWeight: "600",
|
|
2006
|
-
color: _sharedUi.buoyColors.text,
|
|
2007
|
-
flexShrink: 1
|
|
2008
|
-
},
|
|
2009
|
-
proDeviceBadge: {
|
|
2010
|
-
backgroundColor: _sharedUi.buoyColors.success + "20",
|
|
2011
|
-
paddingHorizontal: 5,
|
|
2012
|
-
paddingVertical: 1,
|
|
2013
|
-
borderRadius: 3
|
|
2014
|
-
},
|
|
2015
|
-
proDeviceBadgeText: {
|
|
2016
|
-
fontSize: 8,
|
|
2017
|
-
fontWeight: "700",
|
|
2018
|
-
color: _sharedUi.buoyColors.success,
|
|
2019
|
-
letterSpacing: 0.3
|
|
2020
|
-
},
|
|
2021
|
-
proDeviceDetails: {
|
|
2022
|
-
fontSize: 10,
|
|
2023
|
-
color: _sharedUi.buoyColors.textMuted,
|
|
2024
|
-
marginTop: 2
|
|
2025
|
-
},
|
|
2026
|
-
proDeviceDate: {
|
|
2027
|
-
fontSize: 9,
|
|
2028
|
-
color: _sharedUi.buoyColors.textMuted,
|
|
2029
|
-
marginTop: 2
|
|
2030
|
-
},
|
|
2031
|
-
proDeviceRemoveBtn: {
|
|
2032
|
-
padding: 6,
|
|
2033
|
-
marginLeft: 4
|
|
2034
|
-
},
|
|
2035
|
-
proRegisterDeviceBtn: {
|
|
2036
|
-
flexDirection: "row",
|
|
2037
|
-
alignItems: "center",
|
|
2038
|
-
justifyContent: "center",
|
|
2039
|
-
gap: 8,
|
|
2040
|
-
paddingVertical: 10,
|
|
2041
|
-
paddingHorizontal: 16,
|
|
2042
|
-
borderRadius: 8,
|
|
2043
|
-
backgroundColor: _sharedUi.buoyColors.primary + "15",
|
|
2044
|
-
borderWidth: 1,
|
|
2045
|
-
borderColor: _sharedUi.buoyColors.primary + "40",
|
|
2046
|
-
marginTop: 10
|
|
2047
|
-
},
|
|
2048
|
-
proRegisterDeviceBtnText: {
|
|
2049
|
-
fontSize: 12,
|
|
2050
|
-
fontWeight: "600",
|
|
2051
|
-
color: _sharedUi.buoyColors.primary
|
|
2052
|
-
},
|
|
2053
|
-
proFreeDescription: {
|
|
2054
|
-
fontSize: 11,
|
|
2055
|
-
color: _sharedUi.buoyColors.textSecondary,
|
|
2056
|
-
lineHeight: 16
|
|
2057
|
-
},
|
|
2058
|
-
proActiveDescription: {
|
|
2059
|
-
fontSize: 11,
|
|
2060
|
-
color: _sharedUi.buoyColors.textSecondary,
|
|
2061
|
-
lineHeight: 16
|
|
2062
|
-
},
|
|
2063
|
-
proFeaturesList: {
|
|
2064
|
-
gap: 8
|
|
2065
|
-
},
|
|
2066
|
-
proFeatureItem: {
|
|
2067
|
-
flexDirection: "row",
|
|
2068
|
-
alignItems: "center",
|
|
2069
|
-
gap: 10
|
|
2070
|
-
},
|
|
2071
|
-
proFeatureText: {
|
|
2072
|
-
fontSize: 12,
|
|
2073
|
-
color: _sharedUi.buoyColors.text
|
|
2074
|
-
},
|
|
2075
|
-
proUpgradeBtn: {
|
|
2076
|
-
flexDirection: "row",
|
|
2077
|
-
alignItems: "center",
|
|
2078
|
-
justifyContent: "center",
|
|
2079
|
-
gap: 8,
|
|
2080
|
-
backgroundColor: _sharedUi.buoyColors.primary,
|
|
2081
|
-
borderRadius: 10,
|
|
2082
|
-
paddingVertical: 14,
|
|
2083
|
-
shadowColor: _sharedUi.buoyColors.primary,
|
|
2084
|
-
shadowOffset: {
|
|
2085
|
-
width: 0,
|
|
2086
|
-
height: 0
|
|
2087
|
-
},
|
|
2088
|
-
shadowOpacity: 0.4,
|
|
2089
|
-
shadowRadius: 8
|
|
2090
|
-
},
|
|
2091
|
-
proUpgradeBtnText: {
|
|
2092
|
-
fontSize: 14,
|
|
2093
|
-
fontWeight: "700",
|
|
2094
|
-
color: _sharedUi.buoyColors.base
|
|
1102
|
+
// Footnote inline code
|
|
1103
|
+
footnoteMono: {
|
|
1104
|
+
fontFamily: "monospace",
|
|
1105
|
+
fontSize: _sharedUi.night.font.label,
|
|
1106
|
+
color: _sharedUi.night.color.textSecondary
|
|
2095
1107
|
}
|
|
2096
1108
|
});
|