@tastic/hud 0.21.0 → 0.23.0
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 +36 -15
- package/dist/chrome/index.d.mts +99 -18
- package/dist/chrome/index.d.ts +99 -18
- package/dist/chrome/index.js +363 -63
- package/dist/chrome/index.mjs +19 -3
- package/dist/{chunk-UOA35OWJ.mjs → chunk-BXG44LIA.mjs} +333 -45
- package/dist/index.d.mts +12 -81
- package/dist/index.d.ts +12 -81
- package/dist/index.js +88 -72
- package/dist/index.mjs +105 -365
- package/package.json +3 -2
- package/src/AchievementCatalogSection.tsx +7 -6
- package/src/AchievementRow.tsx +13 -13
- package/src/ActivityStatSection.tsx +10 -5
- package/src/BaseSettingsDialog.tsx +13 -13
- package/src/StatRow.tsx +10 -11
- package/src/StatSection.tsx +14 -14
- package/src/chrome/index.ts +13 -4
- package/src/index.ts +1 -0
- package/src/wellSurface.ts +30 -0
package/dist/chrome/index.mjs
CHANGED
|
@@ -7,16 +7,24 @@ import {
|
|
|
7
7
|
ConfirmDialog,
|
|
8
8
|
ContentGutter,
|
|
9
9
|
CornerActionButtons,
|
|
10
|
+
InlineColorPicker,
|
|
10
11
|
LOCKED_BADGE_COLOR,
|
|
11
12
|
MONO_FONT,
|
|
13
|
+
PopoverBody,
|
|
14
|
+
PressAwayOverlay,
|
|
12
15
|
RotatedFrame,
|
|
13
16
|
StaggeredWord,
|
|
14
17
|
StatRow,
|
|
15
18
|
StatSection,
|
|
16
19
|
UpdateDialog,
|
|
20
|
+
WELL_SHADOW,
|
|
21
|
+
getInlineColorPickerContentSize,
|
|
17
22
|
getStaggeredWordDuration,
|
|
18
|
-
|
|
19
|
-
|
|
23
|
+
useAutoAlign,
|
|
24
|
+
useCompactDialog,
|
|
25
|
+
usePopoverHost,
|
|
26
|
+
useWellColors
|
|
27
|
+
} from "../chunk-BXG44LIA.mjs";
|
|
20
28
|
import {
|
|
21
29
|
COMPACT_DIALOG_HEIGHT,
|
|
22
30
|
DialogHeader,
|
|
@@ -38,19 +46,27 @@ export {
|
|
|
38
46
|
ContentGutter,
|
|
39
47
|
CornerActionButtons,
|
|
40
48
|
DialogHeader,
|
|
49
|
+
InlineColorPicker,
|
|
41
50
|
LOCKED_BADGE_COLOR,
|
|
42
51
|
MONO_FONT,
|
|
43
52
|
OverlayBackdrop,
|
|
44
53
|
OverlayCard,
|
|
54
|
+
PopoverBody,
|
|
55
|
+
PressAwayOverlay,
|
|
45
56
|
RotatedFrame,
|
|
46
57
|
StaggeredWord,
|
|
47
58
|
StatRow,
|
|
48
59
|
StatSection,
|
|
49
60
|
UpdateDialog,
|
|
61
|
+
WELL_SHADOW,
|
|
62
|
+
getInlineColorPickerContentSize,
|
|
50
63
|
getStaggeredWordDuration,
|
|
51
64
|
isCompactDialogHeight,
|
|
52
65
|
overlayActionStyles,
|
|
53
66
|
overlayStyles,
|
|
67
|
+
useAutoAlign,
|
|
54
68
|
useCompactDialog,
|
|
55
|
-
useOverlayCardColors
|
|
69
|
+
useOverlayCardColors,
|
|
70
|
+
usePopoverHost,
|
|
71
|
+
useWellColors
|
|
56
72
|
};
|
|
@@ -8,17 +8,24 @@ import {
|
|
|
8
8
|
useOverlayCardColors
|
|
9
9
|
} from "./chunk-PUF6TABL.mjs";
|
|
10
10
|
|
|
11
|
-
// src/
|
|
11
|
+
// src/wellSurface.ts
|
|
12
12
|
import { useAutoPaperTheme } from "@rific/auto-paper";
|
|
13
|
+
var WELL_SHADOW = "0px 1px 2px rgba(0, 0, 0, 0.3), 0px 1px 3px 1px rgba(0, 0, 0, 0.15)";
|
|
14
|
+
function useWellColors() {
|
|
15
|
+
const { colors } = useAutoPaperTheme();
|
|
16
|
+
return { bg: colors.surface, fg: colors.onSurface, fgMuted: colors.onSurfaceVariant };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// src/AchievementRow.tsx
|
|
13
20
|
import { StyleSheet, View } from "react-native";
|
|
14
21
|
import { Icon, ProgressBar, Text } from "react-native-paper";
|
|
15
22
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
16
23
|
var LOCKED_BADGE_COLOR = "rgba(128,128,128,0.3)";
|
|
17
24
|
function AchievementRow({ icon, title, description, badgeColor, unlockedLabel, checkColor, progress, deviceMarker, fg: fgOverride, fgMuted: fgMutedOverride, sectionBg: sectionBgOverride }) {
|
|
18
|
-
const
|
|
19
|
-
const fg = fgOverride ??
|
|
20
|
-
const fgMuted = fgMutedOverride ??
|
|
21
|
-
const sectionBg = sectionBgOverride ??
|
|
25
|
+
const well = useWellColors();
|
|
26
|
+
const fg = fgOverride ?? well.fg;
|
|
27
|
+
const fgMuted = fgMutedOverride ?? well.fgMuted;
|
|
28
|
+
const sectionBg = sectionBgOverride ?? well.bg;
|
|
22
29
|
const unlocked = unlockedLabel !== void 0;
|
|
23
30
|
return /* @__PURE__ */ jsxs(View, { style: [styles.row, { backgroundColor: sectionBg }], children: [
|
|
24
31
|
/* @__PURE__ */ jsx(View, { style: [styles.badge, { backgroundColor: badgeColor }], children: /* @__PURE__ */ jsx(Icon, { source: icon, size: 20, color: unlocked ? "#000000" : fgMuted }) }),
|
|
@@ -61,6 +68,7 @@ var styles = StyleSheet.create({
|
|
|
61
68
|
row: {
|
|
62
69
|
alignItems: "center",
|
|
63
70
|
borderRadius: 12,
|
|
71
|
+
boxShadow: WELL_SHADOW,
|
|
64
72
|
flexDirection: "row",
|
|
65
73
|
gap: 12,
|
|
66
74
|
padding: 12
|
|
@@ -86,13 +94,13 @@ import { Fragment } from "react";
|
|
|
86
94
|
import { StyleSheet as StyleSheet2 } from "react-native";
|
|
87
95
|
import { Text as Text2 } from "react-native-paper";
|
|
88
96
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
89
|
-
function AchievementCatalogSection({ rows, label = "ALL ACHIEVEMENTS", fg, fgMuted: fgMutedOverride }) {
|
|
97
|
+
function AchievementCatalogSection({ rows, label = "ALL ACHIEVEMENTS", fg, fgMuted: fgMutedOverride, sectionBg }) {
|
|
90
98
|
const { dark } = useAutoPaperTheme2();
|
|
91
99
|
const fgMuted = fgMutedOverride ?? (dark ? "rgba(255,255,255,0.5)" : "rgba(0,0,0,0.5)");
|
|
92
100
|
const tierAccent = (tierColor) => dark ? tierColor : getBlendedColor("#000000", tierColor, 0.5);
|
|
93
101
|
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
94
102
|
/* @__PURE__ */ jsx2(Text2, { variant: "labelMedium", style: [styles2.label, { color: fgMuted, fontFamily: MONO_FONT }], children: label }),
|
|
95
|
-
rows.map((row) => /* @__PURE__ */ jsx2(AchievementRow, { icon: row.icon, title: row.title, description: row.description, badgeColor: row.unlockedAt !== void 0 ? row.tierColor : LOCKED_BADGE_COLOR, checkColor: tierAccent(row.tierColor), unlockedLabel: row.unlockedLabel, progress: row.progress, deviceMarker: row.deviceMarker, fg, fgMuted: fgMutedOverride }, row.id))
|
|
103
|
+
rows.map((row) => /* @__PURE__ */ jsx2(AchievementRow, { icon: row.icon, title: row.title, description: row.description, badgeColor: row.unlockedAt !== void 0 ? row.tierColor : LOCKED_BADGE_COLOR, checkColor: tierAccent(row.tierColor), unlockedLabel: row.unlockedLabel, progress: row.progress, deviceMarker: row.deviceMarker, fg, fgMuted: fgMutedOverride, sectionBg }, row.id))
|
|
96
104
|
] });
|
|
97
105
|
}
|
|
98
106
|
var styles2 = StyleSheet2.create({
|
|
@@ -103,14 +111,13 @@ var styles2 = StyleSheet2.create({
|
|
|
103
111
|
});
|
|
104
112
|
|
|
105
113
|
// src/StatRow.tsx
|
|
106
|
-
import { useAutoPaperTheme as useAutoPaperTheme3 } from "@rific/auto-paper";
|
|
107
114
|
import { StyleSheet as StyleSheet3, View as View2 } from "react-native";
|
|
108
115
|
import { Text as Text3 } from "react-native-paper";
|
|
109
116
|
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
110
117
|
function StatRow({ label, value, fg: fgOverride, fgMuted: fgMutedOverride }) {
|
|
111
|
-
const
|
|
112
|
-
const fg = fgOverride ??
|
|
113
|
-
const fgMuted = fgMutedOverride ??
|
|
118
|
+
const well = useWellColors();
|
|
119
|
+
const fg = fgOverride ?? well.fg;
|
|
120
|
+
const fgMuted = fgMutedOverride ?? well.fgMuted;
|
|
114
121
|
return /* @__PURE__ */ jsxs3(View2, { style: styles3.row, children: [
|
|
115
122
|
/* @__PURE__ */ jsx3(Text3, { variant: "bodyMedium", style: { color: fgMuted }, children: label }),
|
|
116
123
|
/* @__PURE__ */ jsx3(Text3, { variant: "bodyMedium", style: [styles3.value, { color: fg }], children: value })
|
|
@@ -128,14 +135,13 @@ var styles3 = StyleSheet3.create({
|
|
|
128
135
|
});
|
|
129
136
|
|
|
130
137
|
// src/StatSection.tsx
|
|
131
|
-
import { useAutoPaperTheme as useAutoPaperTheme4 } from "@rific/auto-paper";
|
|
132
138
|
import { StyleSheet as StyleSheet4, View as View3 } from "react-native";
|
|
133
139
|
import { Text as Text4 } from "react-native-paper";
|
|
134
140
|
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
135
141
|
function StatSection({ label, fg: fgOverride, sectionBg: sectionBgOverride, children }) {
|
|
136
|
-
const
|
|
137
|
-
const fg = fgOverride ??
|
|
138
|
-
const sectionBg = sectionBgOverride ??
|
|
142
|
+
const well = useWellColors();
|
|
143
|
+
const fg = fgOverride ?? well.fg;
|
|
144
|
+
const sectionBg = sectionBgOverride ?? well.bg;
|
|
139
145
|
return /* @__PURE__ */ jsxs4(View3, { style: [styles4.section, { backgroundColor: sectionBg }], children: [
|
|
140
146
|
/* @__PURE__ */ jsx4(Text4, { variant: "labelMedium", style: [styles4.label, { color: fg }], children: label }),
|
|
141
147
|
children
|
|
@@ -152,6 +158,7 @@ var styles4 = StyleSheet4.create({
|
|
|
152
158
|
},
|
|
153
159
|
section: {
|
|
154
160
|
borderRadius: 12,
|
|
161
|
+
boxShadow: WELL_SHADOW,
|
|
155
162
|
gap: 8,
|
|
156
163
|
padding: 16
|
|
157
164
|
}
|
|
@@ -159,11 +166,11 @@ var styles4 = StyleSheet4.create({
|
|
|
159
166
|
|
|
160
167
|
// src/ActivityStatSection.tsx
|
|
161
168
|
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
162
|
-
function ActivityStatSection({ stats }) {
|
|
163
|
-
return /* @__PURE__ */ jsxs5(StatSection, { label: "ACTIVITY", children: [
|
|
164
|
-
/* @__PURE__ */ jsx5(StatRow, { label: "Days Played", value: String(stats.distinctDaysPlayed) }),
|
|
165
|
-
/* @__PURE__ */ jsx5(StatRow, { label: "Day Streak", value: String(stats.currentDayStreak) }),
|
|
166
|
-
/* @__PURE__ */ jsx5(StatRow, { label: "Best Day Streak", value: String(stats.bestDayStreak) })
|
|
169
|
+
function ActivityStatSection({ stats, fg, fgMuted, sectionBg }) {
|
|
170
|
+
return /* @__PURE__ */ jsxs5(StatSection, { label: "ACTIVITY", fg, sectionBg, children: [
|
|
171
|
+
/* @__PURE__ */ jsx5(StatRow, { label: "Days Played", value: String(stats.distinctDaysPlayed), fg, fgMuted }),
|
|
172
|
+
/* @__PURE__ */ jsx5(StatRow, { label: "Day Streak", value: String(stats.currentDayStreak), fg, fgMuted }),
|
|
173
|
+
/* @__PURE__ */ jsx5(StatRow, { label: "Best Day Streak", value: String(stats.bestDayStreak), fg, fgMuted })
|
|
167
174
|
] });
|
|
168
175
|
}
|
|
169
176
|
|
|
@@ -185,7 +192,7 @@ function useCompactDialog(rotation = 0) {
|
|
|
185
192
|
}
|
|
186
193
|
|
|
187
194
|
// src/ConfirmDialog.tsx
|
|
188
|
-
import { useAutoPaperTheme as
|
|
195
|
+
import { useAutoPaperTheme as useAutoPaperTheme3 } from "@rific/auto-paper";
|
|
189
196
|
import { Button } from "@rific/feedback-press";
|
|
190
197
|
import { toRotationStyle } from "@tastic/core";
|
|
191
198
|
import { useEffect, useRef } from "react";
|
|
@@ -193,7 +200,7 @@ import { BackHandler, StyleSheet as StyleSheet5, View as View4 } from "react-nat
|
|
|
193
200
|
import { Portal, Text as Text5 } from "react-native-paper";
|
|
194
201
|
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
195
202
|
function ConfirmDialog({ visible, title, message, confirmLabel, cancelLabel, onConfirm, onCancel, rotation = 0, icon = "help-circle-outline", destructive = false }) {
|
|
196
|
-
const { colors } =
|
|
203
|
+
const { colors } = useAutoPaperTheme3();
|
|
197
204
|
const { fg } = useOverlayCardColors();
|
|
198
205
|
const { compact, onLayout } = useCompactDialog(rotation);
|
|
199
206
|
const onCancelRef = useRef(onCancel);
|
|
@@ -273,7 +280,8 @@ var styles6 = StyleSheet6.create({
|
|
|
273
280
|
});
|
|
274
281
|
|
|
275
282
|
// src/BaseSettingsDialog.tsx
|
|
276
|
-
import { AutoAppearancePicker, Dialog, FadingScrollView, useAutoPaperTheme as
|
|
283
|
+
import { AutoAppearancePicker, Dialog, FadingScrollView, useAutoPaperTheme as useAutoPaperTheme4, useBlurModule, useThemeSettings } from "@rific/auto-paper";
|
|
284
|
+
import { useExpoKeepAwake, useKeepAwakeSettings } from "@rific/core";
|
|
277
285
|
import { Button as Button2, SoundContext, TouchableRipple, useHapticSettings, useSoundSettings, useVibration } from "@rific/feedback-press";
|
|
278
286
|
import { useUpdater } from "@rific/updater";
|
|
279
287
|
import { rotateInsets as rotateInsets2, useIsTouchPrimaryDevice, useRotation as useRotation2 } from "@tastic/core";
|
|
@@ -307,8 +315,8 @@ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
|
307
315
|
function SettingIcon({ source, color, containerColor }) {
|
|
308
316
|
return /* @__PURE__ */ jsx8(View6, { style: [styles7.iconBadge, { backgroundColor: containerColor }], children: /* @__PURE__ */ jsx8(Icon2, { source, size: 18, color }) });
|
|
309
317
|
}
|
|
310
|
-
function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, version, lockOrientation, onLockOrientationChange, deferBottomEdgeGestures, onDeferBottomEdgeGestures,
|
|
311
|
-
const { colors } =
|
|
318
|
+
function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, version, lockOrientation, onLockOrientationChange, deferBottomEdgeGestures, onDeferBottomEdgeGestures, hideSound = false, hideHaptics = false, hideAppearance = false, hideUpdateCheck = false, onUpdateError, onShowHowToPlay, children }) {
|
|
319
|
+
const { colors } = useAutoPaperTheme4();
|
|
312
320
|
const ambientRotation = useRotation2();
|
|
313
321
|
const rotation = rotationOverride ?? ambientRotation;
|
|
314
322
|
const window = useWindowDimensions3();
|
|
@@ -319,6 +327,8 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
|
|
|
319
327
|
const isTouchPrimary = useIsTouchPrimaryDevice();
|
|
320
328
|
const { settings: hapticSettings, set: setHapticSettings } = useHapticSettings();
|
|
321
329
|
const { settings: soundSettings, set: setSoundSettings } = useSoundSettings();
|
|
330
|
+
const { settings: keepAwakeSettings, set: setKeepAwakeSettings } = useKeepAwakeSettings();
|
|
331
|
+
const expoKeepAwake = useExpoKeepAwake();
|
|
322
332
|
const sound = useContext(SoundContext);
|
|
323
333
|
const { forceShort: forceHapticFeedback } = useVibration();
|
|
324
334
|
const { settings: themeSettings, set: setThemeSettings } = useThemeSettings();
|
|
@@ -337,7 +347,7 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
|
|
|
337
347
|
if (visible && !opened) setOpened(true);
|
|
338
348
|
const showLockOrientation = isTouchPrimary && lockOrientation !== void 0 && onLockOrientationChange !== void 0;
|
|
339
349
|
const showEdgeGuard = Platform2.OS === "ios" && deferBottomEdgeGestures !== void 0 && onDeferBottomEdgeGestures !== void 0;
|
|
340
|
-
const showKeepAwake = isTouchPrimary &&
|
|
350
|
+
const showKeepAwake = isTouchPrimary && expoKeepAwake !== void 0;
|
|
341
351
|
const showHaptics = Platform2.OS !== "web" && !hideHaptics;
|
|
342
352
|
const showSound = !hideSound;
|
|
343
353
|
const showAppearance = !hideAppearance;
|
|
@@ -364,8 +374,8 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
|
|
|
364
374
|
/* @__PURE__ */ jsx8(Text6, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Require second swipe" })
|
|
365
375
|
] })
|
|
366
376
|
] }) }),
|
|
367
|
-
showKeepAwake && /* @__PURE__ */ jsx8(TouchableRipple, { onPress: () =>
|
|
368
|
-
/* @__PURE__ */ jsx8(SettingIcon, { source:
|
|
377
|
+
showKeepAwake && /* @__PURE__ */ jsx8(TouchableRipple, { onPress: () => setKeepAwakeSettings({ enabled: !keepAwakeSettings.enabled }), style: styles7.toggleButton, accessibilityLabel: `Keep awake ${keepAwakeSettings.enabled ? "on" : "off"}`, children: /* @__PURE__ */ jsxs7(View6, { style: styles7.toggleContent, children: [
|
|
378
|
+
/* @__PURE__ */ jsx8(SettingIcon, { source: keepAwakeSettings.enabled ? "eye" : "eye-closed", color: keepAwakeSettings.enabled ? colors.tertiary : colors.onSurfaceVariant, containerColor: keepAwakeSettings.enabled ? colors.tertiaryContainer : colors.surfaceVariant }),
|
|
369
379
|
/* @__PURE__ */ jsxs7(View6, { style: styles7.flexShrink, children: [
|
|
370
380
|
/* @__PURE__ */ jsx8(Text6, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Keep Awake" }),
|
|
371
381
|
/* @__PURE__ */ jsx8(Text6, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Stop auto-lock mid-match" })
|
|
@@ -539,7 +549,7 @@ var styles7 = StyleSheet7.create({
|
|
|
539
549
|
});
|
|
540
550
|
|
|
541
551
|
// src/BaseStatsScreen.tsx
|
|
542
|
-
import { FadingScrollView as FadingScrollView2, useAutoPaperTheme as
|
|
552
|
+
import { FadingScrollView as FadingScrollView2, useAutoPaperTheme as useAutoPaperTheme5 } from "@rific/auto-paper";
|
|
543
553
|
import { Button as Button3, IconButton } from "@rific/feedback-press";
|
|
544
554
|
import { useRotation as useRotation3 } from "@tastic/core";
|
|
545
555
|
import { useState as useState4 } from "react";
|
|
@@ -547,7 +557,7 @@ import { StyleSheet as StyleSheet8, View as View7 } from "react-native";
|
|
|
547
557
|
import { Text as Text7 } from "react-native-paper";
|
|
548
558
|
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
549
559
|
function BaseStatsScreen({ rotation: rotationOverride, title = "Achievements", titleVariant = "headlineSmall", onBack, backLabel = "Back", hitSlop, insets, onReset, resetLabel = "Reset All Stats", resetConfirmTitle = "Reset Everything?", resetConfirmBody = "This permanently erases all stats and achievements. This cannot be undone.", fg: fgOverride, bg: bgOverride, children }) {
|
|
550
|
-
const { dark, colors } =
|
|
560
|
+
const { dark, colors } = useAutoPaperTheme5();
|
|
551
561
|
const ambientRotation = useRotation3();
|
|
552
562
|
const rotation = rotationOverride ?? ambientRotation;
|
|
553
563
|
const [confirmResetVisible, setConfirmResetVisible] = useState4(false);
|
|
@@ -637,17 +647,131 @@ var styles9 = StyleSheet9.create({
|
|
|
637
647
|
}
|
|
638
648
|
});
|
|
639
649
|
|
|
650
|
+
// src/PopoverBody.tsx
|
|
651
|
+
import { StyleSheet as StyleSheet10, View as View9 } from "react-native";
|
|
652
|
+
import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
653
|
+
var CARET_SIZE = 7;
|
|
654
|
+
var CARET_RING_OFFSET = 2;
|
|
655
|
+
var CARET_DIP = 1;
|
|
656
|
+
function PopoverBody({ visible, children, align = "center", verticalAlign = "below", caretColor, caretBorderColor, caretBorderWidth = 1, triggerSize = 0 }) {
|
|
657
|
+
if (!visible) return null;
|
|
658
|
+
const above = verticalAlign === "above";
|
|
659
|
+
const alignStyle = align === "left" ? styles10.contentLeft : align === "right" ? styles10.contentRight : styles10.contentCenter;
|
|
660
|
+
const verticalStyle = above ? styles10.contentAbove : styles10.contentBelow;
|
|
661
|
+
const ringSize = CARET_SIZE + caretBorderWidth;
|
|
662
|
+
const caretOffset = (halfFootprint) => align === "right" ? { right: triggerSize / 2 - halfFootprint } : { left: triggerSize / 2 - halfFootprint };
|
|
663
|
+
const caretFill = above ? "borderTopColor" : "borderBottomColor";
|
|
664
|
+
const caretWidthProp = above ? "borderTopWidth" : "borderBottomWidth";
|
|
665
|
+
const caretEdge = (size) => above ? { bottom: -size + CARET_DIP } : { top: -size + CARET_DIP };
|
|
666
|
+
return /* @__PURE__ */ jsxs10(View9, { style: [styles10.content, alignStyle, verticalStyle], children: [
|
|
667
|
+
children,
|
|
668
|
+
caretColor && /* @__PURE__ */ jsxs10(Fragment2, { children: [
|
|
669
|
+
/* @__PURE__ */ jsx11(View9, { style: [styles10.caret, caretOffset(ringSize), caretEdge(ringSize), { [caretFill]: caretBorderColor ?? caretColor, [caretWidthProp]: ringSize, borderLeftWidth: ringSize, borderRightWidth: ringSize }] }),
|
|
670
|
+
/* @__PURE__ */ jsx11(View9, { style: [styles10.caret, caretOffset(CARET_SIZE), caretEdge(CARET_SIZE - CARET_RING_OFFSET), { [caretFill]: caretColor, [caretWidthProp]: CARET_SIZE, borderLeftWidth: CARET_SIZE, borderRightWidth: CARET_SIZE }] })
|
|
671
|
+
] })
|
|
672
|
+
] });
|
|
673
|
+
}
|
|
674
|
+
var styles10 = StyleSheet10.create({
|
|
675
|
+
caret: {
|
|
676
|
+
borderLeftColor: "transparent",
|
|
677
|
+
borderRightColor: "transparent",
|
|
678
|
+
height: 0,
|
|
679
|
+
position: "absolute",
|
|
680
|
+
width: 0,
|
|
681
|
+
// Explicit, not left to DOM order - the box it dips into is itself a position:'relative' view,
|
|
682
|
+
// which React Native Web always gives an implicit zIndex:0 (see PopoverBody's stacking-context
|
|
683
|
+
// notes elsewhere in this codebase), so painting on top needs a real zIndex to beat that
|
|
684
|
+
// reliably rather than relying on being the later sibling.
|
|
685
|
+
zIndex: 1
|
|
686
|
+
},
|
|
687
|
+
content: {
|
|
688
|
+
position: "absolute",
|
|
689
|
+
zIndex: 50
|
|
690
|
+
},
|
|
691
|
+
contentAbove: {
|
|
692
|
+
bottom: "100%",
|
|
693
|
+
marginBottom: 8
|
|
694
|
+
},
|
|
695
|
+
contentBelow: {
|
|
696
|
+
marginTop: 8,
|
|
697
|
+
top: "100%"
|
|
698
|
+
},
|
|
699
|
+
// Stretched to the anchor's own (trigger) width, with alignItems centering the actual (usually
|
|
700
|
+
// much wider) popover box inside via plain flexbox - not `left:'50%'` plus a percentage
|
|
701
|
+
// `transform`, which depends on native resolving the box's own auto width before applying the
|
|
702
|
+
// transform and has proven unreliable there, visibly shifting the box off-center.
|
|
703
|
+
contentCenter: {
|
|
704
|
+
alignItems: "center",
|
|
705
|
+
left: 0,
|
|
706
|
+
right: 0
|
|
707
|
+
},
|
|
708
|
+
contentLeft: {
|
|
709
|
+
left: 0
|
|
710
|
+
},
|
|
711
|
+
contentRight: {
|
|
712
|
+
right: 0
|
|
713
|
+
}
|
|
714
|
+
});
|
|
715
|
+
|
|
716
|
+
// src/useAutoAlign.ts
|
|
717
|
+
import { useCallback as useCallback3, useEffect as useEffect2, useRef as useRef3, useState as useState5 } from "react";
|
|
718
|
+
import { useWindowDimensions as useWindowDimensions4 } from "react-native";
|
|
719
|
+
var EDGE_MARGIN = 12;
|
|
720
|
+
function rotateRect(x, y, width, height, rotation, windowWidth, windowHeight) {
|
|
721
|
+
if (rotation === 0) return { x, y, width, height };
|
|
722
|
+
const cx = windowWidth / 2;
|
|
723
|
+
const cy = windowHeight / 2;
|
|
724
|
+
const dx = x + width / 2 - cx;
|
|
725
|
+
const dy = y + height / 2 - cy;
|
|
726
|
+
const [newDx, newDy, newWidth, newHeight] = rotation === 180 ? [-dx, -dy, width, height] : rotation === 90 ? [-dy, dx, height, width] : [dy, -dx, height, width];
|
|
727
|
+
return { x: cx + newDx - newWidth / 2, y: cy + newDy - newHeight / 2, width: newWidth, height: newHeight };
|
|
728
|
+
}
|
|
729
|
+
function useAutoAlign(open, contentWidth, contentHeight, rotation = 0) {
|
|
730
|
+
const triggerRef = useRef3(null);
|
|
731
|
+
const { width: windowWidth, height: windowHeight } = useWindowDimensions4();
|
|
732
|
+
const [align, setAlign] = useState5("center");
|
|
733
|
+
const [verticalAlign, setVerticalAlign] = useState5("below");
|
|
734
|
+
const [maxHeight, setMaxHeight] = useState5(contentHeight);
|
|
735
|
+
const [measured, setMeasured] = useState5(false);
|
|
736
|
+
const [prevOpen, setPrevOpen] = useState5(open);
|
|
737
|
+
if (open !== prevOpen) {
|
|
738
|
+
setPrevOpen(open);
|
|
739
|
+
if (open) setMeasured(false);
|
|
740
|
+
}
|
|
741
|
+
const measure = useCallback3(() => {
|
|
742
|
+
triggerRef.current?.measureInWindow((rawX, rawY, rawWidth, rawHeight) => {
|
|
743
|
+
const { x, y, width: triggerWidth, height: triggerHeight } = rotateRect(rawX, rawY, rawWidth, rawHeight, rotation, windowWidth, windowHeight);
|
|
744
|
+
const centerX = x + triggerWidth / 2;
|
|
745
|
+
const overflowsRight = centerX + contentWidth / 2 > windowWidth - EDGE_MARGIN;
|
|
746
|
+
const overflowsLeft = centerX - contentWidth / 2 < EDGE_MARGIN;
|
|
747
|
+
if (overflowsRight && !overflowsLeft) setAlign("right");
|
|
748
|
+
else if (overflowsLeft && !overflowsRight) setAlign("left");
|
|
749
|
+
else setAlign("center");
|
|
750
|
+
const roomBelow = windowHeight - (y + triggerHeight) - EDGE_MARGIN;
|
|
751
|
+
const roomAbove = y - EDGE_MARGIN;
|
|
752
|
+
const above = contentHeight > roomBelow && roomAbove > roomBelow;
|
|
753
|
+
setVerticalAlign(above ? "above" : "below");
|
|
754
|
+
setMaxHeight(Math.max(above ? roomAbove : roomBelow, 0));
|
|
755
|
+
setMeasured(true);
|
|
756
|
+
});
|
|
757
|
+
}, [contentWidth, contentHeight, windowWidth, windowHeight, rotation]);
|
|
758
|
+
useEffect2(() => {
|
|
759
|
+
if (open) measure();
|
|
760
|
+
}, [open, measure]);
|
|
761
|
+
return { align, maxHeight, measured, triggerRef, verticalAlign };
|
|
762
|
+
}
|
|
763
|
+
|
|
640
764
|
// src/CornerActionButtons.tsx
|
|
641
765
|
import { IconButton as IconButton2 } from "@rific/feedback-press";
|
|
642
|
-
import { StyleSheet as
|
|
643
|
-
import { Fragment as
|
|
766
|
+
import { StyleSheet as StyleSheet11 } from "react-native";
|
|
767
|
+
import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
644
768
|
function CornerActionButtons({ onBack, onSettings, fg, insets, backIcon = "arrow-left", backLabel = "Back", hitSlop }) {
|
|
645
|
-
return /* @__PURE__ */
|
|
646
|
-
/* @__PURE__ */
|
|
647
|
-
/* @__PURE__ */
|
|
769
|
+
return /* @__PURE__ */ jsxs11(Fragment3, { children: [
|
|
770
|
+
/* @__PURE__ */ jsx12(IconButton2, { icon: backIcon, iconColor: fg, size: 24, style: [styles11.back, { top: 8 + insets.top, left: 8 + insets.left }], hitSlop, onPress: onBack, accessibilityLabel: backLabel }),
|
|
771
|
+
/* @__PURE__ */ jsx12(IconButton2, { icon: "cog", iconColor: fg, size: 24, style: [styles11.topRight, { top: 8 + insets.top, right: 8 + insets.right }], hitSlop, onPress: onSettings, accessibilityLabel: "Settings" })
|
|
648
772
|
] });
|
|
649
773
|
}
|
|
650
|
-
var
|
|
774
|
+
var styles11 = StyleSheet11.create({
|
|
651
775
|
back: {
|
|
652
776
|
position: "absolute"
|
|
653
777
|
},
|
|
@@ -656,11 +780,167 @@ var styles10 = StyleSheet10.create({
|
|
|
656
780
|
}
|
|
657
781
|
});
|
|
658
782
|
|
|
783
|
+
// src/InlineColorPicker.tsx
|
|
784
|
+
import { defaultColors, getContrastColor } from "@rific/auto-paper";
|
|
785
|
+
import { TouchableRipple as TouchableRipple2 } from "@rific/feedback-press";
|
|
786
|
+
import { clamp, useRotation as useRotation4 } from "@tastic/core";
|
|
787
|
+
import { ScrollView, StyleSheet as StyleSheet12, useWindowDimensions as useWindowDimensions5, View as View11 } from "react-native";
|
|
788
|
+
import { Icon as Icon3, Text as Text8 } from "react-native-paper";
|
|
789
|
+
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
790
|
+
var EMOJI_PATTERN = /\p{Extended_Pictographic}/u;
|
|
791
|
+
var DEFAULT_SIZE = 48;
|
|
792
|
+
var SWATCH_SIZE = 28;
|
|
793
|
+
var SWATCHES_PADDING = 8;
|
|
794
|
+
var SWATCHES_GAP = 6;
|
|
795
|
+
var SWATCHES_BORDER_WIDTH = 2;
|
|
796
|
+
var MIN_COLUMNS = 4;
|
|
797
|
+
var MAX_COLUMNS = 5;
|
|
798
|
+
var SCREEN_MARGIN = 40;
|
|
799
|
+
function widthForColumns(columns) {
|
|
800
|
+
return SWATCHES_BORDER_WIDTH * 2 + SWATCHES_PADDING * 2 + SWATCH_SIZE * columns + SWATCHES_GAP * (columns - 1);
|
|
801
|
+
}
|
|
802
|
+
function getInlineColorPickerContentSize(swatchCount, windowWidth, columns) {
|
|
803
|
+
const autoColumns = clamp(Math.floor((windowWidth - 2 * SCREEN_MARGIN + SWATCHES_GAP) / (SWATCH_SIZE + SWATCHES_GAP)), MIN_COLUMNS, MAX_COLUMNS);
|
|
804
|
+
const resolvedColumns = columns ?? autoColumns;
|
|
805
|
+
const width = widthForColumns(resolvedColumns);
|
|
806
|
+
const rows = Math.ceil(swatchCount / resolvedColumns);
|
|
807
|
+
const height = SWATCHES_BORDER_WIDTH * 2 + SWATCHES_PADDING * 2 + SWATCH_SIZE * rows + SWATCHES_GAP * (rows - 1);
|
|
808
|
+
return { width, height };
|
|
809
|
+
}
|
|
810
|
+
function InlineColorPicker({ id, host, value, onChange, previewValue, swatches = defaultColors, takenValue, allowSwapTaken, dark, align: forcedAlign, alignOverride, rotation: rotationOverride, icon = "palette", tag, labelFontFamily = MONO_FONT, autoDismiss = true, columns, size = DEFAULT_SIZE }) {
|
|
811
|
+
const ambientRotation = useRotation4();
|
|
812
|
+
const rotation = rotationOverride ?? ambientRotation;
|
|
813
|
+
const menuBg = dark ? "#000000" : "#FFFFFF";
|
|
814
|
+
const { width: windowWidth } = useWindowDimensions5();
|
|
815
|
+
const { width: swatchesWidth, height: swatchesHeight } = getInlineColorPickerContentSize(swatches.length, windowWidth, columns);
|
|
816
|
+
const open = host.openId === id;
|
|
817
|
+
const auto = useAutoAlign(open, swatchesWidth, swatchesHeight, rotation);
|
|
818
|
+
const placement = alignOverride ?? auto;
|
|
819
|
+
const { maxHeight, measured, triggerRef, verticalAlign } = placement;
|
|
820
|
+
const align = forcedAlign ?? placement.align;
|
|
821
|
+
const displayFor = previewValue ?? ((hex) => hex);
|
|
822
|
+
const displayValue = displayFor(value);
|
|
823
|
+
const contrastColor = getContrastColor(displayValue);
|
|
824
|
+
const tagFontSize = size * (tag && EMOJI_PATTERN.test(tag) ? 0.6 : 0.4);
|
|
825
|
+
return /* @__PURE__ */ jsxs12(View11, { style: [styles12.anchor, open && styles12.anchorOpen], children: [
|
|
826
|
+
/* @__PURE__ */ jsx13(TouchableRipple2, { onPress: () => host.toggle(id), borderless: true, style: [styles12.trigger, { backgroundColor: displayValue, borderRadius: size / 2, height: size, width: size }], children: /* @__PURE__ */ jsx13(View11, { ref: triggerRef, collapsable: false, style: styles12.triggerMeasure, children: tag ? /* @__PURE__ */ jsx13(Text8, { style: [styles12.tagLabel, { color: contrastColor, fontFamily: labelFontFamily, fontSize: tagFontSize }], numberOfLines: 1, adjustsFontSizeToFit: true, children: tag }) : /* @__PURE__ */ jsx13(Icon3, { source: icon, size: size * 0.6, color: contrastColor }) }) }),
|
|
827
|
+
/* @__PURE__ */ jsx13(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: displayValue, caretBorderWidth: SWATCHES_BORDER_WIDTH, triggerSize: size, children: /* @__PURE__ */ jsx13(ScrollView, { style: [styles12.swatches, { backgroundColor: menuBg, borderColor: displayValue, width: swatchesWidth, maxHeight }], contentContainerStyle: styles12.swatchesContent, showsVerticalScrollIndicator: false, children: swatches.map((swatch) => {
|
|
828
|
+
const selected = swatch.value.toLowerCase() === value.toLowerCase();
|
|
829
|
+
const taken = !selected && !!takenValue && swatch.value.toLowerCase() === takenValue.toLowerCase();
|
|
830
|
+
const swappable = taken && allowSwapTaken;
|
|
831
|
+
const swatchDisplay = displayFor(swatch.value);
|
|
832
|
+
return /* @__PURE__ */ jsx13(
|
|
833
|
+
TouchableRipple2,
|
|
834
|
+
{
|
|
835
|
+
disabled: taken && !swappable,
|
|
836
|
+
onPress: () => {
|
|
837
|
+
onChange(swatch.value);
|
|
838
|
+
if (autoDismiss) host.close();
|
|
839
|
+
},
|
|
840
|
+
borderless: true,
|
|
841
|
+
style: [styles12.swatch, { backgroundColor: swatchDisplay }, selected && styles12.swatchSelected, taken && !swappable && styles12.swatchTaken],
|
|
842
|
+
children: selected ? /* @__PURE__ */ jsx13(Icon3, { source: "check", size: 16, color: getContrastColor(swatchDisplay) }) : swappable ? /* @__PURE__ */ jsx13(Icon3, { source: "swap-horizontal", size: 16, color: getContrastColor(swatchDisplay) }) : taken ? /* @__PURE__ */ jsx13(Icon3, { source: "close", size: 16, color: getContrastColor(swatchDisplay) }) : /* @__PURE__ */ jsx13(View11, {})
|
|
843
|
+
},
|
|
844
|
+
swatch.value
|
|
845
|
+
);
|
|
846
|
+
}) }) })
|
|
847
|
+
] });
|
|
848
|
+
}
|
|
849
|
+
var styles12 = StyleSheet12.create({
|
|
850
|
+
anchor: {
|
|
851
|
+
position: "relative"
|
|
852
|
+
},
|
|
853
|
+
// See SectionedDropdown's identical comment - React Native Web gives every position:'relative' view
|
|
854
|
+
// its own stacking context, so the elevation has to live on the anchor itself, not just the
|
|
855
|
+
// popover content nested inside it, to correctly paint above this anchor's own later siblings.
|
|
856
|
+
anchorOpen: {
|
|
857
|
+
zIndex: 100
|
|
858
|
+
},
|
|
859
|
+
swatch: {
|
|
860
|
+
alignItems: "center",
|
|
861
|
+
borderRadius: SWATCH_SIZE / 2,
|
|
862
|
+
height: SWATCH_SIZE,
|
|
863
|
+
justifyContent: "center",
|
|
864
|
+
width: SWATCH_SIZE
|
|
865
|
+
},
|
|
866
|
+
swatchSelected: {
|
|
867
|
+
borderColor: "#ffffff",
|
|
868
|
+
borderWidth: 2
|
|
869
|
+
},
|
|
870
|
+
swatchTaken: {
|
|
871
|
+
opacity: 0.35
|
|
872
|
+
},
|
|
873
|
+
swatches: {
|
|
874
|
+
borderRadius: 12,
|
|
875
|
+
borderWidth: SWATCHES_BORDER_WIDTH,
|
|
876
|
+
elevation: 8,
|
|
877
|
+
shadowColor: "#000000",
|
|
878
|
+
shadowOffset: { height: 2, width: 0 },
|
|
879
|
+
shadowOpacity: 0.3,
|
|
880
|
+
shadowRadius: 8
|
|
881
|
+
// width is set inline above - border-box sizing means it has to include the border too
|
|
882
|
+
// (2*SWATCHES_BORDER_WIDTH), not just padding+content, or exactly enough room goes missing that
|
|
883
|
+
// the last column silently wraps to a new row. Anything wider than the exact sum just shows as
|
|
884
|
+
// dead space on the right edge of each row instead.
|
|
885
|
+
},
|
|
886
|
+
// Separate from `swatches` itself - see SectionedDropdown's identical menu/menuContent split.
|
|
887
|
+
// The scroll frame's own bounds (including maxHeight) live on the ScrollView; the actual grid
|
|
888
|
+
// wrapping belongs to its contentContainerStyle, which sizes to the unclamped content instead.
|
|
889
|
+
swatchesContent: {
|
|
890
|
+
flexDirection: "row",
|
|
891
|
+
flexWrap: "wrap",
|
|
892
|
+
gap: SWATCHES_GAP,
|
|
893
|
+
padding: SWATCHES_PADDING
|
|
894
|
+
},
|
|
895
|
+
tagLabel: {
|
|
896
|
+
fontWeight: "700",
|
|
897
|
+
letterSpacing: 0.5
|
|
898
|
+
},
|
|
899
|
+
// borderRadius/height/width come from the `size` prop instead (see render-site override) - no
|
|
900
|
+
// fixed default here, since this style object is shared by every caller regardless of size.
|
|
901
|
+
trigger: {
|
|
902
|
+
alignItems: "center",
|
|
903
|
+
alignSelf: "flex-start",
|
|
904
|
+
justifyContent: "center"
|
|
905
|
+
},
|
|
906
|
+
// Wraps just the icon/tag, inside the TouchableRipple, purely so useAutoAlign has a plain View
|
|
907
|
+
// to attach its measurement ref to - TouchableRipple itself doesn't forward a ref to a
|
|
908
|
+
// measurable native node. Padded horizontally so a multi-character tag doesn't butt right up
|
|
909
|
+
// against the trigger's own circular edge (an icon alone doesn't need it, but this style is
|
|
910
|
+
// shared by both).
|
|
911
|
+
triggerMeasure: {
|
|
912
|
+
alignItems: "center",
|
|
913
|
+
height: "100%",
|
|
914
|
+
justifyContent: "center",
|
|
915
|
+
paddingHorizontal: 4,
|
|
916
|
+
width: "100%"
|
|
917
|
+
}
|
|
918
|
+
});
|
|
919
|
+
|
|
920
|
+
// src/usePopoverHost.ts
|
|
921
|
+
import { useCallback as useCallback4, useState as useState6 } from "react";
|
|
922
|
+
function usePopoverHost() {
|
|
923
|
+
const [openId, setOpenId] = useState6(null);
|
|
924
|
+
const toggle = useCallback4((id) => {
|
|
925
|
+
setOpenId((prev) => prev === id ? null : id);
|
|
926
|
+
}, []);
|
|
927
|
+
const close = useCallback4(() => setOpenId(null), []);
|
|
928
|
+
return { openId, toggle, close };
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
// src/PressAwayOverlay.tsx
|
|
932
|
+
import { Pressable, StyleSheet as StyleSheet13 } from "react-native";
|
|
933
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
934
|
+
function PressAwayOverlay({ active, onPress, style }) {
|
|
935
|
+
if (!active) return null;
|
|
936
|
+
return /* @__PURE__ */ jsx14(Pressable, { accessibilityLabel: "Dismiss", accessibilityRole: "button", onPress, style: [StyleSheet13.absoluteFill, style] });
|
|
937
|
+
}
|
|
938
|
+
|
|
659
939
|
// src/StaggeredWord.tsx
|
|
660
|
-
import { useEffect as
|
|
661
|
-
import { StyleSheet as
|
|
940
|
+
import { useEffect as useEffect3 } from "react";
|
|
941
|
+
import { StyleSheet as StyleSheet14, View as View12 } from "react-native";
|
|
662
942
|
import Animated, { Easing, useAnimatedStyle, useSharedValue, withDelay, withTiming } from "react-native-reanimated";
|
|
663
|
-
import { jsx as
|
|
943
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
664
944
|
var STAGGER_MS = 45;
|
|
665
945
|
var LETTER_DURATION_MS = 320;
|
|
666
946
|
function getStaggeredWordDuration(letterCount) {
|
|
@@ -668,7 +948,7 @@ function getStaggeredWordDuration(letterCount) {
|
|
|
668
948
|
}
|
|
669
949
|
function AnimatedLetter({ char, index, color, reducedMotion, fontFamily, fontSize, lineHeight, fontWeight, letterSpacing }) {
|
|
670
950
|
const progress = useSharedValue(reducedMotion ? 1 : 0);
|
|
671
|
-
|
|
951
|
+
useEffect3(() => {
|
|
672
952
|
if (reducedMotion) return;
|
|
673
953
|
progress.value = withDelay(index * STAGGER_MS, withTiming(1, { duration: LETTER_DURATION_MS, easing: Easing.out(Easing.back(1.5)) }));
|
|
674
954
|
}, [reducedMotion]);
|
|
@@ -676,12 +956,12 @@ function AnimatedLetter({ char, index, color, reducedMotion, fontFamily, fontSiz
|
|
|
676
956
|
opacity: progress.value,
|
|
677
957
|
transform: [{ translateY: (1 - progress.value) * 12 }, { scale: 0.85 + progress.value * 0.15 }]
|
|
678
958
|
}));
|
|
679
|
-
return /* @__PURE__ */
|
|
959
|
+
return /* @__PURE__ */ jsx15(Animated.Text, { allowFontScaling: false, style: [{ color, fontFamily, fontSize, lineHeight, fontWeight, letterSpacing }, style], children: char });
|
|
680
960
|
}
|
|
681
961
|
function StaggeredWord({ word, color, fontFamily, fontSize, lineHeight, reducedMotion, startIndex = 0, fontWeight = "bold", letterSpacing, style, onLayout }) {
|
|
682
|
-
return /* @__PURE__ */
|
|
962
|
+
return /* @__PURE__ */ jsx15(View12, { style: [styles13.row, style], onLayout, children: word.split("").map((char, i) => /* @__PURE__ */ jsx15(AnimatedLetter, { char, index: startIndex + i, color, reducedMotion, fontFamily, fontSize, lineHeight, fontWeight, letterSpacing }, i)) });
|
|
683
963
|
}
|
|
684
|
-
var
|
|
964
|
+
var styles13 = StyleSheet14.create({
|
|
685
965
|
row: {
|
|
686
966
|
flexDirection: "row"
|
|
687
967
|
}
|
|
@@ -689,15 +969,17 @@ var styles11 = StyleSheet11.create({
|
|
|
689
969
|
|
|
690
970
|
// src/UpdateDialog.tsx
|
|
691
971
|
import { useUpdater as useUpdater2 } from "@rific/updater";
|
|
692
|
-
import { jsx as
|
|
972
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
693
973
|
function UpdateDialog({ rotation = 0, autoCheck = true, autoPrompt = true, onError }) {
|
|
694
974
|
const { manifest, onConfirm, respond } = useUpdateConfirmBridge();
|
|
695
975
|
useUpdater2({ autoCheck, autoPrompt, onConfirm, onError });
|
|
696
976
|
const date = manifest ? new Date(manifest.createdAt) : null;
|
|
697
|
-
return /* @__PURE__ */
|
|
977
|
+
return /* @__PURE__ */ jsx16(ConfirmDialog, { visible: !!manifest, title: "Update Available", message: date ? `Released ${date.toLocaleDateString()} at ${date.toLocaleTimeString()}` : "", confirmLabel: "Restart", cancelLabel: "Later", icon: "update", rotation, onConfirm: () => respond(true), onCancel: () => respond(false) });
|
|
698
978
|
}
|
|
699
979
|
|
|
700
980
|
export {
|
|
981
|
+
WELL_SHADOW,
|
|
982
|
+
useWellColors,
|
|
701
983
|
LOCKED_BADGE_COLOR,
|
|
702
984
|
AchievementRow,
|
|
703
985
|
MONO_FONT,
|
|
@@ -711,7 +993,13 @@ export {
|
|
|
711
993
|
BaseSettingsDialog,
|
|
712
994
|
BaseStatsScreen,
|
|
713
995
|
ContentGutter,
|
|
996
|
+
PopoverBody,
|
|
997
|
+
useAutoAlign,
|
|
714
998
|
CornerActionButtons,
|
|
999
|
+
getInlineColorPickerContentSize,
|
|
1000
|
+
InlineColorPicker,
|
|
1001
|
+
usePopoverHost,
|
|
1002
|
+
PressAwayOverlay,
|
|
715
1003
|
getStaggeredWordDuration,
|
|
716
1004
|
StaggeredWord,
|
|
717
1005
|
UpdateDialog
|