@buoy-gg/time-machine 7.0.36 → 7.0.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -35
- package/lib/commonjs/components/HeaderActions.js +91 -0
- package/lib/commonjs/components/HeaderReloadButton.js +22 -25
- package/lib/commonjs/components/TimeMachineBody.js +68 -13
- package/lib/commonjs/components/floating/NamePromptModal.js +193 -0
- package/lib/commonjs/components/floating/TimeMachineFloatingTool.js +715 -0
- package/lib/commonjs/components/floating/armedPoint.js +92 -0
- package/lib/commonjs/components/floating/barSettings.js +66 -0
- package/lib/commonjs/components/list/CaptureBar.js +2 -0
- package/lib/commonjs/components/list/RestoreOutcomeCard.js +2 -0
- package/lib/commonjs/components/list/SnapshotRow.js +37 -13
- package/lib/commonjs/components/list/SourcesStrip.js +127 -83
- package/lib/commonjs/components/list/UndoDeleteBar.js +3 -1
- package/lib/commonjs/components/preview/RestorePreviewScreen.js +7 -2
- package/lib/commonjs/components/sources.js +19 -8
- package/lib/commonjs/index.js +42 -0
- package/lib/commonjs/preset.js +6 -4
- package/lib/commonjs/store/sourceIds.js +9 -0
- package/lib/commonjs/store/sourceSettings.js +79 -0
- package/lib/commonjs/store/timeMachineStore.js +75 -10
- package/lib/commonjs/sync/timeMachineSyncAdapter.js +5 -1
- package/lib/commonjs/ui/SwipeActionsRow.js +14 -3
- package/lib/commonjs/ui/primitives.js +2 -0
- package/lib/commonjs/ui/tmTheme.js +18 -5
- package/lib/module/components/HeaderActions.js +85 -0
- package/lib/module/components/HeaderReloadButton.js +24 -27
- package/lib/module/components/TimeMachineBody.js +71 -16
- package/lib/module/components/floating/NamePromptModal.js +188 -0
- package/lib/module/components/floating/TimeMachineFloatingTool.js +708 -0
- package/lib/module/components/floating/armedPoint.js +82 -0
- package/lib/module/components/floating/barSettings.js +57 -0
- package/lib/module/components/list/CaptureBar.js +2 -0
- package/lib/module/components/list/RestoreOutcomeCard.js +2 -0
- package/lib/module/components/list/SnapshotRow.js +37 -13
- package/lib/module/components/list/SourcesStrip.js +130 -84
- package/lib/module/components/list/UndoDeleteBar.js +3 -1
- package/lib/module/components/preview/RestorePreviewScreen.js +7 -2
- package/lib/module/components/sources.js +13 -6
- package/lib/module/index.js +7 -1
- package/lib/module/preset.js +6 -4
- package/lib/module/store/sourceIds.js +5 -0
- package/lib/module/store/sourceSettings.js +69 -0
- package/lib/module/store/timeMachineStore.js +74 -9
- package/lib/module/sync/timeMachineSyncAdapter.js +5 -1
- package/lib/module/ui/SwipeActionsRow.js +14 -3
- package/lib/module/ui/primitives.js +2 -0
- package/lib/module/ui/tmTheme.js +18 -5
- package/lib/typescript/components/HeaderActions.d.ts +7 -0
- package/lib/typescript/components/floating/NamePromptModal.d.ts +9 -0
- package/lib/typescript/components/floating/TimeMachineFloatingTool.d.ts +6 -0
- package/lib/typescript/components/floating/armedPoint.d.ts +14 -0
- package/lib/typescript/components/floating/barSettings.d.ts +7 -0
- package/lib/typescript/components/list/SnapshotRow.d.ts +5 -1
- package/lib/typescript/components/list/SourcesStrip.d.ts +3 -1
- package/lib/typescript/components/sources.d.ts +7 -2
- package/lib/typescript/index.d.ts +3 -1
- package/lib/typescript/preset.d.ts +4 -2
- package/lib/typescript/store/snapshotVault.d.ts +6 -0
- package/lib/typescript/store/sourceIds.d.ts +3 -0
- package/lib/typescript/store/sourceSettings.d.ts +9 -0
- package/lib/typescript/store/timeMachineStore.d.ts +16 -1
- package/lib/typescript/sync/timeMachineSyncAdapter.d.ts +4 -0
- package/lib/typescript/ui/tmTheme.d.ts +17 -4
- package/package.json +10 -7
- package/lib/commonjs/components/HeaderReloadButton.js.map +0 -1
- package/lib/commonjs/components/TimeMachineBody.js.map +0 -1
- package/lib/commonjs/components/TimeMachineModal.js.map +0 -1
- package/lib/commonjs/components/confirm.js.map +0 -1
- package/lib/commonjs/components/format.js.map +0 -1
- package/lib/commonjs/components/list/CaptureBar.js.map +0 -1
- package/lib/commonjs/components/list/RestoreOutcomeCard.js.map +0 -1
- package/lib/commonjs/components/list/SnapshotRow.js.map +0 -1
- package/lib/commonjs/components/list/SourcesStrip.js.map +0 -1
- package/lib/commonjs/components/list/UndoDeleteBar.js.map +0 -1
- package/lib/commonjs/components/list/WipeAllRow.js.map +0 -1
- package/lib/commonjs/components/preview/ItemDiffPanel.js.map +0 -1
- package/lib/commonjs/components/preview/PreviewFlow.js.map +0 -1
- package/lib/commonjs/components/preview/RestorePointNameRow.js.map +0 -1
- package/lib/commonjs/components/preview/RestorePreviewScreen.js.map +0 -1
- package/lib/commonjs/components/preview/verdictMeta.js.map +0 -1
- package/lib/commonjs/components/sources.js.map +0 -1
- package/lib/commonjs/hooks/useTimeMachine.js.map +0 -1
- package/lib/commonjs/index.js.map +0 -1
- package/lib/commonjs/preset.js.map +0 -1
- package/lib/commonjs/store/routeRestore.js.map +0 -1
- package/lib/commonjs/store/snapshotVault.js.map +0 -1
- package/lib/commonjs/store/timeMachineStore.js.map +0 -1
- package/lib/commonjs/sync/timeMachineSyncAdapter.js.map +0 -1
- package/lib/commonjs/ui/SwipeActionsRow.js.map +0 -1
- package/lib/commonjs/ui/primitives.js.map +0 -1
- package/lib/commonjs/ui/tmTheme.js.map +0 -1
- package/lib/module/components/HeaderReloadButton.js.map +0 -1
- package/lib/module/components/TimeMachineBody.js.map +0 -1
- package/lib/module/components/TimeMachineModal.js.map +0 -1
- package/lib/module/components/confirm.js.map +0 -1
- package/lib/module/components/format.js.map +0 -1
- package/lib/module/components/list/CaptureBar.js.map +0 -1
- package/lib/module/components/list/RestoreOutcomeCard.js.map +0 -1
- package/lib/module/components/list/SnapshotRow.js.map +0 -1
- package/lib/module/components/list/SourcesStrip.js.map +0 -1
- package/lib/module/components/list/UndoDeleteBar.js.map +0 -1
- package/lib/module/components/list/WipeAllRow.js.map +0 -1
- package/lib/module/components/preview/ItemDiffPanel.js.map +0 -1
- package/lib/module/components/preview/PreviewFlow.js.map +0 -1
- package/lib/module/components/preview/RestorePointNameRow.js.map +0 -1
- package/lib/module/components/preview/RestorePreviewScreen.js.map +0 -1
- package/lib/module/components/preview/verdictMeta.js.map +0 -1
- package/lib/module/components/sources.js.map +0 -1
- package/lib/module/hooks/useTimeMachine.js.map +0 -1
- package/lib/module/index.js.map +0 -1
- package/lib/module/preset.js.map +0 -1
- package/lib/module/store/routeRestore.js.map +0 -1
- package/lib/module/store/snapshotVault.js.map +0 -1
- package/lib/module/store/timeMachineStore.js.map +0 -1
- package/lib/module/sync/timeMachineSyncAdapter.js.map +0 -1
- package/lib/module/ui/SwipeActionsRow.js.map +0 -1
- package/lib/module/ui/primitives.js.map +0 -1
- package/lib/module/ui/tmTheme.js.map +0 -1
- package/lib/typescript/components/HeaderReloadButton.d.ts.map +0 -1
- package/lib/typescript/components/TimeMachineBody.d.ts.map +0 -1
- package/lib/typescript/components/TimeMachineModal.d.ts.map +0 -1
- package/lib/typescript/components/confirm.d.ts.map +0 -1
- package/lib/typescript/components/format.d.ts.map +0 -1
- package/lib/typescript/components/list/CaptureBar.d.ts.map +0 -1
- package/lib/typescript/components/list/RestoreOutcomeCard.d.ts.map +0 -1
- package/lib/typescript/components/list/SnapshotRow.d.ts.map +0 -1
- package/lib/typescript/components/list/SourcesStrip.d.ts.map +0 -1
- package/lib/typescript/components/list/UndoDeleteBar.d.ts.map +0 -1
- package/lib/typescript/components/list/WipeAllRow.d.ts.map +0 -1
- package/lib/typescript/components/preview/ItemDiffPanel.d.ts.map +0 -1
- package/lib/typescript/components/preview/PreviewFlow.d.ts.map +0 -1
- package/lib/typescript/components/preview/RestorePointNameRow.d.ts.map +0 -1
- package/lib/typescript/components/preview/RestorePreviewScreen.d.ts.map +0 -1
- package/lib/typescript/components/preview/verdictMeta.d.ts.map +0 -1
- package/lib/typescript/components/sources.d.ts.map +0 -1
- package/lib/typescript/hooks/useTimeMachine.d.ts.map +0 -1
- package/lib/typescript/index.d.ts.map +0 -1
- package/lib/typescript/preset.d.ts.map +0 -1
- package/lib/typescript/store/routeRestore.d.ts.map +0 -1
- package/lib/typescript/store/snapshotVault.d.ts.map +0 -1
- package/lib/typescript/store/timeMachineStore.d.ts.map +0 -1
- package/lib/typescript/sync/timeMachineSyncAdapter.d.ts.map +0 -1
- package/lib/typescript/ui/SwipeActionsRow.d.ts.map +0 -1
- package/lib/typescript/ui/primitives.d.ts.map +0 -1
- package/lib/typescript/ui/tmTheme.d.ts.map +0 -1
package/lib/commonjs/index.js
CHANGED
|
@@ -9,6 +9,18 @@ Object.defineProperty(exports, "RESTORE_ORDER", {
|
|
|
9
9
|
return _timeMachineStore.RESTORE_ORDER;
|
|
10
10
|
}
|
|
11
11
|
});
|
|
12
|
+
Object.defineProperty(exports, "SAFETY_SNAPSHOT_NAME", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _timeMachineStore.SAFETY_SNAPSHOT_NAME;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "TIME_MACHINE_FLOATING_TOOL_ID", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () {
|
|
21
|
+
return _TimeMachineFloatingTool.TIME_MACHINE_FLOATING_TOOL_ID;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
12
24
|
Object.defineProperty(exports, "TimeMachineModal", {
|
|
13
25
|
enumerable: true,
|
|
14
26
|
get: function () {
|
|
@@ -45,12 +57,24 @@ Object.defineProperty(exports, "createTimeMachineTool", {
|
|
|
45
57
|
return _preset.createTimeMachineTool;
|
|
46
58
|
}
|
|
47
59
|
});
|
|
60
|
+
Object.defineProperty(exports, "isSourceEnabled", {
|
|
61
|
+
enumerable: true,
|
|
62
|
+
get: function () {
|
|
63
|
+
return _sourceSettings.isSourceEnabled;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
48
66
|
Object.defineProperty(exports, "navigateToRoute", {
|
|
49
67
|
enumerable: true,
|
|
50
68
|
get: function () {
|
|
51
69
|
return _routeRestore.navigateToRoute;
|
|
52
70
|
}
|
|
53
71
|
});
|
|
72
|
+
Object.defineProperty(exports, "openTimeMachineFloatingTool", {
|
|
73
|
+
enumerable: true,
|
|
74
|
+
get: function () {
|
|
75
|
+
return _TimeMachineFloatingTool.openTimeMachineFloatingTool;
|
|
76
|
+
}
|
|
77
|
+
});
|
|
54
78
|
Object.defineProperty(exports, "replaceTimeMachineFromSnapshot", {
|
|
55
79
|
enumerable: true,
|
|
56
80
|
get: function () {
|
|
@@ -63,6 +87,18 @@ Object.defineProperty(exports, "setRemoteTimeMachineHandler", {
|
|
|
63
87
|
return _timeMachineStore.setRemoteTimeMachineHandler;
|
|
64
88
|
}
|
|
65
89
|
});
|
|
90
|
+
Object.defineProperty(exports, "setSourceEnabled", {
|
|
91
|
+
enumerable: true,
|
|
92
|
+
get: function () {
|
|
93
|
+
return _sourceSettings.setSourceEnabled;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
Object.defineProperty(exports, "subscribeSourceSettings", {
|
|
97
|
+
enumerable: true,
|
|
98
|
+
get: function () {
|
|
99
|
+
return _sourceSettings.subscribeSourceSettings;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
66
102
|
Object.defineProperty(exports, "timeMachineStore", {
|
|
67
103
|
enumerable: true,
|
|
68
104
|
get: function () {
|
|
@@ -84,8 +120,10 @@ Object.defineProperty(exports, "timeMachineToolPreset", {
|
|
|
84
120
|
var _routeRestore = require("./store/routeRestore");
|
|
85
121
|
var _preset = require("./preset");
|
|
86
122
|
var _TimeMachineModal = require("./components/TimeMachineModal");
|
|
123
|
+
var _TimeMachineFloatingTool = require("./components/floating/TimeMachineFloatingTool");
|
|
87
124
|
var _timeMachineSyncAdapter = require("./sync/timeMachineSyncAdapter");
|
|
88
125
|
var _timeMachineStore = require("./store/timeMachineStore");
|
|
126
|
+
var _sourceSettings = require("./store/sourceSettings");
|
|
89
127
|
/**
|
|
90
128
|
* @buoy-gg/time-machine
|
|
91
129
|
*
|
|
@@ -102,12 +140,16 @@ var _timeMachineStore = require("./store/timeMachineStore");
|
|
|
102
140
|
|
|
103
141
|
// Components
|
|
104
142
|
|
|
143
|
+
// The floating restore bar (one armed point, one tap to restore)
|
|
144
|
+
|
|
105
145
|
// External-sync adapter (auto-registered by @buoy-gg/core)
|
|
106
146
|
|
|
107
147
|
// Programmatic snapshot control (also used by tests / power users)
|
|
108
148
|
|
|
109
149
|
// Route capture / restore ("also take me back to the screen I was on")
|
|
110
150
|
|
|
151
|
+
// Per-source on/off switches (the Sources strip); off = never captured or restored
|
|
152
|
+
|
|
111
153
|
// Buoy Desktop remote-mirror seam
|
|
112
154
|
|
|
113
155
|
// A reload-mode restore that also restores the route can't navigate itself —
|
package/lib/commonjs/preset.js
CHANGED
|
@@ -5,9 +5,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.createTimeMachineTool = createTimeMachineTool;
|
|
7
7
|
exports.timeMachineToolPreset = void 0;
|
|
8
|
+
var _reactNative = require("react-native");
|
|
8
9
|
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
9
10
|
var _TimeMachineBody = require("./components/TimeMachineBody");
|
|
10
|
-
var
|
|
11
|
+
var _HeaderActions = require("./components/HeaderActions");
|
|
11
12
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
12
13
|
/**
|
|
13
14
|
* Pre-configured Time Machine tool for FloatingDevTools.
|
|
@@ -27,9 +28,10 @@ const timeMachineToolPreset = exports.timeMachineToolPreset = {
|
|
|
27
28
|
slot: "both",
|
|
28
29
|
icon: ({
|
|
29
30
|
size,
|
|
30
|
-
color
|
|
31
|
+
color,
|
|
32
|
+
slot
|
|
31
33
|
}) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.TimeMachineIcon, {
|
|
32
|
-
size: size,
|
|
34
|
+
size: slot === "dial" && _reactNative.Platform.OS !== "web" ? size * 1.5 : size,
|
|
33
35
|
color: color || _sharedUi.TIME_MACHINE_ICON_COLOR
|
|
34
36
|
}),
|
|
35
37
|
component: _TimeMachineBody.TimeMachineBody,
|
|
@@ -39,7 +41,7 @@ const timeMachineToolPreset = exports.timeMachineToolPreset = {
|
|
|
39
41
|
subtitle: "snapshot & restore app state",
|
|
40
42
|
searchable: true,
|
|
41
43
|
searchPlaceholder: "Filter…",
|
|
42
|
-
headerActions: /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
44
|
+
headerActions: /*#__PURE__*/(0, _jsxRuntime.jsx)(_HeaderActions.TimeMachineHeaderActions, {})
|
|
43
45
|
}
|
|
44
46
|
};
|
|
45
47
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ROUTE_SOURCE_ID = void 0;
|
|
7
|
+
/** Id of the route "source": a device capability, not a snapshot provider. */
|
|
8
|
+
const ROUTE_SOURCE_ID = exports.ROUTE_SOURCE_ID = "route";
|
|
9
|
+
//# sourceMappingURL=sourceIds.js.map
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ensureSourceSettingsLoaded = ensureSourceSettingsLoaded;
|
|
7
|
+
exports.getDisabledSources = getDisabledSources;
|
|
8
|
+
exports.isSourceEnabled = isSourceEnabled;
|
|
9
|
+
exports.resetSourceSettingsForTests = resetSourceSettingsForTests;
|
|
10
|
+
exports.setSourceEnabled = setSourceEnabled;
|
|
11
|
+
exports.subscribeSourceSettings = subscribeSourceSettings;
|
|
12
|
+
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
13
|
+
/**
|
|
14
|
+
* Which sources Time Machine is allowed to touch.
|
|
15
|
+
*
|
|
16
|
+
* A source switched off here is left out of every capture and every restore,
|
|
17
|
+
* from the tool, the bar, the desktop and MCP alike: "off" has to mean off
|
|
18
|
+
* everywhere, or the one path that forgets it is the one that breaks the app.
|
|
19
|
+
* The case this exists for is a store whose full replace the app cannot
|
|
20
|
+
* survive (a Zustand store holding live handles, say): leave it off and the
|
|
21
|
+
* rest of the state still round-trips.
|
|
22
|
+
*
|
|
23
|
+
* Persisted as the set of ids that are OFF, so a source that registers for
|
|
24
|
+
* the first time tomorrow starts on, and the default is "everything".
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
const setting = (0, _sharedUi.definePersistedSetting)(_sharedUi.devToolsStorageKeys.timeMachine.disabledSources(), [], {
|
|
28
|
+
sanitize: value => Array.isArray(value) ? value.filter(v => typeof v === "string") : []
|
|
29
|
+
});
|
|
30
|
+
let disabled = new Set();
|
|
31
|
+
let loaded = false;
|
|
32
|
+
let loadPromise = null;
|
|
33
|
+
const listeners = new Set();
|
|
34
|
+
const notify = () => listeners.forEach(listener => listener());
|
|
35
|
+
function ensureSourceSettingsLoaded() {
|
|
36
|
+
if (loaded) return Promise.resolve();
|
|
37
|
+
if (!loadPromise) {
|
|
38
|
+
loadPromise = setting.load().then(ids => {
|
|
39
|
+
// A toggle made while the read was in flight wins over the disk copy.
|
|
40
|
+
if (disabled.size === 0) {
|
|
41
|
+
disabled = new Set(ids);
|
|
42
|
+
notify();
|
|
43
|
+
}
|
|
44
|
+
}).finally(() => {
|
|
45
|
+
loaded = true;
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
return loadPromise;
|
|
49
|
+
}
|
|
50
|
+
function subscribeSourceSettings(listener) {
|
|
51
|
+
listeners.add(listener);
|
|
52
|
+
return () => {
|
|
53
|
+
listeners.delete(listener);
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Stable across renders until something changes, for useSyncExternalStore. */
|
|
58
|
+
function getDisabledSources() {
|
|
59
|
+
return disabled;
|
|
60
|
+
}
|
|
61
|
+
function isSourceEnabled(id) {
|
|
62
|
+
return !disabled.has(id);
|
|
63
|
+
}
|
|
64
|
+
function setSourceEnabled(id, enabled) {
|
|
65
|
+
if (enabled === !disabled.has(id)) return;
|
|
66
|
+
const next = new Set(disabled);
|
|
67
|
+
if (enabled) next.delete(id);else next.add(id);
|
|
68
|
+
disabled = next;
|
|
69
|
+
notify();
|
|
70
|
+
void setting.save([...next]);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Test seam: forget everything without touching storage. */
|
|
74
|
+
function resetSourceSettingsForTests() {
|
|
75
|
+
disabled = new Set();
|
|
76
|
+
loaded = false;
|
|
77
|
+
loadPromise = null;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=sourceSettings.js.map
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.RESTORE_ORDER = void 0;
|
|
6
|
+
exports.SAFETY_SNAPSHOT_NAME = exports.RESTORE_ORDER = void 0;
|
|
7
7
|
exports.replaceTimeMachineFromSnapshot = replaceTimeMachineFromSnapshot;
|
|
8
8
|
exports.setRemoteTimeMachineHandler = setRemoteTimeMachineHandler;
|
|
9
9
|
exports.timeMachineStore = void 0;
|
|
@@ -12,6 +12,8 @@ var _sharedUi = require("@buoy-gg/shared-ui");
|
|
|
12
12
|
var _dataViewer = require("@buoy-gg/shared-ui/dataViewer");
|
|
13
13
|
var _snapshotVault = require("./snapshotVault");
|
|
14
14
|
var _routeRestore = require("./routeRestore");
|
|
15
|
+
var _sourceSettings = require("./sourceSettings");
|
|
16
|
+
var _sourceIds = require("./sourceIds");
|
|
15
17
|
/**
|
|
16
18
|
* Time Machine orchestrator — snapshot CRUD + capture/restore across every
|
|
17
19
|
* registered StateSnapshotProvider (storage, redux, zustand, jotai, query,
|
|
@@ -39,7 +41,22 @@ const RESTORE_ORDER = exports.RESTORE_ORDER = ["storage", "redux", "zustand", "j
|
|
|
39
41
|
function defaultSnapshotName(route) {
|
|
40
42
|
const now = new Date();
|
|
41
43
|
const clock = `${String(now.getHours()).padStart(2, "0")}:${String(now.getMinutes()).padStart(2, "0")}`;
|
|
42
|
-
|
|
44
|
+
const screen = route ? route.pathname === "/" ? "Home" : route.pathname : null;
|
|
45
|
+
return screen ? `${screen} · ${clock}` : `Snapshot · ${clock}`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Two captures in the same minute on the same screen would get the same
|
|
50
|
+
* default name and be told apart by nothing. Number the repeats.
|
|
51
|
+
*/
|
|
52
|
+
function dedupeName(name, existing) {
|
|
53
|
+
const taken = new Set(existing.map(m => m.name));
|
|
54
|
+
if (!taken.has(name)) return name;
|
|
55
|
+
for (let n = 2; n < 1000; n++) {
|
|
56
|
+
const candidate = `${name} (${n})`;
|
|
57
|
+
if (!taken.has(candidate)) return candidate;
|
|
58
|
+
}
|
|
59
|
+
return name;
|
|
43
60
|
}
|
|
44
61
|
|
|
45
62
|
/**
|
|
@@ -53,6 +70,8 @@ function willRestoreRoute(meta) {
|
|
|
53
70
|
|
|
54
71
|
/** Extra knobs a restore accepts beyond mode + exclusions. */
|
|
55
72
|
|
|
73
|
+
const SAFETY_SNAPSHOT_NAME = exports.SAFETY_SNAPSHOT_NAME = "Before last restore";
|
|
74
|
+
|
|
56
75
|
/** Provider capability row as mirrored to a remote dashboard. */
|
|
57
76
|
|
|
58
77
|
/** One side of a preview comparison. */
|
|
@@ -144,7 +163,7 @@ class TimeMachineStore {
|
|
|
144
163
|
}
|
|
145
164
|
|
|
146
165
|
/** Capture all capturable sources (or a subset) into a named snapshot. */
|
|
147
|
-
async capture(name, sourceIds) {
|
|
166
|
+
async capture(name, sourceIds, options) {
|
|
148
167
|
if (remoteHandler) {
|
|
149
168
|
const result = await remoteHandler("capture", {
|
|
150
169
|
name,
|
|
@@ -153,11 +172,12 @@ class TimeMachineStore {
|
|
|
153
172
|
return result.snapshot;
|
|
154
173
|
}
|
|
155
174
|
await this.ensureLoaded();
|
|
175
|
+
await (0, _sourceSettings.ensureSourceSettingsLoaded)();
|
|
156
176
|
this.setState({
|
|
157
177
|
busy: "capture"
|
|
158
178
|
});
|
|
159
179
|
try {
|
|
160
|
-
const providers = (0, _sharedUi.getStateSnapshotProviders)().filter(p => p.status().canCapture && (!sourceIds || sourceIds.includes(p.id)));
|
|
180
|
+
const providers = (0, _sharedUi.getStateSnapshotProviders)().filter(p => p.status().canCapture && (0, _sourceSettings.isSourceEnabled)(p.id) && (!sourceIds || sourceIds.includes(p.id)));
|
|
161
181
|
const data = {};
|
|
162
182
|
const sources = {};
|
|
163
183
|
for (const provider of providers) {
|
|
@@ -174,21 +194,31 @@ class TimeMachineStore {
|
|
|
174
194
|
}
|
|
175
195
|
}
|
|
176
196
|
// Where the app was when this state was true — restoring can return here.
|
|
177
|
-
const route = (0, _routeRestore.captureCurrentRoute)();
|
|
197
|
+
const route = (0, _sourceSettings.isSourceEnabled)(_sourceIds.ROUTE_SOURCE_ID) ? (0, _routeRestore.captureCurrentRoute)() : null;
|
|
198
|
+
// The safety slot is rolling: the previous one goes before this one lands.
|
|
199
|
+
let current = this.state.snapshots;
|
|
200
|
+
if (options?.safety) {
|
|
201
|
+
for (const stale of current.filter(m => m.safety)) {
|
|
202
|
+
current = await (0, _snapshotVault.deleteSnapshot)(stale.id, current);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
178
205
|
const snapshot = {
|
|
179
206
|
meta: {
|
|
180
207
|
id: nextId(),
|
|
181
|
-
name: name.trim() || defaultSnapshotName(route),
|
|
208
|
+
name: options?.safety ? SAFETY_SNAPSHOT_NAME : dedupeName(name.trim() || defaultSnapshotName(route), current),
|
|
182
209
|
createdAt: Date.now(),
|
|
183
210
|
sizeBytes: 0,
|
|
184
211
|
...(route ? {
|
|
185
212
|
route
|
|
186
213
|
} : {}),
|
|
214
|
+
...(options?.safety ? {
|
|
215
|
+
safety: true
|
|
216
|
+
} : {}),
|
|
187
217
|
sources
|
|
188
218
|
},
|
|
189
219
|
data
|
|
190
220
|
};
|
|
191
|
-
const snapshots = await (0, _snapshotVault.saveSnapshot)(snapshot,
|
|
221
|
+
const snapshots = await (0, _snapshotVault.saveSnapshot)(snapshot, current);
|
|
192
222
|
this.setState({
|
|
193
223
|
snapshots
|
|
194
224
|
});
|
|
@@ -211,6 +241,7 @@ class TimeMachineStore {
|
|
|
211
241
|
return result.snapshot;
|
|
212
242
|
}
|
|
213
243
|
await this.ensureLoaded();
|
|
244
|
+
await (0, _sourceSettings.ensureSourceSettingsLoaded)();
|
|
214
245
|
const snapshot = {
|
|
215
246
|
meta: {
|
|
216
247
|
id: nextId(),
|
|
@@ -248,6 +279,16 @@ class TimeMachineStore {
|
|
|
248
279
|
return outcome;
|
|
249
280
|
}
|
|
250
281
|
await this.ensureLoaded();
|
|
282
|
+
await (0, _sourceSettings.ensureSourceSettingsLoaded)();
|
|
283
|
+
// The way back from a mis-tap: capture what is about to be replaced.
|
|
284
|
+
// Restoring the safety slot itself never rolls it, or Undo would eat
|
|
285
|
+
// its own target.
|
|
286
|
+
let safetySnapshotId;
|
|
287
|
+
if (options?.safetyCapture && !this.state.snapshots.find(m => m.id === id)?.safety) {
|
|
288
|
+
safetySnapshotId = (await this.capture(SAFETY_SNAPSHOT_NAME, undefined, {
|
|
289
|
+
safety: true
|
|
290
|
+
})).id;
|
|
291
|
+
}
|
|
251
292
|
this.setState({
|
|
252
293
|
busy: "restore"
|
|
253
294
|
});
|
|
@@ -260,7 +301,10 @@ class TimeMachineStore {
|
|
|
260
301
|
mode,
|
|
261
302
|
at: Date.now(),
|
|
262
303
|
willReload: false,
|
|
263
|
-
results: {}
|
|
304
|
+
results: {},
|
|
305
|
+
...(safetySnapshotId ? {
|
|
306
|
+
safetySnapshotId
|
|
307
|
+
} : {})
|
|
264
308
|
};
|
|
265
309
|
if (stored.meta.baseline) {
|
|
266
310
|
// Fresh install: wipe every clearable source, then reload so all
|
|
@@ -308,10 +352,10 @@ class TimeMachineStore {
|
|
|
308
352
|
// No prompt any more: the point carries its own answer, and having a
|
|
309
353
|
// route means wanting it back unless you said otherwise. An explicit
|
|
310
354
|
// option still wins, so MCP and the desktop can force either way.
|
|
311
|
-
const wantsRoute = options?.restoreRoute ?? willRestoreRoute(stored.meta);
|
|
355
|
+
const wantsRoute = (0, _sourceSettings.isSourceEnabled)(_sourceIds.ROUTE_SOURCE_ID) && (options?.restoreRoute ?? willRestoreRoute(stored.meta));
|
|
312
356
|
if (mode === "reload") {
|
|
313
357
|
// Storage only; everything in-memory rebuilds after the reload.
|
|
314
|
-
if (stored.data.storage && (!includeBySource || includeBySource.has("storage"))) {
|
|
358
|
+
if (stored.data.storage && (0, _sourceSettings.isSourceEnabled)("storage") && (!includeBySource || includeBySource.has("storage"))) {
|
|
315
359
|
outcome.results.storage = await this.restoreSource("storage", stored.data.storage, excludeBySource.get("storage"), includeBySource?.get("storage"));
|
|
316
360
|
}
|
|
317
361
|
// Hand the route to the NEXT boot — this realm is about to die, so the
|
|
@@ -343,6 +387,17 @@ class TimeMachineStore {
|
|
|
343
387
|
for (const sid of sourceIds) {
|
|
344
388
|
// Sources entirely outside the scope are untouched and unreported.
|
|
345
389
|
if (includeBySource && !includeBySource.has(sid)) continue;
|
|
390
|
+
// A source switched off in Sources is left exactly as it is. Reported
|
|
391
|
+
// as a warning, not a failure: this is what you asked for.
|
|
392
|
+
if (!(0, _sourceSettings.isSourceEnabled)(sid)) {
|
|
393
|
+
outcome.results[sid] = {
|
|
394
|
+
ok: true,
|
|
395
|
+
applied: 0,
|
|
396
|
+
skipped: [],
|
|
397
|
+
warnings: ["Switched off in Sources; left as it is"]
|
|
398
|
+
};
|
|
399
|
+
continue;
|
|
400
|
+
}
|
|
346
401
|
outcome.results[sid] = await this.restoreSource(sid, stored.data[sid], excludeBySource.get(sid), includeBySource?.get(sid));
|
|
347
402
|
}
|
|
348
403
|
// Navigate LAST — the screen we land on should read the restored state.
|
|
@@ -409,6 +464,7 @@ class TimeMachineStore {
|
|
|
409
464
|
return;
|
|
410
465
|
}
|
|
411
466
|
await this.ensureLoaded();
|
|
467
|
+
await (0, _sourceSettings.ensureSourceSettingsLoaded)();
|
|
412
468
|
const stored = await (0, _snapshotVault.readSnapshot)(id);
|
|
413
469
|
const snapshots = await (0, _snapshotVault.deleteSnapshot)(id, this.state.snapshots);
|
|
414
470
|
this.setState({
|
|
@@ -448,6 +504,7 @@ class TimeMachineStore {
|
|
|
448
504
|
return;
|
|
449
505
|
}
|
|
450
506
|
await this.ensureLoaded();
|
|
507
|
+
await (0, _sourceSettings.ensureSourceSettingsLoaded)();
|
|
451
508
|
const snapshots = await (0, _snapshotVault.setSnapshotRestoreRoute)(id, restoreRoute, this.state.snapshots);
|
|
452
509
|
this.setState({
|
|
453
510
|
snapshots
|
|
@@ -463,6 +520,7 @@ class TimeMachineStore {
|
|
|
463
520
|
return result?.snapshot ?? null;
|
|
464
521
|
}
|
|
465
522
|
await this.ensureLoaded();
|
|
523
|
+
await (0, _sourceSettings.ensureSourceSettingsLoaded)();
|
|
466
524
|
const source = this.state.snapshots.find(s => s.id === id);
|
|
467
525
|
if (!source) return null;
|
|
468
526
|
const result = await (0, _snapshotVault.duplicateSnapshot)(id, `${source.name} copy`, this.state.snapshots);
|
|
@@ -481,6 +539,7 @@ class TimeMachineStore {
|
|
|
481
539
|
return;
|
|
482
540
|
}
|
|
483
541
|
await this.ensureLoaded();
|
|
542
|
+
await (0, _sourceSettings.ensureSourceSettingsLoaded)();
|
|
484
543
|
const snapshots = await (0, _snapshotVault.renameSnapshot)(id, name, this.state.snapshots);
|
|
485
544
|
this.setState({
|
|
486
545
|
snapshots
|
|
@@ -501,6 +560,7 @@ class TimeMachineStore {
|
|
|
501
560
|
return;
|
|
502
561
|
}
|
|
503
562
|
await this.ensureLoaded();
|
|
563
|
+
await (0, _sourceSettings.ensureSourceSettingsLoaded)();
|
|
504
564
|
const snapshots = await (0, _snapshotVault.setSnapshotScope)(id, scope, this.state.snapshots);
|
|
505
565
|
this.setState({
|
|
506
566
|
snapshots
|
|
@@ -521,6 +581,7 @@ class TimeMachineStore {
|
|
|
521
581
|
return;
|
|
522
582
|
}
|
|
523
583
|
await this.ensureLoaded();
|
|
584
|
+
await (0, _sourceSettings.ensureSourceSettingsLoaded)();
|
|
524
585
|
const snapshots = await (0, _snapshotVault.setSnapshotExclusions)(id, excludedKeys, this.state.snapshots);
|
|
525
586
|
this.setState({
|
|
526
587
|
snapshots
|
|
@@ -638,6 +699,7 @@ class TimeMachineStore {
|
|
|
638
699
|
return;
|
|
639
700
|
}
|
|
640
701
|
await this.ensureLoaded();
|
|
702
|
+
await (0, _sourceSettings.ensureSourceSettingsLoaded)();
|
|
641
703
|
const runId = ++this.previewRunId;
|
|
642
704
|
this.setState({
|
|
643
705
|
preview: {
|
|
@@ -669,6 +731,9 @@ class TimeMachineStore {
|
|
|
669
731
|
const sourceIds = isBaseline ? (0, _sharedUi.getStateSnapshotProviders)().filter(p => p.clear).map(p => p.id) : [...RESTORE_ORDER.filter(sid => sid in rightData), ...Object.keys(rightData).filter(sid => !RESTORE_ORDER.includes(sid))];
|
|
670
732
|
const sources = [];
|
|
671
733
|
for (const sid of sourceIds) {
|
|
734
|
+
// Off in Sources: a restore will not touch it, so there is nothing
|
|
735
|
+
// to preview.
|
|
736
|
+
if (!(0, _sourceSettings.isSourceEnabled)(sid)) continue;
|
|
672
737
|
// Yield a frame between sources — verdict passes are bounded but a
|
|
673
738
|
// five-source build shouldn't run as one synchronous block.
|
|
674
739
|
await new Promise(r => setTimeout(r, 0));
|
|
@@ -9,6 +9,8 @@ var _dataViewer = require("@buoy-gg/shared-ui/dataViewer");
|
|
|
9
9
|
var _timeMachineStore = require("../store/timeMachineStore");
|
|
10
10
|
var _snapshotVault = require("../store/snapshotVault");
|
|
11
11
|
var _routeRestore = require("../store/routeRestore");
|
|
12
|
+
var _sourceSettings = require("../store/sourceSettings");
|
|
13
|
+
var _sourceIds = require("../store/sourceIds");
|
|
12
14
|
/**
|
|
13
15
|
* Sync adapter for the Time Machine tool, consumed by @buoy-gg/external-sync's
|
|
14
16
|
* `useExternalSync` (structurally matches its ToolSyncAdapter interface so
|
|
@@ -31,7 +33,8 @@ function providerStatuses() {
|
|
|
31
33
|
label: p.label,
|
|
32
34
|
canCapture: s.canCapture,
|
|
33
35
|
canRestore: s.canRestore,
|
|
34
|
-
detail: s.detail
|
|
36
|
+
detail: s.detail,
|
|
37
|
+
enabled: (0, _sourceSettings.isSourceEnabled)(p.id)
|
|
35
38
|
};
|
|
36
39
|
});
|
|
37
40
|
}
|
|
@@ -51,6 +54,7 @@ function metadata() {
|
|
|
51
54
|
// a dashboard has no router of its own to probe, so it's mirrored here.
|
|
52
55
|
route: {
|
|
53
56
|
available: (0, _routeRestore.canNavigate)(),
|
|
57
|
+
enabled: (0, _sourceSettings.isSourceEnabled)(_sourceIds.ROUTE_SOURCE_ID),
|
|
54
58
|
...(current ? {
|
|
55
59
|
current: current.href
|
|
56
60
|
} : {})
|
|
@@ -96,11 +96,20 @@ function SwipeActionsRow({
|
|
|
96
96
|
(0, _react.useEffect)(() => () => {
|
|
97
97
|
if (closeOpenRow === close) closeOpenRow = null;
|
|
98
98
|
}, [close]);
|
|
99
|
+
|
|
100
|
+
// The row is glass now, so the actions can't hide under it: they fade in
|
|
101
|
+
// with the first points of the drag instead of sitting there at rest.
|
|
102
|
+
const actionOpacity = translateX.interpolate({
|
|
103
|
+
inputRange: [-24, 0],
|
|
104
|
+
outputRange: [1, 0],
|
|
105
|
+
extrapolate: "clamp"
|
|
106
|
+
});
|
|
99
107
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
100
108
|
style: styles.clip,
|
|
101
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
109
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.View, {
|
|
102
110
|
style: [styles.actionLayer, {
|
|
103
|
-
width: openWidth
|
|
111
|
+
width: openWidth,
|
|
112
|
+
opacity: actionOpacity
|
|
104
113
|
}],
|
|
105
114
|
children: actions.map(action => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
106
115
|
style: [styles.action, action.background ? {
|
|
@@ -159,7 +168,9 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
159
168
|
fontWeight: "600",
|
|
160
169
|
letterSpacing: _tmTheme.tm.tracking.control
|
|
161
170
|
},
|
|
162
|
-
//
|
|
171
|
+
// Glass, like the card it sits in. The actions underneath are faded out
|
|
172
|
+
// at rest (see actionOpacity), which is what keeps them from bleeding
|
|
173
|
+
// through a translucent row.
|
|
163
174
|
content: {
|
|
164
175
|
backgroundColor: _tmTheme.tm.color.group
|
|
165
176
|
}
|
|
@@ -147,6 +147,8 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
147
147
|
marginHorizontal: _tmTheme.tm.gutter,
|
|
148
148
|
backgroundColor: _tmTheme.tm.color.group,
|
|
149
149
|
borderRadius: _tmTheme.tm.radius.group,
|
|
150
|
+
borderWidth: 1,
|
|
151
|
+
borderColor: _tmTheme.tm.color.groupBorder,
|
|
150
152
|
overflow: "hidden"
|
|
151
153
|
},
|
|
152
154
|
separator: {
|
|
@@ -9,7 +9,7 @@ var _sharedUi = require("@buoy-gg/shared-ui");
|
|
|
9
9
|
* Time Machine design tokens — the "modern" surface language.
|
|
10
10
|
*
|
|
11
11
|
* A grouped-inset list system (iOS Settings shape): one dark sheet, rounded
|
|
12
|
-
*
|
|
12
|
+
* glass cards holding hairline-separated rows, uppercase section labels
|
|
13
13
|
* outside the cards, and explanatory footnotes under them.
|
|
14
14
|
*
|
|
15
15
|
* COLOR COMES FROM the shared `night` palette (ui/night/nightTheme.ts) — not
|
|
@@ -39,15 +39,28 @@ const tm = exports.tm = {
|
|
|
39
39
|
* without the list reading through the CTA.
|
|
40
40
|
*/
|
|
41
41
|
sheet: "rgba(5, 5, 5, 0.92)",
|
|
42
|
-
/**
|
|
43
|
-
|
|
42
|
+
/**
|
|
43
|
+
* A grouped card: night glass, so the star field behind the sheet shows
|
|
44
|
+
* through every card the way it does through the header chips. Cards
|
|
45
|
+
* take `groupBorder` as a hairline, or the glass reads as a smudge.
|
|
46
|
+
*/
|
|
47
|
+
group: _sharedUi.night.color.glass,
|
|
48
|
+
groupBorder: _sharedUi.night.color.glassBorder,
|
|
44
49
|
/** Row press / hover wash on top of a group. */
|
|
45
|
-
rowPressed: _sharedUi.night.color.
|
|
50
|
+
rowPressed: _sharedUi.night.color.glassElevated,
|
|
46
51
|
/** Hairline between rows, inset from the left like iOS. */
|
|
47
52
|
separator: _sharedUi.night.color.separator,
|
|
48
53
|
/** Neutral control fill (icon discs, chips, round buttons). */
|
|
49
|
-
fill: _sharedUi.night.color.
|
|
54
|
+
fill: _sharedUi.night.color.glassElevated,
|
|
50
55
|
fillStrong: _sharedUi.night.color.fillTertiary,
|
|
56
|
+
/** Opaque ring around a badge on a glass card (the sheet's own color). */
|
|
57
|
+
ring: _sharedUi.night.color.bg,
|
|
58
|
+
/**
|
|
59
|
+
* Opaque disc behind a Buoy icon. The icons paint their knock-outs in
|
|
60
|
+
* the color they are handed, so a translucent fill turns a floppy disk
|
|
61
|
+
* into a yellow square. Stays solid on purpose.
|
|
62
|
+
*/
|
|
63
|
+
disc: _sharedUi.night.color.surfaceElevated,
|
|
51
64
|
label: _sharedUi.night.color.text,
|
|
52
65
|
labelSecondary: _sharedUi.night.color.textSecondary,
|
|
53
66
|
labelTertiary: _sharedUi.night.color.textTertiary,
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The tool's header actions, in Network's header language: labeled
|
|
5
|
+
* dark-glass chips. "Action bar" is named for the thing it opens, the
|
|
6
|
+
* floating action bar over the app, and takes the accent ink as the one
|
|
7
|
+
* action a newcomer has to find. Reload is the plain JS reload.
|
|
8
|
+
*
|
|
9
|
+
* Action bar puts a restore point on the floating bar and gets the modal out
|
|
10
|
+
* of the way. The preview screen passes the point it is showing as `armId`,
|
|
11
|
+
* so opening it from there arms that point; the list leaves it to the
|
|
12
|
+
* default rule.
|
|
13
|
+
*/
|
|
14
|
+
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
|
|
15
|
+
import { night } from "@buoy-gg/shared-ui";
|
|
16
|
+
import { useToolHost } from "@buoy-gg/core";
|
|
17
|
+
import { HeaderReloadButton } from "./HeaderReloadButton";
|
|
18
|
+
import { openTimeMachineFloatingTool } from "./floating/TimeMachineFloatingTool";
|
|
19
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
20
|
+
export function HeaderBarButton({
|
|
21
|
+
armId
|
|
22
|
+
}) {
|
|
23
|
+
const host = useToolHost();
|
|
24
|
+
const onPress = () => {
|
|
25
|
+
openTimeMachineFloatingTool(armId);
|
|
26
|
+
// Same move as Network: the bar is for using the app, so the modal
|
|
27
|
+
// minimizes to the dock instead of covering the screen the bar controls.
|
|
28
|
+
host.minimize();
|
|
29
|
+
};
|
|
30
|
+
return /*#__PURE__*/_jsxs(TouchableOpacity, {
|
|
31
|
+
style: styles.labeledChip,
|
|
32
|
+
onPress: onPress,
|
|
33
|
+
accessibilityLabel: "Open the floating action bar over the app",
|
|
34
|
+
accessibilityRole: "button",
|
|
35
|
+
testID: "time-machine-header-bar",
|
|
36
|
+
children: [/*#__PURE__*/_jsx(View, {
|
|
37
|
+
style: styles.glyph
|
|
38
|
+
}), /*#__PURE__*/_jsx(Text, {
|
|
39
|
+
style: styles.label,
|
|
40
|
+
children: "Action bar"
|
|
41
|
+
})]
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
export function TimeMachineHeaderActions({
|
|
45
|
+
armId
|
|
46
|
+
}) {
|
|
47
|
+
return /*#__PURE__*/_jsxs(View, {
|
|
48
|
+
style: styles.row,
|
|
49
|
+
children: [/*#__PURE__*/_jsx(HeaderBarButton, {
|
|
50
|
+
armId: armId
|
|
51
|
+
}), /*#__PURE__*/_jsx(HeaderReloadButton, {})]
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
const styles = StyleSheet.create({
|
|
55
|
+
row: {
|
|
56
|
+
flexDirection: "row",
|
|
57
|
+
alignItems: "center",
|
|
58
|
+
gap: 8
|
|
59
|
+
},
|
|
60
|
+
labeledChip: {
|
|
61
|
+
height: 32,
|
|
62
|
+
flexDirection: "row",
|
|
63
|
+
alignItems: "center",
|
|
64
|
+
gap: 6,
|
|
65
|
+
paddingHorizontal: 10,
|
|
66
|
+
borderRadius: 8,
|
|
67
|
+
borderWidth: 1,
|
|
68
|
+
borderColor: night.color.border,
|
|
69
|
+
backgroundColor: night.color.buttonSurface
|
|
70
|
+
},
|
|
71
|
+
// A small strip outline: the thing the button opens.
|
|
72
|
+
glyph: {
|
|
73
|
+
width: 14,
|
|
74
|
+
height: 8,
|
|
75
|
+
borderRadius: 3,
|
|
76
|
+
borderWidth: 1.5,
|
|
77
|
+
borderColor: night.color.accent
|
|
78
|
+
},
|
|
79
|
+
label: {
|
|
80
|
+
fontSize: 11,
|
|
81
|
+
fontWeight: "700",
|
|
82
|
+
color: night.color.accent
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
//# sourceMappingURL=HeaderActions.js.map
|