@tastic/hud 0.8.3 → 0.8.4
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/dist/index.d.mts +12 -4
- package/dist/index.d.ts +12 -4
- package/dist/index.js +187 -160
- package/dist/index.mjs +166 -140
- package/package.json +4 -3
- package/src/BaseSettingsDialog.tsx +12 -27
- package/src/ConfirmDialog.tsx +9 -6
- package/src/UpdateDialog.tsx +28 -0
- package/src/index.ts +1 -0
- package/src/useUpdateConfirmBridge.ts +30 -0
package/dist/index.d.mts
CHANGED
|
@@ -64,11 +64,11 @@ declare function BaseStatsScreen({ rotation: rotationOverride, title, titleVaria
|
|
|
64
64
|
interface ConfirmDialogProps {
|
|
65
65
|
visible: boolean;
|
|
66
66
|
title: string;
|
|
67
|
-
message:
|
|
67
|
+
message: ReactNode;
|
|
68
68
|
confirmLabel: string;
|
|
69
|
-
cancelLabel
|
|
69
|
+
cancelLabel?: string;
|
|
70
70
|
onConfirm: () => void;
|
|
71
|
-
onCancel
|
|
71
|
+
onCancel?: () => void;
|
|
72
72
|
rotation?: ViewRotation;
|
|
73
73
|
icon?: string;
|
|
74
74
|
destructive?: boolean;
|
|
@@ -337,4 +337,12 @@ interface TriggerGaugeProps {
|
|
|
337
337
|
|
|
338
338
|
declare function TriggerGaugeHost(props: TriggerGaugeProps): react.JSX.Element;
|
|
339
339
|
|
|
340
|
-
|
|
340
|
+
interface UpdateDialogProps {
|
|
341
|
+
rotation?: ViewRotation;
|
|
342
|
+
autoCheck?: boolean;
|
|
343
|
+
autoPrompt?: boolean;
|
|
344
|
+
onError?: (message: string) => void;
|
|
345
|
+
}
|
|
346
|
+
declare function UpdateDialog({ rotation, autoCheck, autoPrompt, onError }: UpdateDialogProps): react.JSX.Element;
|
|
347
|
+
|
|
348
|
+
export { AchievementRow, BaseSettingsDialog, type BaseSettingsDialogProps, BaseStatsScreen, ConfirmDialog, type ConfirmDialogProps, ContentGutter, ControlSchemePicker, type ControlSchemePickerProps, CornerActionButtons, type CornerStatusBadgeSeat, CornerStatusBadges, type CornerStatusBadgesProps, InlineColorPicker, LABELED_DROPDOWN_POPOVER_WIDTH, LOCKED_BADGE_COLOR, LabeledDropdown, type LabeledDropdownOption, MONO_FONT, type MenuOption, type MenuSection, type MultiSelectSection, type OrientationMode, type OverlayCardColors, type PopoverAlign, PopoverBody, type PopoverHost, type PopoverRotation, type PopoverVerticalAlign, PressAwayOverlay, ReadyButton, SectionedDropdown, SharedActionBand, type SingleSelectSection, StatRow, StatSection, TriggerGaugeHost, type TriggerGaugeProps, UpdateDialog, type UpdateDialogProps, getLabeledDropdownContentHeight, getOverlayCardColors, loadSkiaWeb, overlayStyles, useAutoAlign, usePopoverHost };
|
package/dist/index.d.ts
CHANGED
|
@@ -64,11 +64,11 @@ declare function BaseStatsScreen({ rotation: rotationOverride, title, titleVaria
|
|
|
64
64
|
interface ConfirmDialogProps {
|
|
65
65
|
visible: boolean;
|
|
66
66
|
title: string;
|
|
67
|
-
message:
|
|
67
|
+
message: ReactNode;
|
|
68
68
|
confirmLabel: string;
|
|
69
|
-
cancelLabel
|
|
69
|
+
cancelLabel?: string;
|
|
70
70
|
onConfirm: () => void;
|
|
71
|
-
onCancel
|
|
71
|
+
onCancel?: () => void;
|
|
72
72
|
rotation?: ViewRotation;
|
|
73
73
|
icon?: string;
|
|
74
74
|
destructive?: boolean;
|
|
@@ -337,4 +337,12 @@ interface TriggerGaugeProps {
|
|
|
337
337
|
|
|
338
338
|
declare function TriggerGaugeHost(props: TriggerGaugeProps): react.JSX.Element;
|
|
339
339
|
|
|
340
|
-
|
|
340
|
+
interface UpdateDialogProps {
|
|
341
|
+
rotation?: ViewRotation;
|
|
342
|
+
autoCheck?: boolean;
|
|
343
|
+
autoPrompt?: boolean;
|
|
344
|
+
onError?: (message: string) => void;
|
|
345
|
+
}
|
|
346
|
+
declare function UpdateDialog({ rotation, autoCheck, autoPrompt, onError }: UpdateDialogProps): react.JSX.Element;
|
|
347
|
+
|
|
348
|
+
export { AchievementRow, BaseSettingsDialog, type BaseSettingsDialogProps, BaseStatsScreen, ConfirmDialog, type ConfirmDialogProps, ContentGutter, ControlSchemePicker, type ControlSchemePickerProps, CornerActionButtons, type CornerStatusBadgeSeat, CornerStatusBadges, type CornerStatusBadgesProps, InlineColorPicker, LABELED_DROPDOWN_POPOVER_WIDTH, LOCKED_BADGE_COLOR, LabeledDropdown, type LabeledDropdownOption, MONO_FONT, type MenuOption, type MenuSection, type MultiSelectSection, type OrientationMode, type OverlayCardColors, type PopoverAlign, PopoverBody, type PopoverHost, type PopoverRotation, type PopoverVerticalAlign, PressAwayOverlay, ReadyButton, SectionedDropdown, SharedActionBand, type SingleSelectSection, StatRow, StatSection, TriggerGaugeHost, type TriggerGaugeProps, UpdateDialog, type UpdateDialogProps, getLabeledDropdownContentHeight, getOverlayCardColors, loadSkiaWeb, overlayStyles, useAutoAlign, usePopoverHost };
|
package/dist/index.js
CHANGED
|
@@ -28,22 +28,22 @@ __export(TriggerGauge_exports, {
|
|
|
28
28
|
function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, dashWidth, startDeg = DEFAULT_START_DEG, endDeg = startDeg }) {
|
|
29
29
|
const totalDurationMs = MOUNT_DURATION_MS + Math.max(0, segments - 1) * MOUNT_STAGGER_MS;
|
|
30
30
|
const mountProgress = (0, import_react_native_reanimated.useSharedValue)(0);
|
|
31
|
-
(0,
|
|
31
|
+
(0, import_react5.useLayoutEffect)(() => {
|
|
32
32
|
mountProgress.value = (0, import_react_native_reanimated.withTiming)(1, { duration: totalDurationMs, easing: import_react_native_reanimated.Easing.out(import_react_native_reanimated.Easing.cubic) });
|
|
33
33
|
}, []);
|
|
34
34
|
const rawSweepDeg = ((endDeg - startDeg) % 360 + 360) % 360;
|
|
35
35
|
const totalSweepDeg = rawSweepDeg === 0 ? 360 : rawSweepDeg;
|
|
36
36
|
const step = segments > 0 ? totalSweepDeg / segments : 0;
|
|
37
|
-
const centerDeg = (0,
|
|
37
|
+
const centerDeg = (0, import_react5.useCallback)((i) => startDeg + (i + 0.5) * step, [startDeg, step]);
|
|
38
38
|
const singleSelect = litIndices.length === 1;
|
|
39
39
|
const angleDeg = (0, import_react_native_reanimated.useSharedValue)(centerDeg(litIndices[0] ?? 0));
|
|
40
40
|
const litIndicesKey = [...litIndices].sort((a, b) => a - b).join(",");
|
|
41
|
-
const [transitionFrom, setTransitionFrom] = (0,
|
|
41
|
+
const [transitionFrom, setTransitionFrom] = (0, import_react5.useState)(litIndices);
|
|
42
42
|
const transitionFromKey = [...transitionFrom].sort((a, b) => a - b).join(",");
|
|
43
|
-
const lastKeyRef = (0,
|
|
44
|
-
const lastIndicesRef = (0,
|
|
43
|
+
const lastKeyRef = (0, import_react5.useRef)(litIndicesKey);
|
|
44
|
+
const lastIndicesRef = (0, import_react5.useRef)(litIndices);
|
|
45
45
|
const selectionProgress = (0, import_react_native_reanimated.useSharedValue)(1);
|
|
46
|
-
(0,
|
|
46
|
+
(0, import_react5.useLayoutEffect)(() => {
|
|
47
47
|
if (litIndicesKey !== lastKeyRef.current) {
|
|
48
48
|
if (singleSelect && lastIndicesRef.current.length === 1) {
|
|
49
49
|
angleDeg.value = (0, import_react_native_reanimated.withTiming)(centerDeg(litIndices[0]), { duration: SELECTION_TRANSITION_DURATION_MS, easing: import_react_native_reanimated.Easing.out(import_react_native_reanimated.Easing.cubic) });
|
|
@@ -125,13 +125,13 @@ function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, das
|
|
|
125
125
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native_skia.Path, { path: litPath, style: "stroke", strokeWidth: LIT_THICKNESS, strokeCap: "round", color: accentColor, opacity: 1 })
|
|
126
126
|
] }) });
|
|
127
127
|
}
|
|
128
|
-
var import_react_native_skia, import_core5,
|
|
128
|
+
var import_react_native_skia, import_core5, import_react5, import_react_native9, import_react_native_reanimated, import_jsx_runtime8, UNLIT_THICKNESS, LIT_THICKNESS, DASH_GAP_PX, ARC_GAP, DEFAULT_START_DEG, MIN_DASH_ANGLE_DEG, MOUNT_DURATION_MS, MOUNT_STAGGER_MS, SELECTION_TRANSITION_DURATION_MS, styles7;
|
|
129
129
|
var init_TriggerGauge = __esm({
|
|
130
130
|
"src/TriggerGauge.tsx"() {
|
|
131
131
|
"use strict";
|
|
132
132
|
import_react_native_skia = require("@shopify/react-native-skia");
|
|
133
133
|
import_core5 = require("@tastic/core");
|
|
134
|
-
|
|
134
|
+
import_react5 = require("react");
|
|
135
135
|
import_react_native9 = require("react-native");
|
|
136
136
|
import_react_native_reanimated = require("react-native-reanimated");
|
|
137
137
|
import_jsx_runtime8 = require("react/jsx-runtime");
|
|
@@ -179,6 +179,7 @@ __export(index_exports, {
|
|
|
179
179
|
StatRow: () => StatRow,
|
|
180
180
|
StatSection: () => StatSection,
|
|
181
181
|
TriggerGaugeHost: () => TriggerGaugeHost,
|
|
182
|
+
UpdateDialog: () => UpdateDialog,
|
|
182
183
|
getLabeledDropdownContentHeight: () => getLabeledDropdownContentHeight,
|
|
183
184
|
getOverlayCardColors: () => getOverlayCardColors,
|
|
184
185
|
loadSkiaWeb: () => loadSkiaWeb,
|
|
@@ -257,11 +258,18 @@ var styles = import_react_native.StyleSheet.create({
|
|
|
257
258
|
});
|
|
258
259
|
|
|
259
260
|
// src/BaseSettingsDialog.tsx
|
|
261
|
+
var import_auto_paper3 = require("@rific/auto-paper");
|
|
262
|
+
var import_feedback_press2 = require("@rific/feedback-press");
|
|
263
|
+
var import_updater = require("@rific/updater");
|
|
264
|
+
var import_core2 = require("@tastic/core");
|
|
265
|
+
var import_react2 = require("react");
|
|
266
|
+
var import_react_native4 = require("react-native");
|
|
267
|
+
var import_react_native_paper3 = require("react-native-paper");
|
|
268
|
+
|
|
269
|
+
// src/ConfirmDialog.tsx
|
|
260
270
|
var import_auto_paper2 = require("@rific/auto-paper");
|
|
261
271
|
var import_feedback_press = require("@rific/feedback-press");
|
|
262
|
-
var import_updater = require("@rific/updater");
|
|
263
272
|
var import_core = require("@tastic/core");
|
|
264
|
-
var import_react = require("react");
|
|
265
273
|
var import_react_native3 = require("react-native");
|
|
266
274
|
var import_react_native_paper2 = require("react-native-paper");
|
|
267
275
|
|
|
@@ -296,56 +304,145 @@ var overlayStyles = import_react_native2.StyleSheet.create({
|
|
|
296
304
|
}
|
|
297
305
|
});
|
|
298
306
|
|
|
299
|
-
// src/
|
|
307
|
+
// src/ConfirmDialog.tsx
|
|
300
308
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
309
|
+
function ConfirmDialog({ visible, title, message, confirmLabel, cancelLabel, onConfirm, onCancel, rotation = 0, icon = "help-circle-outline", destructive = false }) {
|
|
310
|
+
const { dark, colors } = (0, import_auto_paper2.useAutoPaperTheme)();
|
|
311
|
+
if (!visible) return null;
|
|
312
|
+
const { fg, cardBg, cardBorder } = getOverlayCardColors(dark);
|
|
313
|
+
const accent = destructive ? colors.danger : colors.primary;
|
|
314
|
+
const onAccent = destructive ? colors.onDanger : colors.onPrimary;
|
|
315
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.View, { style: [overlayStyles.overlay, styles2.overlay], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.View, { style: [overlayStyles.card, styles2.card, { backgroundColor: cardBg, borderColor: cardBorder }, (0, import_core.toRotationStyle)(rotation)], children: [
|
|
316
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.Icon, { source: icon, size: 64, color: accent }),
|
|
317
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.Text, { variant: "headlineLarge", style: [styles2.title, { color: accent }], children: title }),
|
|
318
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.Text, { variant: "bodyLarge", style: [styles2.body, { color: fg }], children: message }),
|
|
319
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.View, { style: styles2.actions, children: [
|
|
320
|
+
cancelLabel !== void 0 && onCancel !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_feedback_press.Button, { mode: "outlined", onPress: onCancel, style: styles2.actionButton, children: cancelLabel }),
|
|
321
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_feedback_press.Button, { mode: "contained", onPress: onConfirm, style: styles2.actionButton, buttonColor: accent, textColor: onAccent, children: confirmLabel })
|
|
322
|
+
] })
|
|
323
|
+
] }) }) });
|
|
324
|
+
}
|
|
325
|
+
var styles2 = import_react_native3.StyleSheet.create({
|
|
326
|
+
// flexBasis (not flex: 1's own 0%) is each button's real floor: whenever both fit side by side,
|
|
327
|
+
// flexGrow still splits any leftover width evenly beyond that floor, same visual result as the
|
|
328
|
+
// old flex: 1 on a roomy screen - but a button can never be squeezed narrower than 128, only
|
|
329
|
+
// wrap to its own row instead (see actions' flexWrap below). react-native-paper's Button
|
|
330
|
+
// hardcodes numberOfLines={1} on its label with no override, so a button squeezed under its
|
|
331
|
+
// label's natural width silently ellipsizes ("Cancel" -> "Can...") instead of wrapping - assumed
|
|
332
|
+
// fixable by just giving the row more width, until confirmed live that these two-word labels
|
|
333
|
+
// (Cancel/Reset/New Game) can still lose the truncation fight even with the extra room card's own
|
|
334
|
+
// width fix below provides, on a narrow enough screen. flexBasis is the real fix: past a certain
|
|
335
|
+
// width there's no side-by-side arrangement that fits both buttons at their natural label size,
|
|
336
|
+
// so the layout has to give (stack) rather than the label (truncate).
|
|
337
|
+
actionButton: {
|
|
338
|
+
flexBasis: 128,
|
|
339
|
+
flexGrow: 1
|
|
340
|
+
},
|
|
341
|
+
actions: {
|
|
342
|
+
flexDirection: "row",
|
|
343
|
+
flexWrap: "wrap",
|
|
344
|
+
gap: 12,
|
|
345
|
+
width: "100%"
|
|
346
|
+
},
|
|
347
|
+
body: {
|
|
348
|
+
textAlign: "center"
|
|
349
|
+
},
|
|
350
|
+
// Additive on top of overlayCard's own shared `card` shape (borderRadius/borderWidth/gap/maxWidth/
|
|
351
|
+
// padding) — claims its full allowance instead of just maxWidth alone, which only caps how wide the
|
|
352
|
+
// card is allowed to get - without an explicit width, a flex-centered child sizes to its own content
|
|
353
|
+
// instead of stretching, so the card (and therefore actions below) can end up narrower than the
|
|
354
|
+
// screen actually has room for, needlessly forcing the action row to wrap sooner than it has to.
|
|
355
|
+
card: {
|
|
356
|
+
width: "100%"
|
|
357
|
+
},
|
|
358
|
+
// Additive on top of overlayCard's own shared `overlay` backdrop — gives the card room to breathe
|
|
359
|
+
// from the screen edges now that it reliably stretches to fill its full width allowance (see
|
|
360
|
+
// card's own width comment) - without this, width: '100%' would run the card edge-to-edge on a
|
|
361
|
+
// screen narrower than maxWidth's own 360.
|
|
362
|
+
overlay: {
|
|
363
|
+
paddingHorizontal: 24
|
|
364
|
+
},
|
|
365
|
+
// textAlign is load-bearing, not decorative, once `title` wraps to more than one line - centered
|
|
366
|
+
// within card's own alignItems: 'center' only centers the Text's block as a whole; each wrapped
|
|
367
|
+
// line inside that block still defaults to left-aligned without this.
|
|
368
|
+
title: {
|
|
369
|
+
fontWeight: "bold",
|
|
370
|
+
textAlign: "center"
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
// src/useUpdateConfirmBridge.ts
|
|
375
|
+
var import_react = require("react");
|
|
376
|
+
function useUpdateConfirmBridge() {
|
|
377
|
+
const [manifest, setManifest] = (0, import_react.useState)(null);
|
|
378
|
+
const resolveRef = (0, import_react.useRef)(null);
|
|
379
|
+
const onConfirm = (0, import_react.useCallback)(
|
|
380
|
+
(next) => new Promise((resolve) => {
|
|
381
|
+
resolveRef.current = resolve;
|
|
382
|
+
setManifest(next);
|
|
383
|
+
}),
|
|
384
|
+
[]
|
|
385
|
+
);
|
|
386
|
+
const respond = (0, import_react.useCallback)((confirmed) => {
|
|
387
|
+
setManifest(null);
|
|
388
|
+
resolveRef.current?.(confirmed);
|
|
389
|
+
resolveRef.current = null;
|
|
390
|
+
}, []);
|
|
391
|
+
return { manifest, onConfirm, respond };
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// src/BaseSettingsDialog.tsx
|
|
395
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
301
396
|
function SettingIcon({ source, color, containerColor }) {
|
|
302
|
-
return /* @__PURE__ */ (0,
|
|
397
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native4.View, { style: [styles3.iconBadge, { backgroundColor: containerColor }], children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Icon, { source, size: 18, color }) });
|
|
303
398
|
}
|
|
304
399
|
function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, version, lockOrientation, onLockOrientationChange, deferBottomEdgeGestures, onDeferBottomEdgeGestures, hideSound = false, hideHaptics = false, hideAppearance = false, hideUpdateCheck = false, onUpdateError, children }) {
|
|
305
|
-
const {
|
|
306
|
-
const ambientRotation = (0,
|
|
400
|
+
const { colors } = (0, import_auto_paper3.useAutoPaperTheme)();
|
|
401
|
+
const ambientRotation = (0, import_core2.useRotation)();
|
|
307
402
|
const rotation = rotationOverride ?? ambientRotation;
|
|
308
|
-
const isTouchPrimary = (0,
|
|
309
|
-
const { settings: hapticSettings, set: setHapticSettings } = (0,
|
|
310
|
-
const { settings: soundSettings, set: setSoundSettings } = (0,
|
|
311
|
-
const sound = (0,
|
|
312
|
-
const { forceShort: forceHapticFeedback } = (0,
|
|
313
|
-
const [infoMessage, setInfoMessage] = (0,
|
|
403
|
+
const isTouchPrimary = (0, import_core2.useIsTouchPrimaryDevice)();
|
|
404
|
+
const { settings: hapticSettings, set: setHapticSettings } = (0, import_feedback_press2.useHapticSettings)();
|
|
405
|
+
const { settings: soundSettings, set: setSoundSettings } = (0, import_feedback_press2.useSoundSettings)();
|
|
406
|
+
const sound = (0, import_react2.useContext)(import_feedback_press2.SoundContext);
|
|
407
|
+
const { forceShort: forceHapticFeedback } = (0, import_feedback_press2.useVibration)();
|
|
408
|
+
const [infoMessage, setInfoMessage] = (0, import_react2.useState)(null);
|
|
409
|
+
const { manifest: updateManifest, onConfirm: onUpdateConfirm, respond: respondToUpdateConfirm } = useUpdateConfirmBridge();
|
|
314
410
|
const { check, checking, updateReady } = (0, import_updater.useUpdater)({
|
|
315
411
|
autoCheck: false,
|
|
316
412
|
autoPrompt: false,
|
|
413
|
+
onConfirm: onUpdateConfirm,
|
|
317
414
|
onError: onUpdateError,
|
|
318
415
|
onInfo: (title, message) => setInfoMessage({ title, message })
|
|
319
416
|
});
|
|
417
|
+
const updateManifestDate = updateManifest ? new Date(updateManifest.createdAt) : null;
|
|
320
418
|
const showLockOrientation = isTouchPrimary && lockOrientation !== void 0 && onLockOrientationChange !== void 0;
|
|
321
|
-
const showEdgeGuard =
|
|
322
|
-
const showHaptics =
|
|
419
|
+
const showEdgeGuard = import_react_native4.Platform.OS === "ios" && deferBottomEdgeGestures !== void 0 && onDeferBottomEdgeGestures !== void 0;
|
|
420
|
+
const showHaptics = import_react_native4.Platform.OS !== "web" && !hideHaptics;
|
|
323
421
|
const showSound = !hideSound;
|
|
324
422
|
const showAppearance = !hideAppearance;
|
|
325
|
-
const showUpdateCheck =
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
/* @__PURE__ */ (0,
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
/* @__PURE__ */ (0,
|
|
334
|
-
|
|
335
|
-
/* @__PURE__ */ (0,
|
|
336
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Pins the current layout" })
|
|
423
|
+
const showUpdateCheck = import_react_native4.Platform.OS !== "web" && !hideUpdateCheck;
|
|
424
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
425
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_auto_paper3.Dialog, { visible, onDismiss, style: [styles3.dialog, (0, import_core2.toRotationStyle)(rotation)], children: [
|
|
426
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_auto_paper3.Dialog.Title, { children: "Settings" }),
|
|
427
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_auto_paper3.Dialog.ScrollArea, { style: styles3.scrollArea, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native4.ScrollView, { contentContainerStyle: styles3.content, showsVerticalScrollIndicator: false, children: [
|
|
428
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native4.View, { style: styles3.toggleGroup, children: [
|
|
429
|
+
showLockOrientation && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_feedback_press2.TouchableRipple, { onPress: () => onLockOrientationChange(!lockOrientation), style: styles3.toggleButton, accessibilityLabel: `Lock orientation ${lockOrientation ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native4.View, { style: styles3.toggleContent, children: [
|
|
430
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SettingIcon, { source: lockOrientation ? "lock" : "lock-open-variant-outline", color: lockOrientation ? colors.secondary : colors.onSurfaceVariant, containerColor: lockOrientation ? colors.secondaryContainer : colors.surfaceVariant }),
|
|
431
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native4.View, { style: styles3.flexShrink, children: [
|
|
432
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Lock Orientation" }),
|
|
433
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Pins the current layout" })
|
|
337
434
|
] })
|
|
338
435
|
] }) }),
|
|
339
|
-
showEdgeGuard && /* @__PURE__ */ (0,
|
|
340
|
-
/* @__PURE__ */ (0,
|
|
341
|
-
/* @__PURE__ */ (0,
|
|
342
|
-
/* @__PURE__ */ (0,
|
|
343
|
-
/* @__PURE__ */ (0,
|
|
436
|
+
showEdgeGuard && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_feedback_press2.TouchableRipple, { onPress: () => onDeferBottomEdgeGestures(!deferBottomEdgeGestures), style: styles3.toggleButton, accessibilityLabel: `Edge guard ${deferBottomEdgeGestures ? "on" : "off"}`, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native4.View, { style: styles3.toggleContent, children: [
|
|
437
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SettingIcon, { source: deferBottomEdgeGestures ? "shield-check-outline" : "shield-off-outline", color: deferBottomEdgeGestures ? colors.secondary : colors.onSurfaceVariant, containerColor: deferBottomEdgeGestures ? colors.secondaryContainer : colors.surfaceVariant }),
|
|
438
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native4.View, { style: styles3.flexShrink, children: [
|
|
439
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Edge Guard" }),
|
|
440
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Text, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Requires a second swipe" })
|
|
344
441
|
] })
|
|
345
442
|
] }) }),
|
|
346
|
-
(showSound || showHaptics) && /* @__PURE__ */ (0,
|
|
347
|
-
showSound && /* @__PURE__ */ (0,
|
|
348
|
-
|
|
443
|
+
(showSound || showHaptics) && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native4.View, { style: styles3.toggleRow, children: [
|
|
444
|
+
showSound && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
445
|
+
import_feedback_press2.TouchableRipple,
|
|
349
446
|
{
|
|
350
447
|
soundDisabled: true,
|
|
351
448
|
onPress: () => {
|
|
@@ -353,16 +450,16 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
|
|
|
353
450
|
setSoundSettings({ enabled });
|
|
354
451
|
if (enabled) sound.selection?.();
|
|
355
452
|
},
|
|
356
|
-
style:
|
|
453
|
+
style: styles3.toggleButtonInRow,
|
|
357
454
|
accessibilityLabel: `Sound ${soundSettings.enabled ? "on" : "off"}`,
|
|
358
|
-
children: /* @__PURE__ */ (0,
|
|
359
|
-
/* @__PURE__ */ (0,
|
|
360
|
-
/* @__PURE__ */ (0,
|
|
455
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native4.View, { style: styles3.toggleContent, children: [
|
|
456
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SettingIcon, { source: soundSettings.enabled ? "volume-high" : "volume-off", color: soundSettings.enabled ? colors.tertiary : colors.onSurfaceVariant, containerColor: soundSettings.enabled ? colors.tertiaryContainer : colors.surfaceVariant }),
|
|
457
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Sound" })
|
|
361
458
|
] })
|
|
362
459
|
}
|
|
363
460
|
),
|
|
364
|
-
showHaptics && /* @__PURE__ */ (0,
|
|
365
|
-
|
|
461
|
+
showHaptics && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
462
|
+
import_feedback_press2.TouchableRipple,
|
|
366
463
|
{
|
|
367
464
|
hapticDisabled: true,
|
|
368
465
|
onPress: () => {
|
|
@@ -370,40 +467,36 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
|
|
|
370
467
|
setHapticSettings({ vibrate });
|
|
371
468
|
if (vibrate) forceHapticFeedback();
|
|
372
469
|
},
|
|
373
|
-
style:
|
|
470
|
+
style: styles3.toggleButtonInRow,
|
|
374
471
|
accessibilityLabel: `Haptics ${hapticSettings.vibrate ? "on" : "off"}`,
|
|
375
|
-
children: /* @__PURE__ */ (0,
|
|
376
|
-
/* @__PURE__ */ (0,
|
|
377
|
-
/* @__PURE__ */ (0,
|
|
472
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native4.View, { style: styles3.toggleContent, children: [
|
|
473
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SettingIcon, { source: hapticSettings.vibrate ? "vibrate" : "vibrate-off", color: hapticSettings.vibrate ? colors.tertiary : colors.onSurfaceVariant, containerColor: hapticSettings.vibrate ? colors.tertiaryContainer : colors.surfaceVariant }),
|
|
474
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Haptics" })
|
|
378
475
|
] })
|
|
379
476
|
}
|
|
380
477
|
)
|
|
381
478
|
] })
|
|
382
479
|
] }),
|
|
383
|
-
showAppearance && /* @__PURE__ */ (0,
|
|
384
|
-
/* @__PURE__ */ (0,
|
|
385
|
-
/* @__PURE__ */ (0,
|
|
480
|
+
showAppearance && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native4.View, { style: styles3.section, children: [
|
|
481
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Text, { variant: "labelMedium", style: [styles3.sectionLabel, { color: colors.onSurfaceVariant }], children: "APPEARANCE" }),
|
|
482
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_auto_paper3.AutoAppearancePicker, { showLabels: false })
|
|
386
483
|
] }),
|
|
387
484
|
children,
|
|
388
|
-
showUpdateCheck && /* @__PURE__ */ (0,
|
|
389
|
-
/* @__PURE__ */ (0,
|
|
485
|
+
showUpdateCheck && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native4.View, { style: styles3.section, children: [
|
|
486
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native_paper3.Text, { variant: "labelSmall", style: [styles3.sectionLabel, { color: colors.onSurfaceVariant }], children: [
|
|
390
487
|
"VERSION ",
|
|
391
488
|
version,
|
|
392
489
|
updateReady ? " \xB7 UPDATE READY" : ""
|
|
393
490
|
] }),
|
|
394
|
-
/* @__PURE__ */ (0,
|
|
491
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_feedback_press2.Button, { mode: "outlined", onPress: check, loading: checking, disabled: checking, children: "Check for Updates" })
|
|
395
492
|
] })
|
|
396
493
|
] }) })
|
|
397
494
|
] }),
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.Text, { variant: "headlineLarge", style: [styles2.overlayTitle, { color: colors.secondary }], children: infoMessage.title }),
|
|
401
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.Text, { variant: "bodyLarge", style: [styles2.overlayBody, { color: fg }], children: infoMessage.message }),
|
|
402
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_feedback_press.Button, { mode: "contained", onPress: () => setInfoMessage(null), style: styles2.overlayButton, buttonColor: colors.primary, textColor: colors.onPrimary, children: "OK" })
|
|
403
|
-
] }) }) })
|
|
495
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ConfirmDialog, { visible: !!updateManifest, title: "Update Available", message: updateManifestDate ? `Released ${updateManifestDate.toLocaleDateString()} at ${updateManifestDate.toLocaleTimeString()}` : "", confirmLabel: "Restart", cancelLabel: "Later", icon: "update", rotation, onConfirm: () => respondToUpdateConfirm(true), onCancel: () => respondToUpdateConfirm(false) }),
|
|
496
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ConfirmDialog, { visible: !!infoMessage, title: infoMessage?.title ?? "", message: infoMessage?.message ?? "", confirmLabel: "OK", icon: "information-outline", rotation, onConfirm: () => setInfoMessage(null) })
|
|
404
497
|
] });
|
|
405
498
|
}
|
|
406
|
-
var
|
|
499
|
+
var styles3 = import_react_native4.StyleSheet.create({
|
|
407
500
|
content: {
|
|
408
501
|
gap: 24,
|
|
409
502
|
paddingVertical: 20
|
|
@@ -425,9 +518,6 @@ var styles2 = import_react_native3.StyleSheet.create({
|
|
|
425
518
|
justifyContent: "center",
|
|
426
519
|
width: 36
|
|
427
520
|
},
|
|
428
|
-
overlayBody: { textAlign: "center" },
|
|
429
|
-
overlayButton: { width: 160 },
|
|
430
|
-
overlayTitle: { fontWeight: "bold" },
|
|
431
521
|
scrollArea: {
|
|
432
522
|
marginBottom: 0
|
|
433
523
|
},
|
|
@@ -477,89 +567,15 @@ var styles2 = import_react_native3.StyleSheet.create({
|
|
|
477
567
|
var import_auto_paper4 = require("@rific/auto-paper");
|
|
478
568
|
var import_feedback_press3 = require("@rific/feedback-press");
|
|
479
569
|
var import_core3 = require("@tastic/core");
|
|
480
|
-
var
|
|
570
|
+
var import_react3 = require("react");
|
|
481
571
|
var import_react_native5 = require("react-native");
|
|
482
572
|
var import_react_native_paper4 = require("react-native-paper");
|
|
483
|
-
|
|
484
|
-
// src/ConfirmDialog.tsx
|
|
485
|
-
var import_auto_paper3 = require("@rific/auto-paper");
|
|
486
|
-
var import_feedback_press2 = require("@rific/feedback-press");
|
|
487
|
-
var import_core2 = require("@tastic/core");
|
|
488
|
-
var import_react_native4 = require("react-native");
|
|
489
|
-
var import_react_native_paper3 = require("react-native-paper");
|
|
490
|
-
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
491
|
-
function ConfirmDialog({ visible, title, message, confirmLabel, cancelLabel, onConfirm, onCancel, rotation = 0, icon = "help-circle-outline", destructive = false }) {
|
|
492
|
-
const { dark, colors } = (0, import_auto_paper3.useAutoPaperTheme)();
|
|
493
|
-
if (!visible) return null;
|
|
494
|
-
const { fg, cardBg, cardBorder } = getOverlayCardColors(dark);
|
|
495
|
-
const accent = destructive ? colors.danger : colors.primary;
|
|
496
|
-
const onAccent = destructive ? colors.onDanger : colors.onPrimary;
|
|
497
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native4.View, { style: [overlayStyles.overlay, styles3.overlay], children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native4.View, { style: [overlayStyles.card, styles3.card, { backgroundColor: cardBg, borderColor: cardBorder }, (0, import_core2.toRotationStyle)(rotation)], children: [
|
|
498
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Icon, { source: icon, size: 64, color: accent }),
|
|
499
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Text, { variant: "headlineLarge", style: [styles3.title, { color: accent }], children: title }),
|
|
500
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Text, { variant: "bodyLarge", style: [styles3.body, { color: fg }], children: message }),
|
|
501
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native4.View, { style: styles3.actions, children: [
|
|
502
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_feedback_press2.Button, { mode: "outlined", onPress: onCancel, style: styles3.actionButton, children: cancelLabel }),
|
|
503
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_feedback_press2.Button, { mode: "contained", onPress: onConfirm, style: styles3.actionButton, buttonColor: accent, textColor: onAccent, children: confirmLabel })
|
|
504
|
-
] })
|
|
505
|
-
] }) }) });
|
|
506
|
-
}
|
|
507
|
-
var styles3 = import_react_native4.StyleSheet.create({
|
|
508
|
-
// flexBasis (not flex: 1's own 0%) is each button's real floor: whenever both fit side by side,
|
|
509
|
-
// flexGrow still splits any leftover width evenly beyond that floor, same visual result as the
|
|
510
|
-
// old flex: 1 on a roomy screen - but a button can never be squeezed narrower than 128, only
|
|
511
|
-
// wrap to its own row instead (see actions' flexWrap below). react-native-paper's Button
|
|
512
|
-
// hardcodes numberOfLines={1} on its label with no override, so a button squeezed under its
|
|
513
|
-
// label's natural width silently ellipsizes ("Cancel" -> "Can...") instead of wrapping - assumed
|
|
514
|
-
// fixable by just giving the row more width, until confirmed live that these two-word labels
|
|
515
|
-
// (Cancel/Reset/New Game) can still lose the truncation fight even with the extra room card's own
|
|
516
|
-
// width fix below provides, on a narrow enough screen. flexBasis is the real fix: past a certain
|
|
517
|
-
// width there's no side-by-side arrangement that fits both buttons at their natural label size,
|
|
518
|
-
// so the layout has to give (stack) rather than the label (truncate).
|
|
519
|
-
actionButton: {
|
|
520
|
-
flexBasis: 128,
|
|
521
|
-
flexGrow: 1
|
|
522
|
-
},
|
|
523
|
-
actions: {
|
|
524
|
-
flexDirection: "row",
|
|
525
|
-
flexWrap: "wrap",
|
|
526
|
-
gap: 12,
|
|
527
|
-
width: "100%"
|
|
528
|
-
},
|
|
529
|
-
body: {
|
|
530
|
-
textAlign: "center"
|
|
531
|
-
},
|
|
532
|
-
// Additive on top of overlayCard's own shared `card` shape (borderRadius/borderWidth/gap/maxWidth/
|
|
533
|
-
// padding) — claims its full allowance instead of just maxWidth alone, which only caps how wide the
|
|
534
|
-
// card is allowed to get - without an explicit width, a flex-centered child sizes to its own content
|
|
535
|
-
// instead of stretching, so the card (and therefore actions below) can end up narrower than the
|
|
536
|
-
// screen actually has room for, needlessly forcing the action row to wrap sooner than it has to.
|
|
537
|
-
card: {
|
|
538
|
-
width: "100%"
|
|
539
|
-
},
|
|
540
|
-
// Additive on top of overlayCard's own shared `overlay` backdrop — gives the card room to breathe
|
|
541
|
-
// from the screen edges now that it reliably stretches to fill its full width allowance (see
|
|
542
|
-
// card's own width comment) - without this, width: '100%' would run the card edge-to-edge on a
|
|
543
|
-
// screen narrower than maxWidth's own 360.
|
|
544
|
-
overlay: {
|
|
545
|
-
paddingHorizontal: 24
|
|
546
|
-
},
|
|
547
|
-
// textAlign is load-bearing, not decorative, once `title` wraps to more than one line - centered
|
|
548
|
-
// within card's own alignItems: 'center' only centers the Text's block as a whole; each wrapped
|
|
549
|
-
// line inside that block still defaults to left-aligned without this.
|
|
550
|
-
title: {
|
|
551
|
-
fontWeight: "bold",
|
|
552
|
-
textAlign: "center"
|
|
553
|
-
}
|
|
554
|
-
});
|
|
555
|
-
|
|
556
|
-
// src/BaseStatsScreen.tsx
|
|
557
573
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
558
574
|
function BaseStatsScreen({ rotation: rotationOverride, title = "Achievements", titleVariant = "headlineSmall", onBack, 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 }) {
|
|
559
575
|
const { dark, colors } = (0, import_auto_paper4.useAutoPaperTheme)();
|
|
560
576
|
const ambientRotation = (0, import_core3.useRotation)();
|
|
561
577
|
const rotation = rotationOverride ?? ambientRotation;
|
|
562
|
-
const [confirmResetVisible, setConfirmResetVisible] = (0,
|
|
578
|
+
const [confirmResetVisible, setConfirmResetVisible] = (0, import_react3.useState)(false);
|
|
563
579
|
const showReset = !!onReset;
|
|
564
580
|
const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
|
|
565
581
|
const bg = bgOverride ?? (dark ? "#000000" : "#FFFFFF");
|
|
@@ -728,11 +744,11 @@ var styles6 = import_react_native8.StyleSheet.create({
|
|
|
728
744
|
});
|
|
729
745
|
|
|
730
746
|
// src/SkiaGate.tsx
|
|
731
|
-
var
|
|
747
|
+
var import_react4 = require("react");
|
|
732
748
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
733
749
|
function SkiaGate({ getComponent, componentProps, fallback = null }) {
|
|
734
|
-
const [Component, setComponent] = (0,
|
|
735
|
-
(0,
|
|
750
|
+
const [Component, setComponent] = (0, import_react4.useState)(null);
|
|
751
|
+
(0, import_react4.useEffect)(() => {
|
|
736
752
|
let cancelled = false;
|
|
737
753
|
getComponent().then((mod) => {
|
|
738
754
|
if (!cancelled) setComponent(() => mod.default);
|
|
@@ -753,7 +769,7 @@ function TriggerGaugeHost(props) {
|
|
|
753
769
|
}
|
|
754
770
|
|
|
755
771
|
// src/useAutoAlign.ts
|
|
756
|
-
var
|
|
772
|
+
var import_react6 = require("react");
|
|
757
773
|
var import_react_native10 = require("react-native");
|
|
758
774
|
var EDGE_MARGIN = 12;
|
|
759
775
|
function rotateRect(x, y, width, height, rotation, windowWidth, windowHeight) {
|
|
@@ -766,18 +782,18 @@ function rotateRect(x, y, width, height, rotation, windowWidth, windowHeight) {
|
|
|
766
782
|
return { x: cx + newDx - newWidth / 2, y: cy + newDy - newHeight / 2, width: newWidth, height: newHeight };
|
|
767
783
|
}
|
|
768
784
|
function useAutoAlign(open, contentWidth, contentHeight, rotation = 0) {
|
|
769
|
-
const triggerRef = (0,
|
|
785
|
+
const triggerRef = (0, import_react6.useRef)(null);
|
|
770
786
|
const { width: windowWidth, height: windowHeight } = (0, import_react_native10.useWindowDimensions)();
|
|
771
|
-
const [align, setAlign] = (0,
|
|
772
|
-
const [verticalAlign, setVerticalAlign] = (0,
|
|
773
|
-
const [maxHeight, setMaxHeight] = (0,
|
|
774
|
-
const [measured, setMeasured] = (0,
|
|
775
|
-
const [prevOpen, setPrevOpen] = (0,
|
|
787
|
+
const [align, setAlign] = (0, import_react6.useState)("center");
|
|
788
|
+
const [verticalAlign, setVerticalAlign] = (0, import_react6.useState)("below");
|
|
789
|
+
const [maxHeight, setMaxHeight] = (0, import_react6.useState)(contentHeight);
|
|
790
|
+
const [measured, setMeasured] = (0, import_react6.useState)(false);
|
|
791
|
+
const [prevOpen, setPrevOpen] = (0, import_react6.useState)(open);
|
|
776
792
|
if (open !== prevOpen) {
|
|
777
793
|
setPrevOpen(open);
|
|
778
794
|
if (open) setMeasured(false);
|
|
779
795
|
}
|
|
780
|
-
const measure = (0,
|
|
796
|
+
const measure = (0, import_react6.useCallback)(() => {
|
|
781
797
|
triggerRef.current?.measureInWindow((rawX, rawY, rawWidth, rawHeight) => {
|
|
782
798
|
const { x, y, width: triggerWidth, height: triggerHeight } = rotateRect(rawX, rawY, rawWidth, rawHeight, rotation, windowWidth, windowHeight);
|
|
783
799
|
const centerX = x + triggerWidth / 2;
|
|
@@ -794,7 +810,7 @@ function useAutoAlign(open, contentWidth, contentHeight, rotation = 0) {
|
|
|
794
810
|
setMeasured(true);
|
|
795
811
|
});
|
|
796
812
|
}, [contentWidth, contentHeight, windowWidth, windowHeight, rotation]);
|
|
797
|
-
(0,
|
|
813
|
+
(0, import_react6.useEffect)(() => {
|
|
798
814
|
if (open) measure();
|
|
799
815
|
}, [open, measure]);
|
|
800
816
|
return { align, maxHeight, measured, triggerRef, verticalAlign };
|
|
@@ -1402,14 +1418,24 @@ var styles16 = import_react_native21.StyleSheet.create({
|
|
|
1402
1418
|
}
|
|
1403
1419
|
});
|
|
1404
1420
|
|
|
1421
|
+
// src/UpdateDialog.tsx
|
|
1422
|
+
var import_updater2 = require("@rific/updater");
|
|
1423
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
1424
|
+
function UpdateDialog({ rotation = 0, autoCheck = true, autoPrompt = true, onError }) {
|
|
1425
|
+
const { manifest, onConfirm, respond } = useUpdateConfirmBridge();
|
|
1426
|
+
(0, import_updater2.useUpdater)({ autoCheck, autoPrompt, onConfirm, onError });
|
|
1427
|
+
const date = manifest ? new Date(manifest.createdAt) : null;
|
|
1428
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.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) });
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1405
1431
|
// src/usePopoverHost.ts
|
|
1406
|
-
var
|
|
1432
|
+
var import_react7 = require("react");
|
|
1407
1433
|
function usePopoverHost() {
|
|
1408
|
-
const [openId, setOpenId] = (0,
|
|
1409
|
-
const toggle = (0,
|
|
1434
|
+
const [openId, setOpenId] = (0, import_react7.useState)(null);
|
|
1435
|
+
const toggle = (0, import_react7.useCallback)((id) => {
|
|
1410
1436
|
setOpenId((prev) => prev === id ? null : id);
|
|
1411
1437
|
}, []);
|
|
1412
|
-
const close = (0,
|
|
1438
|
+
const close = (0, import_react7.useCallback)(() => setOpenId(null), []);
|
|
1413
1439
|
return { openId, toggle, close };
|
|
1414
1440
|
}
|
|
1415
1441
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -1436,6 +1462,7 @@ function usePopoverHost() {
|
|
|
1436
1462
|
StatRow,
|
|
1437
1463
|
StatSection,
|
|
1438
1464
|
TriggerGaugeHost,
|
|
1465
|
+
UpdateDialog,
|
|
1439
1466
|
getLabeledDropdownContentHeight,
|
|
1440
1467
|
getOverlayCardColors,
|
|
1441
1468
|
loadSkiaWeb,
|