@buoy-gg/time-machine 7.0.40 → 7.0.42

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.
Files changed (173) hide show
  1. package/README.md +4 -0
  2. package/lib/commonjs/components/HeaderActions.js +1 -91
  3. package/lib/commonjs/components/HeaderReloadButton.js +1 -58
  4. package/lib/commonjs/components/TimeMachineBody.js +1 -282
  5. package/lib/commonjs/components/TimeMachineModal.js +1 -74
  6. package/lib/commonjs/components/confirm.js +2 -38
  7. package/lib/commonjs/components/floating/NamePromptModal.js +1 -193
  8. package/lib/commonjs/components/floating/TimeMachineFloatingTool.js +1 -715
  9. package/lib/commonjs/components/floating/armedPoint.js +1 -92
  10. package/lib/commonjs/components/floating/barSettings.js +1 -66
  11. package/lib/commonjs/components/format.js +1 -24
  12. package/lib/commonjs/components/list/CaptureBar.js +1 -97
  13. package/lib/commonjs/components/list/RestoreOutcomeCard.js +1 -175
  14. package/lib/commonjs/components/list/SnapshotRow.js +1 -170
  15. package/lib/commonjs/components/list/SourcesStrip.js +1 -172
  16. package/lib/commonjs/components/list/UndoDeleteBar.js +1 -85
  17. package/lib/commonjs/components/list/WipeAllRow.js +1 -46
  18. package/lib/commonjs/components/preview/ItemDiffPanel.js +1 -79
  19. package/lib/commonjs/components/preview/PreviewFlow.js +1 -51
  20. package/lib/commonjs/components/preview/RestorePointNameRow.js +1 -83
  21. package/lib/commonjs/components/preview/RestorePreviewScreen.js +1 -1010
  22. package/lib/commonjs/components/preview/verdictMeta.js +1 -58
  23. package/lib/commonjs/components/sources.js +1 -83
  24. package/lib/commonjs/hooks/useTimeMachine.js +1 -24
  25. package/lib/commonjs/index.js +1 -161
  26. package/lib/commonjs/preset.js +1 -56
  27. package/lib/commonjs/store/routeRestore.js +1 -188
  28. package/lib/commonjs/store/snapshotVault.js +1 -186
  29. package/lib/commonjs/store/sourceIds.js +1 -9
  30. package/lib/commonjs/store/sourceSettings.js +1 -79
  31. package/lib/commonjs/store/timeMachineStore.js +1 -848
  32. package/lib/commonjs/sync/timeMachineSyncAdapter.js +1 -258
  33. package/lib/commonjs/ui/SwipeActionsRow.js +1 -178
  34. package/lib/commonjs/ui/primitives.js +1 -172
  35. package/lib/commonjs/ui/tmTheme.js +1 -118
  36. package/lib/module/components/HeaderActions.js +1 -85
  37. package/lib/module/components/HeaderReloadButton.js +1 -53
  38. package/lib/module/components/TimeMachineBody.js +1 -277
  39. package/lib/module/components/TimeMachineModal.js +1 -68
  40. package/lib/module/components/confirm.js +2 -33
  41. package/lib/module/components/floating/NamePromptModal.js +1 -188
  42. package/lib/module/components/floating/TimeMachineFloatingTool.js +1 -708
  43. package/lib/module/components/floating/armedPoint.js +1 -82
  44. package/lib/module/components/floating/barSettings.js +1 -57
  45. package/lib/module/components/format.js +1 -19
  46. package/lib/module/components/list/CaptureBar.js +1 -92
  47. package/lib/module/components/list/RestoreOutcomeCard.js +1 -169
  48. package/lib/module/components/list/SnapshotRow.js +1 -167
  49. package/lib/module/components/list/SourcesStrip.js +1 -169
  50. package/lib/module/components/list/UndoDeleteBar.js +1 -82
  51. package/lib/module/components/list/WipeAllRow.js +1 -41
  52. package/lib/module/components/preview/ItemDiffPanel.js +1 -74
  53. package/lib/module/components/preview/PreviewFlow.js +1 -46
  54. package/lib/module/components/preview/RestorePointNameRow.js +1 -78
  55. package/lib/module/components/preview/RestorePreviewScreen.js +1 -1005
  56. package/lib/module/components/preview/verdictMeta.js +1 -54
  57. package/lib/module/components/sources.js +1 -73
  58. package/lib/module/hooks/useTimeMachine.js +1 -19
  59. package/lib/module/index.js +1 -46
  60. package/lib/module/preset.js +1 -51
  61. package/lib/module/store/routeRestore.js +1 -176
  62. package/lib/module/store/snapshotVault.js +1 -170
  63. package/lib/module/store/sourceIds.js +1 -5
  64. package/lib/module/store/sourceSettings.js +1 -69
  65. package/lib/module/store/timeMachineStore.js +1 -839
  66. package/lib/module/sync/timeMachineSyncAdapter.js +1 -253
  67. package/lib/module/ui/SwipeActionsRow.js +1 -173
  68. package/lib/module/ui/primitives.js +1 -164
  69. package/lib/module/ui/tmTheme.js +1 -114
  70. package/lib/web/index.mjs +3 -0
  71. package/package.json +43 -10
  72. package/lib/commonjs/components/HeaderActions.js.map +0 -1
  73. package/lib/commonjs/components/HeaderReloadButton.js.map +0 -1
  74. package/lib/commonjs/components/TimeMachineBody.js.map +0 -1
  75. package/lib/commonjs/components/TimeMachineModal.js.map +0 -1
  76. package/lib/commonjs/components/confirm.js.map +0 -1
  77. package/lib/commonjs/components/floating/NamePromptModal.js.map +0 -1
  78. package/lib/commonjs/components/floating/TimeMachineFloatingTool.js.map +0 -1
  79. package/lib/commonjs/components/floating/armedPoint.js.map +0 -1
  80. package/lib/commonjs/components/floating/barSettings.js.map +0 -1
  81. package/lib/commonjs/components/format.js.map +0 -1
  82. package/lib/commonjs/components/list/CaptureBar.js.map +0 -1
  83. package/lib/commonjs/components/list/RestoreOutcomeCard.js.map +0 -1
  84. package/lib/commonjs/components/list/SnapshotRow.js.map +0 -1
  85. package/lib/commonjs/components/list/SourcesStrip.js.map +0 -1
  86. package/lib/commonjs/components/list/UndoDeleteBar.js.map +0 -1
  87. package/lib/commonjs/components/list/WipeAllRow.js.map +0 -1
  88. package/lib/commonjs/components/preview/ItemDiffPanel.js.map +0 -1
  89. package/lib/commonjs/components/preview/PreviewFlow.js.map +0 -1
  90. package/lib/commonjs/components/preview/RestorePointNameRow.js.map +0 -1
  91. package/lib/commonjs/components/preview/RestorePreviewScreen.js.map +0 -1
  92. package/lib/commonjs/components/preview/verdictMeta.js.map +0 -1
  93. package/lib/commonjs/components/sources.js.map +0 -1
  94. package/lib/commonjs/hooks/useTimeMachine.js.map +0 -1
  95. package/lib/commonjs/index.js.map +0 -1
  96. package/lib/commonjs/preset.js.map +0 -1
  97. package/lib/commonjs/store/routeRestore.js.map +0 -1
  98. package/lib/commonjs/store/snapshotVault.js.map +0 -1
  99. package/lib/commonjs/store/sourceIds.js.map +0 -1
  100. package/lib/commonjs/store/sourceSettings.js.map +0 -1
  101. package/lib/commonjs/store/timeMachineStore.js.map +0 -1
  102. package/lib/commonjs/sync/timeMachineSyncAdapter.js.map +0 -1
  103. package/lib/commonjs/ui/SwipeActionsRow.js.map +0 -1
  104. package/lib/commonjs/ui/primitives.js.map +0 -1
  105. package/lib/commonjs/ui/tmTheme.js.map +0 -1
  106. package/lib/module/components/HeaderActions.js.map +0 -1
  107. package/lib/module/components/HeaderReloadButton.js.map +0 -1
  108. package/lib/module/components/TimeMachineBody.js.map +0 -1
  109. package/lib/module/components/TimeMachineModal.js.map +0 -1
  110. package/lib/module/components/confirm.js.map +0 -1
  111. package/lib/module/components/floating/NamePromptModal.js.map +0 -1
  112. package/lib/module/components/floating/TimeMachineFloatingTool.js.map +0 -1
  113. package/lib/module/components/floating/armedPoint.js.map +0 -1
  114. package/lib/module/components/floating/barSettings.js.map +0 -1
  115. package/lib/module/components/format.js.map +0 -1
  116. package/lib/module/components/list/CaptureBar.js.map +0 -1
  117. package/lib/module/components/list/RestoreOutcomeCard.js.map +0 -1
  118. package/lib/module/components/list/SnapshotRow.js.map +0 -1
  119. package/lib/module/components/list/SourcesStrip.js.map +0 -1
  120. package/lib/module/components/list/UndoDeleteBar.js.map +0 -1
  121. package/lib/module/components/list/WipeAllRow.js.map +0 -1
  122. package/lib/module/components/preview/ItemDiffPanel.js.map +0 -1
  123. package/lib/module/components/preview/PreviewFlow.js.map +0 -1
  124. package/lib/module/components/preview/RestorePointNameRow.js.map +0 -1
  125. package/lib/module/components/preview/RestorePreviewScreen.js.map +0 -1
  126. package/lib/module/components/preview/verdictMeta.js.map +0 -1
  127. package/lib/module/components/sources.js.map +0 -1
  128. package/lib/module/hooks/useTimeMachine.js.map +0 -1
  129. package/lib/module/index.js.map +0 -1
  130. package/lib/module/preset.js.map +0 -1
  131. package/lib/module/store/routeRestore.js.map +0 -1
  132. package/lib/module/store/snapshotVault.js.map +0 -1
  133. package/lib/module/store/sourceIds.js.map +0 -1
  134. package/lib/module/store/sourceSettings.js.map +0 -1
  135. package/lib/module/store/timeMachineStore.js.map +0 -1
  136. package/lib/module/sync/timeMachineSyncAdapter.js.map +0 -1
  137. package/lib/module/ui/SwipeActionsRow.js.map +0 -1
  138. package/lib/module/ui/primitives.js.map +0 -1
  139. package/lib/module/ui/tmTheme.js.map +0 -1
  140. package/lib/typescript/components/HeaderActions.d.ts.map +0 -1
  141. package/lib/typescript/components/HeaderReloadButton.d.ts.map +0 -1
  142. package/lib/typescript/components/TimeMachineBody.d.ts.map +0 -1
  143. package/lib/typescript/components/TimeMachineModal.d.ts.map +0 -1
  144. package/lib/typescript/components/confirm.d.ts.map +0 -1
  145. package/lib/typescript/components/floating/NamePromptModal.d.ts.map +0 -1
  146. package/lib/typescript/components/floating/TimeMachineFloatingTool.d.ts.map +0 -1
  147. package/lib/typescript/components/floating/armedPoint.d.ts.map +0 -1
  148. package/lib/typescript/components/floating/barSettings.d.ts.map +0 -1
  149. package/lib/typescript/components/format.d.ts.map +0 -1
  150. package/lib/typescript/components/list/CaptureBar.d.ts.map +0 -1
  151. package/lib/typescript/components/list/RestoreOutcomeCard.d.ts.map +0 -1
  152. package/lib/typescript/components/list/SnapshotRow.d.ts.map +0 -1
  153. package/lib/typescript/components/list/SourcesStrip.d.ts.map +0 -1
  154. package/lib/typescript/components/list/UndoDeleteBar.d.ts.map +0 -1
  155. package/lib/typescript/components/list/WipeAllRow.d.ts.map +0 -1
  156. package/lib/typescript/components/preview/ItemDiffPanel.d.ts.map +0 -1
  157. package/lib/typescript/components/preview/PreviewFlow.d.ts.map +0 -1
  158. package/lib/typescript/components/preview/RestorePointNameRow.d.ts.map +0 -1
  159. package/lib/typescript/components/preview/RestorePreviewScreen.d.ts.map +0 -1
  160. package/lib/typescript/components/preview/verdictMeta.d.ts.map +0 -1
  161. package/lib/typescript/components/sources.d.ts.map +0 -1
  162. package/lib/typescript/hooks/useTimeMachine.d.ts.map +0 -1
  163. package/lib/typescript/index.d.ts.map +0 -1
  164. package/lib/typescript/preset.d.ts.map +0 -1
  165. package/lib/typescript/store/routeRestore.d.ts.map +0 -1
  166. package/lib/typescript/store/snapshotVault.d.ts.map +0 -1
  167. package/lib/typescript/store/sourceIds.d.ts.map +0 -1
  168. package/lib/typescript/store/sourceSettings.d.ts.map +0 -1
  169. package/lib/typescript/store/timeMachineStore.d.ts.map +0 -1
  170. package/lib/typescript/sync/timeMachineSyncAdapter.d.ts.map +0 -1
  171. package/lib/typescript/ui/SwipeActionsRow.d.ts.map +0 -1
  172. package/lib/typescript/ui/primitives.d.ts.map +0 -1
  173. package/lib/typescript/ui/tmTheme.d.ts.map +0 -1
@@ -1,92 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.ensurePickedPointLoaded = ensurePickedPointLoaded;
7
- exports.getPickedPointId = getPickedPointId;
8
- exports.resetPickedPointForTests = resetPickedPointForTests;
9
- exports.resolveArmedPoint = resolveArmedPoint;
10
- exports.setPickedPointId = setPickedPointId;
11
- exports.subscribePickedPoint = subscribePickedPoint;
12
- var _sharedUi = require("@buoy-gg/shared-ui");
13
- /**
14
- * Which restore point the floating restore bar restores on tap.
15
- *
16
- * The bar needs an answer before the user picks anything, or its first tap is
17
- * a picker instead of a restore. So the armed point is resolved, not just
18
- * stored: an explicit pick wins, then the point restored most recently, then
19
- * the newest capture. Baselines never resolve; restoring one wipes storage
20
- * and reloads behind a confirm dialog, which is not a one-tap action. The
21
- * safety slot never resolves either: Undo is its way in.
22
- *
23
- * The explicit pick is persisted so it survives the reloads the loop itself
24
- * causes (RELOAD APP, reload-mode restores).
25
- */
26
-
27
- const KEY = _sharedUi.devToolsStorageKeys.timeMachine.armedPoint();
28
- let pickedId = null;
29
- let loaded = false;
30
- let loadPromise = null;
31
- const listeners = new Set();
32
- const notify = () => listeners.forEach(listener => listener());
33
- function getPickedPointId() {
34
- return pickedId;
35
- }
36
- function subscribePickedPoint(listener) {
37
- listeners.add(listener);
38
- return () => {
39
- listeners.delete(listener);
40
- };
41
- }
42
-
43
- /** Read the saved pick once. Later calls return the same promise. */
44
- function ensurePickedPointLoaded() {
45
- if (loaded) return Promise.resolve();
46
- if (!loadPromise) {
47
- loadPromise = _sharedUi.persistentStorage.getItem(KEY).then(saved => {
48
- // A pick made while the read was in flight wins over the disk copy.
49
- if (pickedId === null && saved) {
50
- pickedId = saved;
51
- notify();
52
- }
53
- }).catch(() => {}).finally(() => {
54
- loaded = true;
55
- });
56
- }
57
- return loadPromise;
58
- }
59
- function setPickedPointId(id) {
60
- if (pickedId === id) return;
61
- pickedId = id;
62
- notify();
63
- void (id === null ? _sharedUi.persistentStorage.removeItem(KEY) : _sharedUi.persistentStorage.setItem(KEY, id)).catch(() => {});
64
- }
65
-
66
- /** Test seam: forget the pick and the load, without touching storage. */
67
- function resetPickedPointForTests() {
68
- pickedId = null;
69
- loaded = false;
70
- loadPromise = null;
71
- }
72
-
73
- /**
74
- * The point the bar restores: the saved pick if it still exists, else the
75
- * most recently restored point, else the newest capture. Never a baseline.
76
- */
77
- function resolveArmedPoint(snapshots, pickedId) {
78
- const candidates = snapshots.filter(meta => !meta.baseline && !meta.safety);
79
- if (candidates.length === 0) return null;
80
- if (pickedId) {
81
- const picked = candidates.find(meta => meta.id === pickedId);
82
- if (picked) return picked;
83
- }
84
- let best = null;
85
- for (const meta of candidates) {
86
- if (meta.lastRestoredAt === undefined) continue;
87
- if (!best || meta.lastRestoredAt > (best.lastRestoredAt ?? 0)) best = meta;
88
- }
89
- if (best) return best;
90
- return candidates.reduce((newest, meta) => meta.createdAt > newest.createdAt ? meta : newest);
91
- }
92
- //# sourceMappingURL=armedPoint.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.ensurePickedPointLoaded=ensurePickedPointLoaded;exports.getPickedPointId=getPickedPointId;exports.resetPickedPointForTests=resetPickedPointForTests;exports.resolveArmedPoint=resolveArmedPoint;exports.setPickedPointId=setPickedPointId;exports.subscribePickedPoint=subscribePickedPoint;var _sharedUi=require("@buoy-gg/shared-ui");const KEY=_sharedUi.devToolsStorageKeys.timeMachine.armedPoint();let pickedId=null;let loaded=false;let loadPromise=null;const listeners=new Set;const notify=()=>listeners.forEach(e=>e());function getPickedPointId(){return pickedId}function subscribePickedPoint(e){listeners.add(e);return()=>{listeners.delete(e)}}function ensurePickedPointLoaded(){if(loaded)return Promise.resolve();if(!loadPromise){loadPromise=_sharedUi.persistentStorage.getItem(KEY).then(e=>{if(pickedId===null&&e){pickedId=e;notify()}}).catch(()=>{}).finally(()=>{loaded=true})}return loadPromise}function setPickedPointId(e){if(pickedId===e)return;pickedId=e;notify();void(e===null?_sharedUi.persistentStorage.removeItem(KEY):_sharedUi.persistentStorage.setItem(KEY,e)).catch(()=>{})}function resetPickedPointForTests(){pickedId=null;loaded=false;loadPromise=null}function resolveArmedPoint(e,i){const n=e.filter(t=>!t.baseline&&!t.safety);if(n.length===0)return null;if(i){const t=n.find(o=>o.id===i);if(t)return t}let r=null;for(const t of n){if(t.lastRestoredAt===void 0)continue;if(!r||t.lastRestoredAt>(r.lastRestoredAt??0))r=t}if(r)return r;return n.reduce((t,o)=>o.createdAt>t.createdAt?o:t)}
@@ -1,66 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.ensureBarSettingsLoaded = ensureBarSettingsLoaded;
7
- exports.getBarReloadMode = getBarReloadMode;
8
- exports.resetBarSettingsForTests = resetBarSettingsForTests;
9
- exports.setBarReloadMode = setBarReloadMode;
10
- exports.subscribeBarSettings = subscribeBarSettings;
11
- var _sharedUi = require("@buoy-gg/shared-ui");
12
- /**
13
- * The action bar's one setting: restore live, or restore and reload.
14
- *
15
- * Live restore replaces stores in place and is right for state that lives in
16
- * Redux, Zustand, Jotai or the query cache. It cannot reach a React context
17
- * or `useState` that hydrates itself from storage once at mount: the
18
- * storage key comes back, the screen keeps showing what it already had, and
19
- * "restore did nothing" is the report. A restore that reloads the app makes
20
- * those screens rebuild from the restored storage. Persisted, because the
21
- * reload itself is what brings the bar back.
22
- */
23
-
24
- const KEY = _sharedUi.devToolsStorageKeys.timeMachine.barReloadMode();
25
- let reloadMode = false;
26
- let loaded = false;
27
- let loadPromise = null;
28
- const listeners = new Set();
29
- const notify = () => listeners.forEach(listener => listener());
30
- function getBarReloadMode() {
31
- return reloadMode;
32
- }
33
- function subscribeBarSettings(listener) {
34
- listeners.add(listener);
35
- return () => {
36
- listeners.delete(listener);
37
- };
38
- }
39
- function ensureBarSettingsLoaded() {
40
- if (loaded) return Promise.resolve();
41
- if (!loadPromise) {
42
- loadPromise = _sharedUi.persistentStorage.getItem(KEY).then(saved => {
43
- if (!reloadMode && saved === "1") {
44
- reloadMode = true;
45
- notify();
46
- }
47
- }).catch(() => {}).finally(() => {
48
- loaded = true;
49
- });
50
- }
51
- return loadPromise;
52
- }
53
- function setBarReloadMode(on) {
54
- if (on === reloadMode) return;
55
- reloadMode = on;
56
- notify();
57
- void _sharedUi.persistentStorage.setItem(KEY, on ? "1" : "0").catch(() => {});
58
- }
59
-
60
- /** Test seam. */
61
- function resetBarSettingsForTests() {
62
- reloadMode = false;
63
- loaded = false;
64
- loadPromise = null;
65
- }
66
- //# sourceMappingURL=barSettings.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.ensureBarSettingsLoaded=ensureBarSettingsLoaded;exports.getBarReloadMode=getBarReloadMode;exports.resetBarSettingsForTests=resetBarSettingsForTests;exports.setBarReloadMode=setBarReloadMode;exports.subscribeBarSettings=subscribeBarSettings;var _sharedUi=require("@buoy-gg/shared-ui");const KEY=_sharedUi.devToolsStorageKeys.timeMachine.barReloadMode();let reloadMode=false;let loaded=false;let loadPromise=null;const listeners=new Set;const notify=()=>listeners.forEach(e=>e());function getBarReloadMode(){return reloadMode}function subscribeBarSettings(e){listeners.add(e);return()=>{listeners.delete(e)}}function ensureBarSettingsLoaded(){if(loaded)return Promise.resolve();if(!loadPromise){loadPromise=_sharedUi.persistentStorage.getItem(KEY).then(e=>{if(!reloadMode&&e==="1"){reloadMode=true;notify()}}).catch(()=>{}).finally(()=>{loaded=true})}return loadPromise}function setBarReloadMode(e){if(e===reloadMode)return;reloadMode=e;notify();void _sharedUi.persistentStorage.setItem(KEY,e?"1":"0").catch(()=>{})}function resetBarSettingsForTests(){reloadMode=false;loaded=false;loadPromise=null}
@@ -1,24 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.formatBytes = formatBytes;
7
- exports.timeAgo = timeAgo;
8
- /** Display formatting shared by the Time Machine screens. */
9
-
10
- function timeAgo(ts) {
11
- const s = Math.max(0, Math.round((Date.now() - ts) / 1000));
12
- if (s < 60) return `${s}s ago`;
13
- const m = Math.round(s / 60);
14
- if (m < 60) return `${m}m ago`;
15
- const h = Math.round(m / 60);
16
- if (h < 24) return `${h}h ago`;
17
- return `${Math.round(h / 24)}d ago`;
18
- }
19
- function formatBytes(bytes) {
20
- if (bytes < 1024) return `${bytes} B`;
21
- if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
22
- return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
23
- }
24
- //# sourceMappingURL=format.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.formatBytes=formatBytes;exports.timeAgo=timeAgo;function timeAgo(t){const r=Math.max(0,Math.round((Date.now()-t)/1e3));if(r<60)return`${r}s ago`;const o=Math.round(r/60);if(o<60)return`${o}m ago`;const e=Math.round(o/60);if(e<24)return`${e}h ago`;return`${Math.round(e/24)}d ago`}function formatBytes(t){if(t<1024)return`${t} B`;if(t<1024*1024)return`${(t/1024).toFixed(1)} KB`;return`${(t/(1024*1024)).toFixed(1)} MB`}
@@ -1,97 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.CaptureBar = CaptureBar;
7
- var _react = require("react");
8
- var _reactNative = require("react-native");
9
- var _tmTheme = require("../../ui/tmTheme");
10
- var _jsxRuntime = require("react/jsx-runtime");
11
- /**
12
- * Capture bar — the single field-plus-pill control at the top of the list.
13
- *
14
- * Owns the draft name itself so keystrokes re-render this component and not
15
- * the snapshot list underneath it. The parent only hears about a finished
16
- * capture.
17
- */
18
-
19
- function CaptureBar({
20
- disabled,
21
- busy,
22
- onCapture
23
- }) {
24
- const [name, setName] = (0, _react.useState)("");
25
- const capture = () => {
26
- if (disabled) return;
27
- onCapture(name);
28
- setName("");
29
- };
30
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
31
- style: styles.bar,
32
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TextInput, {
33
- style: styles.input,
34
- value: name,
35
- onChangeText: setName,
36
- placeholder: "Name this restore point\u2026",
37
- placeholderTextColor: _tmTheme.tm.color.labelTertiary,
38
- editable: !disabled,
39
- onSubmitEditing: capture,
40
- returnKeyType: "done",
41
- testID: "time-machine-name-input"
42
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
43
- style: [styles.button, disabled ? styles.buttonDisabled : null],
44
- onPress: capture,
45
- disabled: disabled,
46
- accessibilityRole: "button",
47
- accessibilityLabel: "Capture restore point",
48
- testID: "time-machine-capture",
49
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
50
- style: styles.buttonText,
51
- children: busy ? "Capturing…" : "Capture"
52
- })
53
- })]
54
- });
55
- }
56
- const styles = _reactNative.StyleSheet.create({
57
- bar: {
58
- flexDirection: "row",
59
- alignItems: "center",
60
- gap: 8,
61
- marginHorizontal: _tmTheme.tm.gutter,
62
- backgroundColor: _tmTheme.tm.color.group,
63
- borderRadius: _tmTheme.tm.radius.group,
64
- borderWidth: 1,
65
- borderColor: _tmTheme.tm.color.groupBorder,
66
- paddingLeft: _tmTheme.tm.textInset,
67
- padding: 6
68
- },
69
- input: {
70
- flex: 1,
71
- minWidth: 0,
72
- color: _tmTheme.tm.color.label,
73
- fontSize: _tmTheme.tm.font.row,
74
- letterSpacing: _tmTheme.tm.tracking.row,
75
- // Zero out the platform chrome so the field reads as part of the card.
76
- padding: 0,
77
- backgroundColor: "transparent"
78
- },
79
- button: {
80
- height: 34,
81
- paddingHorizontal: 16,
82
- borderRadius: _tmTheme.tm.radius.pill,
83
- backgroundColor: _tmTheme.tm.color.accent,
84
- alignItems: "center",
85
- justifyContent: "center"
86
- },
87
- buttonDisabled: {
88
- opacity: 0.4
89
- },
90
- buttonText: {
91
- color: _tmTheme.tm.color.onAccent,
92
- fontSize: _tmTheme.tm.font.control,
93
- fontWeight: "600",
94
- letterSpacing: _tmTheme.tm.tracking.control
95
- }
96
- });
97
- //# sourceMappingURL=CaptureBar.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.CaptureBar=CaptureBar;var _react=require("react");var _reactNative=require("react-native");var _tmTheme=require("../../ui/tmTheme");var _jsxRuntime=require("react/jsx-runtime");function CaptureBar({disabled:t,busy:n,onCapture:a}){const[e,r]=(0,_react.useState)("");const o=()=>{if(t)return;a(e);r("")};return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.bar,children:[(0,_jsxRuntime.jsx)(_reactNative.TextInput,{style:styles.input,value:e,onChangeText:r,placeholder:"Name this restore point\u2026",placeholderTextColor:_tmTheme.tm.color.labelTertiary,editable:!t,onSubmitEditing:o,returnKeyType:"done",testID:"time-machine-name-input"}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{style:[styles.button,t?styles.buttonDisabled:null],onPress:o,disabled:t,accessibilityRole:"button",accessibilityLabel:"Capture restore point",testID:"time-machine-capture",children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.buttonText,children:n?"Capturing\u2026":"Capture"})})]})}const styles=_reactNative.StyleSheet.create({bar:{flexDirection:"row",alignItems:"center",gap:8,marginHorizontal:_tmTheme.tm.gutter,backgroundColor:_tmTheme.tm.color.group,borderRadius:_tmTheme.tm.radius.group,borderWidth:1,borderColor:_tmTheme.tm.color.groupBorder,paddingLeft:_tmTheme.tm.textInset,padding:6},input:{flex:1,minWidth:0,color:_tmTheme.tm.color.label,fontSize:_tmTheme.tm.font.row,letterSpacing:_tmTheme.tm.tracking.row,padding:0,backgroundColor:"transparent"},button:{height:34,paddingHorizontal:16,borderRadius:_tmTheme.tm.radius.pill,backgroundColor:_tmTheme.tm.color.accent,alignItems:"center",justifyContent:"center"},buttonDisabled:{opacity:.4},buttonText:{color:_tmTheme.tm.color.onAccent,fontSize:_tmTheme.tm.font.control,fontWeight:"600",letterSpacing:_tmTheme.tm.tracking.control}});
@@ -1,175 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.RestoreOutcomeCard = RestoreOutcomeCard;
7
- exports.restoreNeedsAttention = restoreNeedsAttention;
8
- var _reactNative = require("react-native");
9
- var _sharedUi = require("@buoy-gg/shared-ui");
10
- var _tmTheme = require("../../ui/tmTheme");
11
- var _timeMachineStore = require("../../store/timeMachineStore");
12
- var _jsxRuntime = require("react/jsx-runtime");
13
- /**
14
- * What the last restore did, shown ONLY when something went wrong.
15
- *
16
- * A clean restore says so with a toast and then gets out of the way — the
17
- * restored app is the proof, and a wall of green ticks on top of the list
18
- * every single time was noise. A restore that skipped or failed a source is
19
- * the opposite: nothing else on screen would ever tell you, so it stays until
20
- * dismissed.
21
- */
22
-
23
- const HIT = {
24
- top: 10,
25
- bottom: 10,
26
- left: 10,
27
- right: 10
28
- };
29
-
30
- /**
31
- * Did this restore do anything the app itself won't show you? Warnings alone
32
- * don't count — "1 derived atom recomputes" is true of every restore and
33
- * would put the card back on screen permanently.
34
- */
35
- function restoreNeedsAttention(outcome) {
36
- if (Object.values(outcome.results).some(r => !r.ok || r.skipped.length > 0)) return true;
37
- const route = outcome.route;
38
- return route?.status === "failed" || route?.status === "unavailable";
39
- }
40
-
41
- /** ✓ / ✕ / ↻ line — the glyph carries the meaning, the color reinforces it. */
42
- function ResultLine({
43
- glyph,
44
- text,
45
- ok,
46
- testID
47
- }) {
48
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
49
- style: [styles.line, {
50
- color: ok ? _tmTheme.tm.color.accent : _tmTheme.tm.color.warning
51
- }],
52
- numberOfLines: 2,
53
- testID: testID,
54
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
55
- style: styles.glyph,
56
- children: [glyph, " "]
57
- }), text]
58
- });
59
- }
60
- const ROUTE_TEST_ID = "time-machine-outcome-route";
61
- function RouteResult({
62
- route
63
- }) {
64
- if (route.status === "navigated") return /*#__PURE__*/(0, _jsxRuntime.jsx)(ResultLine, {
65
- glyph: "\u2713",
66
- ok: true,
67
- text: `route — ${route.href}`,
68
- testID: ROUTE_TEST_ID
69
- });
70
- if (route.status === "deferred") return /*#__PURE__*/(0, _jsxRuntime.jsx)(ResultLine, {
71
- glyph: "\u21BB",
72
- ok: true,
73
- text: `route — ${route.href} after reload`,
74
- testID: ROUTE_TEST_ID
75
- });
76
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(ResultLine, {
77
- glyph: "\u2715",
78
- ok: false,
79
- text: `route — ${route.error ?? route.status}`,
80
- testID: ROUTE_TEST_ID
81
- });
82
- }
83
- function RestoreOutcomeCard({
84
- outcome
85
- }) {
86
- const entries = Object.entries(outcome.results);
87
- const reloading = outcome.mode === "reload" || outcome.willReload;
88
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
89
- style: styles.card,
90
- testID: "time-machine-outcome",
91
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
92
- style: styles.headerRow,
93
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
94
- style: styles.title,
95
- numberOfLines: 1,
96
- testID: "time-machine-outcome-title",
97
- children: ["Restored \u201C", outcome.snapshotName, "\u201D", reloading ? " · reloading" : ""]
98
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
99
- onPress: () => _timeMachineStore.timeMachineStore.clearLastOutcome(),
100
- hitSlop: HIT,
101
- accessibilityRole: "button",
102
- accessibilityLabel: "Dismiss restore result",
103
- testID: "time-machine-outcome-dismiss",
104
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.X, {
105
- size: 13,
106
- color: _tmTheme.tm.color.labelSecondary
107
- })
108
- })]
109
- }), entries.length === 0 && !outcome.route ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
110
- style: styles.empty,
111
- testID: "time-machine-outcome-empty",
112
- children: "No sources restored."
113
- }) : null, outcome.route ? /*#__PURE__*/(0, _jsxRuntime.jsx)(RouteResult, {
114
- route: outcome.route
115
- }) : null, entries.map(([sourceId, result]) => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
116
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(ResultLine, {
117
- testID: `time-machine-outcome-${sourceId}`,
118
- glyph: result.ok ? "✓" : "✕",
119
- ok: result.ok,
120
- text: `${sourceId} — applied ${result.applied}${result.skipped.length > 0 ? `, skipped ${result.skipped.length}` : ""}`
121
- }), result.skipped.slice(0, 3).map(skip => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
122
- style: styles.detail,
123
- numberOfLines: 2,
124
- children: [skip.id, ": ", skip.reason]
125
- }, skip.id)), result.warnings.slice(0, 3).map(warning => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
126
- style: styles.detail,
127
- numberOfLines: 2,
128
- children: ["\u26A0 ", warning]
129
- }, warning))]
130
- }, sourceId))]
131
- });
132
- }
133
- const styles = _reactNative.StyleSheet.create({
134
- card: {
135
- marginHorizontal: _tmTheme.tm.gutter,
136
- marginTop: 12,
137
- backgroundColor: _tmTheme.tm.color.group,
138
- borderRadius: _tmTheme.tm.radius.group,
139
- borderWidth: 1,
140
- borderColor: _tmTheme.tm.color.groupBorder,
141
- padding: 14,
142
- gap: 4
143
- },
144
- headerRow: {
145
- flexDirection: "row",
146
- alignItems: "center",
147
- gap: 10,
148
- marginBottom: 2
149
- },
150
- title: {
151
- flex: 1,
152
- color: _tmTheme.tm.color.label,
153
- fontSize: 15,
154
- fontWeight: "600",
155
- letterSpacing: _tmTheme.tm.tracking.control
156
- },
157
- line: {
158
- fontSize: _tmTheme.tm.font.footnote,
159
- lineHeight: _tmTheme.tm.font.footnote * 1.4
160
- },
161
- glyph: {
162
- fontWeight: "700"
163
- },
164
- detail: {
165
- color: _tmTheme.tm.color.labelTertiary,
166
- fontSize: _tmTheme.tm.font.mono,
167
- lineHeight: _tmTheme.tm.font.mono * 1.4,
168
- paddingLeft: 14
169
- },
170
- empty: {
171
- color: _tmTheme.tm.color.labelSecondary,
172
- fontSize: _tmTheme.tm.font.footnote
173
- }
174
- });
175
- //# sourceMappingURL=RestoreOutcomeCard.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.RestoreOutcomeCard=RestoreOutcomeCard;exports.restoreNeedsAttention=restoreNeedsAttention;var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _tmTheme=require("../../ui/tmTheme");var _timeMachineStore=require("../../store/timeMachineStore");var _jsxRuntime=require("react/jsx-runtime");const HIT={top:10,bottom:10,left:10,right:10};function restoreNeedsAttention(e){if(Object.values(e.results).some(o=>!o.ok||o.skipped.length>0))return true;const t=e.route;return t?.status==="failed"||t?.status==="unavailable"}function ResultLine({glyph:e,text:t,ok:o,testID:s}){return(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:[styles.line,{color:o?_tmTheme.tm.color.accent:_tmTheme.tm.color.warning}],numberOfLines:2,testID:s,children:[(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.glyph,children:[e," "]}),t]})}const ROUTE_TEST_ID="time-machine-outcome-route";function RouteResult({route:e}){if(e.status==="navigated")return(0,_jsxRuntime.jsx)(ResultLine,{glyph:"\u2713",ok:true,text:`route \u2014 ${e.href}`,testID:ROUTE_TEST_ID});if(e.status==="deferred")return(0,_jsxRuntime.jsx)(ResultLine,{glyph:"\u21BB",ok:true,text:`route \u2014 ${e.href} after reload`,testID:ROUTE_TEST_ID});return(0,_jsxRuntime.jsx)(ResultLine,{glyph:"\u2715",ok:false,text:`route \u2014 ${e.error??e.status}`,testID:ROUTE_TEST_ID})}function RestoreOutcomeCard({outcome:e}){const t=Object.entries(e.results);const o=e.mode==="reload"||e.willReload;return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.card,testID:"time-machine-outcome",children:[(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.headerRow,children:[(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.title,numberOfLines:1,testID:"time-machine-outcome-title",children:["Restored \u201C",e.snapshotName,"\u201D",o?" \xB7 reloading":""]}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{onPress:()=>_timeMachineStore.timeMachineStore.clearLastOutcome(),hitSlop:HIT,accessibilityRole:"button",accessibilityLabel:"Dismiss restore result",testID:"time-machine-outcome-dismiss",children:(0,_jsxRuntime.jsx)(_sharedUi.X,{size:13,color:_tmTheme.tm.color.labelSecondary})})]}),t.length===0&&!e.route?(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.empty,testID:"time-machine-outcome-empty",children:"No sources restored."}):null,e.route?(0,_jsxRuntime.jsx)(RouteResult,{route:e.route}):null,t.map(([s,r])=>(0,_jsxRuntime.jsxs)(_reactNative.View,{children:[(0,_jsxRuntime.jsx)(ResultLine,{testID:`time-machine-outcome-${s}`,glyph:r.ok?"\u2713":"\u2715",ok:r.ok,text:`${s} \u2014 applied ${r.applied}${r.skipped.length>0?`, skipped ${r.skipped.length}`:""}`}),r.skipped.slice(0,3).map(i=>(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.detail,numberOfLines:2,children:[i.id,": ",i.reason]},i.id)),r.warnings.slice(0,3).map(i=>(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.detail,numberOfLines:2,children:["\u26A0 ",i]},i))]},s))]})}const styles=_reactNative.StyleSheet.create({card:{marginHorizontal:_tmTheme.tm.gutter,marginTop:12,backgroundColor:_tmTheme.tm.color.group,borderRadius:_tmTheme.tm.radius.group,borderWidth:1,borderColor:_tmTheme.tm.color.groupBorder,padding:14,gap:4},headerRow:{flexDirection:"row",alignItems:"center",gap:10,marginBottom:2},title:{flex:1,color:_tmTheme.tm.color.label,fontSize:15,fontWeight:"600",letterSpacing:_tmTheme.tm.tracking.control},line:{fontSize:_tmTheme.tm.font.footnote,lineHeight:_tmTheme.tm.font.footnote*1.4},glyph:{fontWeight:"700"},detail:{color:_tmTheme.tm.color.labelTertiary,fontSize:_tmTheme.tm.font.mono,lineHeight:_tmTheme.tm.font.mono*1.4,paddingLeft:14},empty:{color:_tmTheme.tm.color.labelSecondary,fontSize:_tmTheme.tm.font.footnote}});
@@ -1,170 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.SnapshotRow = SnapshotRow;
7
- var _reactNative = require("react-native");
8
- var _primitives = require("../../ui/primitives");
9
- var _SwipeActionsRow = require("../../ui/SwipeActionsRow");
10
- var _tmTheme = require("../../ui/tmTheme");
11
- var _format = require("../format");
12
- var _jsxRuntime = require("react/jsx-runtime");
13
- /**
14
- * One restore point in the list: what it is, when it was taken, how big it
15
- * is, where it was captured — and the single action worth having at arm's
16
- * reach. Tapping the row opens the restore preview; the pill restores now.
17
- *
18
- * The route is shown as context — where this state was true. Whether a
19
- * restore also navigates there is decided in the restore preview, beside the
20
- * other changes it is about to make.
21
- *
22
- * Duplicate and delete live behind a swipe. A destructive target beside
23
- * "Restore" is a mis-tap that costs a snapshot, and the two-step gesture is
24
- * deliberate enough — recovery is the undo the list offers after, not a
25
- * dialog before. Renaming is NOT here: it belongs with the restore point's
26
- * other settings, on the preview screen.
27
- */
28
-
29
- /** "15h ago · 9.5 KB · 5 sources · skips 2" */function describe(meta) {
30
- if (meta.baseline) return "Wipes to fresh install";
31
- const parts = [(0, _format.timeAgo)(meta.createdAt), (0, _format.formatBytes)(meta.sizeBytes), `${Object.keys(meta.sources).length} sources`];
32
- // A saved selection is worth stating on the row — this restore point no
33
- // longer does the obvious thing, and one tap on RESTORE honors it.
34
- if (meta.excludedKeys?.length) parts.push(`skips ${meta.excludedKeys.length}`);else if (meta.scope?.length) parts.push(`scoped (${meta.scope.length})`);
35
- // The bar's own undo slot: kept for one restore, not a point you chose.
36
- if (meta.safety) parts.unshift("safety copy");
37
- return parts.join(" · ");
38
- }
39
- function SnapshotRow({
40
- meta,
41
- busy,
42
- armed = false,
43
- onOpen,
44
- onRestore,
45
- onDelete,
46
- onDuplicate,
47
- onArm
48
- }) {
49
- const testID = `time-machine-snap-${meta.id}`;
50
- return /*#__PURE__*/(0, _jsxRuntime.jsx)(_SwipeActionsRow.SwipeActionsRow, {
51
- testID: testID,
52
- actions: [
53
- // "Bar": put this point on the floating action bar.
54
- {
55
- label: "Bar",
56
- onPress: onArm
57
- },
58
- // "Dup" over "Copy": on a row full of text, "Copy" reads as
59
- // copy-to-clipboard.
60
- {
61
- label: "Dup",
62
- onPress: onDuplicate
63
- }, {
64
- label: "Delete",
65
- onPress: onDelete,
66
- background: _tmTheme.tm.color.danger,
67
- color: _tmTheme.tm.color.onDanger
68
- }],
69
- children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
70
- style: styles.row,
71
- children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
72
- style: styles.text,
73
- onPress: onOpen,
74
- activeOpacity: 0.7,
75
- accessibilityRole: "button",
76
- accessibilityLabel: `${meta.name}. ${describe(meta)}. Open restore preview`,
77
- testID: testID,
78
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
79
- style: styles.name,
80
- numberOfLines: 1,
81
- testID: `${testID}-name`,
82
- children: meta.name
83
- }), armed ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
84
- style: styles.armed,
85
- numberOfLines: 1,
86
- testID: `${testID}-armed`,
87
- children: "On the action bar"
88
- }) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
89
- style: styles.meta,
90
- numberOfLines: 1,
91
- testID: `${testID}-meta`,
92
- children: describe(meta)
93
- }), meta.lastRestoredAt ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
94
- style: styles.restored,
95
- numberOfLines: 1,
96
- testID: `${testID}-restored`,
97
- children: ["Restored ", (0, _format.timeAgo)(meta.lastRestoredAt)]
98
- }) : null, meta.route ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
99
- style: styles.route,
100
- numberOfLines: 1,
101
- testID: `${testID}-route`,
102
- children: meta.route.href
103
- }) : null]
104
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
105
- onPress: onRestore,
106
- disabled: busy,
107
- style: [styles.restore, busy ? styles.actionDisabled : null],
108
- accessibilityRole: "button",
109
- accessibilityLabel: meta.baseline ? "Wipe and reload" : "Restore",
110
- testID: `${testID}-restore`,
111
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_primitives.PillLabel, {
112
- testID: `${testID}-restore-label`,
113
- label: meta.baseline ? "Wipe" : "Restore",
114
- color: meta.baseline ? _tmTheme.tm.color.danger : _tmTheme.tm.color.accent,
115
- background: meta.baseline ? _tmTheme.tm.color.dangerSoft : _tmTheme.tm.color.accentSoft
116
- })
117
- })]
118
- })
119
- });
120
- }
121
- const styles = _reactNative.StyleSheet.create({
122
- row: {
123
- flexDirection: "row",
124
- alignItems: "center",
125
- gap: 10,
126
- paddingHorizontal: _tmTheme.tm.textInset
127
- },
128
- // The text block is the tallest child, so its padding sets the row height
129
- // and the open target spans the full row.
130
- text: {
131
- flex: 1,
132
- minWidth: 0,
133
- paddingVertical: 11
134
- },
135
- restore: {
136
- justifyContent: "center"
137
- },
138
- name: {
139
- color: _tmTheme.tm.color.label,
140
- fontSize: _tmTheme.tm.font.row,
141
- fontWeight: "600",
142
- letterSpacing: _tmTheme.tm.tracking.row
143
- },
144
- meta: {
145
- color: _tmTheme.tm.color.labelSecondary,
146
- fontSize: _tmTheme.tm.font.footnote,
147
- marginTop: 2,
148
- fontVariant: ["tabular-nums"]
149
- },
150
- restored: {
151
- color: _tmTheme.tm.color.accent,
152
- fontSize: _tmTheme.tm.font.footnote,
153
- marginTop: 2
154
- },
155
- armed: {
156
- color: _tmTheme.tm.color.accent,
157
- fontSize: _tmTheme.tm.font.footnote,
158
- marginTop: 2
159
- },
160
- route: {
161
- color: _tmTheme.tm.color.labelTertiary,
162
- fontFamily: _tmTheme.TM_MONO,
163
- fontSize: _tmTheme.tm.font.mono,
164
- marginTop: 4
165
- },
166
- actionDisabled: {
167
- opacity: 0.4
168
- }
169
- });
170
- //# sourceMappingURL=SnapshotRow.js.map
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.SnapshotRow=SnapshotRow;var _reactNative=require("react-native");var _primitives=require("../../ui/primitives");var _SwipeActionsRow=require("../../ui/SwipeActionsRow");var _tmTheme=require("../../ui/tmTheme");var _format=require("../format");var _jsxRuntime=require("react/jsx-runtime");function describe(e){if(e.baseline)return"Wipes to fresh install";const o=[(0,_format.timeAgo)(e.createdAt),(0,_format.formatBytes)(e.sizeBytes),`${Object.keys(e.sources).length} sources`];if(e.excludedKeys?.length)o.push(`skips ${e.excludedKeys.length}`);else if(e.scope?.length)o.push(`scoped (${e.scope.length})`);if(e.safety)o.unshift("safety copy");return o.join(" \xB7 ")}function SnapshotRow({meta:e,busy:o,armed:r=false,onOpen:s,onRestore:n,onDelete:i,onDuplicate:l,onArm:c}){const t=`time-machine-snap-${e.id}`;return(0,_jsxRuntime.jsx)(_SwipeActionsRow.SwipeActionsRow,{testID:t,actions:[{label:"Bar",onPress:c},{label:"Dup",onPress:l},{label:"Delete",onPress:i,background:_tmTheme.tm.color.danger,color:_tmTheme.tm.color.onDanger}],children:(0,_jsxRuntime.jsxs)(_reactNative.View,{style:styles.row,children:[(0,_jsxRuntime.jsxs)(_reactNative.TouchableOpacity,{style:styles.text,onPress:s,activeOpacity:.7,accessibilityRole:"button",accessibilityLabel:`${e.name}. ${describe(e)}. Open restore preview`,testID:t,children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.name,numberOfLines:1,testID:`${t}-name`,children:e.name}),r?(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.armed,numberOfLines:1,testID:`${t}-armed`,children:"On the action bar"}):null,(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.meta,numberOfLines:1,testID:`${t}-meta`,children:describe(e)}),e.lastRestoredAt?(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:styles.restored,numberOfLines:1,testID:`${t}-restored`,children:["Restored ",(0,_format.timeAgo)(e.lastRestoredAt)]}):null,e.route?(0,_jsxRuntime.jsx)(_reactNative.Text,{style:styles.route,numberOfLines:1,testID:`${t}-route`,children:e.route.href}):null]}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{onPress:n,disabled:o,style:[styles.restore,o?styles.actionDisabled:null],accessibilityRole:"button",accessibilityLabel:e.baseline?"Wipe and reload":"Restore",testID:`${t}-restore`,children:(0,_jsxRuntime.jsx)(_primitives.PillLabel,{testID:`${t}-restore-label`,label:e.baseline?"Wipe":"Restore",color:e.baseline?_tmTheme.tm.color.danger:_tmTheme.tm.color.accent,background:e.baseline?_tmTheme.tm.color.dangerSoft:_tmTheme.tm.color.accentSoft})})]})})}const styles=_reactNative.StyleSheet.create({row:{flexDirection:"row",alignItems:"center",gap:10,paddingHorizontal:_tmTheme.tm.textInset},text:{flex:1,minWidth:0,paddingVertical:11},restore:{justifyContent:"center"},name:{color:_tmTheme.tm.color.label,fontSize:_tmTheme.tm.font.row,fontWeight:"600",letterSpacing:_tmTheme.tm.tracking.row},meta:{color:_tmTheme.tm.color.labelSecondary,fontSize:_tmTheme.tm.font.footnote,marginTop:2,fontVariant:["tabular-nums"]},restored:{color:_tmTheme.tm.color.accent,fontSize:_tmTheme.tm.font.footnote,marginTop:2},armed:{color:_tmTheme.tm.color.accent,fontSize:_tmTheme.tm.font.footnote,marginTop:2},route:{color:_tmTheme.tm.color.labelTertiary,fontFamily:_tmTheme.TM_MONO,fontSize:_tmTheme.tm.font.mono,marginTop:4},actionDisabled:{opacity:.4}});