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