@tastic/hud 0.8.2 → 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 +44 -8
- package/dist/index.d.ts +44 -8
- package/dist/index.js +308 -277
- package/dist/index.mjs +228 -200
- package/package.json +5 -4
- package/src/BaseSettingsDialog.tsx +16 -51
- package/src/BaseStatsScreen.tsx +2 -2
- package/src/ConfirmDialog.tsx +27 -37
- package/src/UpdateDialog.tsx +28 -0
- package/src/index.ts +2 -0
- package/src/overlayCard.ts +48 -0
- package/src/useUpdateConfirmBridge.ts +30 -0
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) });
|
|
@@ -72,7 +72,7 @@ function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, das
|
|
|
72
72
|
if (mountProgress.value < 1) {
|
|
73
73
|
const startFrac = i * MOUNT_STAGGER_MS / totalDurationMs;
|
|
74
74
|
const endFrac = startFrac + MOUNT_DURATION_MS / totalDurationMs;
|
|
75
|
-
local = (0,
|
|
75
|
+
local = (0, import_core5.clamp)((mountProgress.value - startFrac) / (endFrac - startFrac), 0, 1);
|
|
76
76
|
}
|
|
77
77
|
const sweep = dashAngleDeg * local;
|
|
78
78
|
if (sweep <= 0) continue;
|
|
@@ -96,7 +96,7 @@ function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, das
|
|
|
96
96
|
if (!isLitNow) continue;
|
|
97
97
|
const startFrac = i * MOUNT_STAGGER_MS / totalDurationMs;
|
|
98
98
|
const endFrac = startFrac + MOUNT_DURATION_MS / totalDurationMs;
|
|
99
|
-
local = (0,
|
|
99
|
+
local = (0, import_core5.clamp)((mountProgress.value - startFrac) / (endFrac - startFrac), 0, 1);
|
|
100
100
|
} else if (isLitNow === wasLit) {
|
|
101
101
|
local = 1;
|
|
102
102
|
} else if (isLitNow) {
|
|
@@ -120,19 +120,19 @@ function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, das
|
|
|
120
120
|
height: canvasSize,
|
|
121
121
|
width: canvasSize
|
|
122
122
|
};
|
|
123
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
123
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native9.View, { style: [styles7.container, gaugeSizeStyle], pointerEvents: "none", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native_skia.Canvas, { style: canvasSizeStyle, children: [
|
|
124
124
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native_skia.Path, { path: unlitPath, style: "stroke", strokeWidth: UNLIT_THICKNESS, strokeCap: "round", color: mutedColor, opacity: 0.35 }),
|
|
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,
|
|
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
|
-
|
|
134
|
-
|
|
135
|
-
|
|
133
|
+
import_core5 = require("@tastic/core");
|
|
134
|
+
import_react5 = require("react");
|
|
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");
|
|
138
138
|
UNLIT_THICKNESS = 3;
|
|
@@ -144,7 +144,7 @@ var init_TriggerGauge = __esm({
|
|
|
144
144
|
MOUNT_DURATION_MS = 450;
|
|
145
145
|
MOUNT_STAGGER_MS = 40;
|
|
146
146
|
SELECTION_TRANSITION_DURATION_MS = 260;
|
|
147
|
-
styles7 =
|
|
147
|
+
styles7 = import_react_native9.StyleSheet.create({
|
|
148
148
|
container: {
|
|
149
149
|
alignItems: "center",
|
|
150
150
|
justifyContent: "center",
|
|
@@ -179,8 +179,11 @@ __export(index_exports, {
|
|
|
179
179
|
StatRow: () => StatRow,
|
|
180
180
|
StatSection: () => StatSection,
|
|
181
181
|
TriggerGaugeHost: () => TriggerGaugeHost,
|
|
182
|
+
UpdateDialog: () => UpdateDialog,
|
|
182
183
|
getLabeledDropdownContentHeight: () => getLabeledDropdownContentHeight,
|
|
184
|
+
getOverlayCardColors: () => getOverlayCardColors,
|
|
183
185
|
loadSkiaWeb: () => loadSkiaWeb,
|
|
186
|
+
overlayStyles: () => overlayStyles,
|
|
184
187
|
useAutoAlign: () => useAutoAlign,
|
|
185
188
|
usePopoverHost: () => usePopoverHost
|
|
186
189
|
});
|
|
@@ -255,64 +258,191 @@ var styles = import_react_native.StyleSheet.create({
|
|
|
255
258
|
});
|
|
256
259
|
|
|
257
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
|
|
258
270
|
var import_auto_paper2 = require("@rific/auto-paper");
|
|
259
271
|
var import_feedback_press = require("@rific/feedback-press");
|
|
260
|
-
var import_updater = require("@rific/updater");
|
|
261
272
|
var import_core = require("@tastic/core");
|
|
262
|
-
var
|
|
263
|
-
var import_react_native2 = require("react-native");
|
|
273
|
+
var import_react_native3 = require("react-native");
|
|
264
274
|
var import_react_native_paper2 = require("react-native-paper");
|
|
275
|
+
|
|
276
|
+
// src/overlayCard.ts
|
|
277
|
+
var import_react_native2 = require("react-native");
|
|
278
|
+
function getOverlayCardColors(dark) {
|
|
279
|
+
return {
|
|
280
|
+
fg: dark ? "#FFFFFF" : "#000000",
|
|
281
|
+
fgMuted: dark ? "rgba(255,255,255,0.4)" : "rgba(0,0,0,0.4)",
|
|
282
|
+
cardBg: dark ? "#111111" : "#F2F2F2",
|
|
283
|
+
cardBorder: dark ? "rgba(255,255,255,0.2)" : "rgba(0,0,0,0.2)"
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
var overlayStyles = import_react_native2.StyleSheet.create({
|
|
287
|
+
card: {
|
|
288
|
+
alignItems: "center",
|
|
289
|
+
borderRadius: 20,
|
|
290
|
+
borderWidth: 1,
|
|
291
|
+
gap: 16,
|
|
292
|
+
maxWidth: 360,
|
|
293
|
+
padding: 32
|
|
294
|
+
},
|
|
295
|
+
overlay: {
|
|
296
|
+
alignItems: "center",
|
|
297
|
+
backgroundColor: "rgba(0,0,0,0.72)",
|
|
298
|
+
bottom: 0,
|
|
299
|
+
justifyContent: "center",
|
|
300
|
+
left: 0,
|
|
301
|
+
position: "absolute",
|
|
302
|
+
right: 0,
|
|
303
|
+
top: 0
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
// src/ConfirmDialog.tsx
|
|
265
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");
|
|
266
396
|
function SettingIcon({ source, color, containerColor }) {
|
|
267
|
-
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 }) });
|
|
268
398
|
}
|
|
269
399
|
function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, version, lockOrientation, onLockOrientationChange, deferBottomEdgeGestures, onDeferBottomEdgeGestures, hideSound = false, hideHaptics = false, hideAppearance = false, hideUpdateCheck = false, onUpdateError, children }) {
|
|
270
|
-
const {
|
|
271
|
-
const ambientRotation = (0,
|
|
400
|
+
const { colors } = (0, import_auto_paper3.useAutoPaperTheme)();
|
|
401
|
+
const ambientRotation = (0, import_core2.useRotation)();
|
|
272
402
|
const rotation = rotationOverride ?? ambientRotation;
|
|
273
|
-
const isTouchPrimary = (0,
|
|
274
|
-
const { settings: hapticSettings, set: setHapticSettings } = (0,
|
|
275
|
-
const { settings: soundSettings, set: setSoundSettings } = (0,
|
|
276
|
-
const sound = (0,
|
|
277
|
-
const { forceShort: forceHapticFeedback } = (0,
|
|
278
|
-
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();
|
|
279
410
|
const { check, checking, updateReady } = (0, import_updater.useUpdater)({
|
|
280
411
|
autoCheck: false,
|
|
281
412
|
autoPrompt: false,
|
|
413
|
+
onConfirm: onUpdateConfirm,
|
|
282
414
|
onError: onUpdateError,
|
|
283
415
|
onInfo: (title, message) => setInfoMessage({ title, message })
|
|
284
416
|
});
|
|
417
|
+
const updateManifestDate = updateManifest ? new Date(updateManifest.createdAt) : null;
|
|
285
418
|
const showLockOrientation = isTouchPrimary && lockOrientation !== void 0 && onLockOrientationChange !== void 0;
|
|
286
|
-
const showEdgeGuard =
|
|
287
|
-
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;
|
|
288
421
|
const showSound = !hideSound;
|
|
289
422
|
const showAppearance = !hideAppearance;
|
|
290
|
-
const showUpdateCheck =
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native2.View, { style: styles2.flexShrink, children: [
|
|
302
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.Text, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Lock Orientation" }),
|
|
303
|
-
/* @__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" })
|
|
304
434
|
] })
|
|
305
435
|
] }) }),
|
|
306
|
-
showEdgeGuard && /* @__PURE__ */ (0,
|
|
307
|
-
/* @__PURE__ */ (0,
|
|
308
|
-
/* @__PURE__ */ (0,
|
|
309
|
-
/* @__PURE__ */ (0,
|
|
310
|
-
/* @__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" })
|
|
311
441
|
] })
|
|
312
442
|
] }) }),
|
|
313
|
-
(showSound || showHaptics) && /* @__PURE__ */ (0,
|
|
314
|
-
showSound && /* @__PURE__ */ (0,
|
|
315
|
-
|
|
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,
|
|
316
446
|
{
|
|
317
447
|
soundDisabled: true,
|
|
318
448
|
onPress: () => {
|
|
@@ -320,16 +450,16 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
|
|
|
320
450
|
setSoundSettings({ enabled });
|
|
321
451
|
if (enabled) sound.selection?.();
|
|
322
452
|
},
|
|
323
|
-
style:
|
|
453
|
+
style: styles3.toggleButtonInRow,
|
|
324
454
|
accessibilityLabel: `Sound ${soundSettings.enabled ? "on" : "off"}`,
|
|
325
|
-
children: /* @__PURE__ */ (0,
|
|
326
|
-
/* @__PURE__ */ (0,
|
|
327
|
-
/* @__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" })
|
|
328
458
|
] })
|
|
329
459
|
}
|
|
330
460
|
),
|
|
331
|
-
showHaptics && /* @__PURE__ */ (0,
|
|
332
|
-
|
|
461
|
+
showHaptics && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
462
|
+
import_feedback_press2.TouchableRipple,
|
|
333
463
|
{
|
|
334
464
|
hapticDisabled: true,
|
|
335
465
|
onPress: () => {
|
|
@@ -337,40 +467,36 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
|
|
|
337
467
|
setHapticSettings({ vibrate });
|
|
338
468
|
if (vibrate) forceHapticFeedback();
|
|
339
469
|
},
|
|
340
|
-
style:
|
|
470
|
+
style: styles3.toggleButtonInRow,
|
|
341
471
|
accessibilityLabel: `Haptics ${hapticSettings.vibrate ? "on" : "off"}`,
|
|
342
|
-
children: /* @__PURE__ */ (0,
|
|
343
|
-
/* @__PURE__ */ (0,
|
|
344
|
-
/* @__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" })
|
|
345
475
|
] })
|
|
346
476
|
}
|
|
347
477
|
)
|
|
348
478
|
] })
|
|
349
479
|
] }),
|
|
350
|
-
showAppearance && /* @__PURE__ */ (0,
|
|
351
|
-
/* @__PURE__ */ (0,
|
|
352
|
-
/* @__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 })
|
|
353
483
|
] }),
|
|
354
484
|
children,
|
|
355
|
-
showUpdateCheck && /* @__PURE__ */ (0,
|
|
356
|
-
/* @__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: [
|
|
357
487
|
"VERSION ",
|
|
358
488
|
version,
|
|
359
489
|
updateReady ? " \xB7 UPDATE READY" : ""
|
|
360
490
|
] }),
|
|
361
|
-
/* @__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" })
|
|
362
492
|
] })
|
|
363
493
|
] }) })
|
|
364
494
|
] }),
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.Text, { variant: "headlineLarge", style: [styles2.overlayTitle, { color: colors.secondary }], children: infoMessage.title }),
|
|
368
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native_paper2.Text, { variant: "bodyLarge", style: [styles2.overlayBody, { color: fg }], children: infoMessage.message }),
|
|
369
|
-
/* @__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" })
|
|
370
|
-
] }) }) })
|
|
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) })
|
|
371
497
|
] });
|
|
372
498
|
}
|
|
373
|
-
var
|
|
499
|
+
var styles3 = import_react_native4.StyleSheet.create({
|
|
374
500
|
content: {
|
|
375
501
|
gap: 24,
|
|
376
502
|
paddingVertical: 20
|
|
@@ -392,27 +518,6 @@ var styles2 = import_react_native2.StyleSheet.create({
|
|
|
392
518
|
justifyContent: "center",
|
|
393
519
|
width: 36
|
|
394
520
|
},
|
|
395
|
-
overlay: {
|
|
396
|
-
alignItems: "center",
|
|
397
|
-
backgroundColor: "rgba(0,0,0,0.72)",
|
|
398
|
-
bottom: 0,
|
|
399
|
-
justifyContent: "center",
|
|
400
|
-
left: 0,
|
|
401
|
-
position: "absolute",
|
|
402
|
-
right: 0,
|
|
403
|
-
top: 0
|
|
404
|
-
},
|
|
405
|
-
overlayBody: { textAlign: "center" },
|
|
406
|
-
overlayButton: { width: 160 },
|
|
407
|
-
overlayCard: {
|
|
408
|
-
alignItems: "center",
|
|
409
|
-
borderRadius: 20,
|
|
410
|
-
borderWidth: 1,
|
|
411
|
-
gap: 16,
|
|
412
|
-
maxWidth: 360,
|
|
413
|
-
padding: 32
|
|
414
|
-
},
|
|
415
|
-
overlayTitle: { fontWeight: "bold" },
|
|
416
521
|
scrollArea: {
|
|
417
522
|
marginBottom: 0
|
|
418
523
|
},
|
|
@@ -461,112 +566,25 @@ var styles2 = import_react_native2.StyleSheet.create({
|
|
|
461
566
|
// src/BaseStatsScreen.tsx
|
|
462
567
|
var import_auto_paper4 = require("@rific/auto-paper");
|
|
463
568
|
var import_feedback_press3 = require("@rific/feedback-press");
|
|
464
|
-
var
|
|
465
|
-
var
|
|
466
|
-
var
|
|
569
|
+
var import_core3 = require("@tastic/core");
|
|
570
|
+
var import_react3 = require("react");
|
|
571
|
+
var import_react_native5 = require("react-native");
|
|
467
572
|
var import_react_native_paper4 = require("react-native-paper");
|
|
468
|
-
|
|
469
|
-
// src/ConfirmDialog.tsx
|
|
470
|
-
var import_auto_paper3 = require("@rific/auto-paper");
|
|
471
|
-
var import_feedback_press2 = require("@rific/feedback-press");
|
|
472
|
-
var import_react_native3 = require("react-native");
|
|
473
|
-
var import_react_native_paper3 = require("react-native-paper");
|
|
474
|
-
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
475
|
-
function ConfirmDialog({ visible, title, message, confirmLabel, cancelLabel, onConfirm, onCancel, rotation = 0, icon = "help-circle-outline", destructive = false }) {
|
|
476
|
-
const { dark, colors } = (0, import_auto_paper3.useAutoPaperTheme)();
|
|
477
|
-
if (!visible) return null;
|
|
478
|
-
const fg = dark ? "#FFFFFF" : "#000000";
|
|
479
|
-
const cardBg = dark ? "#111111" : "#F2F2F2";
|
|
480
|
-
const cardBorder = dark ? "rgba(255,255,255,0.2)" : "rgba(0,0,0,0.2)";
|
|
481
|
-
const accent = destructive ? colors.danger : colors.primary;
|
|
482
|
-
const onAccent = destructive ? colors.onDanger : colors.onPrimary;
|
|
483
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Portal, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native3.View, { style: styles3.overlay, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native3.View, { style: [styles3.card, { backgroundColor: cardBg, borderColor: cardBorder }, rotation % 360 !== 0 && { transform: [{ rotate: `${rotation}deg` }] }], children: [
|
|
484
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Icon, { source: icon, size: 64, color: accent }),
|
|
485
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Text, { variant: "headlineLarge", style: [styles3.title, { color: accent }], children: title }),
|
|
486
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_native_paper3.Text, { variant: "bodyLarge", style: [styles3.body, { color: fg }], children: message }),
|
|
487
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_native3.View, { style: styles3.actions, children: [
|
|
488
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_feedback_press2.Button, { mode: "outlined", onPress: onCancel, style: styles3.actionButton, children: cancelLabel }),
|
|
489
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_feedback_press2.Button, { mode: "contained", onPress: onConfirm, style: styles3.actionButton, buttonColor: accent, textColor: onAccent, children: confirmLabel })
|
|
490
|
-
] })
|
|
491
|
-
] }) }) });
|
|
492
|
-
}
|
|
493
|
-
var styles3 = import_react_native3.StyleSheet.create({
|
|
494
|
-
// flexBasis (not flex: 1's own 0%) is each button's real floor: whenever both fit side by side,
|
|
495
|
-
// flexGrow still splits any leftover width evenly beyond that floor, same visual result as the
|
|
496
|
-
// old flex: 1 on a roomy screen - but a button can never be squeezed narrower than 128, only
|
|
497
|
-
// wrap to its own row instead (see actions' flexWrap below). react-native-paper's Button
|
|
498
|
-
// hardcodes numberOfLines={1} on its label with no override, so a button squeezed under its
|
|
499
|
-
// label's natural width silently ellipsizes ("Cancel" -> "Can...") instead of wrapping - assumed
|
|
500
|
-
// fixable by just giving the row more width, until confirmed live that these two-word labels
|
|
501
|
-
// (Cancel/Reset/New Game) can still lose the truncation fight even with the extra room card's own
|
|
502
|
-
// width fix below provides, on a narrow enough screen. flexBasis is the real fix: past a certain
|
|
503
|
-
// width there's no side-by-side arrangement that fits both buttons at their natural label size,
|
|
504
|
-
// so the layout has to give (stack) rather than the label (truncate).
|
|
505
|
-
actionButton: {
|
|
506
|
-
flexBasis: 128,
|
|
507
|
-
flexGrow: 1
|
|
508
|
-
},
|
|
509
|
-
actions: {
|
|
510
|
-
flexDirection: "row",
|
|
511
|
-
flexWrap: "wrap",
|
|
512
|
-
gap: 12,
|
|
513
|
-
width: "100%"
|
|
514
|
-
},
|
|
515
|
-
body: {
|
|
516
|
-
textAlign: "center"
|
|
517
|
-
},
|
|
518
|
-
card: {
|
|
519
|
-
alignItems: "center",
|
|
520
|
-
borderRadius: 20,
|
|
521
|
-
borderWidth: 1,
|
|
522
|
-
gap: 16,
|
|
523
|
-
maxWidth: 360,
|
|
524
|
-
padding: 32,
|
|
525
|
-
// Claims its full allowance instead of just maxWidth alone, which only caps how wide the card
|
|
526
|
-
// is allowed to get - without an explicit width, a flex-centered child sizes to its own content
|
|
527
|
-
// instead of stretching, so the card (and therefore actions below) can end up narrower than the
|
|
528
|
-
// screen actually has room for, needlessly forcing the action row to wrap sooner than it has to.
|
|
529
|
-
width: "100%"
|
|
530
|
-
},
|
|
531
|
-
overlay: {
|
|
532
|
-
alignItems: "center",
|
|
533
|
-
backgroundColor: "rgba(0,0,0,0.72)",
|
|
534
|
-
bottom: 0,
|
|
535
|
-
justifyContent: "center",
|
|
536
|
-
left: 0,
|
|
537
|
-
// Gives the card room to breathe from the screen edges now that it reliably stretches to fill
|
|
538
|
-
// its full width allowance (see card's own width comment) - without this, width: '100%' would
|
|
539
|
-
// run the card edge-to-edge on a screen narrower than maxWidth's own 360.
|
|
540
|
-
paddingHorizontal: 24,
|
|
541
|
-
position: "absolute",
|
|
542
|
-
right: 0,
|
|
543
|
-
top: 0
|
|
544
|
-
},
|
|
545
|
-
// textAlign is load-bearing, not decorative, once `title` wraps to more than one line - centered
|
|
546
|
-
// within card's own alignItems: 'center' only centers the Text's block as a whole; each wrapped
|
|
547
|
-
// line inside that block still defaults to left-aligned without this.
|
|
548
|
-
title: {
|
|
549
|
-
fontWeight: "bold",
|
|
550
|
-
textAlign: "center"
|
|
551
|
-
}
|
|
552
|
-
});
|
|
553
|
-
|
|
554
|
-
// src/BaseStatsScreen.tsx
|
|
555
573
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
556
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 }) {
|
|
557
575
|
const { dark, colors } = (0, import_auto_paper4.useAutoPaperTheme)();
|
|
558
|
-
const ambientRotation = (0,
|
|
576
|
+
const ambientRotation = (0, import_core3.useRotation)();
|
|
559
577
|
const rotation = rotationOverride ?? ambientRotation;
|
|
560
|
-
const [confirmResetVisible, setConfirmResetVisible] = (0,
|
|
578
|
+
const [confirmResetVisible, setConfirmResetVisible] = (0, import_react3.useState)(false);
|
|
561
579
|
const showReset = !!onReset;
|
|
562
580
|
const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
|
|
563
581
|
const bg = bgOverride ?? (dark ? "#000000" : "#FFFFFF");
|
|
564
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
565
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
582
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native5.View, { style: [styles4.container, { backgroundColor: bg }], children: [
|
|
583
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native5.View, { style: [styles4.header, { paddingTop: 8 + insets.top, paddingLeft: 8 + insets.left }], children: [
|
|
566
584
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_feedback_press3.IconButton, { icon: "arrow-left", iconColor: fg, size: 24, onPress: onBack }),
|
|
567
585
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_paper4.Text, { variant: titleVariant, style: [styles4.title, { color: fg }], children: title })
|
|
568
586
|
] }),
|
|
569
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
587
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_native5.ScrollView, { style: styles4.scrollView, contentContainerStyle: [styles4.content, { paddingBottom: 32 + insets.bottom }], showsVerticalScrollIndicator: false, children: [
|
|
570
588
|
children,
|
|
571
589
|
showReset && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_feedback_press3.Button, { mode: "contained", onPress: () => setConfirmResetVisible(true), buttonColor: colors.danger, textColor: colors.onDanger, style: styles4.resetButton, children: resetLabel })
|
|
572
590
|
] }),
|
|
@@ -590,7 +608,7 @@ function BaseStatsScreen({ rotation: rotationOverride, title = "Achievements", t
|
|
|
590
608
|
)
|
|
591
609
|
] });
|
|
592
610
|
}
|
|
593
|
-
var styles4 =
|
|
611
|
+
var styles4 = import_react_native5.StyleSheet.create({
|
|
594
612
|
container: {
|
|
595
613
|
flex: 1
|
|
596
614
|
},
|
|
@@ -621,19 +639,19 @@ var styles4 = import_react_native4.StyleSheet.create({
|
|
|
621
639
|
});
|
|
622
640
|
|
|
623
641
|
// src/ContentGutter.tsx
|
|
624
|
-
var
|
|
625
|
-
var
|
|
642
|
+
var import_core4 = require("@tastic/core");
|
|
643
|
+
var import_react_native6 = require("react-native");
|
|
626
644
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
627
645
|
function ContentGutter({ maxContentWidth, leftGutter, rightGutter, style, children }) {
|
|
628
|
-
const { width: windowWidth } = (0,
|
|
629
|
-
const { contentWidth, gutterWidth } = (0,
|
|
630
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
631
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
632
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
633
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
646
|
+
const { width: windowWidth } = (0, import_react_native6.useWindowDimensions)();
|
|
647
|
+
const { contentWidth, gutterWidth } = (0, import_core4.computeContentBounds)(windowWidth, maxContentWidth ?? Infinity);
|
|
648
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native6.View, { style: [styles5.row, style], children: [
|
|
649
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native6.View, { style: [styles5.gutter, { width: gutterWidth }], children: leftGutter }),
|
|
650
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native6.View, { style: { width: contentWidth }, children }),
|
|
651
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native6.View, { style: [styles5.gutter, { width: gutterWidth }], children: rightGutter })
|
|
634
652
|
] });
|
|
635
653
|
}
|
|
636
|
-
var styles5 =
|
|
654
|
+
var styles5 = import_react_native6.StyleSheet.create({
|
|
637
655
|
// overflow:'hidden' keeps an oversized leftGutter/rightGutter from bleeding into the content
|
|
638
656
|
// column instead of clipping cleanly at its own real width.
|
|
639
657
|
gutter: {
|
|
@@ -645,22 +663,22 @@ var styles5 = import_react_native5.StyleSheet.create({
|
|
|
645
663
|
});
|
|
646
664
|
|
|
647
665
|
// src/ControlSchemePicker.tsx
|
|
648
|
-
var
|
|
649
|
-
var
|
|
666
|
+
var import_core7 = require("@tastic/core");
|
|
667
|
+
var import_react_native12 = require("react-native");
|
|
650
668
|
|
|
651
669
|
// src/SectionedDropdown.tsx
|
|
652
670
|
var import_auto_paper5 = require("@rific/auto-paper");
|
|
653
671
|
var import_feedback_press4 = require("@rific/feedback-press");
|
|
654
|
-
var
|
|
655
|
-
var
|
|
672
|
+
var import_core6 = require("@tastic/core");
|
|
673
|
+
var import_react_native11 = require("react-native");
|
|
656
674
|
var import_react_native_paper5 = require("react-native-paper");
|
|
657
675
|
|
|
658
676
|
// src/fonts.ts
|
|
659
|
-
var
|
|
660
|
-
var MONO_FONT =
|
|
677
|
+
var import_react_native7 = require("react-native");
|
|
678
|
+
var MONO_FONT = import_react_native7.Platform.select({ ios: "Menlo", android: "monospace", default: "monospace" });
|
|
661
679
|
|
|
662
680
|
// src/PopoverBody.tsx
|
|
663
|
-
var
|
|
681
|
+
var import_react_native8 = require("react-native");
|
|
664
682
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
665
683
|
var CARET_SIZE = 7;
|
|
666
684
|
var CARET_RING_OFFSET = 2;
|
|
@@ -675,15 +693,15 @@ function PopoverBody({ visible, children, align = "center", verticalAlign = "bel
|
|
|
675
693
|
const caretFill = above ? "borderTopColor" : "borderBottomColor";
|
|
676
694
|
const caretWidthProp = above ? "borderTopWidth" : "borderBottomWidth";
|
|
677
695
|
const caretEdge = (size) => above ? { bottom: -size + CARET_DIP } : { top: -size + CARET_DIP };
|
|
678
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
696
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native8.View, { style: [styles6.content, alignStyle, verticalStyle], children: [
|
|
679
697
|
children,
|
|
680
698
|
caretColor && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
|
|
681
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
682
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
699
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native8.View, { style: [styles6.caret, caretOffset(ringSize), caretEdge(ringSize), { [caretFill]: caretBorderColor ?? caretColor, [caretWidthProp]: ringSize, borderLeftWidth: ringSize, borderRightWidth: ringSize }] }),
|
|
700
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_native8.View, { style: [styles6.caret, caretOffset(CARET_SIZE), caretEdge(CARET_SIZE - CARET_RING_OFFSET), { [caretFill]: caretColor, [caretWidthProp]: CARET_SIZE, borderLeftWidth: CARET_SIZE, borderRightWidth: CARET_SIZE }] })
|
|
683
701
|
] })
|
|
684
702
|
] });
|
|
685
703
|
}
|
|
686
|
-
var styles6 =
|
|
704
|
+
var styles6 = import_react_native8.StyleSheet.create({
|
|
687
705
|
caret: {
|
|
688
706
|
borderLeftColor: "transparent",
|
|
689
707
|
borderRightColor: "transparent",
|
|
@@ -726,11 +744,11 @@ var styles6 = import_react_native7.StyleSheet.create({
|
|
|
726
744
|
});
|
|
727
745
|
|
|
728
746
|
// src/SkiaGate.tsx
|
|
729
|
-
var
|
|
747
|
+
var import_react4 = require("react");
|
|
730
748
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
731
749
|
function SkiaGate({ getComponent, componentProps, fallback = null }) {
|
|
732
|
-
const [Component, setComponent] = (0,
|
|
733
|
-
(0,
|
|
750
|
+
const [Component, setComponent] = (0, import_react4.useState)(null);
|
|
751
|
+
(0, import_react4.useEffect)(() => {
|
|
734
752
|
let cancelled = false;
|
|
735
753
|
getComponent().then((mod) => {
|
|
736
754
|
if (!cancelled) setComponent(() => mod.default);
|
|
@@ -751,8 +769,8 @@ function TriggerGaugeHost(props) {
|
|
|
751
769
|
}
|
|
752
770
|
|
|
753
771
|
// src/useAutoAlign.ts
|
|
754
|
-
var
|
|
755
|
-
var
|
|
772
|
+
var import_react6 = require("react");
|
|
773
|
+
var import_react_native10 = require("react-native");
|
|
756
774
|
var EDGE_MARGIN = 12;
|
|
757
775
|
function rotateRect(x, y, width, height, rotation, windowWidth, windowHeight) {
|
|
758
776
|
if (rotation === 0) return { x, y, width, height };
|
|
@@ -764,18 +782,18 @@ function rotateRect(x, y, width, height, rotation, windowWidth, windowHeight) {
|
|
|
764
782
|
return { x: cx + newDx - newWidth / 2, y: cy + newDy - newHeight / 2, width: newWidth, height: newHeight };
|
|
765
783
|
}
|
|
766
784
|
function useAutoAlign(open, contentWidth, contentHeight, rotation = 0) {
|
|
767
|
-
const triggerRef = (0,
|
|
768
|
-
const { width: windowWidth, height: windowHeight } = (0,
|
|
769
|
-
const [align, setAlign] = (0,
|
|
770
|
-
const [verticalAlign, setVerticalAlign] = (0,
|
|
771
|
-
const [maxHeight, setMaxHeight] = (0,
|
|
772
|
-
const [measured, setMeasured] = (0,
|
|
773
|
-
const [prevOpen, setPrevOpen] = (0,
|
|
785
|
+
const triggerRef = (0, import_react6.useRef)(null);
|
|
786
|
+
const { width: windowWidth, height: windowHeight } = (0, import_react_native10.useWindowDimensions)();
|
|
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);
|
|
774
792
|
if (open !== prevOpen) {
|
|
775
793
|
setPrevOpen(open);
|
|
776
794
|
if (open) setMeasured(false);
|
|
777
795
|
}
|
|
778
|
-
const measure = (0,
|
|
796
|
+
const measure = (0, import_react6.useCallback)(() => {
|
|
779
797
|
triggerRef.current?.measureInWindow((rawX, rawY, rawWidth, rawHeight) => {
|
|
780
798
|
const { x, y, width: triggerWidth, height: triggerHeight } = rotateRect(rawX, rawY, rawWidth, rawHeight, rotation, windowWidth, windowHeight);
|
|
781
799
|
const centerX = x + triggerWidth / 2;
|
|
@@ -792,7 +810,7 @@ function useAutoAlign(open, contentWidth, contentHeight, rotation = 0) {
|
|
|
792
810
|
setMeasured(true);
|
|
793
811
|
});
|
|
794
812
|
}, [contentWidth, contentHeight, windowWidth, windowHeight, rotation]);
|
|
795
|
-
(0,
|
|
813
|
+
(0, import_react6.useEffect)(() => {
|
|
796
814
|
if (open) measure();
|
|
797
815
|
}, [open, measure]);
|
|
798
816
|
return { align, maxHeight, measured, triggerRef, verticalAlign };
|
|
@@ -811,7 +829,7 @@ var MENU_ITEM_HEIGHT_WITH_DESCRIPTION = 58;
|
|
|
811
829
|
var MENU_DIVIDER_HEIGHT = 9;
|
|
812
830
|
var MENU_VERTICAL_PADDING = 12;
|
|
813
831
|
function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accentColor, mutedColor, onAccentColor, dark, align: alignOverride, rotation: rotationOverride, autoDismiss = true, labelFontFamily = MONO_FONT, allClearLabels = { all: "All", clear: "Clear" } }) {
|
|
814
|
-
const ambientRotation = (0,
|
|
832
|
+
const ambientRotation = (0, import_core6.useRotation)();
|
|
815
833
|
const rotation = rotationOverride ?? ambientRotation;
|
|
816
834
|
const menuBg = dark ? "#000000" : "#FFFFFF";
|
|
817
835
|
const menuBorderColor = (0, import_auto_paper5.getBlendedColor)(mutedColor, menuBg, 0.5);
|
|
@@ -850,13 +868,13 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
|
|
|
850
868
|
const anchorStyle = [styles8.anchor, open && styles8.anchorOpen];
|
|
851
869
|
const menuStyle = { backgroundColor: menuBg, borderColor: menuBorderColor, maxHeight };
|
|
852
870
|
const dividerStyle = { backgroundColor: menuBorderColor };
|
|
853
|
-
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
854
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
871
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { style: anchorStyle, children: [
|
|
872
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { ref: triggerRef, collapsable: false, style: styles8.triggerBox, children: [
|
|
855
873
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TriggerGaugeHost, { segments: gaugeSegments, litIndices: gaugeLitIndices, size: TRIGGER_SIZE, accentColor, mutedColor }),
|
|
856
874
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_feedback_press4.IconButton, { icon: triggerIcon, iconColor: triggerIconColor, size: triggerIconSize, accessibilityLabel, onPress: () => host.toggle(id) })
|
|
857
875
|
] }),
|
|
858
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: menuBorderColor, caretBorderWidth: MENU_BORDER_WIDTH, triggerSize: TRIGGER_SIZE, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
859
|
-
sectionIndex > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
876
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: menuBorderColor, caretBorderWidth: MENU_BORDER_WIDTH, triggerSize: TRIGGER_SIZE, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native11.ScrollView, { style: [styles8.menu, menuStyle], contentContainerStyle: styles8.menuContent, showsVerticalScrollIndicator: false, children: sections.map((section, sectionIndex) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { children: [
|
|
877
|
+
sectionIndex > 0 && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native11.View, { style: [styles8.divider, dividerStyle] }),
|
|
860
878
|
section.kind === "single" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
861
879
|
SingleSection,
|
|
862
880
|
{
|
|
@@ -889,9 +907,9 @@ function SingleSection({
|
|
|
889
907
|
const itemStyle = [styles8.item, selected && { backgroundColor: accentColor }, taken && styles8.itemTaken];
|
|
890
908
|
const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
|
|
891
909
|
const descriptionStyle = { fontFamily: labelFontFamily, color: rowColor };
|
|
892
|
-
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_feedback_press4.TouchableRipple, { disabled: taken, onPress: () => onSelect(option.value), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
910
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_feedback_press4.TouchableRipple, { disabled: taken, onPress: () => onSelect(option.value), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { style: styles8.itemRow, children: [
|
|
893
911
|
option.icon && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper5.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
|
|
894
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
912
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { style: styles8.itemLabelColumn, children: [
|
|
895
913
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper5.Text, { variant: "labelLarge", style: labelStyle, children: option.label }),
|
|
896
914
|
option.description && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper5.Text, { variant: "labelSmall", style: descriptionStyle, children: option.description })
|
|
897
915
|
] })
|
|
@@ -915,7 +933,7 @@ function MultiSection({
|
|
|
915
933
|
const nextSelected = selected && i < section.options.length - 1 && section.value.includes(section.options[i + 1].value);
|
|
916
934
|
const itemStyle = [styles8.item, selected && { backgroundColor: accentColor }, prevSelected && { borderTopLeftRadius: 0, borderTopRightRadius: 0 }, nextSelected && { borderBottomLeftRadius: 0, borderBottomRightRadius: 0 }];
|
|
917
935
|
const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
|
|
918
|
-
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_feedback_press4.TouchableRipple, { onPress: () => section.onChange(selected ? section.value.filter((v) => v !== option.value) : [...section.value, option.value]), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
936
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_feedback_press4.TouchableRipple, { onPress: () => section.onChange(selected ? section.value.filter((v) => v !== option.value) : [...section.value, option.value]), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native11.View, { style: styles8.itemRow, children: [
|
|
919
937
|
option.icon && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper5.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
|
|
920
938
|
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper5.Text, { variant: "labelLarge", style: [styles8.itemLabelFlex, labelStyle], children: option.label })
|
|
921
939
|
] }) }, option.value);
|
|
@@ -923,7 +941,7 @@ function MultiSection({
|
|
|
923
941
|
section.allClear && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_feedback_press4.TouchableRipple, { onPress: () => section.onChange(allSelected ? [] : section.options.map((o) => o.value)), style: styles8.item, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native_paper5.Text, { variant: "labelLarge", style: [styles8.allClearLabel, { fontFamily: labelFontFamily, color: accentColor }], children: allSelected ? allClearLabels.clear : allClearLabels.all }) })
|
|
924
942
|
] });
|
|
925
943
|
}
|
|
926
|
-
var styles8 =
|
|
944
|
+
var styles8 = import_react_native11.StyleSheet.create({
|
|
927
945
|
allClearLabel: {
|
|
928
946
|
fontWeight: "bold",
|
|
929
947
|
textAlign: "center"
|
|
@@ -940,7 +958,7 @@ var styles8 = import_react_native10.StyleSheet.create({
|
|
|
940
958
|
zIndex: 100
|
|
941
959
|
},
|
|
942
960
|
divider: {
|
|
943
|
-
height:
|
|
961
|
+
height: import_react_native11.StyleSheet.hairlineWidth,
|
|
944
962
|
marginVertical: 4
|
|
945
963
|
},
|
|
946
964
|
item: {
|
|
@@ -995,14 +1013,14 @@ var styles8 = import_react_native10.StyleSheet.create({
|
|
|
995
1013
|
// src/ControlSchemePicker.tsx
|
|
996
1014
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
997
1015
|
function ControlSchemePicker({ id, host, value, onChange, options, takenValue, accentColor, mutedColor, onAccentColor, dark, align, labelFontFamily }) {
|
|
998
|
-
const isTouchPrimary = (0,
|
|
999
|
-
if (
|
|
1016
|
+
const isTouchPrimary = (0, import_core7.useIsTouchPrimaryDevice)();
|
|
1017
|
+
if (import_react_native12.Platform.OS !== "web" || isTouchPrimary) return null;
|
|
1000
1018
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SectionedDropdown, { id, host, icon: "keyboard-outline", accessibilityLabel: "Control scheme", sections: [{ kind: "single", id: "controls", options, value, onChange, takenValue }], accentColor, mutedColor, onAccentColor, dark, align, labelFontFamily });
|
|
1001
1019
|
}
|
|
1002
1020
|
|
|
1003
1021
|
// src/CornerActionButtons.tsx
|
|
1004
1022
|
var import_feedback_press5 = require("@rific/feedback-press");
|
|
1005
|
-
var
|
|
1023
|
+
var import_react_native13 = require("react-native");
|
|
1006
1024
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1007
1025
|
function CornerActionButtons({ onBack, onSettings, fg, insets, backIcon = "arrow-left", backLabel = "Back" }) {
|
|
1008
1026
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
|
|
@@ -1010,7 +1028,7 @@ function CornerActionButtons({ onBack, onSettings, fg, insets, backIcon = "arrow
|
|
|
1010
1028
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_feedback_press5.IconButton, { icon: "cog", iconColor: fg, size: 24, style: [styles9.topRight, { top: 8 + insets.top, right: 8 + insets.right }], onPress: onSettings, accessibilityLabel: "Settings" })
|
|
1011
1029
|
] });
|
|
1012
1030
|
}
|
|
1013
|
-
var styles9 =
|
|
1031
|
+
var styles9 = import_react_native13.StyleSheet.create({
|
|
1014
1032
|
back: {
|
|
1015
1033
|
position: "absolute"
|
|
1016
1034
|
},
|
|
@@ -1020,22 +1038,22 @@ var styles9 = import_react_native12.StyleSheet.create({
|
|
|
1020
1038
|
});
|
|
1021
1039
|
|
|
1022
1040
|
// src/CornerStatusBadges.tsx
|
|
1023
|
-
var
|
|
1041
|
+
var import_react_native14 = require("react-native");
|
|
1024
1042
|
var import_react_native_paper6 = require("react-native-paper");
|
|
1025
1043
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1026
1044
|
var BADGE_SIZE = 30;
|
|
1027
1045
|
function StatusBadge({ icon }) {
|
|
1028
|
-
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1046
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native14.View, { style: styles10.badge, children: icon && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native_paper6.Icon, { source: icon, size: 16, color: "rgba(255,255,255,0.85)" }) });
|
|
1029
1047
|
}
|
|
1030
1048
|
function CornerStatusBadges({ orientationMode, p1OnRight, p1, p2 }) {
|
|
1031
1049
|
const p1OnRightSide = orientationMode === "sideBySide" && p1OnRight;
|
|
1032
1050
|
const p2OnLeftSide = orientationMode === "sideBySide" && !p1OnRight;
|
|
1033
1051
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
|
|
1034
|
-
p1 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1035
|
-
p2 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1052
|
+
p1 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native14.View, { pointerEvents: "none", style: p1OnRightSide ? styles10.bottomRight : styles10.bottomLeft, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(StatusBadge, { icon: p1.icon }) }),
|
|
1053
|
+
p2 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native14.View, { pointerEvents: "none", style: p2OnLeftSide ? styles10.topLeft : styles10.topRight, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(StatusBadge, { icon: p2.icon }) })
|
|
1036
1054
|
] });
|
|
1037
1055
|
}
|
|
1038
|
-
var styles10 =
|
|
1056
|
+
var styles10 = import_react_native14.StyleSheet.create({
|
|
1039
1057
|
badge: {
|
|
1040
1058
|
alignItems: "center",
|
|
1041
1059
|
backgroundColor: "rgba(0,0,0,0.28)",
|
|
@@ -1056,8 +1074,8 @@ var styles10 = import_react_native13.StyleSheet.create({
|
|
|
1056
1074
|
// src/InlineColorPicker.tsx
|
|
1057
1075
|
var import_auto_paper6 = require("@rific/auto-paper");
|
|
1058
1076
|
var import_feedback_press6 = require("@rific/feedback-press");
|
|
1059
|
-
var
|
|
1060
|
-
var
|
|
1077
|
+
var import_core8 = require("@tastic/core");
|
|
1078
|
+
var import_react_native15 = require("react-native");
|
|
1061
1079
|
var import_react_native_paper7 = require("react-native-paper");
|
|
1062
1080
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
1063
1081
|
var EMOJI_PATTERN = /\p{Extended_Pictographic}/u;
|
|
@@ -1073,11 +1091,11 @@ function widthForColumns(columns) {
|
|
|
1073
1091
|
return SWATCHES_BORDER_WIDTH * 2 + SWATCHES_PADDING * 2 + SWATCH_SIZE * columns + SWATCHES_GAP * (columns - 1);
|
|
1074
1092
|
}
|
|
1075
1093
|
function InlineColorPicker({ id, host, value, onChange, previewValue, swatches = import_auto_paper6.defaultColors, takenValue, allowSwapTaken, dark, align: alignOverride, rotation: rotationOverride, icon = "palette", tag, labelFontFamily = MONO_FONT, autoDismiss = true, columns, size = DEFAULT_SIZE }) {
|
|
1076
|
-
const ambientRotation = (0,
|
|
1094
|
+
const ambientRotation = (0, import_core8.useRotation)();
|
|
1077
1095
|
const rotation = rotationOverride ?? ambientRotation;
|
|
1078
1096
|
const menuBg = dark ? "#000000" : "#FFFFFF";
|
|
1079
|
-
const { width: windowWidth } = (0,
|
|
1080
|
-
const autoColumns = (0,
|
|
1097
|
+
const { width: windowWidth } = (0, import_react_native15.useWindowDimensions)();
|
|
1098
|
+
const autoColumns = (0, import_core8.clamp)(Math.floor((windowWidth - 2 * SCREEN_MARGIN + SWATCHES_GAP) / (SWATCH_SIZE + SWATCHES_GAP)), MIN_COLUMNS, MAX_COLUMNS);
|
|
1081
1099
|
const resolvedColumns = columns ?? autoColumns;
|
|
1082
1100
|
const swatchesWidth = widthForColumns(resolvedColumns);
|
|
1083
1101
|
const swatchRows = Math.ceil(swatches.length / resolvedColumns);
|
|
@@ -1089,9 +1107,9 @@ function InlineColorPicker({ id, host, value, onChange, previewValue, swatches =
|
|
|
1089
1107
|
const displayValue = displayFor(value);
|
|
1090
1108
|
const contrastColor = (0, import_auto_paper6.getContrastColor)(displayValue);
|
|
1091
1109
|
const tagFontSize = size * (tag && EMOJI_PATTERN.test(tag) ? 0.6 : 0.4);
|
|
1092
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1093
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_feedback_press6.TouchableRipple, { onPress: () => host.toggle(id), borderless: true, style: [styles11.trigger, { backgroundColor: displayValue, borderRadius: size / 2, height: size, width: size }], children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1094
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: displayValue, caretBorderWidth: SWATCHES_BORDER_WIDTH, triggerSize: size, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1110
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native15.View, { style: [styles11.anchor, open && styles11.anchorOpen], children: [
|
|
1111
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_feedback_press6.TouchableRipple, { onPress: () => host.toggle(id), borderless: true, style: [styles11.trigger, { backgroundColor: displayValue, borderRadius: size / 2, height: size, width: size }], children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native15.View, { ref: triggerRef, collapsable: false, style: styles11.triggerMeasure, children: tag ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper7.Text, { style: [styles11.tagLabel, { color: contrastColor, fontFamily: labelFontFamily, fontSize: tagFontSize }], numberOfLines: 1, adjustsFontSizeToFit: true, children: tag }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper7.Icon, { source: icon, size: size * 0.6, color: contrastColor }) }) }),
|
|
1112
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: displayValue, caretBorderWidth: SWATCHES_BORDER_WIDTH, triggerSize: size, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native15.ScrollView, { style: [styles11.swatches, { backgroundColor: menuBg, borderColor: displayValue, width: swatchesWidth, maxHeight }], contentContainerStyle: styles11.swatchesContent, showsVerticalScrollIndicator: false, children: swatches.map((swatch) => {
|
|
1095
1113
|
const selected = swatch.value.toLowerCase() === value.toLowerCase();
|
|
1096
1114
|
const taken = !selected && !!takenValue && swatch.value.toLowerCase() === takenValue.toLowerCase();
|
|
1097
1115
|
const swappable = taken && allowSwapTaken;
|
|
@@ -1106,14 +1124,14 @@ function InlineColorPicker({ id, host, value, onChange, previewValue, swatches =
|
|
|
1106
1124
|
},
|
|
1107
1125
|
borderless: true,
|
|
1108
1126
|
style: [styles11.swatch, { backgroundColor: swatchDisplay }, selected && styles11.swatchSelected, taken && !swappable && styles11.swatchTaken],
|
|
1109
|
-
children: selected ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper7.Icon, { source: "check", size: 16, color: (0, import_auto_paper6.getContrastColor)(swatchDisplay) }) : swappable ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper7.Icon, { source: "swap-horizontal", size: 16, color: (0, import_auto_paper6.getContrastColor)(swatchDisplay) }) : taken ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper7.Icon, { source: "close", size: 16, color: (0, import_auto_paper6.getContrastColor)(swatchDisplay) }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1127
|
+
children: selected ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper7.Icon, { source: "check", size: 16, color: (0, import_auto_paper6.getContrastColor)(swatchDisplay) }) : swappable ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper7.Icon, { source: "swap-horizontal", size: 16, color: (0, import_auto_paper6.getContrastColor)(swatchDisplay) }) : taken ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper7.Icon, { source: "close", size: 16, color: (0, import_auto_paper6.getContrastColor)(swatchDisplay) }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native15.View, {})
|
|
1110
1128
|
},
|
|
1111
1129
|
swatch.value
|
|
1112
1130
|
);
|
|
1113
1131
|
}) }) })
|
|
1114
1132
|
] });
|
|
1115
1133
|
}
|
|
1116
|
-
var styles11 =
|
|
1134
|
+
var styles11 = import_react_native15.StyleSheet.create({
|
|
1117
1135
|
anchor: {
|
|
1118
1136
|
position: "relative"
|
|
1119
1137
|
},
|
|
@@ -1187,7 +1205,7 @@ var styles11 = import_react_native14.StyleSheet.create({
|
|
|
1187
1205
|
// src/LabeledDropdown.tsx
|
|
1188
1206
|
var import_auto_paper7 = require("@rific/auto-paper");
|
|
1189
1207
|
var import_feedback_press7 = require("@rific/feedback-press");
|
|
1190
|
-
var
|
|
1208
|
+
var import_react_native16 = require("react-native");
|
|
1191
1209
|
var import_react_native_paper8 = require("react-native-paper");
|
|
1192
1210
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
1193
1211
|
var TRIGGER_HEIGHT = 28;
|
|
@@ -1212,22 +1230,22 @@ function LabeledDropdown({ id, host, options, value, onChange, color, dark, alig
|
|
|
1212
1230
|
onChange(option.value);
|
|
1213
1231
|
host.close();
|
|
1214
1232
|
};
|
|
1215
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
1216
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => host.toggle(id), style: styles12.trigger, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
1233
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native16.View, { style: [styles12.anchor, open && styles12.anchorOpen], children: [
|
|
1234
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => host.toggle(id), style: styles12.trigger, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native16.View, { ref: triggerRef, collapsable: false, style: styles12.triggerInner, children: [
|
|
1217
1235
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native_paper8.Text, { style: [styles12.triggerLabel, { color }], numberOfLines: 1, children: (selected?.label ?? "").toUpperCase() }),
|
|
1218
1236
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native_paper8.Icon, { source: "menu-down", size: 16, color })
|
|
1219
1237
|
] }) }),
|
|
1220
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: color, caretBorderWidth: 2, triggerSize: TRIGGER_HEIGHT, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
1238
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: color, caretBorderWidth: 2, triggerSize: TRIGGER_HEIGHT, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native16.ScrollView, { style: [styles12.menu, { backgroundColor: menuBg, borderColor: color, width: POPOVER_WIDTH, maxHeight }], contentContainerStyle: styles12.menuContent, showsVerticalScrollIndicator: false, children: options.map((option) => {
|
|
1221
1239
|
const isSelected = option.value === value;
|
|
1222
1240
|
const onColor = (0, import_auto_paper7.getContrastColor)(color);
|
|
1223
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => handleSelect(option), style: [styles12.row, isSelected && { backgroundColor: color }], children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
|
|
1241
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_feedback_press7.TouchableRipple, { onPress: () => handleSelect(option), style: [styles12.row, isSelected && { backgroundColor: color }], children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native16.View, { style: styles12.rowInner, children: [
|
|
1224
1242
|
option.icon && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native_paper8.Icon, { source: option.icon, size: 18, color: isSelected ? onColor : fg }),
|
|
1225
1243
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native_paper8.Text, { style: [styles12.rowLabel, { color: isSelected ? onColor : fg }], numberOfLines: 1, children: option.label })
|
|
1226
1244
|
] }) }, option.value);
|
|
1227
1245
|
}) }) })
|
|
1228
1246
|
] });
|
|
1229
1247
|
}
|
|
1230
|
-
var styles12 =
|
|
1248
|
+
var styles12 = import_react_native16.StyleSheet.create({
|
|
1231
1249
|
anchor: {
|
|
1232
1250
|
position: "relative"
|
|
1233
1251
|
},
|
|
@@ -1285,16 +1303,16 @@ function loadSkiaWeb() {
|
|
|
1285
1303
|
}
|
|
1286
1304
|
|
|
1287
1305
|
// src/PressAwayOverlay.tsx
|
|
1288
|
-
var
|
|
1306
|
+
var import_react_native17 = require("react-native");
|
|
1289
1307
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1290
1308
|
function PressAwayOverlay({ active, onPress, style }) {
|
|
1291
1309
|
if (!active) return null;
|
|
1292
|
-
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1310
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native17.Pressable, { accessibilityLabel: "Dismiss", accessibilityRole: "button", onPress, style: [import_react_native17.StyleSheet.absoluteFill, style] });
|
|
1293
1311
|
}
|
|
1294
1312
|
|
|
1295
1313
|
// src/ReadyButton.tsx
|
|
1296
1314
|
var import_feedback_press8 = require("@rific/feedback-press");
|
|
1297
|
-
var
|
|
1315
|
+
var import_react_native18 = require("react-native");
|
|
1298
1316
|
var import_react_native_paper9 = require("react-native-paper");
|
|
1299
1317
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
1300
1318
|
function ReadyButton({ color, ready, onToggleReady, style, labelFontFamily = MONO_FONT }) {
|
|
@@ -1303,7 +1321,7 @@ function ReadyButton({ color, ready, onToggleReady, style, labelFontFamily = MON
|
|
|
1303
1321
|
const labelColorStyle = { color: ready ? "#000000" : color };
|
|
1304
1322
|
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_feedback_press8.TouchableRipple, { onPress: onToggleReady, borderless: true, style: readyButtonStyle, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native_paper9.Text, { variant: "labelLarge", style: [labelTextStyle, labelColorStyle], children: ready ? "READY \u2713" : "READY?" }) });
|
|
1305
1323
|
}
|
|
1306
|
-
var styles13 =
|
|
1324
|
+
var styles13 = import_react_native18.StyleSheet.create({
|
|
1307
1325
|
readyButton: {
|
|
1308
1326
|
alignItems: "center",
|
|
1309
1327
|
borderRadius: 12,
|
|
@@ -1317,11 +1335,11 @@ var styles13 = import_react_native17.StyleSheet.create({
|
|
|
1317
1335
|
|
|
1318
1336
|
// src/SharedActionBand.tsx
|
|
1319
1337
|
var import_feedback_press9 = require("@rific/feedback-press");
|
|
1320
|
-
var
|
|
1338
|
+
var import_react_native19 = require("react-native");
|
|
1321
1339
|
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
1322
1340
|
function SharedActionBand({ onBack, onSettings, onRandomize, onReset, fg, popoverOpen, children }) {
|
|
1323
|
-
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
1324
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
1341
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native19.View, { style: [styles14.column, popoverOpen && styles14.columnOpen], children: [
|
|
1342
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native19.View, { style: styles14.actionsRow, children: [
|
|
1325
1343
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_feedback_press9.IconButton, { icon: "arrow-left", iconColor: fg, size: 20, onPress: onBack, accessibilityLabel: "Back" }),
|
|
1326
1344
|
onRandomize && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_feedback_press9.IconButton, { icon: "dice-multiple", iconColor: fg, size: 18, onPress: onRandomize, accessibilityLabel: "Randomize match settings" }),
|
|
1327
1345
|
onReset && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_feedback_press9.IconButton, { icon: "restore", iconColor: fg, size: 18, onPress: onReset, accessibilityLabel: "Reset match settings to defaults" }),
|
|
@@ -1330,7 +1348,7 @@ function SharedActionBand({ onBack, onSettings, onRandomize, onReset, fg, popove
|
|
|
1330
1348
|
children
|
|
1331
1349
|
] });
|
|
1332
1350
|
}
|
|
1333
|
-
var styles14 =
|
|
1351
|
+
var styles14 = import_react_native19.StyleSheet.create({
|
|
1334
1352
|
actionsRow: {
|
|
1335
1353
|
alignItems: "center",
|
|
1336
1354
|
flexDirection: "row",
|
|
@@ -1347,19 +1365,19 @@ var styles14 = import_react_native18.StyleSheet.create({
|
|
|
1347
1365
|
|
|
1348
1366
|
// src/StatRow.tsx
|
|
1349
1367
|
var import_auto_paper8 = require("@rific/auto-paper");
|
|
1350
|
-
var
|
|
1368
|
+
var import_react_native20 = require("react-native");
|
|
1351
1369
|
var import_react_native_paper10 = require("react-native-paper");
|
|
1352
1370
|
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
1353
1371
|
function StatRow({ label, value, fg: fgOverride, fgMuted: fgMutedOverride }) {
|
|
1354
1372
|
const { dark } = (0, import_auto_paper8.useAutoPaperTheme)();
|
|
1355
1373
|
const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
|
|
1356
1374
|
const fgMuted = fgMutedOverride ?? (dark ? "rgba(255,255,255,0.5)" : "rgba(0,0,0,0.5)");
|
|
1357
|
-
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
1375
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_react_native20.View, { style: styles15.row, children: [
|
|
1358
1376
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_native_paper10.Text, { variant: "bodyMedium", style: { color: fgMuted }, children: label }),
|
|
1359
1377
|
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_native_paper10.Text, { variant: "bodyMedium", style: [styles15.value, { color: fg }], children: value })
|
|
1360
1378
|
] });
|
|
1361
1379
|
}
|
|
1362
|
-
var styles15 =
|
|
1380
|
+
var styles15 = import_react_native20.StyleSheet.create({
|
|
1363
1381
|
row: {
|
|
1364
1382
|
alignItems: "center",
|
|
1365
1383
|
flexDirection: "row",
|
|
@@ -1372,19 +1390,19 @@ var styles15 = import_react_native19.StyleSheet.create({
|
|
|
1372
1390
|
|
|
1373
1391
|
// src/StatSection.tsx
|
|
1374
1392
|
var import_auto_paper9 = require("@rific/auto-paper");
|
|
1375
|
-
var
|
|
1393
|
+
var import_react_native21 = require("react-native");
|
|
1376
1394
|
var import_react_native_paper11 = require("react-native-paper");
|
|
1377
1395
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
1378
1396
|
function StatSection({ label, fg: fgOverride, sectionBg: sectionBgOverride, children }) {
|
|
1379
1397
|
const { dark } = (0, import_auto_paper9.useAutoPaperTheme)();
|
|
1380
1398
|
const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
|
|
1381
1399
|
const sectionBg = sectionBgOverride ?? (dark ? "rgba(255,255,255,0.06)" : "rgba(0,0,0,0.04)");
|
|
1382
|
-
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
1400
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_react_native21.View, { style: [styles16.section, { backgroundColor: sectionBg }], children: [
|
|
1383
1401
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native_paper11.Text, { variant: "labelMedium", style: [styles16.label, { color: fg }], children: label }),
|
|
1384
1402
|
children
|
|
1385
1403
|
] });
|
|
1386
1404
|
}
|
|
1387
|
-
var styles16 =
|
|
1405
|
+
var styles16 = import_react_native21.StyleSheet.create({
|
|
1388
1406
|
// Bold and full-contrast (fg), not the original fontless/fgMuted treatment — that read at the
|
|
1389
1407
|
// same visual weight as StatRow's own row labels below it (both used the identical muted color;
|
|
1390
1408
|
// letterSpacing/variant alone didn't separate them enough to read as "this is the group header"
|
|
@@ -1400,14 +1418,24 @@ var styles16 = import_react_native20.StyleSheet.create({
|
|
|
1400
1418
|
}
|
|
1401
1419
|
});
|
|
1402
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
|
+
|
|
1403
1431
|
// src/usePopoverHost.ts
|
|
1404
|
-
var
|
|
1432
|
+
var import_react7 = require("react");
|
|
1405
1433
|
function usePopoverHost() {
|
|
1406
|
-
const [openId, setOpenId] = (0,
|
|
1407
|
-
const toggle = (0,
|
|
1434
|
+
const [openId, setOpenId] = (0, import_react7.useState)(null);
|
|
1435
|
+
const toggle = (0, import_react7.useCallback)((id) => {
|
|
1408
1436
|
setOpenId((prev) => prev === id ? null : id);
|
|
1409
1437
|
}, []);
|
|
1410
|
-
const close = (0,
|
|
1438
|
+
const close = (0, import_react7.useCallback)(() => setOpenId(null), []);
|
|
1411
1439
|
return { openId, toggle, close };
|
|
1412
1440
|
}
|
|
1413
1441
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -1434,8 +1462,11 @@ function usePopoverHost() {
|
|
|
1434
1462
|
StatRow,
|
|
1435
1463
|
StatSection,
|
|
1436
1464
|
TriggerGaugeHost,
|
|
1465
|
+
UpdateDialog,
|
|
1437
1466
|
getLabeledDropdownContentHeight,
|
|
1467
|
+
getOverlayCardColors,
|
|
1438
1468
|
loadSkiaWeb,
|
|
1469
|
+
overlayStyles,
|
|
1439
1470
|
useAutoAlign,
|
|
1440
1471
|
usePopoverHost
|
|
1441
1472
|
});
|