@buoy-gg/time-machine 7.0.35 → 7.0.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +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 +11 -8
- 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
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* The reload header action: a plain JS-bundle reload (no restore), so
|
|
5
|
+
* in-memory state rebuilds from whatever is persisted.
|
|
6
|
+
*
|
|
7
|
+
* A labeled dark-glass chip, the same shape as the Pin chip beside it and
|
|
8
|
+
* Network's "Override": the words are the whole explanation.
|
|
8
9
|
*/
|
|
9
10
|
import { StyleSheet, Text, TouchableOpacity } from "react-native";
|
|
10
|
-
import {
|
|
11
|
-
import { jsx as _jsx
|
|
11
|
+
import { night, scheduleReloadApp } from "@buoy-gg/shared-ui";
|
|
12
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
12
13
|
export function HeaderReloadButton() {
|
|
13
14
|
const onPress = () => {
|
|
14
15
|
try {
|
|
@@ -19,38 +20,34 @@ export function HeaderReloadButton() {
|
|
|
19
20
|
// No reload mechanism available (bare production build) — nothing to do.
|
|
20
21
|
}
|
|
21
22
|
};
|
|
22
|
-
return /*#__PURE__*/
|
|
23
|
-
style: styles.
|
|
23
|
+
return /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
24
|
+
style: styles.chip,
|
|
24
25
|
onPress: onPress,
|
|
25
|
-
hitSlop: {
|
|
26
|
-
top: 8,
|
|
27
|
-
bottom: 8,
|
|
28
|
-
left: 8,
|
|
29
|
-
right: 8
|
|
30
|
-
},
|
|
31
26
|
accessibilityLabel: "Reload app",
|
|
27
|
+
accessibilityHint: "Reloads the JavaScript bundle without restoring anything",
|
|
32
28
|
accessibilityRole: "button",
|
|
33
29
|
testID: "time-machine-reload-app",
|
|
34
|
-
children:
|
|
35
|
-
size: 12,
|
|
36
|
-
color: night.color.textSecondary
|
|
37
|
-
}), /*#__PURE__*/_jsx(Text, {
|
|
30
|
+
children: /*#__PURE__*/_jsx(Text, {
|
|
38
31
|
style: styles.label,
|
|
39
|
-
children: "
|
|
40
|
-
})
|
|
32
|
+
children: "Reload app"
|
|
33
|
+
})
|
|
41
34
|
});
|
|
42
35
|
}
|
|
43
36
|
const styles = StyleSheet.create({
|
|
44
|
-
|
|
45
|
-
|
|
37
|
+
chip: {
|
|
38
|
+
height: 32,
|
|
39
|
+
paddingHorizontal: 10,
|
|
40
|
+
borderRadius: 8,
|
|
41
|
+
borderWidth: 1,
|
|
42
|
+
borderColor: night.color.border,
|
|
43
|
+
backgroundColor: night.color.buttonSurface,
|
|
46
44
|
alignItems: "center",
|
|
47
|
-
|
|
48
|
-
padding: 4
|
|
45
|
+
justifyContent: "center"
|
|
49
46
|
},
|
|
50
47
|
label: {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
48
|
+
fontSize: 11,
|
|
49
|
+
fontWeight: "700",
|
|
50
|
+
color: night.color.textSecondary
|
|
54
51
|
}
|
|
55
52
|
});
|
|
56
53
|
//# sourceMappingURL=HeaderReloadButton.js.map
|
|
@@ -13,11 +13,10 @@
|
|
|
13
13
|
* Sources strip, one card of restore points with swipe-to-delete, and the
|
|
14
14
|
* app-wide wipe kept last and understated.
|
|
15
15
|
*/
|
|
16
|
-
import { useState } from "react";
|
|
17
|
-
import { ScrollView, StyleSheet, View } from "react-native";
|
|
18
|
-
import { useSafeAreaInsets, useLimit, ToolEmptyState } from "@buoy-gg/shared-ui";
|
|
16
|
+
import { useRef, useState, useSyncExternalStore } from "react";
|
|
17
|
+
import { ScrollView, StyleSheet, Text, TouchableOpacity, View } from "react-native";
|
|
18
|
+
import { useSafeAreaInsets, useLimit, ToolEmptyState, getFloatingTools, subscribeFloatingTools } from "@buoy-gg/shared-ui";
|
|
19
19
|
import { useToolHost } from "@buoy-gg/core";
|
|
20
|
-
import { useIsPro } from "@buoy-gg/license";
|
|
21
20
|
import { useTimeMachineState } from "../hooks/useTimeMachine";
|
|
22
21
|
import { timeMachineStore } from "../store/timeMachineStore";
|
|
23
22
|
import { Footnote, Group, SectionLabel } from "../ui/primitives";
|
|
@@ -31,7 +30,11 @@ import { UndoDeleteBar } from "./list/UndoDeleteBar";
|
|
|
31
30
|
import { SourcesStrip } from "./list/SourcesStrip";
|
|
32
31
|
import { WipeAllRow } from "./list/WipeAllRow";
|
|
33
32
|
import { PreviewScreen } from "./preview/PreviewFlow";
|
|
33
|
+
import { TIME_MACHINE_FLOATING_TOOL_ID, openTimeMachineFloatingTool } from "./floating/TimeMachineFloatingTool";
|
|
34
|
+
import { getPickedPointId, resolveArmedPoint, subscribePickedPoint } from "./floating/armedPoint";
|
|
35
|
+
import { setSourceEnabled } from "../store/sourceSettings";
|
|
34
36
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
37
|
+
const isBarOpen = () => getFloatingTools().some(tool => tool.id === TIME_MACHINE_FLOATING_TOOL_ID);
|
|
35
38
|
export function TimeMachineBody() {
|
|
36
39
|
const [screen, setScreen] = useState({
|
|
37
40
|
kind: "list"
|
|
@@ -78,21 +81,35 @@ function RestorePointList({
|
|
|
78
81
|
hasLoaded,
|
|
79
82
|
busy,
|
|
80
83
|
lastOutcome,
|
|
81
|
-
recentlyDeleted
|
|
84
|
+
recentlyDeleted,
|
|
85
|
+
remoteProviders
|
|
82
86
|
} = useTimeMachineState();
|
|
83
|
-
const isPro = useIsPro();
|
|
84
87
|
const snapshotLimit = useLimit("timeMachine.snapshots");
|
|
85
88
|
const host = useToolHost();
|
|
86
89
|
const insets = useSafeAreaInsets({
|
|
87
90
|
minBottom: 16
|
|
88
91
|
});
|
|
92
|
+
// Which point the floating restore bar has armed, while the bar is open.
|
|
93
|
+
const barOpen = useSyncExternalStore(subscribeFloatingTools, isBarOpen, isBarOpen);
|
|
94
|
+
const pickedId = useSyncExternalStore(subscribePickedPoint, getPickedPointId, getPickedPointId);
|
|
95
|
+
const armedId = barOpen ? resolveArmedPoint(snapshots, pickedId)?.id : undefined;
|
|
96
|
+
// Restoring the same point from this list again and again is what the bar
|
|
97
|
+
// is for; say so once, at the moment it is true.
|
|
98
|
+
const listRestores = useRef({});
|
|
99
|
+
const [barHintFor, setBarHintFor] = useState(null);
|
|
100
|
+
const putOnBar = id => {
|
|
101
|
+
setBarHintFor(null);
|
|
102
|
+
openTimeMachineFloatingTool(id);
|
|
103
|
+
host.minimize();
|
|
104
|
+
};
|
|
89
105
|
|
|
90
106
|
// Header search (when hosted by the core shell) filters the list.
|
|
91
107
|
const query = host.search.trim().toLowerCase();
|
|
92
108
|
const visible = query ? snapshots.filter(s => s.name.toLowerCase().includes(query)) : snapshots;
|
|
93
109
|
|
|
94
|
-
// Infinity for Pro, so this is simply false for them.
|
|
95
|
-
|
|
110
|
+
// Infinity for Pro, so this is simply false for them. The bar's safety
|
|
111
|
+
// slot is not a point you chose to keep, so it does not count.
|
|
112
|
+
const atCaptureLimit = snapshots.filter(s => !s.safety).length >= snapshotLimit;
|
|
96
113
|
const captureDisabled = busy !== null || atCaptureLimit;
|
|
97
114
|
|
|
98
115
|
/**
|
|
@@ -112,12 +129,16 @@ function RestorePointList({
|
|
|
112
129
|
confirmDestructive("Restore fresh install?", "This wipes all app storage and reloads the app.", "Wipe & reload", () => void timeMachineStore.restore(meta.id, "reload"));
|
|
113
130
|
return;
|
|
114
131
|
}
|
|
132
|
+
const count = (listRestores.current[meta.id] ?? 0) + 1;
|
|
133
|
+
listRestores.current[meta.id] = count;
|
|
134
|
+
if (count >= 2 && !barOpen) setBarHintFor(meta.id);
|
|
115
135
|
void timeMachineStore.restore(meta.id, "live").then(outcome => {
|
|
116
136
|
const clean = Object.values(outcome.results).every(r => r.ok);
|
|
117
137
|
if (!clean || outcome.willReload) return;
|
|
118
138
|
host.minimize();
|
|
119
139
|
});
|
|
120
140
|
};
|
|
141
|
+
const barHint = barHintFor && !barOpen ? snapshots.find(s => s.id === barHintFor) ?? null : null;
|
|
121
142
|
return /*#__PURE__*/_jsxs(ScrollView, {
|
|
122
143
|
style: styles.fill,
|
|
123
144
|
contentContainerStyle: [styles.content, {
|
|
@@ -147,24 +168,47 @@ function RestorePointList({
|
|
|
147
168
|
}), atCaptureLimit ? /*#__PURE__*/_jsxs(Footnote, {
|
|
148
169
|
tone: "warning",
|
|
149
170
|
testID: "time-machine-limit",
|
|
150
|
-
children: ["Free plan keeps ", snapshotLimit, " restore
|
|
171
|
+
children: ["Free plan keeps ", snapshotLimit, " restore point", snapshotLimit === 1 ? "" : "s", ". Upgrade to Pro for unlimited snapshots."]
|
|
151
172
|
}) : null, /*#__PURE__*/_jsx(SectionLabel, {
|
|
152
173
|
children: "Sources"
|
|
153
174
|
}), /*#__PURE__*/_jsx(SourcesStrip, {
|
|
154
|
-
sources: sources
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
175
|
+
sources: sources,
|
|
176
|
+
onToggle: remoteProviders ? undefined : setSourceEnabled
|
|
177
|
+
}), remoteProviders ? null : /*#__PURE__*/_jsx(Footnote, {
|
|
178
|
+
testID: "time-machine-sources-hint",
|
|
179
|
+
children: "Switch a source off to leave it out of every capture and restore."
|
|
180
|
+
}), /*#__PURE__*/_jsx(SectionLabel, {
|
|
159
181
|
children: "Restore Points"
|
|
160
|
-
}), /*#__PURE__*/_jsxs(
|
|
182
|
+
}), barHint ? /*#__PURE__*/_jsxs(View, {
|
|
183
|
+
style: styles.barHint,
|
|
184
|
+
testID: "time-machine-bar-hint",
|
|
185
|
+
children: [/*#__PURE__*/_jsxs(Footnote, {
|
|
186
|
+
children: ["Restoring \"", barHint.name, "\" a lot? Put it on the floating action bar and restore it with one tap."]
|
|
187
|
+
}), /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
188
|
+
onPress: () => putOnBar(barHint.id),
|
|
189
|
+
accessibilityRole: "button",
|
|
190
|
+
testID: "time-machine-bar-hint-pin",
|
|
191
|
+
hitSlop: {
|
|
192
|
+
top: 6,
|
|
193
|
+
bottom: 6,
|
|
194
|
+
left: 6,
|
|
195
|
+
right: 6
|
|
196
|
+
},
|
|
197
|
+
children: /*#__PURE__*/_jsx(Text, {
|
|
198
|
+
style: styles.barHintAction,
|
|
199
|
+
children: "Open the action bar"
|
|
200
|
+
})
|
|
201
|
+
})]
|
|
202
|
+
}) : null, /*#__PURE__*/_jsxs(Group, {
|
|
161
203
|
children: [visible.map(meta => /*#__PURE__*/_jsx(SnapshotRow, {
|
|
162
204
|
meta: meta,
|
|
163
205
|
busy: busy !== null,
|
|
206
|
+
armed: meta.id === armedId,
|
|
164
207
|
onOpen: () => onOpenPreview(meta),
|
|
165
208
|
onRestore: () => restore(meta),
|
|
166
209
|
onDelete: () => void timeMachineStore.delete(meta.id),
|
|
167
|
-
onDuplicate: () => void timeMachineStore.duplicate(meta.id)
|
|
210
|
+
onDuplicate: () => void timeMachineStore.duplicate(meta.id),
|
|
211
|
+
onArm: () => putOnBar(meta.id)
|
|
168
212
|
}, meta.id)), visible.length === 0 ? /*#__PURE__*/_jsx(ToolEmptyState, {
|
|
169
213
|
testID: "time-machine-empty",
|
|
170
214
|
...(!hasLoaded ? {
|
|
@@ -200,6 +244,17 @@ function RestorePointList({
|
|
|
200
244
|
});
|
|
201
245
|
}
|
|
202
246
|
const styles = StyleSheet.create({
|
|
247
|
+
barHint: {
|
|
248
|
+
marginHorizontal: tm.gutter,
|
|
249
|
+
marginBottom: 8
|
|
250
|
+
},
|
|
251
|
+
barHintAction: {
|
|
252
|
+
color: tm.color.accent,
|
|
253
|
+
fontSize: tm.font.footnote,
|
|
254
|
+
fontWeight: "600",
|
|
255
|
+
paddingHorizontal: tm.textInset,
|
|
256
|
+
paddingTop: 2
|
|
257
|
+
},
|
|
203
258
|
fill: {
|
|
204
259
|
flex: 1,
|
|
205
260
|
// Transparent so JsModal's ToolBackground shows through (the modal paints opaque base beneath it).
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* "Name this restore point": the dialog `+` on the restore bar opens.
|
|
5
|
+
*
|
|
6
|
+
* A real Modal rather than a panel under the strip, so it sits centered over
|
|
7
|
+
* the app, above the keyboard, wherever the strip happens to be. An empty
|
|
8
|
+
* name is allowed: the store then names the point after the screen and the
|
|
9
|
+
* time, the same default the tool's capture bar uses.
|
|
10
|
+
*/
|
|
11
|
+
import { useEffect, useState } from "react";
|
|
12
|
+
import { KeyboardAvoidingView, Modal, Platform, Pressable, StyleSheet, Text, TextInput, TouchableOpacity, View } from "react-native";
|
|
13
|
+
import { night } from "@buoy-gg/shared-ui";
|
|
14
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
15
|
+
export function NamePromptModal({
|
|
16
|
+
visible,
|
|
17
|
+
summary,
|
|
18
|
+
onCapture,
|
|
19
|
+
onCancel
|
|
20
|
+
}) {
|
|
21
|
+
const [name, setName] = useState("");
|
|
22
|
+
// Every opening starts blank, so a cancelled name never comes back.
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (visible) setName("");
|
|
25
|
+
}, [visible]);
|
|
26
|
+
const submit = () => onCapture(name.trim());
|
|
27
|
+
return /*#__PURE__*/_jsx(Modal, {
|
|
28
|
+
visible: visible,
|
|
29
|
+
transparent: true,
|
|
30
|
+
animationType: "fade",
|
|
31
|
+
onRequestClose: onCancel,
|
|
32
|
+
statusBarTranslucent: true,
|
|
33
|
+
children: /*#__PURE__*/_jsx(KeyboardAvoidingView, {
|
|
34
|
+
behavior: Platform.OS === "ios" ? "padding" : undefined,
|
|
35
|
+
style: styles.fill,
|
|
36
|
+
children: /*#__PURE__*/_jsx(Pressable, {
|
|
37
|
+
style: styles.backdrop,
|
|
38
|
+
onPress: onCancel,
|
|
39
|
+
accessibilityLabel: "Cancel",
|
|
40
|
+
testID: "time-machine-bar-name-backdrop",
|
|
41
|
+
children: /*#__PURE__*/_jsxs(Pressable, {
|
|
42
|
+
style: styles.card,
|
|
43
|
+
onPress: event => event.stopPropagation(),
|
|
44
|
+
testID: "time-machine-bar-name-panel"
|
|
45
|
+
// A Pressable is one accessibility element by default, which
|
|
46
|
+
// hid the field and both buttons from VoiceOver and from tests.
|
|
47
|
+
,
|
|
48
|
+
accessible: false,
|
|
49
|
+
children: [/*#__PURE__*/_jsx(Text, {
|
|
50
|
+
style: styles.title,
|
|
51
|
+
children: "Name this restore point"
|
|
52
|
+
}), summary ? /*#__PURE__*/_jsx(Text, {
|
|
53
|
+
style: styles.summary,
|
|
54
|
+
testID: "time-machine-bar-name-summary",
|
|
55
|
+
children: summary
|
|
56
|
+
}) : null, /*#__PURE__*/_jsx(TextInput, {
|
|
57
|
+
testID: "time-machine-bar-name-input",
|
|
58
|
+
accessibilityLabel: "Restore point name",
|
|
59
|
+
value: name,
|
|
60
|
+
onChangeText: setName,
|
|
61
|
+
onSubmitEditing: submit,
|
|
62
|
+
placeholder: "Screen and time, if left empty",
|
|
63
|
+
placeholderTextColor: night.color.placeholder,
|
|
64
|
+
autoFocus: true,
|
|
65
|
+
autoCorrect: false
|
|
66
|
+
// Names are labels, not sentences: "bag" should stay "bag".
|
|
67
|
+
,
|
|
68
|
+
autoCapitalize: "none",
|
|
69
|
+
returnKeyType: "done",
|
|
70
|
+
style: styles.input
|
|
71
|
+
}), /*#__PURE__*/_jsx(Text, {
|
|
72
|
+
style: styles.hint,
|
|
73
|
+
children: "Captures the state the app is in right now and arms it on the bar."
|
|
74
|
+
}), /*#__PURE__*/_jsxs(View, {
|
|
75
|
+
style: styles.actions,
|
|
76
|
+
children: [/*#__PURE__*/_jsx(TouchableOpacity, {
|
|
77
|
+
testID: "time-machine-bar-name-cancel",
|
|
78
|
+
accessibilityRole: "button",
|
|
79
|
+
onPress: onCancel,
|
|
80
|
+
style: styles.secondary,
|
|
81
|
+
children: /*#__PURE__*/_jsx(Text, {
|
|
82
|
+
style: styles.secondaryText,
|
|
83
|
+
children: "Cancel"
|
|
84
|
+
})
|
|
85
|
+
}), /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
86
|
+
testID: "time-machine-bar-name-capture",
|
|
87
|
+
accessibilityRole: "button",
|
|
88
|
+
accessibilityLabel: "Capture and arm this restore point",
|
|
89
|
+
onPress: submit,
|
|
90
|
+
style: styles.primary,
|
|
91
|
+
children: /*#__PURE__*/_jsx(Text, {
|
|
92
|
+
style: styles.primaryText,
|
|
93
|
+
children: "Capture"
|
|
94
|
+
})
|
|
95
|
+
})]
|
|
96
|
+
})]
|
|
97
|
+
})
|
|
98
|
+
})
|
|
99
|
+
})
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
const styles = StyleSheet.create({
|
|
103
|
+
fill: {
|
|
104
|
+
flex: 1
|
|
105
|
+
},
|
|
106
|
+
backdrop: {
|
|
107
|
+
flex: 1,
|
|
108
|
+
backgroundColor: "rgba(0, 0, 0, 0.55)",
|
|
109
|
+
alignItems: "center",
|
|
110
|
+
justifyContent: "center",
|
|
111
|
+
padding: 24
|
|
112
|
+
},
|
|
113
|
+
card: {
|
|
114
|
+
width: "100%",
|
|
115
|
+
maxWidth: 360,
|
|
116
|
+
borderRadius: night.radius.sheet,
|
|
117
|
+
borderWidth: 1,
|
|
118
|
+
borderColor: night.color.separator,
|
|
119
|
+
backgroundColor: night.color.surface,
|
|
120
|
+
padding: 18,
|
|
121
|
+
gap: 12,
|
|
122
|
+
shadowColor: "#000",
|
|
123
|
+
shadowOffset: {
|
|
124
|
+
width: 0,
|
|
125
|
+
height: 12
|
|
126
|
+
},
|
|
127
|
+
shadowOpacity: 0.4,
|
|
128
|
+
shadowRadius: 24,
|
|
129
|
+
elevation: 12
|
|
130
|
+
},
|
|
131
|
+
title: {
|
|
132
|
+
color: night.color.text,
|
|
133
|
+
fontSize: night.font.title,
|
|
134
|
+
fontWeight: "600"
|
|
135
|
+
},
|
|
136
|
+
input: {
|
|
137
|
+
minHeight: 44,
|
|
138
|
+
borderRadius: night.radius.input,
|
|
139
|
+
borderWidth: 1,
|
|
140
|
+
borderColor: night.color.accentBorder,
|
|
141
|
+
backgroundColor: night.color.surfaceElevated,
|
|
142
|
+
color: night.color.text,
|
|
143
|
+
fontSize: night.font.row,
|
|
144
|
+
paddingHorizontal: 12
|
|
145
|
+
},
|
|
146
|
+
summary: {
|
|
147
|
+
color: night.color.textTertiary,
|
|
148
|
+
fontSize: night.font.caption,
|
|
149
|
+
marginTop: -6
|
|
150
|
+
},
|
|
151
|
+
hint: {
|
|
152
|
+
color: night.color.textSecondary,
|
|
153
|
+
fontSize: night.font.caption,
|
|
154
|
+
lineHeight: 18
|
|
155
|
+
},
|
|
156
|
+
actions: {
|
|
157
|
+
flexDirection: "row",
|
|
158
|
+
justifyContent: "flex-end",
|
|
159
|
+
gap: 10,
|
|
160
|
+
marginTop: 4
|
|
161
|
+
},
|
|
162
|
+
secondary: {
|
|
163
|
+
minHeight: 40,
|
|
164
|
+
paddingHorizontal: 14,
|
|
165
|
+
borderRadius: night.radius.input,
|
|
166
|
+
alignItems: "center",
|
|
167
|
+
justifyContent: "center"
|
|
168
|
+
},
|
|
169
|
+
secondaryText: {
|
|
170
|
+
color: night.color.textSecondary,
|
|
171
|
+
fontSize: 14,
|
|
172
|
+
fontWeight: "600"
|
|
173
|
+
},
|
|
174
|
+
primary: {
|
|
175
|
+
minHeight: 40,
|
|
176
|
+
paddingHorizontal: 18,
|
|
177
|
+
borderRadius: night.radius.input,
|
|
178
|
+
backgroundColor: night.color.accent,
|
|
179
|
+
alignItems: "center",
|
|
180
|
+
justifyContent: "center"
|
|
181
|
+
},
|
|
182
|
+
primaryText: {
|
|
183
|
+
color: night.color.onAccent,
|
|
184
|
+
fontSize: 14,
|
|
185
|
+
fontWeight: "700"
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
//# sourceMappingURL=NamePromptModal.js.map
|