@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.js
CHANGED
|
@@ -40,21 +40,29 @@ __export(chrome_exports, {
|
|
|
40
40
|
ContentGutter: () => ContentGutter,
|
|
41
41
|
CornerActionButtons: () => CornerActionButtons,
|
|
42
42
|
DialogHeader: () => DialogHeader,
|
|
43
|
+
InlineColorPicker: () => InlineColorPicker,
|
|
43
44
|
LOCKED_BADGE_COLOR: () => LOCKED_BADGE_COLOR,
|
|
44
45
|
MONO_FONT: () => MONO_FONT,
|
|
45
46
|
OverlayBackdrop: () => OverlayBackdrop,
|
|
46
47
|
OverlayCard: () => OverlayCard,
|
|
48
|
+
PopoverBody: () => PopoverBody,
|
|
49
|
+
PressAwayOverlay: () => PressAwayOverlay,
|
|
47
50
|
RotatedFrame: () => RotatedFrame,
|
|
48
51
|
StaggeredWord: () => StaggeredWord,
|
|
49
52
|
StatRow: () => StatRow,
|
|
50
53
|
StatSection: () => StatSection,
|
|
51
54
|
UpdateDialog: () => UpdateDialog,
|
|
55
|
+
WELL_SHADOW: () => WELL_SHADOW,
|
|
56
|
+
getInlineColorPickerContentSize: () => getInlineColorPickerContentSize,
|
|
52
57
|
getStaggeredWordDuration: () => getStaggeredWordDuration,
|
|
53
58
|
isCompactDialogHeight: () => isCompactDialogHeight,
|
|
54
59
|
overlayActionStyles: () => overlayActionStyles,
|
|
55
60
|
overlayStyles: () => overlayStyles,
|
|
61
|
+
useAutoAlign: () => useAutoAlign,
|
|
56
62
|
useCompactDialog: () => useCompactDialog,
|
|
57
|
-
useOverlayCardColors: () => useOverlayCardColors
|
|
63
|
+
useOverlayCardColors: () => useOverlayCardColors,
|
|
64
|
+
usePopoverHost: () => usePopoverHost,
|
|
65
|
+
useWellColors: () => useWellColors
|
|
58
66
|
});
|
|
59
67
|
module.exports = __toCommonJS(chrome_exports);
|
|
60
68
|
|
|
@@ -65,16 +73,25 @@ var import_react_native3 = require("react-native");
|
|
|
65
73
|
var import_react_native_paper2 = require("react-native-paper");
|
|
66
74
|
|
|
67
75
|
// src/AchievementRow.tsx
|
|
68
|
-
var import_auto_paper = require("@rific/auto-paper");
|
|
69
76
|
var import_react_native = require("react-native");
|
|
70
77
|
var import_react_native_paper = require("react-native-paper");
|
|
78
|
+
|
|
79
|
+
// src/wellSurface.ts
|
|
80
|
+
var import_auto_paper = require("@rific/auto-paper");
|
|
81
|
+
var WELL_SHADOW = "0px 1px 2px rgba(0, 0, 0, 0.3), 0px 1px 3px 1px rgba(0, 0, 0, 0.15)";
|
|
82
|
+
function useWellColors() {
|
|
83
|
+
const { colors } = (0, import_auto_paper.useAutoPaperTheme)();
|
|
84
|
+
return { bg: colors.surface, fg: colors.onSurface, fgMuted: colors.onSurfaceVariant };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// src/AchievementRow.tsx
|
|
71
88
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
72
89
|
var LOCKED_BADGE_COLOR = "rgba(128,128,128,0.3)";
|
|
73
90
|
function AchievementRow({ icon, title, description, badgeColor, unlockedLabel, checkColor, progress, deviceMarker, fg: fgOverride, fgMuted: fgMutedOverride, sectionBg: sectionBgOverride }) {
|
|
74
|
-
const
|
|
75
|
-
const fg = fgOverride ??
|
|
76
|
-
const fgMuted = fgMutedOverride ??
|
|
77
|
-
const sectionBg = sectionBgOverride ??
|
|
91
|
+
const well = useWellColors();
|
|
92
|
+
const fg = fgOverride ?? well.fg;
|
|
93
|
+
const fgMuted = fgMutedOverride ?? well.fgMuted;
|
|
94
|
+
const sectionBg = sectionBgOverride ?? well.bg;
|
|
78
95
|
const unlocked = unlockedLabel !== void 0;
|
|
79
96
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native.View, { style: [styles.row, { backgroundColor: sectionBg }], children: [
|
|
80
97
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { style: [styles.badge, { backgroundColor: badgeColor }], children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native_paper.Icon, { source: icon, size: 20, color: unlocked ? "#000000" : fgMuted }) }),
|
|
@@ -117,6 +134,7 @@ var styles = import_react_native.StyleSheet.create({
|
|
|
117
134
|
row: {
|
|
118
135
|
alignItems: "center",
|
|
119
136
|
borderRadius: 12,
|
|
137
|
+
boxShadow: WELL_SHADOW,
|
|
120
138
|
flexDirection: "row",
|
|
121
139
|
gap: 12,
|
|
122
140
|
padding: 12
|
|
@@ -138,13 +156,13 @@ var MONO_FONT = import_react_native2.Platform.select({ ios: "Menlo", android: "m
|
|
|
138
156
|
|
|
139
157
|
// src/AchievementCatalogSection.tsx
|
|
140
158
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
141
|
-
function AchievementCatalogSection({ rows, label = "ALL ACHIEVEMENTS", fg, fgMuted: fgMutedOverride }) {
|
|
159
|
+
function AchievementCatalogSection({ rows, label = "ALL ACHIEVEMENTS", fg, fgMuted: fgMutedOverride, sectionBg }) {
|
|
142
160
|
const { dark } = (0, import_auto_paper2.useAutoPaperTheme)();
|
|
143
161
|
const fgMuted = fgMutedOverride ?? (dark ? "rgba(255,255,255,0.5)" : "rgba(0,0,0,0.5)");
|
|
144
162
|
const tierAccent = (tierColor) => dark ? tierColor : (0, import_auto_paper2.getBlendedColor)("#000000", tierColor, 0.5);
|
|
145
163
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react.Fragment, { children: [
|
|
146
164
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.Text, { variant: "labelMedium", style: [styles2.label, { color: fgMuted, fontFamily: MONO_FONT }], children: label }),
|
|
147
|
-
rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(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))
|
|
165
|
+
rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(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))
|
|
148
166
|
] });
|
|
149
167
|
}
|
|
150
168
|
var styles2 = import_react_native3.StyleSheet.create({
|
|
@@ -155,14 +173,13 @@ var styles2 = import_react_native3.StyleSheet.create({
|
|
|
155
173
|
});
|
|
156
174
|
|
|
157
175
|
// src/StatRow.tsx
|
|
158
|
-
var import_auto_paper3 = require("@rific/auto-paper");
|
|
159
176
|
var import_react_native4 = require("react-native");
|
|
160
177
|
var import_react_native_paper3 = require("react-native-paper");
|
|
161
178
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
162
179
|
function StatRow({ label, value, fg: fgOverride, fgMuted: fgMutedOverride }) {
|
|
163
|
-
const
|
|
164
|
-
const fg = fgOverride ??
|
|
165
|
-
const fgMuted = fgMutedOverride ??
|
|
180
|
+
const well = useWellColors();
|
|
181
|
+
const fg = fgOverride ?? well.fg;
|
|
182
|
+
const fgMuted = fgMutedOverride ?? well.fgMuted;
|
|
166
183
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native4.View, { style: styles3.row, children: [
|
|
167
184
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Text, { variant: "bodyMedium", style: { color: fgMuted }, children: label }),
|
|
168
185
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Text, { variant: "bodyMedium", style: [styles3.value, { color: fg }], children: value })
|
|
@@ -180,14 +197,13 @@ var styles3 = import_react_native4.StyleSheet.create({
|
|
|
180
197
|
});
|
|
181
198
|
|
|
182
199
|
// src/StatSection.tsx
|
|
183
|
-
var import_auto_paper4 = require("@rific/auto-paper");
|
|
184
200
|
var import_react_native5 = require("react-native");
|
|
185
201
|
var import_react_native_paper4 = require("react-native-paper");
|
|
186
202
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
187
203
|
function StatSection({ label, fg: fgOverride, sectionBg: sectionBgOverride, children }) {
|
|
188
|
-
const
|
|
189
|
-
const fg = fgOverride ??
|
|
190
|
-
const sectionBg = sectionBgOverride ??
|
|
204
|
+
const well = useWellColors();
|
|
205
|
+
const fg = fgOverride ?? well.fg;
|
|
206
|
+
const sectionBg = sectionBgOverride ?? well.bg;
|
|
191
207
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native5.View, { style: [styles4.section, { backgroundColor: sectionBg }], children: [
|
|
192
208
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_paper4.Text, { variant: "labelMedium", style: [styles4.label, { color: fg }], children: label }),
|
|
193
209
|
children
|
|
@@ -204,6 +220,7 @@ var styles4 = import_react_native5.StyleSheet.create({
|
|
|
204
220
|
},
|
|
205
221
|
section: {
|
|
206
222
|
borderRadius: 12,
|
|
223
|
+
boxShadow: WELL_SHADOW,
|
|
207
224
|
gap: 8,
|
|
208
225
|
padding: 16
|
|
209
226
|
}
|
|
@@ -211,26 +228,27 @@ var styles4 = import_react_native5.StyleSheet.create({
|
|
|
211
228
|
|
|
212
229
|
// src/ActivityStatSection.tsx
|
|
213
230
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
214
|
-
function ActivityStatSection({ stats }) {
|
|
215
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(StatSection, { label: "ACTIVITY", children: [
|
|
216
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(StatRow, { label: "Days Played", value: String(stats.distinctDaysPlayed) }),
|
|
217
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(StatRow, { label: "Day Streak", value: String(stats.currentDayStreak) }),
|
|
218
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(StatRow, { label: "Best Day Streak", value: String(stats.bestDayStreak) })
|
|
231
|
+
function ActivityStatSection({ stats, fg, fgMuted, sectionBg }) {
|
|
232
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(StatSection, { label: "ACTIVITY", fg, sectionBg, children: [
|
|
233
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(StatRow, { label: "Days Played", value: String(stats.distinctDaysPlayed), fg, fgMuted }),
|
|
234
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(StatRow, { label: "Day Streak", value: String(stats.currentDayStreak), fg, fgMuted }),
|
|
235
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(StatRow, { label: "Best Day Streak", value: String(stats.bestDayStreak), fg, fgMuted })
|
|
219
236
|
] });
|
|
220
237
|
}
|
|
221
238
|
|
|
222
239
|
// src/BaseSettingsDialog.tsx
|
|
223
|
-
var
|
|
240
|
+
var import_auto_paper6 = require("@rific/auto-paper");
|
|
241
|
+
var import_core4 = require("@rific/core");
|
|
224
242
|
var import_feedback_press2 = require("@rific/feedback-press");
|
|
225
243
|
var import_updater = require("@rific/updater");
|
|
226
|
-
var
|
|
244
|
+
var import_core5 = require("@tastic/core");
|
|
227
245
|
var import_react6 = require("react");
|
|
228
246
|
var import_react_native12 = require("react-native");
|
|
229
247
|
var import_react_native_paper8 = require("react-native-paper");
|
|
230
248
|
var import_react_native_safe_area_context2 = require("react-native-safe-area-context");
|
|
231
249
|
|
|
232
250
|
// src/ConfirmDialog.tsx
|
|
233
|
-
var
|
|
251
|
+
var import_auto_paper5 = require("@rific/auto-paper");
|
|
234
252
|
var import_feedback_press = require("@rific/feedback-press");
|
|
235
253
|
var import_core2 = require("@tastic/core");
|
|
236
254
|
var import_react3 = require("react");
|
|
@@ -238,7 +256,7 @@ var import_react_native10 = require("react-native");
|
|
|
238
256
|
var import_react_native_paper6 = require("react-native-paper");
|
|
239
257
|
|
|
240
258
|
// src/DialogHeader.tsx
|
|
241
|
-
var
|
|
259
|
+
var import_auto_paper3 = require("@rific/auto-paper");
|
|
242
260
|
var import_react_native6 = require("react-native");
|
|
243
261
|
var import_react_native_paper5 = require("react-native-paper");
|
|
244
262
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
@@ -247,7 +265,7 @@ function isCompactDialogHeight(height) {
|
|
|
247
265
|
return height < COMPACT_DIALOG_HEIGHT;
|
|
248
266
|
}
|
|
249
267
|
function DialogHeader({ icon, title, color, compact = false, style }) {
|
|
250
|
-
const { colors } = (0,
|
|
268
|
+
const { colors } = (0, import_auto_paper3.useAutoPaperTheme)();
|
|
251
269
|
const accent = color ?? colors.primary;
|
|
252
270
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native6.View, { style: [compact ? styles5.compact : styles5.full, style], children: [
|
|
253
271
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native_paper5.Icon, { source: icon, size: compact ? COMPACT_ICON_SIZE : ICON_SIZE, color: accent }),
|
|
@@ -344,11 +362,11 @@ var overlayActionStyles = import_react_native7.StyleSheet.create({
|
|
|
344
362
|
});
|
|
345
363
|
|
|
346
364
|
// src/OverlaySurface.tsx
|
|
347
|
-
var
|
|
365
|
+
var import_auto_paper4 = require("@rific/auto-paper");
|
|
348
366
|
var import_react_native8 = require("react-native");
|
|
349
367
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
350
368
|
function useOverlayCardColors() {
|
|
351
|
-
const { colors } = (0,
|
|
369
|
+
const { colors } = (0, import_auto_paper4.useAutoPaperTheme)();
|
|
352
370
|
return { fg: colors.onSurface, fgMuted: colors.onSurfaceVariant, cardBorder: colors.outlineVariant, backdrop: colors.backdrop };
|
|
353
371
|
}
|
|
354
372
|
function OverlayBackdrop({ children, style, onLayout }) {
|
|
@@ -356,9 +374,9 @@ function OverlayBackdrop({ children, style, onLayout }) {
|
|
|
356
374
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native8.View, { onLayout, style: [overlayStyles.overlay, { backgroundColor: backdrop }, style], children });
|
|
357
375
|
}
|
|
358
376
|
function OverlayCard({ children, style, ...rest }) {
|
|
359
|
-
const { isV3, roundness } = (0,
|
|
360
|
-
const blur = (0,
|
|
361
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
377
|
+
const { isV3, roundness } = (0, import_auto_paper4.useAutoPaperTheme)();
|
|
378
|
+
const blur = (0, import_auto_paper4.useBlur)();
|
|
379
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_auto_paper4.BlurView, { blur, style: [overlayStyles.card, styles6.card, { borderRadius: (isV3 ? 7 : 1) * roundness }, style], ...rest, children });
|
|
362
380
|
}
|
|
363
381
|
var styles6 = import_react_native8.StyleSheet.create({
|
|
364
382
|
card: { overflow: "hidden" }
|
|
@@ -384,7 +402,7 @@ function useCompactDialog(rotation = 0) {
|
|
|
384
402
|
// src/ConfirmDialog.tsx
|
|
385
403
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
386
404
|
function ConfirmDialog({ visible, title, message, confirmLabel, cancelLabel, onConfirm, onCancel, rotation = 0, icon = "help-circle-outline", destructive = false }) {
|
|
387
|
-
const { colors } = (0,
|
|
405
|
+
const { colors } = (0, import_auto_paper5.useAutoPaperTheme)();
|
|
388
406
|
const { fg } = useOverlayCardColors();
|
|
389
407
|
const { compact, onLayout } = useCompactDialog(rotation);
|
|
390
408
|
const onCancelRef = (0, import_react3.useRef)(onCancel);
|
|
@@ -488,22 +506,24 @@ var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
|
488
506
|
function SettingIcon({ source, color, containerColor }) {
|
|
489
507
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native12.View, { style: [styles9.iconBadge, { backgroundColor: containerColor }], children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper8.Icon, { source, size: 18, color }) });
|
|
490
508
|
}
|
|
491
|
-
function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, version, lockOrientation, onLockOrientationChange, deferBottomEdgeGestures, onDeferBottomEdgeGestures,
|
|
492
|
-
const { colors } = (0,
|
|
493
|
-
const ambientRotation = (0,
|
|
509
|
+
function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, version, lockOrientation, onLockOrientationChange, deferBottomEdgeGestures, onDeferBottomEdgeGestures, hideSound = false, hideHaptics = false, hideAppearance = false, hideUpdateCheck = false, onUpdateError, onShowHowToPlay, children }) {
|
|
510
|
+
const { colors } = (0, import_auto_paper6.useAutoPaperTheme)();
|
|
511
|
+
const ambientRotation = (0, import_core5.useRotation)();
|
|
494
512
|
const rotation = rotationOverride ?? ambientRotation;
|
|
495
513
|
const window = (0, import_react_native12.useWindowDimensions)();
|
|
496
514
|
const turned = rotation === 90 || rotation === -90;
|
|
497
515
|
const compactHeader = isCompactDialogHeight(turned ? window.width : window.height);
|
|
498
|
-
const insets = (0,
|
|
516
|
+
const insets = (0, import_core5.rotateInsets)((0, import_react_native_safe_area_context2.useSafeAreaInsets)(), rotation);
|
|
499
517
|
const sheetWidth = Math.min(overlayStyles.card.maxWidth, (turned ? window.height : window.width) - 2 * Math.max(insets.left, insets.right, SHEET_GUTTER));
|
|
500
|
-
const isTouchPrimary = (0,
|
|
518
|
+
const isTouchPrimary = (0, import_core5.useIsTouchPrimaryDevice)();
|
|
501
519
|
const { settings: hapticSettings, set: setHapticSettings } = (0, import_feedback_press2.useHapticSettings)();
|
|
502
520
|
const { settings: soundSettings, set: setSoundSettings } = (0, import_feedback_press2.useSoundSettings)();
|
|
521
|
+
const { settings: keepAwakeSettings, set: setKeepAwakeSettings } = (0, import_core4.useKeepAwakeSettings)();
|
|
522
|
+
const expoKeepAwake = (0, import_core4.useExpoKeepAwake)();
|
|
503
523
|
const sound = (0, import_react6.useContext)(import_feedback_press2.SoundContext);
|
|
504
524
|
const { forceShort: forceHapticFeedback } = (0, import_feedback_press2.useVibration)();
|
|
505
|
-
const { settings: themeSettings, set: setThemeSettings } = (0,
|
|
506
|
-
const expoBlur = (0,
|
|
525
|
+
const { settings: themeSettings, set: setThemeSettings } = (0, import_auto_paper6.useThemeSettings)();
|
|
526
|
+
const expoBlur = (0, import_auto_paper6.useBlurModule)();
|
|
507
527
|
const [infoMessage, setInfoMessage] = (0, import_react6.useState)(null);
|
|
508
528
|
const { manifest: updateManifest, onConfirm: onUpdateConfirm, respond: respondToUpdateConfirm } = useUpdateConfirmBridge();
|
|
509
529
|
const { check, checking, updateReady } = (0, import_updater.useUpdater)({
|
|
@@ -518,7 +538,7 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
|
|
|
518
538
|
if (visible && !opened) setOpened(true);
|
|
519
539
|
const showLockOrientation = isTouchPrimary && lockOrientation !== void 0 && onLockOrientationChange !== void 0;
|
|
520
540
|
const showEdgeGuard = import_react_native12.Platform.OS === "ios" && deferBottomEdgeGestures !== void 0 && onDeferBottomEdgeGestures !== void 0;
|
|
521
|
-
const showKeepAwake = isTouchPrimary &&
|
|
541
|
+
const showKeepAwake = isTouchPrimary && expoKeepAwake !== void 0;
|
|
522
542
|
const showHaptics = import_react_native12.Platform.OS !== "web" && !hideHaptics;
|
|
523
543
|
const showSound = !hideSound;
|
|
524
544
|
const showAppearance = !hideAppearance;
|
|
@@ -526,8 +546,8 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
|
|
|
526
546
|
const showUpdateCheck = import_react_native12.Platform.OS !== "web" && !hideUpdateCheck;
|
|
527
547
|
if (!opened) return null;
|
|
528
548
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper8.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(RotatedFrame, { rotation, rotatedSafeArea: true, portalHost: true, passThrough: true, children: [
|
|
529
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
530
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
549
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_auto_paper6.Dialog, { visible, onDismiss, style: [styles9.dialog, { width: sheetWidth }], children: [
|
|
550
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_auto_paper6.Dialog.ScrollArea, { style: styles9.scrollArea, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_auto_paper6.FadingScrollView, { contentContainerStyle: styles9.scrollContent, showsVerticalScrollIndicator: false, children: [
|
|
531
551
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(DialogHeader, { icon: "cog", title: "Settings", compact: compactHeader }),
|
|
532
552
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native12.View, { style: styles9.content, children: [
|
|
533
553
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native12.View, { style: styles9.toggleGroup, children: [
|
|
@@ -545,8 +565,8 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
|
|
|
545
565
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper8.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Require second swipe" })
|
|
546
566
|
] })
|
|
547
567
|
] }) }),
|
|
548
|
-
showKeepAwake && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_feedback_press2.TouchableRipple, { onPress: () =>
|
|
549
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SettingIcon, { source:
|
|
568
|
+
showKeepAwake && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_feedback_press2.TouchableRipple, { onPress: () => setKeepAwakeSettings({ enabled: !keepAwakeSettings.enabled }), style: styles9.toggleButton, accessibilityLabel: `Keep awake ${keepAwakeSettings.enabled ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native12.View, { style: styles9.toggleContent, children: [
|
|
569
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SettingIcon, { source: keepAwakeSettings.enabled ? "eye" : "eye-closed", color: keepAwakeSettings.enabled ? colors.tertiary : colors.onSurfaceVariant, containerColor: keepAwakeSettings.enabled ? colors.tertiaryContainer : colors.surfaceVariant }),
|
|
550
570
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native12.View, { style: styles9.flexShrink, children: [
|
|
551
571
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper8.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Keep Awake" }),
|
|
552
572
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper8.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Stop auto-lock mid-match" })
|
|
@@ -609,7 +629,7 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
|
|
|
609
629
|
] }),
|
|
610
630
|
showAppearance && /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native12.View, { style: styles9.section, children: [
|
|
611
631
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper8.Text, { variant: "labelMedium", style: [styles9.sectionLabel, { color: colors.onSurfaceVariant }], children: "APPEARANCE" }),
|
|
612
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
632
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_auto_paper6.AutoAppearancePicker, { showLabels: false }),
|
|
613
633
|
showBlur && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_feedback_press2.TouchableRipple, { onPress: () => setThemeSettings({ blur: !themeSettings.blur }), style: styles9.toggleButton, accessibilityLabel: `Blur ${themeSettings.blur ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native12.View, { style: styles9.toggleContent, children: [
|
|
614
634
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SettingIcon, { source: themeSettings.blur ? "blur" : "blur-off", color: themeSettings.blur ? colors.tertiary : colors.onSurfaceVariant, containerColor: themeSettings.blur ? colors.tertiaryContainer : colors.surfaceVariant }),
|
|
615
635
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native12.View, { style: styles9.flexShrink, children: [
|
|
@@ -720,16 +740,16 @@ var styles9 = import_react_native12.StyleSheet.create({
|
|
|
720
740
|
});
|
|
721
741
|
|
|
722
742
|
// src/BaseStatsScreen.tsx
|
|
723
|
-
var
|
|
743
|
+
var import_auto_paper7 = require("@rific/auto-paper");
|
|
724
744
|
var import_feedback_press3 = require("@rific/feedback-press");
|
|
725
|
-
var
|
|
745
|
+
var import_core6 = require("@tastic/core");
|
|
726
746
|
var import_react7 = require("react");
|
|
727
747
|
var import_react_native13 = require("react-native");
|
|
728
748
|
var import_react_native_paper9 = require("react-native-paper");
|
|
729
749
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
730
750
|
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 }) {
|
|
731
|
-
const { dark, colors } = (0,
|
|
732
|
-
const ambientRotation = (0,
|
|
751
|
+
const { dark, colors } = (0, import_auto_paper7.useAutoPaperTheme)();
|
|
752
|
+
const ambientRotation = (0, import_core6.useRotation)();
|
|
733
753
|
const rotation = rotationOverride ?? ambientRotation;
|
|
734
754
|
const [confirmResetVisible, setConfirmResetVisible] = (0, import_react7.useState)(false);
|
|
735
755
|
const showReset = !!onReset;
|
|
@@ -740,7 +760,7 @@ function BaseStatsScreen({ rotation: rotationOverride, title = "Achievements", t
|
|
|
740
760
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_feedback_press3.IconButton, { icon: "arrow-left", iconColor: fg, size: 24, hitSlop, onPress: onBack, accessibilityLabel: backLabel }),
|
|
741
761
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native_paper9.Text, { variant: titleVariant, style: [styles10.title, { color: fg }], children: title })
|
|
742
762
|
] }),
|
|
743
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
763
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_auto_paper7.FadingScrollView, { style: styles10.scrollView, contentContainerStyle: [styles10.content, { paddingBottom: 32 + insets.bottom }], showsVerticalScrollIndicator: false, children: [
|
|
744
764
|
children,
|
|
745
765
|
showReset && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_feedback_press3.Button, { mode: "contained", onPress: () => setConfirmResetVisible(true), buttonColor: colors.danger, textColor: colors.onDanger, style: styles10.resetButton, children: resetLabel })
|
|
746
766
|
] }),
|
|
@@ -795,12 +815,12 @@ var styles10 = import_react_native13.StyleSheet.create({
|
|
|
795
815
|
});
|
|
796
816
|
|
|
797
817
|
// src/ContentGutter.tsx
|
|
798
|
-
var
|
|
818
|
+
var import_core7 = require("@tastic/core");
|
|
799
819
|
var import_react_native14 = require("react-native");
|
|
800
820
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
801
821
|
function ContentGutter({ maxContentWidth, leftGutter, rightGutter, style, children }) {
|
|
802
|
-
const { width: windowWidth } = (0,
|
|
803
|
-
const { contentWidth, gutterWidth } = (0,
|
|
822
|
+
const { width: windowWidth } = (0, import_core7.useRotatedWindowDimensions)();
|
|
823
|
+
const { contentWidth, gutterWidth } = (0, import_core7.computeContentBounds)(windowWidth, maxContentWidth ?? Infinity);
|
|
804
824
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native14.View, { style: [styles11.row, style], children: [
|
|
805
825
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native14.View, { style: [styles11.gutter, { width: gutterWidth }], children: leftGutter }),
|
|
806
826
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native14.View, { style: { width: contentWidth }, children }),
|
|
@@ -837,11 +857,272 @@ var styles12 = import_react_native15.StyleSheet.create({
|
|
|
837
857
|
}
|
|
838
858
|
});
|
|
839
859
|
|
|
840
|
-
// src/
|
|
841
|
-
var
|
|
860
|
+
// src/InlineColorPicker.tsx
|
|
861
|
+
var import_auto_paper8 = require("@rific/auto-paper");
|
|
862
|
+
var import_feedback_press5 = require("@rific/feedback-press");
|
|
863
|
+
var import_core8 = require("@tastic/core");
|
|
864
|
+
var import_react_native18 = require("react-native");
|
|
865
|
+
var import_react_native_paper10 = require("react-native-paper");
|
|
866
|
+
|
|
867
|
+
// src/PopoverBody.tsx
|
|
842
868
|
var import_react_native16 = require("react-native");
|
|
843
|
-
var import_react_native_reanimated = __toESM(require("react-native-reanimated"));
|
|
844
869
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
870
|
+
var CARET_SIZE = 7;
|
|
871
|
+
var CARET_RING_OFFSET = 2;
|
|
872
|
+
var CARET_DIP = 1;
|
|
873
|
+
function PopoverBody({ visible, children, align = "center", verticalAlign = "below", caretColor, caretBorderColor, caretBorderWidth = 1, triggerSize = 0 }) {
|
|
874
|
+
if (!visible) return null;
|
|
875
|
+
const above = verticalAlign === "above";
|
|
876
|
+
const alignStyle = align === "left" ? styles13.contentLeft : align === "right" ? styles13.contentRight : styles13.contentCenter;
|
|
877
|
+
const verticalStyle = above ? styles13.contentAbove : styles13.contentBelow;
|
|
878
|
+
const ringSize = CARET_SIZE + caretBorderWidth;
|
|
879
|
+
const caretOffset = (halfFootprint) => align === "right" ? { right: triggerSize / 2 - halfFootprint } : { left: triggerSize / 2 - halfFootprint };
|
|
880
|
+
const caretFill = above ? "borderTopColor" : "borderBottomColor";
|
|
881
|
+
const caretWidthProp = above ? "borderTopWidth" : "borderBottomWidth";
|
|
882
|
+
const caretEdge = (size) => above ? { bottom: -size + CARET_DIP } : { top: -size + CARET_DIP };
|
|
883
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native16.View, { style: [styles13.content, alignStyle, verticalStyle], children: [
|
|
884
|
+
children,
|
|
885
|
+
caretColor && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
886
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native16.View, { style: [styles13.caret, caretOffset(ringSize), caretEdge(ringSize), { [caretFill]: caretBorderColor ?? caretColor, [caretWidthProp]: ringSize, borderLeftWidth: ringSize, borderRightWidth: ringSize }] }),
|
|
887
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native16.View, { style: [styles13.caret, caretOffset(CARET_SIZE), caretEdge(CARET_SIZE - CARET_RING_OFFSET), { [caretFill]: caretColor, [caretWidthProp]: CARET_SIZE, borderLeftWidth: CARET_SIZE, borderRightWidth: CARET_SIZE }] })
|
|
888
|
+
] })
|
|
889
|
+
] });
|
|
890
|
+
}
|
|
891
|
+
var styles13 = import_react_native16.StyleSheet.create({
|
|
892
|
+
caret: {
|
|
893
|
+
borderLeftColor: "transparent",
|
|
894
|
+
borderRightColor: "transparent",
|
|
895
|
+
height: 0,
|
|
896
|
+
position: "absolute",
|
|
897
|
+
width: 0,
|
|
898
|
+
// Explicit, not left to DOM order - the box it dips into is itself a position:'relative' view,
|
|
899
|
+
// which React Native Web always gives an implicit zIndex:0 (see PopoverBody's stacking-context
|
|
900
|
+
// notes elsewhere in this codebase), so painting on top needs a real zIndex to beat that
|
|
901
|
+
// reliably rather than relying on being the later sibling.
|
|
902
|
+
zIndex: 1
|
|
903
|
+
},
|
|
904
|
+
content: {
|
|
905
|
+
position: "absolute",
|
|
906
|
+
zIndex: 50
|
|
907
|
+
},
|
|
908
|
+
contentAbove: {
|
|
909
|
+
bottom: "100%",
|
|
910
|
+
marginBottom: 8
|
|
911
|
+
},
|
|
912
|
+
contentBelow: {
|
|
913
|
+
marginTop: 8,
|
|
914
|
+
top: "100%"
|
|
915
|
+
},
|
|
916
|
+
// Stretched to the anchor's own (trigger) width, with alignItems centering the actual (usually
|
|
917
|
+
// much wider) popover box inside via plain flexbox - not `left:'50%'` plus a percentage
|
|
918
|
+
// `transform`, which depends on native resolving the box's own auto width before applying the
|
|
919
|
+
// transform and has proven unreliable there, visibly shifting the box off-center.
|
|
920
|
+
contentCenter: {
|
|
921
|
+
alignItems: "center",
|
|
922
|
+
left: 0,
|
|
923
|
+
right: 0
|
|
924
|
+
},
|
|
925
|
+
contentLeft: {
|
|
926
|
+
left: 0
|
|
927
|
+
},
|
|
928
|
+
contentRight: {
|
|
929
|
+
right: 0
|
|
930
|
+
}
|
|
931
|
+
});
|
|
932
|
+
|
|
933
|
+
// src/useAutoAlign.ts
|
|
934
|
+
var import_react8 = require("react");
|
|
935
|
+
var import_react_native17 = require("react-native");
|
|
936
|
+
var EDGE_MARGIN = 12;
|
|
937
|
+
function rotateRect(x, y, width, height, rotation, windowWidth, windowHeight) {
|
|
938
|
+
if (rotation === 0) return { x, y, width, height };
|
|
939
|
+
const cx = windowWidth / 2;
|
|
940
|
+
const cy = windowHeight / 2;
|
|
941
|
+
const dx = x + width / 2 - cx;
|
|
942
|
+
const dy = y + height / 2 - cy;
|
|
943
|
+
const [newDx, newDy, newWidth, newHeight] = rotation === 180 ? [-dx, -dy, width, height] : rotation === 90 ? [-dy, dx, height, width] : [dy, -dx, height, width];
|
|
944
|
+
return { x: cx + newDx - newWidth / 2, y: cy + newDy - newHeight / 2, width: newWidth, height: newHeight };
|
|
945
|
+
}
|
|
946
|
+
function useAutoAlign(open, contentWidth, contentHeight, rotation = 0) {
|
|
947
|
+
const triggerRef = (0, import_react8.useRef)(null);
|
|
948
|
+
const { width: windowWidth, height: windowHeight } = (0, import_react_native17.useWindowDimensions)();
|
|
949
|
+
const [align, setAlign] = (0, import_react8.useState)("center");
|
|
950
|
+
const [verticalAlign, setVerticalAlign] = (0, import_react8.useState)("below");
|
|
951
|
+
const [maxHeight, setMaxHeight] = (0, import_react8.useState)(contentHeight);
|
|
952
|
+
const [measured, setMeasured] = (0, import_react8.useState)(false);
|
|
953
|
+
const [prevOpen, setPrevOpen] = (0, import_react8.useState)(open);
|
|
954
|
+
if (open !== prevOpen) {
|
|
955
|
+
setPrevOpen(open);
|
|
956
|
+
if (open) setMeasured(false);
|
|
957
|
+
}
|
|
958
|
+
const measure = (0, import_react8.useCallback)(() => {
|
|
959
|
+
triggerRef.current?.measureInWindow((rawX, rawY, rawWidth, rawHeight) => {
|
|
960
|
+
const { x, y, width: triggerWidth, height: triggerHeight } = rotateRect(rawX, rawY, rawWidth, rawHeight, rotation, windowWidth, windowHeight);
|
|
961
|
+
const centerX = x + triggerWidth / 2;
|
|
962
|
+
const overflowsRight = centerX + contentWidth / 2 > windowWidth - EDGE_MARGIN;
|
|
963
|
+
const overflowsLeft = centerX - contentWidth / 2 < EDGE_MARGIN;
|
|
964
|
+
if (overflowsRight && !overflowsLeft) setAlign("right");
|
|
965
|
+
else if (overflowsLeft && !overflowsRight) setAlign("left");
|
|
966
|
+
else setAlign("center");
|
|
967
|
+
const roomBelow = windowHeight - (y + triggerHeight) - EDGE_MARGIN;
|
|
968
|
+
const roomAbove = y - EDGE_MARGIN;
|
|
969
|
+
const above = contentHeight > roomBelow && roomAbove > roomBelow;
|
|
970
|
+
setVerticalAlign(above ? "above" : "below");
|
|
971
|
+
setMaxHeight(Math.max(above ? roomAbove : roomBelow, 0));
|
|
972
|
+
setMeasured(true);
|
|
973
|
+
});
|
|
974
|
+
}, [contentWidth, contentHeight, windowWidth, windowHeight, rotation]);
|
|
975
|
+
(0, import_react8.useEffect)(() => {
|
|
976
|
+
if (open) measure();
|
|
977
|
+
}, [open, measure]);
|
|
978
|
+
return { align, maxHeight, measured, triggerRef, verticalAlign };
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
// src/InlineColorPicker.tsx
|
|
982
|
+
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
983
|
+
var EMOJI_PATTERN = /\p{Extended_Pictographic}/u;
|
|
984
|
+
var DEFAULT_SIZE = 48;
|
|
985
|
+
var SWATCH_SIZE = 28;
|
|
986
|
+
var SWATCHES_PADDING = 8;
|
|
987
|
+
var SWATCHES_GAP = 6;
|
|
988
|
+
var SWATCHES_BORDER_WIDTH = 2;
|
|
989
|
+
var MIN_COLUMNS = 4;
|
|
990
|
+
var MAX_COLUMNS = 5;
|
|
991
|
+
var SCREEN_MARGIN = 40;
|
|
992
|
+
function widthForColumns(columns) {
|
|
993
|
+
return SWATCHES_BORDER_WIDTH * 2 + SWATCHES_PADDING * 2 + SWATCH_SIZE * columns + SWATCHES_GAP * (columns - 1);
|
|
994
|
+
}
|
|
995
|
+
function getInlineColorPickerContentSize(swatchCount, windowWidth, columns) {
|
|
996
|
+
const autoColumns = (0, import_core8.clamp)(Math.floor((windowWidth - 2 * SCREEN_MARGIN + SWATCHES_GAP) / (SWATCH_SIZE + SWATCHES_GAP)), MIN_COLUMNS, MAX_COLUMNS);
|
|
997
|
+
const resolvedColumns = columns ?? autoColumns;
|
|
998
|
+
const width = widthForColumns(resolvedColumns);
|
|
999
|
+
const rows = Math.ceil(swatchCount / resolvedColumns);
|
|
1000
|
+
const height = SWATCHES_BORDER_WIDTH * 2 + SWATCHES_PADDING * 2 + SWATCH_SIZE * rows + SWATCHES_GAP * (rows - 1);
|
|
1001
|
+
return { width, height };
|
|
1002
|
+
}
|
|
1003
|
+
function InlineColorPicker({ id, host, value, onChange, previewValue, swatches = import_auto_paper8.defaultColors, takenValue, allowSwapTaken, dark, align: forcedAlign, alignOverride, rotation: rotationOverride, icon = "palette", tag, labelFontFamily = MONO_FONT, autoDismiss = true, columns, size = DEFAULT_SIZE }) {
|
|
1004
|
+
const ambientRotation = (0, import_core8.useRotation)();
|
|
1005
|
+
const rotation = rotationOverride ?? ambientRotation;
|
|
1006
|
+
const menuBg = dark ? "#000000" : "#FFFFFF";
|
|
1007
|
+
const { width: windowWidth } = (0, import_react_native18.useWindowDimensions)();
|
|
1008
|
+
const { width: swatchesWidth, height: swatchesHeight } = getInlineColorPickerContentSize(swatches.length, windowWidth, columns);
|
|
1009
|
+
const open = host.openId === id;
|
|
1010
|
+
const auto = useAutoAlign(open, swatchesWidth, swatchesHeight, rotation);
|
|
1011
|
+
const placement = alignOverride ?? auto;
|
|
1012
|
+
const { maxHeight, measured, triggerRef, verticalAlign } = placement;
|
|
1013
|
+
const align = forcedAlign ?? placement.align;
|
|
1014
|
+
const displayFor = previewValue ?? ((hex) => hex);
|
|
1015
|
+
const displayValue = displayFor(value);
|
|
1016
|
+
const contrastColor = (0, import_auto_paper8.getContrastColor)(displayValue);
|
|
1017
|
+
const tagFontSize = size * (tag && EMOJI_PATTERN.test(tag) ? 0.6 : 0.4);
|
|
1018
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native18.View, { style: [styles14.anchor, open && styles14.anchorOpen], children: [
|
|
1019
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_feedback_press5.TouchableRipple, { onPress: () => host.toggle(id), borderless: true, style: [styles14.trigger, { backgroundColor: displayValue, borderRadius: size / 2, height: size, width: size }], children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native18.View, { ref: triggerRef, collapsable: false, style: styles14.triggerMeasure, children: tag ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native_paper10.Text, { style: [styles14.tagLabel, { color: contrastColor, fontFamily: labelFontFamily, fontSize: tagFontSize }], numberOfLines: 1, adjustsFontSizeToFit: true, children: tag }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native_paper10.Icon, { source: icon, size: size * 0.6, color: contrastColor }) }) }),
|
|
1020
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: displayValue, caretBorderWidth: SWATCHES_BORDER_WIDTH, triggerSize: size, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native18.ScrollView, { style: [styles14.swatches, { backgroundColor: menuBg, borderColor: displayValue, width: swatchesWidth, maxHeight }], contentContainerStyle: styles14.swatchesContent, showsVerticalScrollIndicator: false, children: swatches.map((swatch) => {
|
|
1021
|
+
const selected = swatch.value.toLowerCase() === value.toLowerCase();
|
|
1022
|
+
const taken = !selected && !!takenValue && swatch.value.toLowerCase() === takenValue.toLowerCase();
|
|
1023
|
+
const swappable = taken && allowSwapTaken;
|
|
1024
|
+
const swatchDisplay = displayFor(swatch.value);
|
|
1025
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1026
|
+
import_feedback_press5.TouchableRipple,
|
|
1027
|
+
{
|
|
1028
|
+
disabled: taken && !swappable,
|
|
1029
|
+
onPress: () => {
|
|
1030
|
+
onChange(swatch.value);
|
|
1031
|
+
if (autoDismiss) host.close();
|
|
1032
|
+
},
|
|
1033
|
+
borderless: true,
|
|
1034
|
+
style: [styles14.swatch, { backgroundColor: swatchDisplay }, selected && styles14.swatchSelected, taken && !swappable && styles14.swatchTaken],
|
|
1035
|
+
children: selected ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native_paper10.Icon, { source: "check", size: 16, color: (0, import_auto_paper8.getContrastColor)(swatchDisplay) }) : swappable ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native_paper10.Icon, { source: "swap-horizontal", size: 16, color: (0, import_auto_paper8.getContrastColor)(swatchDisplay) }) : taken ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native_paper10.Icon, { source: "close", size: 16, color: (0, import_auto_paper8.getContrastColor)(swatchDisplay) }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native18.View, {})
|
|
1036
|
+
},
|
|
1037
|
+
swatch.value
|
|
1038
|
+
);
|
|
1039
|
+
}) }) })
|
|
1040
|
+
] });
|
|
1041
|
+
}
|
|
1042
|
+
var styles14 = import_react_native18.StyleSheet.create({
|
|
1043
|
+
anchor: {
|
|
1044
|
+
position: "relative"
|
|
1045
|
+
},
|
|
1046
|
+
// See SectionedDropdown's identical comment - React Native Web gives every position:'relative' view
|
|
1047
|
+
// its own stacking context, so the elevation has to live on the anchor itself, not just the
|
|
1048
|
+
// popover content nested inside it, to correctly paint above this anchor's own later siblings.
|
|
1049
|
+
anchorOpen: {
|
|
1050
|
+
zIndex: 100
|
|
1051
|
+
},
|
|
1052
|
+
swatch: {
|
|
1053
|
+
alignItems: "center",
|
|
1054
|
+
borderRadius: SWATCH_SIZE / 2,
|
|
1055
|
+
height: SWATCH_SIZE,
|
|
1056
|
+
justifyContent: "center",
|
|
1057
|
+
width: SWATCH_SIZE
|
|
1058
|
+
},
|
|
1059
|
+
swatchSelected: {
|
|
1060
|
+
borderColor: "#ffffff",
|
|
1061
|
+
borderWidth: 2
|
|
1062
|
+
},
|
|
1063
|
+
swatchTaken: {
|
|
1064
|
+
opacity: 0.35
|
|
1065
|
+
},
|
|
1066
|
+
swatches: {
|
|
1067
|
+
borderRadius: 12,
|
|
1068
|
+
borderWidth: SWATCHES_BORDER_WIDTH,
|
|
1069
|
+
elevation: 8,
|
|
1070
|
+
shadowColor: "#000000",
|
|
1071
|
+
shadowOffset: { height: 2, width: 0 },
|
|
1072
|
+
shadowOpacity: 0.3,
|
|
1073
|
+
shadowRadius: 8
|
|
1074
|
+
// width is set inline above - border-box sizing means it has to include the border too
|
|
1075
|
+
// (2*SWATCHES_BORDER_WIDTH), not just padding+content, or exactly enough room goes missing that
|
|
1076
|
+
// the last column silently wraps to a new row. Anything wider than the exact sum just shows as
|
|
1077
|
+
// dead space on the right edge of each row instead.
|
|
1078
|
+
},
|
|
1079
|
+
// Separate from `swatches` itself - see SectionedDropdown's identical menu/menuContent split.
|
|
1080
|
+
// The scroll frame's own bounds (including maxHeight) live on the ScrollView; the actual grid
|
|
1081
|
+
// wrapping belongs to its contentContainerStyle, which sizes to the unclamped content instead.
|
|
1082
|
+
swatchesContent: {
|
|
1083
|
+
flexDirection: "row",
|
|
1084
|
+
flexWrap: "wrap",
|
|
1085
|
+
gap: SWATCHES_GAP,
|
|
1086
|
+
padding: SWATCHES_PADDING
|
|
1087
|
+
},
|
|
1088
|
+
tagLabel: {
|
|
1089
|
+
fontWeight: "700",
|
|
1090
|
+
letterSpacing: 0.5
|
|
1091
|
+
},
|
|
1092
|
+
// borderRadius/height/width come from the `size` prop instead (see render-site override) - no
|
|
1093
|
+
// fixed default here, since this style object is shared by every caller regardless of size.
|
|
1094
|
+
trigger: {
|
|
1095
|
+
alignItems: "center",
|
|
1096
|
+
alignSelf: "flex-start",
|
|
1097
|
+
justifyContent: "center"
|
|
1098
|
+
},
|
|
1099
|
+
// Wraps just the icon/tag, inside the TouchableRipple, purely so useAutoAlign has a plain View
|
|
1100
|
+
// to attach its measurement ref to - TouchableRipple itself doesn't forward a ref to a
|
|
1101
|
+
// measurable native node. Padded horizontally so a multi-character tag doesn't butt right up
|
|
1102
|
+
// against the trigger's own circular edge (an icon alone doesn't need it, but this style is
|
|
1103
|
+
// shared by both).
|
|
1104
|
+
triggerMeasure: {
|
|
1105
|
+
alignItems: "center",
|
|
1106
|
+
height: "100%",
|
|
1107
|
+
justifyContent: "center",
|
|
1108
|
+
paddingHorizontal: 4,
|
|
1109
|
+
width: "100%"
|
|
1110
|
+
}
|
|
1111
|
+
});
|
|
1112
|
+
|
|
1113
|
+
// src/PressAwayOverlay.tsx
|
|
1114
|
+
var import_react_native19 = require("react-native");
|
|
1115
|
+
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1116
|
+
function PressAwayOverlay({ active, onPress, style }) {
|
|
1117
|
+
if (!active) return null;
|
|
1118
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native19.Pressable, { accessibilityLabel: "Dismiss", accessibilityRole: "button", onPress, style: [import_react_native19.StyleSheet.absoluteFill, style] });
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
// src/StaggeredWord.tsx
|
|
1122
|
+
var import_react9 = require("react");
|
|
1123
|
+
var import_react_native20 = require("react-native");
|
|
1124
|
+
var import_react_native_reanimated = __toESM(require("react-native-reanimated"));
|
|
1125
|
+
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
845
1126
|
var STAGGER_MS = 45;
|
|
846
1127
|
var LETTER_DURATION_MS = 320;
|
|
847
1128
|
function getStaggeredWordDuration(letterCount) {
|
|
@@ -849,7 +1130,7 @@ function getStaggeredWordDuration(letterCount) {
|
|
|
849
1130
|
}
|
|
850
1131
|
function AnimatedLetter({ char, index, color, reducedMotion, fontFamily, fontSize, lineHeight, fontWeight, letterSpacing }) {
|
|
851
1132
|
const progress = (0, import_react_native_reanimated.useSharedValue)(reducedMotion ? 1 : 0);
|
|
852
|
-
(0,
|
|
1133
|
+
(0, import_react9.useEffect)(() => {
|
|
853
1134
|
if (reducedMotion) return;
|
|
854
1135
|
progress.value = (0, import_react_native_reanimated.withDelay)(index * STAGGER_MS, (0, import_react_native_reanimated.withTiming)(1, { duration: LETTER_DURATION_MS, easing: import_react_native_reanimated.Easing.out(import_react_native_reanimated.Easing.back(1.5)) }));
|
|
855
1136
|
}, [reducedMotion]);
|
|
@@ -857,12 +1138,12 @@ function AnimatedLetter({ char, index, color, reducedMotion, fontFamily, fontSiz
|
|
|
857
1138
|
opacity: progress.value,
|
|
858
1139
|
transform: [{ translateY: (1 - progress.value) * 12 }, { scale: 0.85 + progress.value * 0.15 }]
|
|
859
1140
|
}));
|
|
860
|
-
return /* @__PURE__ */ (0,
|
|
1141
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native_reanimated.default.Text, { allowFontScaling: false, style: [{ color, fontFamily, fontSize, lineHeight, fontWeight, letterSpacing }, style], children: char });
|
|
861
1142
|
}
|
|
862
1143
|
function StaggeredWord({ word, color, fontFamily, fontSize, lineHeight, reducedMotion, startIndex = 0, fontWeight = "bold", letterSpacing, style, onLayout }) {
|
|
863
|
-
return /* @__PURE__ */ (0,
|
|
1144
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native20.View, { style: [styles15.row, style], onLayout, children: word.split("").map((char, i) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(AnimatedLetter, { char, index: startIndex + i, color, reducedMotion, fontFamily, fontSize, lineHeight, fontWeight, letterSpacing }, i)) });
|
|
864
1145
|
}
|
|
865
|
-
var
|
|
1146
|
+
var styles15 = import_react_native20.StyleSheet.create({
|
|
866
1147
|
row: {
|
|
867
1148
|
flexDirection: "row"
|
|
868
1149
|
}
|
|
@@ -870,12 +1151,23 @@ var styles13 = import_react_native16.StyleSheet.create({
|
|
|
870
1151
|
|
|
871
1152
|
// src/UpdateDialog.tsx
|
|
872
1153
|
var import_updater2 = require("@rific/updater");
|
|
873
|
-
var
|
|
1154
|
+
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
874
1155
|
function UpdateDialog({ rotation = 0, autoCheck = true, autoPrompt = true, onError }) {
|
|
875
1156
|
const { manifest, onConfirm, respond } = useUpdateConfirmBridge();
|
|
876
1157
|
(0, import_updater2.useUpdater)({ autoCheck, autoPrompt, onConfirm, onError });
|
|
877
1158
|
const date = manifest ? new Date(manifest.createdAt) : null;
|
|
878
|
-
return /* @__PURE__ */ (0,
|
|
1159
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(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) });
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
// src/usePopoverHost.ts
|
|
1163
|
+
var import_react10 = require("react");
|
|
1164
|
+
function usePopoverHost() {
|
|
1165
|
+
const [openId, setOpenId] = (0, import_react10.useState)(null);
|
|
1166
|
+
const toggle = (0, import_react10.useCallback)((id) => {
|
|
1167
|
+
setOpenId((prev) => prev === id ? null : id);
|
|
1168
|
+
}, []);
|
|
1169
|
+
const close = (0, import_react10.useCallback)(() => setOpenId(null), []);
|
|
1170
|
+
return { openId, toggle, close };
|
|
879
1171
|
}
|
|
880
1172
|
// Annotate the CommonJS export names for ESM import in node:
|
|
881
1173
|
0 && (module.exports = {
|
|
@@ -889,19 +1181,27 @@ function UpdateDialog({ rotation = 0, autoCheck = true, autoPrompt = true, onErr
|
|
|
889
1181
|
ContentGutter,
|
|
890
1182
|
CornerActionButtons,
|
|
891
1183
|
DialogHeader,
|
|
1184
|
+
InlineColorPicker,
|
|
892
1185
|
LOCKED_BADGE_COLOR,
|
|
893
1186
|
MONO_FONT,
|
|
894
1187
|
OverlayBackdrop,
|
|
895
1188
|
OverlayCard,
|
|
1189
|
+
PopoverBody,
|
|
1190
|
+
PressAwayOverlay,
|
|
896
1191
|
RotatedFrame,
|
|
897
1192
|
StaggeredWord,
|
|
898
1193
|
StatRow,
|
|
899
1194
|
StatSection,
|
|
900
1195
|
UpdateDialog,
|
|
1196
|
+
WELL_SHADOW,
|
|
1197
|
+
getInlineColorPickerContentSize,
|
|
901
1198
|
getStaggeredWordDuration,
|
|
902
1199
|
isCompactDialogHeight,
|
|
903
1200
|
overlayActionStyles,
|
|
904
1201
|
overlayStyles,
|
|
1202
|
+
useAutoAlign,
|
|
905
1203
|
useCompactDialog,
|
|
906
|
-
useOverlayCardColors
|
|
1204
|
+
useOverlayCardColors,
|
|
1205
|
+
usePopoverHost,
|
|
1206
|
+
useWellColors
|
|
907
1207
|
});
|