@tastic/hud 0.8.5 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +425 -23
- package/dist/chunk-32U2OIRW.mjs +77 -0
- package/dist/guide/index.d.mts +118 -0
- package/dist/guide/index.d.ts +118 -0
- package/dist/guide/index.js +543 -0
- package/dist/guide/index.mjs +428 -0
- package/dist/index.d.mts +145 -16
- package/dist/index.d.ts +145 -16
- package/dist/index.js +612 -322
- package/dist/index.mjs +533 -334
- package/package.json +46 -11
- package/src/AchievementCatalogSection.tsx +60 -0
- package/src/AchievementUnlockList.tsx +98 -0
- package/src/ActivityStatSection.tsx +29 -0
- package/src/BaseSettingsDialog.tsx +32 -1
- package/src/ConfirmDialog.tsx +4 -43
- package/src/ContentGutter.tsx +12 -5
- package/src/ControlSchemePicker.tsx +11 -2
- package/src/InlineColorPicker.tsx +38 -11
- package/src/LabeledDropdown.tsx +5 -17
- package/src/PlayerSetupPanel.tsx +196 -0
- package/src/SectionedDropdown.tsx +18 -7
- package/src/StaggeredWord.tsx +114 -0
- package/src/guide/DirectionKeysHint.tsx +96 -0
- package/src/guide/GuideProvider.tsx +87 -0
- package/src/guide/HowToPlayDialog.tsx +224 -0
- package/src/guide/SeatDevicesHint.tsx +52 -0
- package/src/guide/SeatDiagram.tsx +72 -0
- package/src/guide/SwipeHint.tsx +115 -0
- package/src/guide/guideSlice.ts +131 -0
- package/src/guide/index.ts +14 -0
- package/src/guide/types.ts +16 -0
- package/src/index.ts +10 -3
- package/src/overlayCard.ts +51 -4
- package/src/useAutoAlign.ts +17 -1
- package/src/useQuitConfirmation.ts +61 -0
- package/src/useZoneClampedAlign.ts +135 -0
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SkiaGate
|
|
3
3
|
} from "./chunk-XEOFR236.mjs";
|
|
4
|
+
import {
|
|
5
|
+
getOverlayCardColors,
|
|
6
|
+
overlayActionStyles,
|
|
7
|
+
overlayStyles
|
|
8
|
+
} from "./chunk-32U2OIRW.mjs";
|
|
9
|
+
|
|
10
|
+
// src/AchievementCatalogSection.tsx
|
|
11
|
+
import { useAutoPaperTheme as useAutoPaperTheme2 } from "@rific/auto-paper";
|
|
12
|
+
import { Fragment } from "react";
|
|
13
|
+
import { StyleSheet as StyleSheet2 } from "react-native";
|
|
14
|
+
import { Text as Text2 } from "react-native-paper";
|
|
4
15
|
|
|
5
16
|
// src/AchievementRow.tsx
|
|
6
17
|
import { useAutoPaperTheme } from "@rific/auto-paper";
|
|
@@ -70,112 +81,170 @@ var styles = StyleSheet.create({
|
|
|
70
81
|
}
|
|
71
82
|
});
|
|
72
83
|
|
|
73
|
-
// src/
|
|
74
|
-
import {
|
|
75
|
-
|
|
76
|
-
import { useUpdater } from "@rific/updater";
|
|
77
|
-
import { toRotationStyle as toRotationStyle2, useIsTouchPrimaryDevice, useRotation } from "@tastic/core";
|
|
78
|
-
import { useContext, useState as useState2 } from "react";
|
|
79
|
-
import { Platform, ScrollView, StyleSheet as StyleSheet4, View as View3 } from "react-native";
|
|
80
|
-
import { Icon as Icon3, Text as Text3 } from "react-native-paper";
|
|
84
|
+
// src/fonts.ts
|
|
85
|
+
import { Platform } from "react-native";
|
|
86
|
+
var MONO_FONT = Platform.select({ ios: "Menlo", android: "monospace", default: "monospace" });
|
|
81
87
|
|
|
82
|
-
// src/
|
|
83
|
-
import {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
+
// src/AchievementCatalogSection.tsx
|
|
89
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
90
|
+
function AchievementCatalogSection({ rows, label = "ALL ACHIEVEMENTS", fg, fgMuted: fgMutedOverride }) {
|
|
91
|
+
const { dark } = useAutoPaperTheme2();
|
|
92
|
+
const fgMuted = fgMutedOverride ?? (dark ? "rgba(255,255,255,0.5)" : "rgba(0,0,0,0.5)");
|
|
93
|
+
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
94
|
+
/* @__PURE__ */ jsx2(Text2, { variant: "labelMedium", style: [styles2.label, { color: fgMuted, fontFamily: MONO_FONT }], children: label }),
|
|
95
|
+
rows.map((row) => /* @__PURE__ */ jsx2(AchievementRow, { icon: row.icon, title: row.title, description: row.description, badgeColor: row.unlockedAt !== void 0 ? row.tierColor : LOCKED_BADGE_COLOR, checkColor: row.tierColor, unlockedLabel: row.unlockedLabel, progress: row.progress, deviceMarker: row.deviceMarker, fg, fgMuted: fgMutedOverride }, row.id))
|
|
96
|
+
] });
|
|
97
|
+
}
|
|
98
|
+
var styles2 = StyleSheet2.create({
|
|
99
|
+
label: {
|
|
100
|
+
letterSpacing: 2,
|
|
101
|
+
marginTop: 8
|
|
102
|
+
}
|
|
103
|
+
});
|
|
88
104
|
|
|
89
|
-
// src/
|
|
90
|
-
import {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
};
|
|
105
|
+
// src/AchievementUnlockList.tsx
|
|
106
|
+
import { getContrastColor, useAutoPaperTheme as useAutoPaperTheme3 } from "@rific/auto-paper";
|
|
107
|
+
import { ProfileChip } from "@tastic/profile";
|
|
108
|
+
import { StyleSheet as StyleSheet3, View as View2 } from "react-native";
|
|
109
|
+
import { Icon as Icon2, Text as Text3 } from "react-native-paper";
|
|
110
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
111
|
+
var AVATAR_SIZE = 18;
|
|
112
|
+
function AchievementUnlockList({ unlocks, seats, owners, tierColors, fg: fgOverride, style }) {
|
|
113
|
+
const { dark } = useAutoPaperTheme3();
|
|
114
|
+
const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
|
|
115
|
+
const rows = seats.flatMap((seat) => (unlocks[seat] ?? []).map((achievement) => ({ seat, achievement })));
|
|
116
|
+
if (rows.length === 0) return null;
|
|
117
|
+
return /* @__PURE__ */ jsx3(View2, { style: [styles3.list, style], children: rows.map(({ seat, achievement }) => {
|
|
118
|
+
const owner = owners[seat];
|
|
119
|
+
return /* @__PURE__ */ jsxs3(View2, { style: styles3.row, children: [
|
|
120
|
+
owner.profile ? /* @__PURE__ */ jsx3(ProfileChip, { profile: owner.profile, size: AVATAR_SIZE }) : /* @__PURE__ */ jsx3(View2, { style: [styles3.circle, { backgroundColor: owner.color }], children: /* @__PURE__ */ jsx3(Icon2, { source: "account", size: 10, color: getContrastColor(owner.color) }) }),
|
|
121
|
+
/* @__PURE__ */ jsx3(View2, { style: [styles3.circle, { backgroundColor: tierColors[achievement.tier] }], children: /* @__PURE__ */ jsx3(Icon2, { source: achievement.icon, size: 12, color: "#000000" }) }),
|
|
122
|
+
/* @__PURE__ */ jsx3(Text3, { style: [styles3.label, { color: fg }], numberOfLines: 1, children: achievement.title })
|
|
123
|
+
] }, `${seat}-${achievement.id}`);
|
|
124
|
+
}) });
|
|
98
125
|
}
|
|
99
|
-
var
|
|
100
|
-
|
|
126
|
+
var styles3 = StyleSheet3.create({
|
|
127
|
+
circle: {
|
|
101
128
|
alignItems: "center",
|
|
102
|
-
borderRadius:
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
padding: 32
|
|
129
|
+
borderRadius: AVATAR_SIZE / 2,
|
|
130
|
+
height: AVATAR_SIZE,
|
|
131
|
+
justifyContent: "center",
|
|
132
|
+
width: AVATAR_SIZE
|
|
107
133
|
},
|
|
108
|
-
|
|
134
|
+
label: {
|
|
135
|
+
flexShrink: 1,
|
|
136
|
+
fontSize: 12,
|
|
137
|
+
fontWeight: "700"
|
|
138
|
+
},
|
|
139
|
+
list: {
|
|
140
|
+
gap: 6
|
|
141
|
+
},
|
|
142
|
+
row: {
|
|
109
143
|
alignItems: "center",
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
144
|
+
flexDirection: "row",
|
|
145
|
+
gap: 6
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// src/StatRow.tsx
|
|
150
|
+
import { useAutoPaperTheme as useAutoPaperTheme4 } from "@rific/auto-paper";
|
|
151
|
+
import { StyleSheet as StyleSheet4, View as View3 } from "react-native";
|
|
152
|
+
import { Text as Text4 } from "react-native-paper";
|
|
153
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
154
|
+
function StatRow({ label, value, fg: fgOverride, fgMuted: fgMutedOverride }) {
|
|
155
|
+
const { dark } = useAutoPaperTheme4();
|
|
156
|
+
const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
|
|
157
|
+
const fgMuted = fgMutedOverride ?? (dark ? "rgba(255,255,255,0.5)" : "rgba(0,0,0,0.5)");
|
|
158
|
+
return /* @__PURE__ */ jsxs4(View3, { style: styles4.row, children: [
|
|
159
|
+
/* @__PURE__ */ jsx4(Text4, { variant: "bodyMedium", style: { color: fgMuted }, children: label }),
|
|
160
|
+
/* @__PURE__ */ jsx4(Text4, { variant: "bodyMedium", style: [styles4.value, { color: fg }], children: value })
|
|
161
|
+
] });
|
|
162
|
+
}
|
|
163
|
+
var styles4 = StyleSheet4.create({
|
|
164
|
+
row: {
|
|
165
|
+
alignItems: "center",
|
|
166
|
+
flexDirection: "row",
|
|
167
|
+
justifyContent: "space-between"
|
|
168
|
+
},
|
|
169
|
+
value: {
|
|
170
|
+
fontWeight: "bold"
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
// src/StatSection.tsx
|
|
175
|
+
import { useAutoPaperTheme as useAutoPaperTheme5 } from "@rific/auto-paper";
|
|
176
|
+
import { StyleSheet as StyleSheet5, View as View4 } from "react-native";
|
|
177
|
+
import { Text as Text5 } from "react-native-paper";
|
|
178
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
179
|
+
function StatSection({ label, fg: fgOverride, sectionBg: sectionBgOverride, children }) {
|
|
180
|
+
const { dark } = useAutoPaperTheme5();
|
|
181
|
+
const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
|
|
182
|
+
const sectionBg = sectionBgOverride ?? (dark ? "rgba(255,255,255,0.06)" : "rgba(0,0,0,0.04)");
|
|
183
|
+
return /* @__PURE__ */ jsxs5(View4, { style: [styles5.section, { backgroundColor: sectionBg }], children: [
|
|
184
|
+
/* @__PURE__ */ jsx5(Text5, { variant: "labelMedium", style: [styles5.label, { color: fg }], children: label }),
|
|
185
|
+
children
|
|
186
|
+
] });
|
|
187
|
+
}
|
|
188
|
+
var styles5 = StyleSheet5.create({
|
|
189
|
+
// Bold and full-contrast (fg), not the original fontless/fgMuted treatment — that read at the
|
|
190
|
+
// same visual weight as StatRow's own row labels below it (both used the identical muted color;
|
|
191
|
+
// letterSpacing/variant alone didn't separate them enough to read as "this is the group header"
|
|
192
|
+
// at a glance). Matches AchievementRow's own title styling (bold + fg) below it in the same list.
|
|
193
|
+
label: {
|
|
194
|
+
fontWeight: "bold",
|
|
195
|
+
letterSpacing: 2
|
|
196
|
+
},
|
|
197
|
+
section: {
|
|
198
|
+
borderRadius: 12,
|
|
199
|
+
gap: 8,
|
|
200
|
+
padding: 16
|
|
117
201
|
}
|
|
118
202
|
});
|
|
119
203
|
|
|
204
|
+
// src/ActivityStatSection.tsx
|
|
205
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
206
|
+
function ActivityStatSection({ stats }) {
|
|
207
|
+
return /* @__PURE__ */ jsxs6(StatSection, { label: "ACTIVITY", children: [
|
|
208
|
+
/* @__PURE__ */ jsx6(StatRow, { label: "Days Played", value: String(stats.distinctDaysPlayed) }),
|
|
209
|
+
/* @__PURE__ */ jsx6(StatRow, { label: "Day Streak", value: String(stats.currentDayStreak) }),
|
|
210
|
+
/* @__PURE__ */ jsx6(StatRow, { label: "Best Day Streak", value: String(stats.bestDayStreak) })
|
|
211
|
+
] });
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// src/BaseSettingsDialog.tsx
|
|
215
|
+
import { AutoAppearancePicker, Dialog, useAutoPaperTheme as useAutoPaperTheme7 } from "@rific/auto-paper";
|
|
216
|
+
import { Button as Button2, SoundContext, TouchableRipple, useHapticSettings, useSoundSettings, useVibration } from "@rific/feedback-press";
|
|
217
|
+
import { useUpdater } from "@rific/updater";
|
|
218
|
+
import { toRotationStyle as toRotationStyle2, useIsTouchPrimaryDevice, useRotation } from "@tastic/core";
|
|
219
|
+
import { useContext, useState as useState2 } from "react";
|
|
220
|
+
import { Platform as Platform2, ScrollView, StyleSheet as StyleSheet7, View as View6 } from "react-native";
|
|
221
|
+
import { Icon as Icon4, Text as Text7 } from "react-native-paper";
|
|
222
|
+
|
|
120
223
|
// src/ConfirmDialog.tsx
|
|
121
|
-
import {
|
|
224
|
+
import { useAutoPaperTheme as useAutoPaperTheme6 } from "@rific/auto-paper";
|
|
225
|
+
import { Button } from "@rific/feedback-press";
|
|
226
|
+
import { toRotationStyle } from "@tastic/core";
|
|
227
|
+
import { StyleSheet as StyleSheet6, View as View5 } from "react-native";
|
|
228
|
+
import { Icon as Icon3, Portal, Text as Text6 } from "react-native-paper";
|
|
229
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
122
230
|
function ConfirmDialog({ visible, title, message, confirmLabel, cancelLabel, onConfirm, onCancel, rotation = 0, icon = "help-circle-outline", destructive = false }) {
|
|
123
|
-
const { dark, colors } =
|
|
231
|
+
const { dark, colors } = useAutoPaperTheme6();
|
|
124
232
|
if (!visible) return null;
|
|
125
233
|
const { fg, cardBg, cardBorder } = getOverlayCardColors(dark);
|
|
126
234
|
const accent = destructive ? colors.danger : colors.primary;
|
|
127
235
|
const onAccent = destructive ? colors.onDanger : colors.onPrimary;
|
|
128
236
|
const showCancel = cancelLabel !== void 0 && onCancel !== void 0;
|
|
129
|
-
return /* @__PURE__ */
|
|
130
|
-
/* @__PURE__ */
|
|
131
|
-
/* @__PURE__ */
|
|
132
|
-
/* @__PURE__ */
|
|
133
|
-
/* @__PURE__ */
|
|
134
|
-
showCancel && /* @__PURE__ */
|
|
135
|
-
/* @__PURE__ */
|
|
237
|
+
return /* @__PURE__ */ jsx7(Portal, { children: /* @__PURE__ */ jsx7(View5, { style: [overlayStyles.overlay, styles6.overlay], children: /* @__PURE__ */ jsxs7(View5, { style: [overlayStyles.card, styles6.card, { backgroundColor: cardBg, borderColor: cardBorder }, toRotationStyle(rotation)], children: [
|
|
238
|
+
/* @__PURE__ */ jsx7(Icon3, { source: icon, size: 64, color: accent }),
|
|
239
|
+
/* @__PURE__ */ jsx7(Text6, { variant: "headlineLarge", style: [styles6.title, { color: accent }], children: title }),
|
|
240
|
+
/* @__PURE__ */ jsx7(Text6, { variant: "bodyLarge", style: [styles6.body, { color: fg }], children: message }),
|
|
241
|
+
/* @__PURE__ */ jsxs7(View5, { style: overlayActionStyles.actions, children: [
|
|
242
|
+
showCancel && /* @__PURE__ */ jsx7(Button, { mode: "outlined", onPress: onCancel, style: overlayActionStyles.actionButton, children: cancelLabel }),
|
|
243
|
+
/* @__PURE__ */ jsx7(Button, { mode: "contained", onPress: onConfirm, style: showCancel ? overlayActionStyles.actionButton : overlayActionStyles.actionButtonSingle, buttonColor: accent, textColor: onAccent, children: confirmLabel })
|
|
136
244
|
] })
|
|
137
245
|
] }) }) });
|
|
138
246
|
}
|
|
139
|
-
var
|
|
140
|
-
// minWidth (not flexBasis) is each button's real floor - whenever both fit side by side, flexGrow
|
|
141
|
-
// still splits any leftover width evenly beyond that floor, same visual result as a plain flex: 1
|
|
142
|
-
// on a roomy screen, but a button can never be squeezed narrower than 128, only wrap to its own
|
|
143
|
-
// row instead (see actions' flexWrap below). This used to be flexBasis: 128, which measured
|
|
144
|
-
// correctly on web but rendered every button roughly SQUARE on iOS - confirmed live (see the
|
|
145
|
-
// "Quit Match?" Cancel/Quit buttons and the single-button "OK" dialogs both coming out ~128pt
|
|
146
|
-
// tall instead of wide). Root cause: react-native-paper's Button renders its Surface as two
|
|
147
|
-
// nested views on iOS only (Surface.tsx's SurfaceIOS, for shadow rendering) - only a curated
|
|
148
|
-
// allowlist of style keys (flex/flexGrow/flexShrink/width/height/position/... - notably NOT
|
|
149
|
-
// flexBasis) reaches the outer view, which is the real flex item inside this row; every other
|
|
150
|
-
// key, flexBasis included, falls through to an inner view whose own unspecified flexDirection
|
|
151
|
-
// defaults to column. flexGrow: 1 landed on the (row-context) outer view and grew width
|
|
152
|
-
// correctly; flexBasis: 128 landed on the (column-context) inner view instead, where a flexBasis
|
|
153
|
-
// sets HEIGHT, not width. minWidth isn't axis-relative like flexBasis, so it constrains width
|
|
154
|
-
// correctly regardless of which of the two views it ends up on. react-native-paper's Button also
|
|
155
|
-
// hardcodes numberOfLines={1} on its label with no override, so a button squeezed under its
|
|
156
|
-
// label's natural width silently ellipsizes ("Cancel" -> "Can...") instead of wrapping - assumed
|
|
157
|
-
// fixable by just giving the row more width, until confirmed live that these two-word labels
|
|
158
|
-
// (Cancel/Reset/New Game) can still lose the truncation fight even with the extra room card's own
|
|
159
|
-
// width fix below provides, on a narrow enough screen.
|
|
160
|
-
actionButton: {
|
|
161
|
-
flexGrow: 1,
|
|
162
|
-
minWidth: 128
|
|
163
|
-
},
|
|
164
|
-
// A lone confirm button (no cancel - BaseSettingsDialog's info-only "OK" dialogs, e.g. the
|
|
165
|
-
// update-check "no update found" message) has nothing left to share actions' width with, so
|
|
166
|
-
// actionButton's own flexGrow: 1 would stretch it across the entire row instead of reading as a
|
|
167
|
-
// normal button. Same 128 floor, no flexGrow, so it stays at that natural size instead of filling
|
|
168
|
-
// the card - centered by actions' own justifyContent below.
|
|
169
|
-
actionButtonSingle: {
|
|
170
|
-
minWidth: 128
|
|
171
|
-
},
|
|
172
|
-
actions: {
|
|
173
|
-
flexDirection: "row",
|
|
174
|
-
flexWrap: "wrap",
|
|
175
|
-
gap: 12,
|
|
176
|
-
justifyContent: "center",
|
|
177
|
-
width: "100%"
|
|
178
|
-
},
|
|
247
|
+
var styles6 = StyleSheet6.create({
|
|
179
248
|
body: {
|
|
180
249
|
textAlign: "center"
|
|
181
250
|
},
|
|
@@ -224,12 +293,12 @@ function useUpdateConfirmBridge() {
|
|
|
224
293
|
}
|
|
225
294
|
|
|
226
295
|
// src/BaseSettingsDialog.tsx
|
|
227
|
-
import { Fragment, jsx as
|
|
296
|
+
import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
228
297
|
function SettingIcon({ source, color, containerColor }) {
|
|
229
|
-
return /* @__PURE__ */
|
|
298
|
+
return /* @__PURE__ */ jsx8(View6, { style: [styles7.iconBadge, { backgroundColor: containerColor }], children: /* @__PURE__ */ jsx8(Icon4, { source, size: 18, color }) });
|
|
230
299
|
}
|
|
231
|
-
function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, version, lockOrientation, onLockOrientationChange, deferBottomEdgeGestures, onDeferBottomEdgeGestures, hideSound = false, hideHaptics = false, hideAppearance = false, hideUpdateCheck = false, onUpdateError, children }) {
|
|
232
|
-
const { colors } =
|
|
300
|
+
function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, version, lockOrientation, onLockOrientationChange, deferBottomEdgeGestures, onDeferBottomEdgeGestures, hideSound = false, hideHaptics = false, hideAppearance = false, hideUpdateCheck = false, onUpdateError, onShowHowToPlay, children }) {
|
|
301
|
+
const { colors } = useAutoPaperTheme7();
|
|
233
302
|
const ambientRotation = useRotation();
|
|
234
303
|
const rotation = rotationOverride ?? ambientRotation;
|
|
235
304
|
const isTouchPrimary = useIsTouchPrimaryDevice();
|
|
@@ -248,32 +317,32 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
|
|
|
248
317
|
});
|
|
249
318
|
const updateManifestDate = updateManifest ? new Date(updateManifest.createdAt) : null;
|
|
250
319
|
const showLockOrientation = isTouchPrimary && lockOrientation !== void 0 && onLockOrientationChange !== void 0;
|
|
251
|
-
const showEdgeGuard =
|
|
252
|
-
const showHaptics =
|
|
320
|
+
const showEdgeGuard = Platform2.OS === "ios" && deferBottomEdgeGestures !== void 0 && onDeferBottomEdgeGestures !== void 0;
|
|
321
|
+
const showHaptics = Platform2.OS !== "web" && !hideHaptics;
|
|
253
322
|
const showSound = !hideSound;
|
|
254
323
|
const showAppearance = !hideAppearance;
|
|
255
|
-
const showUpdateCheck =
|
|
256
|
-
return /* @__PURE__ */
|
|
257
|
-
/* @__PURE__ */
|
|
258
|
-
/* @__PURE__ */
|
|
259
|
-
/* @__PURE__ */
|
|
260
|
-
/* @__PURE__ */
|
|
261
|
-
showLockOrientation && /* @__PURE__ */
|
|
262
|
-
/* @__PURE__ */
|
|
263
|
-
/* @__PURE__ */
|
|
264
|
-
/* @__PURE__ */
|
|
265
|
-
/* @__PURE__ */
|
|
324
|
+
const showUpdateCheck = Platform2.OS !== "web" && !hideUpdateCheck;
|
|
325
|
+
return /* @__PURE__ */ jsxs8(Fragment2, { children: [
|
|
326
|
+
/* @__PURE__ */ jsxs8(Dialog, { visible, onDismiss, style: [styles7.dialog, toRotationStyle2(rotation)], children: [
|
|
327
|
+
/* @__PURE__ */ jsx8(Dialog.Title, { children: "Settings" }),
|
|
328
|
+
/* @__PURE__ */ jsx8(Dialog.ScrollArea, { style: styles7.scrollArea, children: /* @__PURE__ */ jsxs8(ScrollView, { contentContainerStyle: styles7.content, showsVerticalScrollIndicator: false, children: [
|
|
329
|
+
/* @__PURE__ */ jsxs8(View6, { style: styles7.toggleGroup, children: [
|
|
330
|
+
showLockOrientation && /* @__PURE__ */ jsx8(TouchableRipple, { onPress: () => onLockOrientationChange(!lockOrientation), style: styles7.toggleButton, accessibilityLabel: `Lock orientation ${lockOrientation ? "on" : "off"}`, children: /* @__PURE__ */ jsxs8(View6, { style: styles7.toggleContent, children: [
|
|
331
|
+
/* @__PURE__ */ jsx8(SettingIcon, { source: lockOrientation ? "lock" : "lock-open-variant-outline", color: lockOrientation ? colors.secondary : colors.onSurfaceVariant, containerColor: lockOrientation ? colors.secondaryContainer : colors.surfaceVariant }),
|
|
332
|
+
/* @__PURE__ */ jsxs8(View6, { style: styles7.flexShrink, children: [
|
|
333
|
+
/* @__PURE__ */ jsx8(Text7, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Lock Orientation" }),
|
|
334
|
+
/* @__PURE__ */ jsx8(Text7, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Pins the current layout" })
|
|
266
335
|
] })
|
|
267
336
|
] }) }),
|
|
268
|
-
showEdgeGuard && /* @__PURE__ */
|
|
269
|
-
/* @__PURE__ */
|
|
270
|
-
/* @__PURE__ */
|
|
271
|
-
/* @__PURE__ */
|
|
272
|
-
/* @__PURE__ */
|
|
337
|
+
showEdgeGuard && /* @__PURE__ */ jsx8(TouchableRipple, { onPress: () => onDeferBottomEdgeGestures(!deferBottomEdgeGestures), style: styles7.toggleButton, accessibilityLabel: `Edge guard ${deferBottomEdgeGestures ? "on" : "off"}`, children: /* @__PURE__ */ jsxs8(View6, { style: styles7.toggleContent, children: [
|
|
338
|
+
/* @__PURE__ */ jsx8(SettingIcon, { source: deferBottomEdgeGestures ? "shield-check-outline" : "shield-off-outline", color: deferBottomEdgeGestures ? colors.secondary : colors.onSurfaceVariant, containerColor: deferBottomEdgeGestures ? colors.secondaryContainer : colors.surfaceVariant }),
|
|
339
|
+
/* @__PURE__ */ jsxs8(View6, { style: styles7.flexShrink, children: [
|
|
340
|
+
/* @__PURE__ */ jsx8(Text7, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Edge Guard" }),
|
|
341
|
+
/* @__PURE__ */ jsx8(Text7, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Requires a second swipe" })
|
|
273
342
|
] })
|
|
274
343
|
] }) }),
|
|
275
|
-
(showSound || showHaptics) && /* @__PURE__ */
|
|
276
|
-
showSound && /* @__PURE__ */
|
|
344
|
+
(showSound || showHaptics) && /* @__PURE__ */ jsxs8(View6, { style: styles7.toggleRow, children: [
|
|
345
|
+
showSound && /* @__PURE__ */ jsx8(
|
|
277
346
|
TouchableRipple,
|
|
278
347
|
{
|
|
279
348
|
soundDisabled: true,
|
|
@@ -282,15 +351,15 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
|
|
|
282
351
|
setSoundSettings({ enabled });
|
|
283
352
|
if (enabled) sound.selection?.();
|
|
284
353
|
},
|
|
285
|
-
style:
|
|
354
|
+
style: styles7.toggleButtonInRow,
|
|
286
355
|
accessibilityLabel: `Sound ${soundSettings.enabled ? "on" : "off"}`,
|
|
287
|
-
children: /* @__PURE__ */
|
|
288
|
-
/* @__PURE__ */
|
|
289
|
-
/* @__PURE__ */
|
|
356
|
+
children: /* @__PURE__ */ jsxs8(View6, { style: styles7.toggleContent, children: [
|
|
357
|
+
/* @__PURE__ */ jsx8(SettingIcon, { source: soundSettings.enabled ? "volume-high" : "volume-off", color: soundSettings.enabled ? colors.tertiary : colors.onSurfaceVariant, containerColor: soundSettings.enabled ? colors.tertiaryContainer : colors.surfaceVariant }),
|
|
358
|
+
/* @__PURE__ */ jsx8(Text7, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Sound" })
|
|
290
359
|
] })
|
|
291
360
|
}
|
|
292
361
|
),
|
|
293
|
-
showHaptics && /* @__PURE__ */
|
|
362
|
+
showHaptics && /* @__PURE__ */ jsx8(
|
|
294
363
|
TouchableRipple,
|
|
295
364
|
{
|
|
296
365
|
hapticDisabled: true,
|
|
@@ -299,36 +368,54 @@ function BaseSettingsDialog({ visible, onDismiss, rotation: rotationOverride, ve
|
|
|
299
368
|
setHapticSettings({ vibrate });
|
|
300
369
|
if (vibrate) forceHapticFeedback();
|
|
301
370
|
},
|
|
302
|
-
style:
|
|
371
|
+
style: styles7.toggleButtonInRow,
|
|
303
372
|
accessibilityLabel: `Haptics ${hapticSettings.vibrate ? "on" : "off"}`,
|
|
304
|
-
children: /* @__PURE__ */
|
|
305
|
-
/* @__PURE__ */
|
|
306
|
-
/* @__PURE__ */
|
|
373
|
+
children: /* @__PURE__ */ jsxs8(View6, { style: styles7.toggleContent, children: [
|
|
374
|
+
/* @__PURE__ */ jsx8(SettingIcon, { source: hapticSettings.vibrate ? "vibrate" : "vibrate-off", color: hapticSettings.vibrate ? colors.tertiary : colors.onSurfaceVariant, containerColor: hapticSettings.vibrate ? colors.tertiaryContainer : colors.surfaceVariant }),
|
|
375
|
+
/* @__PURE__ */ jsx8(Text7, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "Haptics" })
|
|
307
376
|
] })
|
|
308
377
|
}
|
|
309
378
|
)
|
|
310
|
-
] })
|
|
379
|
+
] }),
|
|
380
|
+
onShowHowToPlay && /* @__PURE__ */ jsx8(
|
|
381
|
+
TouchableRipple,
|
|
382
|
+
{
|
|
383
|
+
onPress: () => {
|
|
384
|
+
onDismiss();
|
|
385
|
+
onShowHowToPlay();
|
|
386
|
+
},
|
|
387
|
+
style: styles7.toggleButton,
|
|
388
|
+
accessibilityLabel: "How to Play",
|
|
389
|
+
children: /* @__PURE__ */ jsxs8(View6, { style: styles7.toggleContent, children: [
|
|
390
|
+
/* @__PURE__ */ jsx8(SettingIcon, { source: "help-circle-outline", color: colors.secondary, containerColor: colors.secondaryContainer }),
|
|
391
|
+
/* @__PURE__ */ jsxs8(View6, { style: styles7.flexShrink, children: [
|
|
392
|
+
/* @__PURE__ */ jsx8(Text7, { variant: "bodyLarge", style: { color: colors.onSurface }, children: "How to Play" }),
|
|
393
|
+
/* @__PURE__ */ jsx8(Text7, { variant: "bodySmall", numberOfLines: 1, style: { color: colors.onSurfaceVariant }, children: "Replay the quick intro" })
|
|
394
|
+
] })
|
|
395
|
+
] })
|
|
396
|
+
}
|
|
397
|
+
)
|
|
311
398
|
] }),
|
|
312
|
-
showAppearance && /* @__PURE__ */
|
|
313
|
-
/* @__PURE__ */
|
|
314
|
-
/* @__PURE__ */
|
|
399
|
+
showAppearance && /* @__PURE__ */ jsxs8(View6, { style: styles7.section, children: [
|
|
400
|
+
/* @__PURE__ */ jsx8(Text7, { variant: "labelMedium", style: [styles7.sectionLabel, { color: colors.onSurfaceVariant }], children: "APPEARANCE" }),
|
|
401
|
+
/* @__PURE__ */ jsx8(AutoAppearancePicker, { showLabels: false })
|
|
315
402
|
] }),
|
|
316
403
|
children,
|
|
317
|
-
showUpdateCheck && /* @__PURE__ */
|
|
318
|
-
/* @__PURE__ */
|
|
404
|
+
showUpdateCheck && /* @__PURE__ */ jsxs8(View6, { style: styles7.section, children: [
|
|
405
|
+
/* @__PURE__ */ jsxs8(Text7, { variant: "labelSmall", style: [styles7.sectionLabel, { color: colors.onSurfaceVariant }], children: [
|
|
319
406
|
"VERSION ",
|
|
320
407
|
version,
|
|
321
408
|
updateReady ? " \xB7 UPDATE READY" : ""
|
|
322
409
|
] }),
|
|
323
|
-
/* @__PURE__ */
|
|
410
|
+
/* @__PURE__ */ jsx8(Button2, { mode: "outlined", onPress: check, loading: checking, disabled: checking, children: "Check for Updates" })
|
|
324
411
|
] })
|
|
325
412
|
] }) })
|
|
326
413
|
] }),
|
|
327
|
-
/* @__PURE__ */
|
|
328
|
-
/* @__PURE__ */
|
|
414
|
+
/* @__PURE__ */ jsx8(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) }),
|
|
415
|
+
/* @__PURE__ */ jsx8(ConfirmDialog, { visible: !!infoMessage, title: infoMessage?.title ?? "", message: infoMessage?.message ?? "", confirmLabel: "OK", icon: "information-outline", rotation, onConfirm: () => setInfoMessage(null) })
|
|
329
416
|
] });
|
|
330
417
|
}
|
|
331
|
-
var
|
|
418
|
+
var styles7 = StyleSheet7.create({
|
|
332
419
|
content: {
|
|
333
420
|
gap: 24,
|
|
334
421
|
paddingVertical: 20
|
|
@@ -396,31 +483,31 @@ var styles3 = StyleSheet4.create({
|
|
|
396
483
|
});
|
|
397
484
|
|
|
398
485
|
// src/BaseStatsScreen.tsx
|
|
399
|
-
import { useAutoPaperTheme as
|
|
486
|
+
import { useAutoPaperTheme as useAutoPaperTheme8 } from "@rific/auto-paper";
|
|
400
487
|
import { Button as Button3, IconButton } from "@rific/feedback-press";
|
|
401
488
|
import { useRotation as useRotation2 } from "@tastic/core";
|
|
402
489
|
import { useState as useState3 } from "react";
|
|
403
|
-
import { ScrollView as ScrollView2, StyleSheet as
|
|
404
|
-
import { Text as
|
|
405
|
-
import { jsx as
|
|
490
|
+
import { ScrollView as ScrollView2, StyleSheet as StyleSheet8, View as View7 } from "react-native";
|
|
491
|
+
import { Text as Text8 } from "react-native-paper";
|
|
492
|
+
import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
406
493
|
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 }) {
|
|
407
|
-
const { dark, colors } =
|
|
494
|
+
const { dark, colors } = useAutoPaperTheme8();
|
|
408
495
|
const ambientRotation = useRotation2();
|
|
409
496
|
const rotation = rotationOverride ?? ambientRotation;
|
|
410
497
|
const [confirmResetVisible, setConfirmResetVisible] = useState3(false);
|
|
411
498
|
const showReset = !!onReset;
|
|
412
499
|
const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
|
|
413
500
|
const bg = bgOverride ?? (dark ? "#000000" : "#FFFFFF");
|
|
414
|
-
return /* @__PURE__ */
|
|
415
|
-
/* @__PURE__ */
|
|
416
|
-
/* @__PURE__ */
|
|
417
|
-
/* @__PURE__ */
|
|
501
|
+
return /* @__PURE__ */ jsxs9(View7, { style: [styles8.container, { backgroundColor: bg }], children: [
|
|
502
|
+
/* @__PURE__ */ jsxs9(View7, { style: [styles8.header, { paddingTop: 8 + insets.top, paddingLeft: 8 + insets.left }], children: [
|
|
503
|
+
/* @__PURE__ */ jsx9(IconButton, { icon: "arrow-left", iconColor: fg, size: 24, onPress: onBack }),
|
|
504
|
+
/* @__PURE__ */ jsx9(Text8, { variant: titleVariant, style: [styles8.title, { color: fg }], children: title })
|
|
418
505
|
] }),
|
|
419
|
-
/* @__PURE__ */
|
|
506
|
+
/* @__PURE__ */ jsxs9(ScrollView2, { style: styles8.scrollView, contentContainerStyle: [styles8.content, { paddingBottom: 32 + insets.bottom }], showsVerticalScrollIndicator: false, children: [
|
|
420
507
|
children,
|
|
421
|
-
showReset && /* @__PURE__ */
|
|
508
|
+
showReset && /* @__PURE__ */ jsx9(Button3, { mode: "contained", onPress: () => setConfirmResetVisible(true), buttonColor: colors.danger, textColor: colors.onDanger, style: styles8.resetButton, children: resetLabel })
|
|
422
509
|
] }),
|
|
423
|
-
/* @__PURE__ */
|
|
510
|
+
/* @__PURE__ */ jsx9(
|
|
424
511
|
ConfirmDialog,
|
|
425
512
|
{
|
|
426
513
|
visible: confirmResetVisible,
|
|
@@ -440,7 +527,7 @@ function BaseStatsScreen({ rotation: rotationOverride, title = "Achievements", t
|
|
|
440
527
|
)
|
|
441
528
|
] });
|
|
442
529
|
}
|
|
443
|
-
var
|
|
530
|
+
var styles8 = StyleSheet8.create({
|
|
444
531
|
container: {
|
|
445
532
|
flex: 1
|
|
446
533
|
},
|
|
@@ -471,19 +558,19 @@ var styles4 = StyleSheet5.create({
|
|
|
471
558
|
});
|
|
472
559
|
|
|
473
560
|
// src/ContentGutter.tsx
|
|
474
|
-
import { computeContentBounds } from "@tastic/core";
|
|
475
|
-
import { StyleSheet as
|
|
476
|
-
import { jsx as
|
|
561
|
+
import { computeContentBounds, useRotatedWindowDimensions } from "@tastic/core";
|
|
562
|
+
import { StyleSheet as StyleSheet9, View as View8 } from "react-native";
|
|
563
|
+
import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
477
564
|
function ContentGutter({ maxContentWidth, leftGutter, rightGutter, style, children }) {
|
|
478
|
-
const { width: windowWidth } =
|
|
565
|
+
const { width: windowWidth } = useRotatedWindowDimensions();
|
|
479
566
|
const { contentWidth, gutterWidth } = computeContentBounds(windowWidth, maxContentWidth ?? Infinity);
|
|
480
|
-
return /* @__PURE__ */
|
|
481
|
-
/* @__PURE__ */
|
|
482
|
-
/* @__PURE__ */
|
|
483
|
-
/* @__PURE__ */
|
|
567
|
+
return /* @__PURE__ */ jsxs10(View8, { style: [styles9.row, style], children: [
|
|
568
|
+
/* @__PURE__ */ jsx10(View8, { style: [styles9.gutter, { width: gutterWidth }], children: leftGutter }),
|
|
569
|
+
/* @__PURE__ */ jsx10(View8, { style: { width: contentWidth }, children }),
|
|
570
|
+
/* @__PURE__ */ jsx10(View8, { style: [styles9.gutter, { width: gutterWidth }], children: rightGutter })
|
|
484
571
|
] });
|
|
485
572
|
}
|
|
486
|
-
var
|
|
573
|
+
var styles9 = StyleSheet9.create({
|
|
487
574
|
// overflow:'hidden' keeps an oversized leftGutter/rightGutter from bleeding into the content
|
|
488
575
|
// column instead of clipping cleanly at its own real width.
|
|
489
576
|
gutter: {
|
|
@@ -502,38 +589,34 @@ import { Platform as Platform3 } from "react-native";
|
|
|
502
589
|
import { getBlendedColor, getColorRoles } from "@rific/auto-paper";
|
|
503
590
|
import { IconButton as IconButton2, TouchableRipple as TouchableRipple2 } from "@rific/feedback-press";
|
|
504
591
|
import { useRotation as useRotation3 } from "@tastic/core";
|
|
505
|
-
import { ScrollView as ScrollView3, StyleSheet as
|
|
506
|
-
import { Icon as
|
|
507
|
-
|
|
508
|
-
// src/fonts.ts
|
|
509
|
-
import { Platform as Platform2 } from "react-native";
|
|
510
|
-
var MONO_FONT = Platform2.select({ ios: "Menlo", android: "monospace", default: "monospace" });
|
|
592
|
+
import { ScrollView as ScrollView3, StyleSheet as StyleSheet11, View as View11 } from "react-native";
|
|
593
|
+
import { Icon as Icon5, Text as Text9 } from "react-native-paper";
|
|
511
594
|
|
|
512
595
|
// src/PopoverBody.tsx
|
|
513
|
-
import { StyleSheet as
|
|
514
|
-
import { Fragment as
|
|
596
|
+
import { StyleSheet as StyleSheet10, View as View9 } from "react-native";
|
|
597
|
+
import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
515
598
|
var CARET_SIZE = 7;
|
|
516
599
|
var CARET_RING_OFFSET = 2;
|
|
517
600
|
var CARET_DIP = 1;
|
|
518
601
|
function PopoverBody({ visible, children, align = "center", verticalAlign = "below", caretColor, caretBorderColor, caretBorderWidth = 1, triggerSize = 0 }) {
|
|
519
602
|
if (!visible) return null;
|
|
520
603
|
const above = verticalAlign === "above";
|
|
521
|
-
const alignStyle = align === "left" ?
|
|
522
|
-
const verticalStyle = above ?
|
|
604
|
+
const alignStyle = align === "left" ? styles10.contentLeft : align === "right" ? styles10.contentRight : styles10.contentCenter;
|
|
605
|
+
const verticalStyle = above ? styles10.contentAbove : styles10.contentBelow;
|
|
523
606
|
const ringSize = CARET_SIZE + caretBorderWidth;
|
|
524
607
|
const caretOffset = (halfFootprint) => align === "right" ? { right: triggerSize / 2 - halfFootprint } : { left: triggerSize / 2 - halfFootprint };
|
|
525
608
|
const caretFill = above ? "borderTopColor" : "borderBottomColor";
|
|
526
609
|
const caretWidthProp = above ? "borderTopWidth" : "borderBottomWidth";
|
|
527
610
|
const caretEdge = (size) => above ? { bottom: -size + CARET_DIP } : { top: -size + CARET_DIP };
|
|
528
|
-
return /* @__PURE__ */
|
|
611
|
+
return /* @__PURE__ */ jsxs11(View9, { style: [styles10.content, alignStyle, verticalStyle], children: [
|
|
529
612
|
children,
|
|
530
|
-
caretColor && /* @__PURE__ */
|
|
531
|
-
/* @__PURE__ */
|
|
532
|
-
/* @__PURE__ */
|
|
613
|
+
caretColor && /* @__PURE__ */ jsxs11(Fragment3, { children: [
|
|
614
|
+
/* @__PURE__ */ jsx11(View9, { style: [styles10.caret, caretOffset(ringSize), caretEdge(ringSize), { [caretFill]: caretBorderColor ?? caretColor, [caretWidthProp]: ringSize, borderLeftWidth: ringSize, borderRightWidth: ringSize }] }),
|
|
615
|
+
/* @__PURE__ */ jsx11(View9, { style: [styles10.caret, caretOffset(CARET_SIZE), caretEdge(CARET_SIZE - CARET_RING_OFFSET), { [caretFill]: caretColor, [caretWidthProp]: CARET_SIZE, borderLeftWidth: CARET_SIZE, borderRightWidth: CARET_SIZE }] })
|
|
533
616
|
] })
|
|
534
617
|
] });
|
|
535
618
|
}
|
|
536
|
-
var
|
|
619
|
+
var styles10 = StyleSheet10.create({
|
|
537
620
|
caret: {
|
|
538
621
|
borderLeftColor: "transparent",
|
|
539
622
|
borderRightColor: "transparent",
|
|
@@ -576,15 +659,15 @@ var styles6 = StyleSheet7.create({
|
|
|
576
659
|
});
|
|
577
660
|
|
|
578
661
|
// src/TriggerGaugeHost.tsx
|
|
579
|
-
import { jsx as
|
|
662
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
580
663
|
var getTriggerGauge = () => import("./TriggerGauge-2OJOOF6I.mjs").then((mod) => ({ default: mod.TriggerGauge }));
|
|
581
664
|
function TriggerGaugeHost(props) {
|
|
582
|
-
return /* @__PURE__ */
|
|
665
|
+
return /* @__PURE__ */ jsx12(SkiaGate, { getComponent: getTriggerGauge, componentProps: props });
|
|
583
666
|
}
|
|
584
667
|
|
|
585
668
|
// src/useAutoAlign.ts
|
|
586
669
|
import { useCallback as useCallback2, useEffect, useRef as useRef2, useState as useState4 } from "react";
|
|
587
|
-
import { useWindowDimensions
|
|
670
|
+
import { useWindowDimensions } from "react-native";
|
|
588
671
|
var EDGE_MARGIN = 12;
|
|
589
672
|
function rotateRect(x, y, width, height, rotation, windowWidth, windowHeight) {
|
|
590
673
|
if (rotation === 0) return { x, y, width, height };
|
|
@@ -597,7 +680,7 @@ function rotateRect(x, y, width, height, rotation, windowWidth, windowHeight) {
|
|
|
597
680
|
}
|
|
598
681
|
function useAutoAlign(open, contentWidth, contentHeight, rotation = 0) {
|
|
599
682
|
const triggerRef = useRef2(null);
|
|
600
|
-
const { width: windowWidth, height: windowHeight } =
|
|
683
|
+
const { width: windowWidth, height: windowHeight } = useWindowDimensions();
|
|
601
684
|
const [align, setAlign] = useState4("center");
|
|
602
685
|
const [verticalAlign, setVerticalAlign] = useState4("below");
|
|
603
686
|
const [maxHeight, setMaxHeight] = useState4(contentHeight);
|
|
@@ -631,7 +714,7 @@ function useAutoAlign(open, contentWidth, contentHeight, rotation = 0) {
|
|
|
631
714
|
}
|
|
632
715
|
|
|
633
716
|
// src/SectionedDropdown.tsx
|
|
634
|
-
import { Fragment as
|
|
717
|
+
import { Fragment as Fragment4, jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
635
718
|
var MENU_BORDER_WIDTH = 1;
|
|
636
719
|
var TRIGGER_SIZE = 44;
|
|
637
720
|
var MENU_MIN_WIDTH = 200;
|
|
@@ -642,7 +725,7 @@ var MENU_ITEM_HEIGHT = 40;
|
|
|
642
725
|
var MENU_ITEM_HEIGHT_WITH_DESCRIPTION = 58;
|
|
643
726
|
var MENU_DIVIDER_HEIGHT = 9;
|
|
644
727
|
var MENU_VERTICAL_PADDING = 12;
|
|
645
|
-
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" } }) {
|
|
728
|
+
function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accentColor, mutedColor, onAccentColor, dark, align: forcedAlign, alignOverride, rotation: rotationOverride, autoDismiss = true, labelFontFamily = MONO_FONT, allClearLabels = { all: "All", clear: "Clear" } }) {
|
|
646
729
|
const ambientRotation = useRotation3();
|
|
647
730
|
const rotation = rotationOverride ?? ambientRotation;
|
|
648
731
|
const menuBg = dark ? "#000000" : "#FFFFFF";
|
|
@@ -656,8 +739,10 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
|
|
|
656
739
|
const divider = sectionIndex > 0 ? MENU_DIVIDER_HEIGHT : 0;
|
|
657
740
|
return sum + rows + footer + divider;
|
|
658
741
|
}, 0);
|
|
659
|
-
const
|
|
660
|
-
const
|
|
742
|
+
const auto = useAutoAlign(open, MENU_MAX_WIDTH, estimatedHeight, rotation);
|
|
743
|
+
const placement = alignOverride ?? auto;
|
|
744
|
+
const { maxHeight, measured, triggerRef, verticalAlign } = placement;
|
|
745
|
+
const align = forcedAlign ?? placement.align;
|
|
661
746
|
const onlySection = sections.length === 1 ? sections[0] : null;
|
|
662
747
|
const selectedOption = onlySection?.kind === "single" ? onlySection.options.find((o) => o.value === onlySection.value) : void 0;
|
|
663
748
|
const triggerIcon = selectedOption?.icon ?? icon;
|
|
@@ -679,17 +764,17 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
|
|
|
679
764
|
}
|
|
680
765
|
gaugeOffset += section.options.length;
|
|
681
766
|
}
|
|
682
|
-
const anchorStyle = [
|
|
767
|
+
const anchorStyle = [styles11.anchor, open && styles11.anchorOpen];
|
|
683
768
|
const menuStyle = { backgroundColor: menuBg, borderColor: menuBorderColor, maxHeight };
|
|
684
769
|
const dividerStyle = { backgroundColor: menuBorderColor };
|
|
685
|
-
return /* @__PURE__ */
|
|
686
|
-
/* @__PURE__ */
|
|
687
|
-
/* @__PURE__ */
|
|
688
|
-
/* @__PURE__ */
|
|
770
|
+
return /* @__PURE__ */ jsxs12(View11, { style: anchorStyle, children: [
|
|
771
|
+
/* @__PURE__ */ jsxs12(View11, { ref: triggerRef, collapsable: false, style: styles11.triggerBox, children: [
|
|
772
|
+
/* @__PURE__ */ jsx13(TriggerGaugeHost, { segments: gaugeSegments, litIndices: gaugeLitIndices, size: TRIGGER_SIZE, accentColor, mutedColor }),
|
|
773
|
+
/* @__PURE__ */ jsx13(IconButton2, { icon: triggerIcon, iconColor: triggerIconColor, size: triggerIconSize, accessibilityLabel, onPress: () => host.toggle(id) })
|
|
689
774
|
] }),
|
|
690
|
-
/* @__PURE__ */
|
|
691
|
-
sectionIndex > 0 && /* @__PURE__ */
|
|
692
|
-
section.kind === "single" ? /* @__PURE__ */
|
|
775
|
+
/* @__PURE__ */ jsx13(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: menuBorderColor, caretBorderWidth: MENU_BORDER_WIDTH, triggerSize: TRIGGER_SIZE, children: /* @__PURE__ */ jsx13(ScrollView3, { style: [styles11.menu, menuStyle], contentContainerStyle: styles11.menuContent, showsVerticalScrollIndicator: false, children: sections.map((section, sectionIndex) => /* @__PURE__ */ jsxs12(View11, { children: [
|
|
776
|
+
sectionIndex > 0 && /* @__PURE__ */ jsx13(View11, { style: [styles11.divider, dividerStyle] }),
|
|
777
|
+
section.kind === "single" ? /* @__PURE__ */ jsx13(
|
|
693
778
|
SingleSection,
|
|
694
779
|
{
|
|
695
780
|
section,
|
|
@@ -702,7 +787,7 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
|
|
|
702
787
|
if (autoDismiss) host.close();
|
|
703
788
|
}
|
|
704
789
|
}
|
|
705
|
-
) : /* @__PURE__ */
|
|
790
|
+
) : /* @__PURE__ */ jsx13(MultiSection, { section, accentColor, onAccentColor: resolvedOnAccentColor, mutedColor, labelFontFamily, allClearLabels })
|
|
706
791
|
] }, section.id)) }) })
|
|
707
792
|
] });
|
|
708
793
|
}
|
|
@@ -714,18 +799,18 @@ function SingleSection({
|
|
|
714
799
|
labelFontFamily,
|
|
715
800
|
onSelect
|
|
716
801
|
}) {
|
|
717
|
-
return /* @__PURE__ */
|
|
802
|
+
return /* @__PURE__ */ jsx13(Fragment4, { children: section.options.map((option) => {
|
|
718
803
|
const selected = option.value === section.value;
|
|
719
804
|
const taken = !selected && option.value === section.takenValue;
|
|
720
805
|
const rowColor = selected ? onAccentColor : mutedColor;
|
|
721
|
-
const itemStyle = [
|
|
806
|
+
const itemStyle = [styles11.item, selected && { backgroundColor: accentColor }, taken && styles11.itemTaken];
|
|
722
807
|
const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
|
|
723
808
|
const descriptionStyle = { fontFamily: labelFontFamily, color: rowColor };
|
|
724
|
-
return /* @__PURE__ */
|
|
725
|
-
option.icon && /* @__PURE__ */
|
|
726
|
-
/* @__PURE__ */
|
|
727
|
-
/* @__PURE__ */
|
|
728
|
-
option.description && /* @__PURE__ */
|
|
809
|
+
return /* @__PURE__ */ jsx13(TouchableRipple2, { disabled: taken, onPress: () => onSelect(option.value), style: itemStyle, children: /* @__PURE__ */ jsxs12(View11, { style: styles11.itemRow, children: [
|
|
810
|
+
option.icon && /* @__PURE__ */ jsx13(Icon5, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
|
|
811
|
+
/* @__PURE__ */ jsxs12(View11, { style: styles11.itemLabelColumn, children: [
|
|
812
|
+
/* @__PURE__ */ jsx13(Text9, { variant: "labelLarge", style: labelStyle, children: option.label }),
|
|
813
|
+
option.description && /* @__PURE__ */ jsx13(Text9, { variant: "labelSmall", style: descriptionStyle, children: option.description })
|
|
729
814
|
] })
|
|
730
815
|
] }) }, option.value);
|
|
731
816
|
}) });
|
|
@@ -739,23 +824,23 @@ function MultiSection({
|
|
|
739
824
|
allClearLabels
|
|
740
825
|
}) {
|
|
741
826
|
const allSelected = section.value.length === section.options.length;
|
|
742
|
-
return /* @__PURE__ */
|
|
827
|
+
return /* @__PURE__ */ jsxs12(Fragment4, { children: [
|
|
743
828
|
section.options.map((option, i) => {
|
|
744
829
|
const selected = section.value.includes(option.value);
|
|
745
830
|
const rowColor = selected ? onAccentColor : mutedColor;
|
|
746
831
|
const prevSelected = selected && i > 0 && section.value.includes(section.options[i - 1].value);
|
|
747
832
|
const nextSelected = selected && i < section.options.length - 1 && section.value.includes(section.options[i + 1].value);
|
|
748
|
-
const itemStyle = [
|
|
833
|
+
const itemStyle = [styles11.item, selected && { backgroundColor: accentColor }, prevSelected && { borderTopLeftRadius: 0, borderTopRightRadius: 0 }, nextSelected && { borderBottomLeftRadius: 0, borderBottomRightRadius: 0 }];
|
|
749
834
|
const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
|
|
750
|
-
return /* @__PURE__ */
|
|
751
|
-
option.icon && /* @__PURE__ */
|
|
752
|
-
/* @__PURE__ */
|
|
835
|
+
return /* @__PURE__ */ jsx13(TouchableRipple2, { onPress: () => section.onChange(selected ? section.value.filter((v) => v !== option.value) : [...section.value, option.value]), style: itemStyle, children: /* @__PURE__ */ jsxs12(View11, { style: styles11.itemRow, children: [
|
|
836
|
+
option.icon && /* @__PURE__ */ jsx13(Icon5, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
|
|
837
|
+
/* @__PURE__ */ jsx13(Text9, { variant: "labelLarge", style: [styles11.itemLabelFlex, labelStyle], children: option.label })
|
|
753
838
|
] }) }, option.value);
|
|
754
839
|
}),
|
|
755
|
-
section.allClear && /* @__PURE__ */
|
|
840
|
+
section.allClear && /* @__PURE__ */ jsx13(TouchableRipple2, { onPress: () => section.onChange(allSelected ? [] : section.options.map((o) => o.value)), style: styles11.item, children: /* @__PURE__ */ jsx13(Text9, { variant: "labelLarge", style: [styles11.allClearLabel, { fontFamily: labelFontFamily, color: accentColor }], children: allSelected ? allClearLabels.clear : allClearLabels.all }) })
|
|
756
841
|
] });
|
|
757
842
|
}
|
|
758
|
-
var
|
|
843
|
+
var styles11 = StyleSheet11.create({
|
|
759
844
|
allClearLabel: {
|
|
760
845
|
fontWeight: "bold",
|
|
761
846
|
textAlign: "center"
|
|
@@ -772,7 +857,7 @@ var styles7 = StyleSheet8.create({
|
|
|
772
857
|
zIndex: 100
|
|
773
858
|
},
|
|
774
859
|
divider: {
|
|
775
|
-
height:
|
|
860
|
+
height: StyleSheet11.hairlineWidth,
|
|
776
861
|
marginVertical: 4
|
|
777
862
|
},
|
|
778
863
|
item: {
|
|
@@ -825,24 +910,24 @@ var styles7 = StyleSheet8.create({
|
|
|
825
910
|
});
|
|
826
911
|
|
|
827
912
|
// src/ControlSchemePicker.tsx
|
|
828
|
-
import { jsx as
|
|
829
|
-
function ControlSchemePicker({ id, host, value, onChange, options, takenValue, accentColor, mutedColor, onAccentColor, dark, align, labelFontFamily }) {
|
|
913
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
914
|
+
function ControlSchemePicker({ id, host, value, onChange, options, takenValue, accentColor, mutedColor, onAccentColor, dark, align, alignOverride, rotation, labelFontFamily }) {
|
|
830
915
|
const isTouchPrimary = useIsTouchPrimaryDevice2();
|
|
831
916
|
if (Platform3.OS !== "web" || isTouchPrimary) return null;
|
|
832
|
-
return /* @__PURE__ */
|
|
917
|
+
return /* @__PURE__ */ jsx14(SectionedDropdown, { id, host, icon: "keyboard-outline", accessibilityLabel: "Control scheme", sections: [{ kind: "single", id: "controls", options, value, onChange, takenValue }], accentColor, mutedColor, onAccentColor, dark, align, alignOverride, rotation, labelFontFamily });
|
|
833
918
|
}
|
|
834
919
|
|
|
835
920
|
// src/CornerActionButtons.tsx
|
|
836
921
|
import { IconButton as IconButton3 } from "@rific/feedback-press";
|
|
837
|
-
import { StyleSheet as
|
|
838
|
-
import { Fragment as
|
|
922
|
+
import { StyleSheet as StyleSheet12 } from "react-native";
|
|
923
|
+
import { Fragment as Fragment5, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
839
924
|
function CornerActionButtons({ onBack, onSettings, fg, insets, backIcon = "arrow-left", backLabel = "Back" }) {
|
|
840
|
-
return /* @__PURE__ */
|
|
841
|
-
/* @__PURE__ */
|
|
842
|
-
/* @__PURE__ */
|
|
925
|
+
return /* @__PURE__ */ jsxs13(Fragment5, { children: [
|
|
926
|
+
/* @__PURE__ */ jsx15(IconButton3, { icon: backIcon, iconColor: fg, size: 24, style: [styles12.back, { top: 8 + insets.top, left: 8 + insets.left }], onPress: onBack, accessibilityLabel: backLabel }),
|
|
927
|
+
/* @__PURE__ */ jsx15(IconButton3, { icon: "cog", iconColor: fg, size: 24, style: [styles12.topRight, { top: 8 + insets.top, right: 8 + insets.right }], onPress: onSettings, accessibilityLabel: "Settings" })
|
|
843
928
|
] });
|
|
844
929
|
}
|
|
845
|
-
var
|
|
930
|
+
var styles12 = StyleSheet12.create({
|
|
846
931
|
back: {
|
|
847
932
|
position: "absolute"
|
|
848
933
|
},
|
|
@@ -852,22 +937,22 @@ var styles8 = StyleSheet9.create({
|
|
|
852
937
|
});
|
|
853
938
|
|
|
854
939
|
// src/CornerStatusBadges.tsx
|
|
855
|
-
import { StyleSheet as
|
|
856
|
-
import { Icon as
|
|
857
|
-
import { Fragment as
|
|
940
|
+
import { StyleSheet as StyleSheet13, View as View12 } from "react-native";
|
|
941
|
+
import { Icon as Icon6 } from "react-native-paper";
|
|
942
|
+
import { Fragment as Fragment6, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
858
943
|
var BADGE_SIZE = 30;
|
|
859
944
|
function StatusBadge({ icon }) {
|
|
860
|
-
return /* @__PURE__ */
|
|
945
|
+
return /* @__PURE__ */ jsx16(View12, { style: styles13.badge, children: icon && /* @__PURE__ */ jsx16(Icon6, { source: icon, size: 16, color: "rgba(255,255,255,0.85)" }) });
|
|
861
946
|
}
|
|
862
947
|
function CornerStatusBadges({ orientationMode, p1OnRight, p1, p2 }) {
|
|
863
948
|
const p1OnRightSide = orientationMode === "sideBySide" && p1OnRight;
|
|
864
949
|
const p2OnLeftSide = orientationMode === "sideBySide" && !p1OnRight;
|
|
865
|
-
return /* @__PURE__ */
|
|
866
|
-
p1 && /* @__PURE__ */
|
|
867
|
-
p2 && /* @__PURE__ */
|
|
950
|
+
return /* @__PURE__ */ jsxs14(Fragment6, { children: [
|
|
951
|
+
p1 && /* @__PURE__ */ jsx16(View12, { pointerEvents: "none", style: p1OnRightSide ? styles13.bottomRight : styles13.bottomLeft, children: /* @__PURE__ */ jsx16(StatusBadge, { icon: p1.icon }) }),
|
|
952
|
+
p2 && /* @__PURE__ */ jsx16(View12, { pointerEvents: "none", style: p2OnLeftSide ? styles13.topLeft : styles13.topRight, children: /* @__PURE__ */ jsx16(StatusBadge, { icon: p2.icon }) })
|
|
868
953
|
] });
|
|
869
954
|
}
|
|
870
|
-
var
|
|
955
|
+
var styles13 = StyleSheet13.create({
|
|
871
956
|
badge: {
|
|
872
957
|
alignItems: "center",
|
|
873
958
|
backgroundColor: "rgba(0,0,0,0.28)",
|
|
@@ -886,12 +971,12 @@ var styles9 = StyleSheet10.create({
|
|
|
886
971
|
});
|
|
887
972
|
|
|
888
973
|
// src/InlineColorPicker.tsx
|
|
889
|
-
import { defaultColors, getContrastColor } from "@rific/auto-paper";
|
|
974
|
+
import { defaultColors, getContrastColor as getContrastColor2 } from "@rific/auto-paper";
|
|
890
975
|
import { TouchableRipple as TouchableRipple3 } from "@rific/feedback-press";
|
|
891
976
|
import { clamp, useRotation as useRotation4 } from "@tastic/core";
|
|
892
|
-
import { ScrollView as ScrollView4, StyleSheet as
|
|
893
|
-
import { Icon as
|
|
894
|
-
import { jsx as
|
|
977
|
+
import { ScrollView as ScrollView4, StyleSheet as StyleSheet14, useWindowDimensions as useWindowDimensions2, View as View13 } from "react-native";
|
|
978
|
+
import { Icon as Icon7, Text as Text10 } from "react-native-paper";
|
|
979
|
+
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
895
980
|
var EMOJI_PATTERN = /\p{Extended_Pictographic}/u;
|
|
896
981
|
var DEFAULT_SIZE = 48;
|
|
897
982
|
var SWATCH_SIZE = 28;
|
|
@@ -904,31 +989,37 @@ var SCREEN_MARGIN = 40;
|
|
|
904
989
|
function widthForColumns(columns) {
|
|
905
990
|
return SWATCHES_BORDER_WIDTH * 2 + SWATCHES_PADDING * 2 + SWATCH_SIZE * columns + SWATCHES_GAP * (columns - 1);
|
|
906
991
|
}
|
|
907
|
-
function
|
|
992
|
+
function getInlineColorPickerContentSize(swatchCount, windowWidth, columns) {
|
|
993
|
+
const autoColumns = clamp(Math.floor((windowWidth - 2 * SCREEN_MARGIN + SWATCHES_GAP) / (SWATCH_SIZE + SWATCHES_GAP)), MIN_COLUMNS, MAX_COLUMNS);
|
|
994
|
+
const resolvedColumns = columns ?? autoColumns;
|
|
995
|
+
const width = widthForColumns(resolvedColumns);
|
|
996
|
+
const rows = Math.ceil(swatchCount / resolvedColumns);
|
|
997
|
+
const height = SWATCHES_BORDER_WIDTH * 2 + SWATCHES_PADDING * 2 + SWATCH_SIZE * rows + SWATCHES_GAP * (rows - 1);
|
|
998
|
+
return { width, height };
|
|
999
|
+
}
|
|
1000
|
+
function InlineColorPicker({ id, host, value, onChange, previewValue, swatches = defaultColors, takenValue, allowSwapTaken, dark, align: forcedAlign, alignOverride, rotation: rotationOverride, icon = "palette", tag, labelFontFamily = MONO_FONT, autoDismiss = true, columns, size = DEFAULT_SIZE }) {
|
|
908
1001
|
const ambientRotation = useRotation4();
|
|
909
1002
|
const rotation = rotationOverride ?? ambientRotation;
|
|
910
1003
|
const menuBg = dark ? "#000000" : "#FFFFFF";
|
|
911
|
-
const { width: windowWidth } =
|
|
912
|
-
const
|
|
913
|
-
const resolvedColumns = columns ?? autoColumns;
|
|
914
|
-
const swatchesWidth = widthForColumns(resolvedColumns);
|
|
915
|
-
const swatchRows = Math.ceil(swatches.length / resolvedColumns);
|
|
916
|
-
const swatchesHeight = SWATCHES_BORDER_WIDTH * 2 + SWATCHES_PADDING * 2 + SWATCH_SIZE * swatchRows + SWATCHES_GAP * (swatchRows - 1);
|
|
1004
|
+
const { width: windowWidth } = useWindowDimensions2();
|
|
1005
|
+
const { width: swatchesWidth, height: swatchesHeight } = getInlineColorPickerContentSize(swatches.length, windowWidth, columns);
|
|
917
1006
|
const open = host.openId === id;
|
|
918
|
-
const
|
|
919
|
-
const
|
|
1007
|
+
const auto = useAutoAlign(open, swatchesWidth, swatchesHeight, rotation);
|
|
1008
|
+
const placement = alignOverride ?? auto;
|
|
1009
|
+
const { maxHeight, measured, triggerRef, verticalAlign } = placement;
|
|
1010
|
+
const align = forcedAlign ?? placement.align;
|
|
920
1011
|
const displayFor = previewValue ?? ((hex) => hex);
|
|
921
1012
|
const displayValue = displayFor(value);
|
|
922
|
-
const contrastColor =
|
|
1013
|
+
const contrastColor = getContrastColor2(displayValue);
|
|
923
1014
|
const tagFontSize = size * (tag && EMOJI_PATTERN.test(tag) ? 0.6 : 0.4);
|
|
924
|
-
return /* @__PURE__ */
|
|
925
|
-
/* @__PURE__ */
|
|
926
|
-
/* @__PURE__ */
|
|
1015
|
+
return /* @__PURE__ */ jsxs15(View13, { style: [styles14.anchor, open && styles14.anchorOpen], children: [
|
|
1016
|
+
/* @__PURE__ */ jsx17(TouchableRipple3, { onPress: () => host.toggle(id), borderless: true, style: [styles14.trigger, { backgroundColor: displayValue, borderRadius: size / 2, height: size, width: size }], children: /* @__PURE__ */ jsx17(View13, { ref: triggerRef, collapsable: false, style: styles14.triggerMeasure, children: tag ? /* @__PURE__ */ jsx17(Text10, { style: [styles14.tagLabel, { color: contrastColor, fontFamily: labelFontFamily, fontSize: tagFontSize }], numberOfLines: 1, adjustsFontSizeToFit: true, children: tag }) : /* @__PURE__ */ jsx17(Icon7, { source: icon, size: size * 0.6, color: contrastColor }) }) }),
|
|
1017
|
+
/* @__PURE__ */ jsx17(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: displayValue, caretBorderWidth: SWATCHES_BORDER_WIDTH, triggerSize: size, children: /* @__PURE__ */ jsx17(ScrollView4, { style: [styles14.swatches, { backgroundColor: menuBg, borderColor: displayValue, width: swatchesWidth, maxHeight }], contentContainerStyle: styles14.swatchesContent, showsVerticalScrollIndicator: false, children: swatches.map((swatch) => {
|
|
927
1018
|
const selected = swatch.value.toLowerCase() === value.toLowerCase();
|
|
928
1019
|
const taken = !selected && !!takenValue && swatch.value.toLowerCase() === takenValue.toLowerCase();
|
|
929
1020
|
const swappable = taken && allowSwapTaken;
|
|
930
1021
|
const swatchDisplay = displayFor(swatch.value);
|
|
931
|
-
return /* @__PURE__ */
|
|
1022
|
+
return /* @__PURE__ */ jsx17(
|
|
932
1023
|
TouchableRipple3,
|
|
933
1024
|
{
|
|
934
1025
|
disabled: taken && !swappable,
|
|
@@ -937,15 +1028,15 @@ function InlineColorPicker({ id, host, value, onChange, previewValue, swatches =
|
|
|
937
1028
|
if (autoDismiss) host.close();
|
|
938
1029
|
},
|
|
939
1030
|
borderless: true,
|
|
940
|
-
style: [
|
|
941
|
-
children: selected ? /* @__PURE__ */
|
|
1031
|
+
style: [styles14.swatch, { backgroundColor: swatchDisplay }, selected && styles14.swatchSelected, taken && !swappable && styles14.swatchTaken],
|
|
1032
|
+
children: selected ? /* @__PURE__ */ jsx17(Icon7, { source: "check", size: 16, color: getContrastColor2(swatchDisplay) }) : swappable ? /* @__PURE__ */ jsx17(Icon7, { source: "swap-horizontal", size: 16, color: getContrastColor2(swatchDisplay) }) : taken ? /* @__PURE__ */ jsx17(Icon7, { source: "close", size: 16, color: getContrastColor2(swatchDisplay) }) : /* @__PURE__ */ jsx17(View13, {})
|
|
942
1033
|
},
|
|
943
1034
|
swatch.value
|
|
944
1035
|
);
|
|
945
1036
|
}) }) })
|
|
946
1037
|
] });
|
|
947
1038
|
}
|
|
948
|
-
var
|
|
1039
|
+
var styles14 = StyleSheet14.create({
|
|
949
1040
|
anchor: {
|
|
950
1041
|
position: "relative"
|
|
951
1042
|
},
|
|
@@ -1017,11 +1108,11 @@ var styles10 = StyleSheet11.create({
|
|
|
1017
1108
|
});
|
|
1018
1109
|
|
|
1019
1110
|
// src/LabeledDropdown.tsx
|
|
1020
|
-
import { getContrastColor as
|
|
1111
|
+
import { getContrastColor as getContrastColor3 } from "@rific/auto-paper";
|
|
1021
1112
|
import { TouchableRipple as TouchableRipple4 } from "@rific/feedback-press";
|
|
1022
|
-
import { ScrollView as ScrollView5, StyleSheet as
|
|
1023
|
-
import { Icon as
|
|
1024
|
-
import { jsx as
|
|
1113
|
+
import { ScrollView as ScrollView5, StyleSheet as StyleSheet15, View as View14 } from "react-native";
|
|
1114
|
+
import { Icon as Icon8, Text as Text11 } from "react-native-paper";
|
|
1115
|
+
import { jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1025
1116
|
var TRIGGER_HEIGHT = 28;
|
|
1026
1117
|
var POPOVER_WIDTH = 180;
|
|
1027
1118
|
var ROW_HEIGHT = 36;
|
|
@@ -1044,22 +1135,22 @@ function LabeledDropdown({ id, host, options, value, onChange, color, dark, alig
|
|
|
1044
1135
|
onChange(option.value);
|
|
1045
1136
|
host.close();
|
|
1046
1137
|
};
|
|
1047
|
-
return /* @__PURE__ */
|
|
1048
|
-
/* @__PURE__ */
|
|
1049
|
-
/* @__PURE__ */
|
|
1050
|
-
/* @__PURE__ */
|
|
1138
|
+
return /* @__PURE__ */ jsxs16(View14, { style: [styles15.anchor, open && styles15.anchorOpen], children: [
|
|
1139
|
+
/* @__PURE__ */ jsx18(TouchableRipple4, { onPress: () => host.toggle(id), style: styles15.trigger, children: /* @__PURE__ */ jsxs16(View14, { ref: triggerRef, collapsable: false, style: styles15.triggerInner, children: [
|
|
1140
|
+
/* @__PURE__ */ jsx18(Text11, { style: [styles15.triggerLabel, { color }], numberOfLines: 1, children: (selected?.label ?? "").toUpperCase() }),
|
|
1141
|
+
/* @__PURE__ */ jsx18(Icon8, { source: "menu-down", size: 16, color })
|
|
1051
1142
|
] }) }),
|
|
1052
|
-
/* @__PURE__ */
|
|
1143
|
+
/* @__PURE__ */ jsx18(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: color, caretBorderWidth: 2, triggerSize: TRIGGER_HEIGHT, children: /* @__PURE__ */ jsx18(ScrollView5, { style: [styles15.menu, { backgroundColor: menuBg, borderColor: color, width: POPOVER_WIDTH, maxHeight }], contentContainerStyle: styles15.menuContent, showsVerticalScrollIndicator: false, children: options.map((option) => {
|
|
1053
1144
|
const isSelected = option.value === value;
|
|
1054
|
-
const onColor =
|
|
1055
|
-
return /* @__PURE__ */
|
|
1056
|
-
option.icon && /* @__PURE__ */
|
|
1057
|
-
/* @__PURE__ */
|
|
1145
|
+
const onColor = getContrastColor3(color);
|
|
1146
|
+
return /* @__PURE__ */ jsx18(TouchableRipple4, { onPress: () => handleSelect(option), style: [styles15.row, isSelected && { backgroundColor: color }], children: /* @__PURE__ */ jsxs16(View14, { style: styles15.rowInner, children: [
|
|
1147
|
+
option.icon && /* @__PURE__ */ jsx18(Icon8, { source: option.icon, size: 18, color: isSelected ? onColor : fg }),
|
|
1148
|
+
/* @__PURE__ */ jsx18(Text11, { style: [styles15.rowLabel, { color: isSelected ? onColor : fg }], numberOfLines: 1, children: option.label })
|
|
1058
1149
|
] }) }, option.value);
|
|
1059
1150
|
}) }) })
|
|
1060
1151
|
] });
|
|
1061
1152
|
}
|
|
1062
|
-
var
|
|
1153
|
+
var styles15 = StyleSheet15.create({
|
|
1063
1154
|
anchor: {
|
|
1064
1155
|
position: "relative"
|
|
1065
1156
|
},
|
|
@@ -1116,26 +1207,23 @@ function loadSkiaWeb() {
|
|
|
1116
1207
|
return Promise.resolve();
|
|
1117
1208
|
}
|
|
1118
1209
|
|
|
1119
|
-
// src/
|
|
1120
|
-
import {
|
|
1121
|
-
import {
|
|
1122
|
-
|
|
1123
|
-
if (!active) return null;
|
|
1124
|
-
return /* @__PURE__ */ jsx14(Pressable, { accessibilityLabel: "Dismiss", accessibilityRole: "button", onPress, style: [StyleSheet13.absoluteFill, style] });
|
|
1125
|
-
}
|
|
1210
|
+
// src/PlayerSetupPanel.tsx
|
|
1211
|
+
import { ProfilePicker } from "@tastic/profile";
|
|
1212
|
+
import { StyleSheet as StyleSheet17, View as View15 } from "react-native";
|
|
1213
|
+
import { Text as Text13 } from "react-native-paper";
|
|
1126
1214
|
|
|
1127
1215
|
// src/ReadyButton.tsx
|
|
1128
1216
|
import { TouchableRipple as TouchableRipple5 } from "@rific/feedback-press";
|
|
1129
|
-
import { StyleSheet as
|
|
1130
|
-
import { Text as
|
|
1131
|
-
import { jsx as
|
|
1217
|
+
import { StyleSheet as StyleSheet16 } from "react-native";
|
|
1218
|
+
import { Text as Text12 } from "react-native-paper";
|
|
1219
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
1132
1220
|
function ReadyButton({ color, ready, onToggleReady, style, labelFontFamily = MONO_FONT }) {
|
|
1133
|
-
const readyButtonStyle = [
|
|
1221
|
+
const readyButtonStyle = [styles16.readyButton, { borderColor: color }, ready && { backgroundColor: color }, style];
|
|
1134
1222
|
const labelTextStyle = { fontFamily: labelFontFamily, fontWeight: "bold" };
|
|
1135
1223
|
const labelColorStyle = { color: ready ? "#000000" : color };
|
|
1136
|
-
return /* @__PURE__ */
|
|
1224
|
+
return /* @__PURE__ */ jsx19(TouchableRipple5, { onPress: onToggleReady, borderless: true, style: readyButtonStyle, children: /* @__PURE__ */ jsx19(Text12, { variant: "labelLarge", style: [labelTextStyle, labelColorStyle], children: ready ? "READY \u2713" : "READY?" }) });
|
|
1137
1225
|
}
|
|
1138
|
-
var
|
|
1226
|
+
var styles16 = StyleSheet16.create({
|
|
1139
1227
|
readyButton: {
|
|
1140
1228
|
alignItems: "center",
|
|
1141
1229
|
borderRadius: 12,
|
|
@@ -1147,22 +1235,97 @@ var styles12 = StyleSheet14.create({
|
|
|
1147
1235
|
}
|
|
1148
1236
|
});
|
|
1149
1237
|
|
|
1238
|
+
// src/usePopoverHost.ts
|
|
1239
|
+
import { useCallback as useCallback3, useState as useState5 } from "react";
|
|
1240
|
+
function usePopoverHost() {
|
|
1241
|
+
const [openId, setOpenId] = useState5(null);
|
|
1242
|
+
const toggle = useCallback3((id) => {
|
|
1243
|
+
setOpenId((prev) => prev === id ? null : id);
|
|
1244
|
+
}, []);
|
|
1245
|
+
const close = useCallback3(() => setOpenId(null), []);
|
|
1246
|
+
return { openId, toggle, close };
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
// src/PlayerSetupPanel.tsx
|
|
1250
|
+
import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1251
|
+
function getColorPopoverId(idPrefix) {
|
|
1252
|
+
return `${idPrefix}-color`;
|
|
1253
|
+
}
|
|
1254
|
+
function getCpuDifficultyPopoverId(idPrefix) {
|
|
1255
|
+
return `${idPrefix}-difficulty`;
|
|
1256
|
+
}
|
|
1257
|
+
function PlayerSetupPanel({ idPrefix, host, label, labelFontFamily, color, onColorChange, swatches, takenColor, allowSwapTaken, colorAlignOverride, colorRotation, isHuman, secondPicker, secondPickerId, ready, onToggleReady, dark, showReadyButton = true, profiles, selectedProfileId, takenProfileId, guestLabel, onProfileSelect, onManageProfiles, cpuDifficulty, cpuDifficultyOptions, onCpuDifficultyChange, cpuDifficultyAlignOverride, humanIcon = "face-man", cpuIcon = "robot" }) {
|
|
1258
|
+
const ownHost = usePopoverHost();
|
|
1259
|
+
const popover = host ?? ownHost;
|
|
1260
|
+
const ownPopoverOpen = popover.openId?.startsWith(`${idPrefix}-`) ?? false;
|
|
1261
|
+
const pickerRowPopoverOpen = popover.openId === getColorPopoverId(idPrefix) || secondPickerId !== void 0 && popover.openId === secondPickerId;
|
|
1262
|
+
const showProfilePicker = isHuman && profiles !== void 0 && !!onProfileSelect;
|
|
1263
|
+
const showCpuDifficulty = !isHuman && cpuDifficulty !== void 0 && cpuDifficultyOptions !== void 0 && !!onCpuDifficultyChange;
|
|
1264
|
+
const selectedProfile = profiles?.find((p) => p.id === selectedProfileId) ?? null;
|
|
1265
|
+
return /* @__PURE__ */ jsxs17(View15, { style: [styles17.panel, ownPopoverOpen && styles17.panelOpen], children: [
|
|
1266
|
+
showProfilePicker ? /* @__PURE__ */ jsx20(ProfilePicker, { idPrefix, host: popover, profiles, selectedId: selectedProfileId ?? null, takenId: takenProfileId, color, dark, guestLabel: guestLabel ?? "GUEST", onSelect: (profile) => onProfileSelect?.(profile), onManage: onManageProfiles }) : showCpuDifficulty ? /* @__PURE__ */ jsx20(LabeledDropdown, { id: getCpuDifficultyPopoverId(idPrefix), host: popover, options: cpuDifficultyOptions, value: cpuDifficulty, onChange: onCpuDifficultyChange, color, dark, alignOverride: cpuDifficultyAlignOverride }) : label && /* @__PURE__ */ jsx20(Text13, { variant: "labelSmall", style: { color, fontFamily: labelFontFamily }, children: label }),
|
|
1267
|
+
/* @__PURE__ */ jsxs17(View15, { style: [styles17.pickerRow, pickerRowPopoverOpen && styles17.pickerRowOpen], children: [
|
|
1268
|
+
/* @__PURE__ */ jsx20(InlineColorPicker, { id: getColorPopoverId(idPrefix), host: popover, value: color, onChange: onColorChange, swatches, takenValue: takenColor, allowSwapTaken, alignOverride: colorAlignOverride, rotation: colorRotation, dark, tag: isHuman ? selectedProfile?.tag : void 0, icon: isHuman ? humanIcon : cpuIcon }),
|
|
1269
|
+
secondPicker
|
|
1270
|
+
] }),
|
|
1271
|
+
isHuman && showReadyButton && onToggleReady && /* @__PURE__ */ jsx20(ReadyButton, { color, ready: ready ?? false, onToggleReady })
|
|
1272
|
+
] });
|
|
1273
|
+
}
|
|
1274
|
+
var styles17 = StyleSheet17.create({
|
|
1275
|
+
panel: {
|
|
1276
|
+
alignItems: "center",
|
|
1277
|
+
gap: 12
|
|
1278
|
+
},
|
|
1279
|
+
// See SectionedDropdown's anchorOpen comment — this panel is typically a sibling of another
|
|
1280
|
+
// panel (and/or a shared-controls row), so a popover escaping this panel's bounds needs the panel
|
|
1281
|
+
// itself elevated, not just the popover content, to paint above a later sibling.
|
|
1282
|
+
panelOpen: {
|
|
1283
|
+
zIndex: 100
|
|
1284
|
+
},
|
|
1285
|
+
// Same gap as `panel`'s own vertical rhythm, reused horizontally — the color picker and (when
|
|
1286
|
+
// present) secondPicker sit side by side within this row instead of stacked in the panel's own
|
|
1287
|
+
// column.
|
|
1288
|
+
pickerRow: {
|
|
1289
|
+
alignItems: "center",
|
|
1290
|
+
flexDirection: "row",
|
|
1291
|
+
gap: 12
|
|
1292
|
+
},
|
|
1293
|
+
// A popover is an absolutely-positioned sibling of its own trigger — so a tall one (the color
|
|
1294
|
+
// swatch grid) can extend down far enough to overlap the ReadyButton below, which paints on top of
|
|
1295
|
+
// it by default DOM order since it's a later sibling within `panel`. `panel`'s own panelOpen
|
|
1296
|
+
// elevation only helps this panel paint above OTHER panels (see its own comment) — it does nothing
|
|
1297
|
+
// for stacking *within* this panel, since React Native Web gives each View its own stacking
|
|
1298
|
+
// context. This is what actually fixes that: elevate pickerRow itself above its own later sibling
|
|
1299
|
+
// whenever one of its own popovers is open.
|
|
1300
|
+
pickerRowOpen: {
|
|
1301
|
+
zIndex: 100
|
|
1302
|
+
}
|
|
1303
|
+
});
|
|
1304
|
+
|
|
1305
|
+
// src/PressAwayOverlay.tsx
|
|
1306
|
+
import { Pressable, StyleSheet as StyleSheet18 } from "react-native";
|
|
1307
|
+
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
1308
|
+
function PressAwayOverlay({ active, onPress, style }) {
|
|
1309
|
+
if (!active) return null;
|
|
1310
|
+
return /* @__PURE__ */ jsx21(Pressable, { accessibilityLabel: "Dismiss", accessibilityRole: "button", onPress, style: [StyleSheet18.absoluteFill, style] });
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1150
1313
|
// src/SharedActionBand.tsx
|
|
1151
1314
|
import { IconButton as IconButton4 } from "@rific/feedback-press";
|
|
1152
|
-
import { StyleSheet as
|
|
1153
|
-
import { jsx as
|
|
1315
|
+
import { StyleSheet as StyleSheet19, View as View16 } from "react-native";
|
|
1316
|
+
import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1154
1317
|
function SharedActionBand({ onBack, onSettings, onRandomize, onReset, fg, popoverOpen, children }) {
|
|
1155
|
-
return /* @__PURE__ */
|
|
1156
|
-
/* @__PURE__ */
|
|
1157
|
-
/* @__PURE__ */
|
|
1158
|
-
onRandomize && /* @__PURE__ */
|
|
1159
|
-
onReset && /* @__PURE__ */
|
|
1160
|
-
/* @__PURE__ */
|
|
1318
|
+
return /* @__PURE__ */ jsxs18(View16, { style: [styles18.column, popoverOpen && styles18.columnOpen], children: [
|
|
1319
|
+
/* @__PURE__ */ jsxs18(View16, { style: styles18.actionsRow, children: [
|
|
1320
|
+
/* @__PURE__ */ jsx22(IconButton4, { icon: "arrow-left", iconColor: fg, size: 20, onPress: onBack, accessibilityLabel: "Back" }),
|
|
1321
|
+
onRandomize && /* @__PURE__ */ jsx22(IconButton4, { icon: "dice-multiple", iconColor: fg, size: 18, onPress: onRandomize, accessibilityLabel: "Randomize match settings" }),
|
|
1322
|
+
onReset && /* @__PURE__ */ jsx22(IconButton4, { icon: "restore", iconColor: fg, size: 18, onPress: onReset, accessibilityLabel: "Reset match settings to defaults" }),
|
|
1323
|
+
/* @__PURE__ */ jsx22(IconButton4, { icon: "cog", iconColor: fg, size: 20, onPress: onSettings, accessibilityLabel: "Settings" })
|
|
1161
1324
|
] }),
|
|
1162
1325
|
children
|
|
1163
1326
|
] });
|
|
1164
1327
|
}
|
|
1165
|
-
var
|
|
1328
|
+
var styles18 = StyleSheet19.create({
|
|
1166
1329
|
actionsRow: {
|
|
1167
1330
|
alignItems: "center",
|
|
1168
1331
|
flexDirection: "row",
|
|
@@ -1177,83 +1340,110 @@ var styles13 = StyleSheet15.create({
|
|
|
1177
1340
|
}
|
|
1178
1341
|
});
|
|
1179
1342
|
|
|
1180
|
-
// src/
|
|
1181
|
-
import {
|
|
1182
|
-
import { StyleSheet as
|
|
1183
|
-
import {
|
|
1184
|
-
import { jsx as
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
return /* @__PURE__ */ jsxs13(View13, { style: styles14.row, children: [
|
|
1190
|
-
/* @__PURE__ */ jsx17(Text9, { variant: "bodyMedium", style: { color: fgMuted }, children: label }),
|
|
1191
|
-
/* @__PURE__ */ jsx17(Text9, { variant: "bodyMedium", style: [styles14.value, { color: fg }], children: value })
|
|
1192
|
-
] });
|
|
1343
|
+
// src/StaggeredWord.tsx
|
|
1344
|
+
import { useEffect as useEffect2 } from "react";
|
|
1345
|
+
import { StyleSheet as StyleSheet20, View as View17 } from "react-native";
|
|
1346
|
+
import Animated, { Easing, useAnimatedStyle, useSharedValue, withDelay, withTiming } from "react-native-reanimated";
|
|
1347
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
1348
|
+
var STAGGER_MS = 45;
|
|
1349
|
+
var LETTER_DURATION_MS = 320;
|
|
1350
|
+
function getStaggeredWordDuration(letterCount) {
|
|
1351
|
+
return (letterCount - 1) * STAGGER_MS + LETTER_DURATION_MS;
|
|
1193
1352
|
}
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
},
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
});
|
|
1204
|
-
|
|
1205
|
-
// src/StatSection.tsx
|
|
1206
|
-
import { useAutoPaperTheme as useAutoPaperTheme6 } from "@rific/auto-paper";
|
|
1207
|
-
import { StyleSheet as StyleSheet17, View as View14 } from "react-native";
|
|
1208
|
-
import { Text as Text10 } from "react-native-paper";
|
|
1209
|
-
import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1210
|
-
function StatSection({ label, fg: fgOverride, sectionBg: sectionBgOverride, children }) {
|
|
1211
|
-
const { dark } = useAutoPaperTheme6();
|
|
1212
|
-
const fg = fgOverride ?? (dark ? "#FFFFFF" : "#000000");
|
|
1213
|
-
const sectionBg = sectionBgOverride ?? (dark ? "rgba(255,255,255,0.06)" : "rgba(0,0,0,0.04)");
|
|
1214
|
-
return /* @__PURE__ */ jsxs14(View14, { style: [styles15.section, { backgroundColor: sectionBg }], children: [
|
|
1215
|
-
/* @__PURE__ */ jsx18(Text10, { variant: "labelMedium", style: [styles15.label, { color: fg }], children: label }),
|
|
1216
|
-
children
|
|
1217
|
-
] });
|
|
1353
|
+
function AnimatedLetter({ char, index, color, reducedMotion, fontFamily, fontSize, lineHeight, fontWeight, letterSpacing }) {
|
|
1354
|
+
const progress = useSharedValue(reducedMotion ? 1 : 0);
|
|
1355
|
+
useEffect2(() => {
|
|
1356
|
+
if (reducedMotion) return;
|
|
1357
|
+
progress.value = withDelay(index * STAGGER_MS, withTiming(1, { duration: LETTER_DURATION_MS, easing: Easing.out(Easing.back(1.5)) }));
|
|
1358
|
+
}, [reducedMotion]);
|
|
1359
|
+
const style = useAnimatedStyle(() => ({
|
|
1360
|
+
opacity: progress.value,
|
|
1361
|
+
transform: [{ translateY: (1 - progress.value) * 12 }, { scale: 0.85 + progress.value * 0.15 }]
|
|
1362
|
+
}));
|
|
1363
|
+
return /* @__PURE__ */ jsx23(Animated.Text, { allowFontScaling: false, style: [{ color, fontFamily, fontSize, lineHeight, fontWeight, letterSpacing }, style], children: char });
|
|
1218
1364
|
}
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
fontWeight: "bold",
|
|
1226
|
-
letterSpacing: 2
|
|
1227
|
-
},
|
|
1228
|
-
section: {
|
|
1229
|
-
borderRadius: 12,
|
|
1230
|
-
gap: 8,
|
|
1231
|
-
padding: 16
|
|
1365
|
+
function StaggeredWord({ word, color, fontFamily, fontSize, lineHeight, reducedMotion, startIndex = 0, fontWeight = "bold", letterSpacing, style, onLayout }) {
|
|
1366
|
+
return /* @__PURE__ */ jsx23(View17, { style: [styles19.row, style], onLayout, children: word.split("").map((char, i) => /* @__PURE__ */ jsx23(AnimatedLetter, { char, index: startIndex + i, color, reducedMotion, fontFamily, fontSize, lineHeight, fontWeight, letterSpacing }, i)) });
|
|
1367
|
+
}
|
|
1368
|
+
var styles19 = StyleSheet20.create({
|
|
1369
|
+
row: {
|
|
1370
|
+
flexDirection: "row"
|
|
1232
1371
|
}
|
|
1233
1372
|
});
|
|
1234
1373
|
|
|
1235
1374
|
// src/UpdateDialog.tsx
|
|
1236
1375
|
import { useUpdater as useUpdater2 } from "@rific/updater";
|
|
1237
|
-
import { jsx as
|
|
1376
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
1238
1377
|
function UpdateDialog({ rotation = 0, autoCheck = true, autoPrompt = true, onError }) {
|
|
1239
1378
|
const { manifest, onConfirm, respond } = useUpdateConfirmBridge();
|
|
1240
1379
|
useUpdater2({ autoCheck, autoPrompt, onConfirm, onError });
|
|
1241
1380
|
const date = manifest ? new Date(manifest.createdAt) : null;
|
|
1242
|
-
return /* @__PURE__ */
|
|
1381
|
+
return /* @__PURE__ */ jsx24(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) });
|
|
1243
1382
|
}
|
|
1244
1383
|
|
|
1245
|
-
// src/
|
|
1246
|
-
import { useCallback as
|
|
1247
|
-
function
|
|
1248
|
-
const [
|
|
1249
|
-
const
|
|
1250
|
-
|
|
1384
|
+
// src/useQuitConfirmation.ts
|
|
1385
|
+
import { useCallback as useCallback4, useEffect as useEffect3, useRef as useRef3, useState as useState6 } from "react";
|
|
1386
|
+
function useQuitConfirmation(hasProgress, onConfirmedBack) {
|
|
1387
|
+
const [confirmVisible, setConfirmVisible] = useState6(false);
|
|
1388
|
+
const hasProgressRef = useRef3(hasProgress);
|
|
1389
|
+
useEffect3(() => {
|
|
1390
|
+
hasProgressRef.current = hasProgress;
|
|
1391
|
+
});
|
|
1392
|
+
const onConfirmedBackRef = useRef3(onConfirmedBack);
|
|
1393
|
+
useEffect3(() => {
|
|
1394
|
+
onConfirmedBackRef.current = onConfirmedBack;
|
|
1395
|
+
});
|
|
1396
|
+
const requestBack = useCallback4(() => {
|
|
1397
|
+
if (hasProgressRef.current()) setConfirmVisible(true);
|
|
1398
|
+
else onConfirmedBackRef.current();
|
|
1251
1399
|
}, []);
|
|
1252
|
-
const
|
|
1253
|
-
return {
|
|
1400
|
+
const cancelBack = useCallback4(() => setConfirmVisible(false), []);
|
|
1401
|
+
return { confirmVisible, requestBack, cancelBack };
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
// src/useZoneClampedAlign.ts
|
|
1405
|
+
import { useZoneBounds } from "@tastic/split-screen";
|
|
1406
|
+
import { useEffect as useEffect4, useState as useState7 } from "react";
|
|
1407
|
+
import { useWindowDimensions as useWindowDimensions3 } from "react-native";
|
|
1408
|
+
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
1409
|
+
var EDGE_MARGIN2 = 12;
|
|
1410
|
+
function useZoneClampedAlign(open, contentWidth, contentHeight, rotation = 0) {
|
|
1411
|
+
const auto = useAutoAlign(open, contentWidth, contentHeight, rotation);
|
|
1412
|
+
const zone = useZoneBounds();
|
|
1413
|
+
const { height: windowHeight } = useWindowDimensions3();
|
|
1414
|
+
const insets = useSafeAreaInsets();
|
|
1415
|
+
const shouldMeasure = open && auto.measured && zone !== null;
|
|
1416
|
+
const [ownBounds, setOwnBounds] = useState7(null);
|
|
1417
|
+
const [prevShouldMeasure, setPrevShouldMeasure] = useState7(shouldMeasure);
|
|
1418
|
+
if (shouldMeasure !== prevShouldMeasure) {
|
|
1419
|
+
setPrevShouldMeasure(shouldMeasure);
|
|
1420
|
+
setOwnBounds(null);
|
|
1421
|
+
}
|
|
1422
|
+
useEffect4(() => {
|
|
1423
|
+
if (!shouldMeasure) return;
|
|
1424
|
+
auto.triggerRef.current?.measureInWindow((_x, y, _width, height) => {
|
|
1425
|
+
const belowShared = zone.zoneSide === "belowShared";
|
|
1426
|
+
const awayRoom = belowShared ? windowHeight - insets.bottom - (y + height) - EDGE_MARGIN2 : y - insets.top - EDGE_MARGIN2;
|
|
1427
|
+
const towardRoom = belowShared ? y - zone.sharedEdgeY - EDGE_MARGIN2 : zone.sharedEdgeY - (y + height) - EDGE_MARGIN2;
|
|
1428
|
+
const useToward = contentHeight > awayRoom && towardRoom > awayRoom;
|
|
1429
|
+
let awaySide = belowShared ? "below" : "above";
|
|
1430
|
+
let towardSide = belowShared ? "above" : "below";
|
|
1431
|
+
if (zone.rotated) {
|
|
1432
|
+
awaySide = awaySide === "above" ? "below" : "above";
|
|
1433
|
+
towardSide = towardSide === "above" ? "below" : "above";
|
|
1434
|
+
}
|
|
1435
|
+
setOwnBounds({ maxHeight: Math.max(useToward ? towardRoom : awayRoom, 0), verticalAlign: useToward ? towardSide : awaySide });
|
|
1436
|
+
});
|
|
1437
|
+
}, [shouldMeasure, zone, auto.triggerRef, contentHeight, windowHeight, insets.top, insets.bottom]);
|
|
1438
|
+
if (!zone) return auto;
|
|
1439
|
+
if (!ownBounds) return { ...auto, measured: false };
|
|
1440
|
+
return { ...auto, maxHeight: ownBounds.maxHeight, measured: auto.measured, verticalAlign: ownBounds.verticalAlign };
|
|
1254
1441
|
}
|
|
1255
1442
|
export {
|
|
1443
|
+
AchievementCatalogSection,
|
|
1256
1444
|
AchievementRow,
|
|
1445
|
+
AchievementUnlockList,
|
|
1446
|
+
ActivityStatSection,
|
|
1257
1447
|
BaseSettingsDialog,
|
|
1258
1448
|
BaseStatsScreen,
|
|
1259
1449
|
ConfirmDialog,
|
|
@@ -1266,20 +1456,29 @@ export {
|
|
|
1266
1456
|
LOCKED_BADGE_COLOR,
|
|
1267
1457
|
LabeledDropdown,
|
|
1268
1458
|
MONO_FONT,
|
|
1459
|
+
PlayerSetupPanel,
|
|
1269
1460
|
PopoverBody,
|
|
1270
1461
|
PressAwayOverlay,
|
|
1271
1462
|
ReadyButton,
|
|
1272
1463
|
SectionedDropdown,
|
|
1273
1464
|
SharedActionBand,
|
|
1274
1465
|
SkiaGate,
|
|
1466
|
+
StaggeredWord,
|
|
1275
1467
|
StatRow,
|
|
1276
1468
|
StatSection,
|
|
1277
1469
|
TriggerGaugeHost,
|
|
1278
1470
|
UpdateDialog,
|
|
1471
|
+
getColorPopoverId,
|
|
1472
|
+
getCpuDifficultyPopoverId,
|
|
1473
|
+
getInlineColorPickerContentSize,
|
|
1279
1474
|
getLabeledDropdownContentHeight,
|
|
1280
1475
|
getOverlayCardColors,
|
|
1476
|
+
getStaggeredWordDuration,
|
|
1281
1477
|
loadSkiaWeb,
|
|
1478
|
+
overlayActionStyles,
|
|
1282
1479
|
overlayStyles,
|
|
1283
1480
|
useAutoAlign,
|
|
1284
|
-
usePopoverHost
|
|
1481
|
+
usePopoverHost,
|
|
1482
|
+
useQuitConfirmation,
|
|
1483
|
+
useZoneClampedAlign
|
|
1285
1484
|
};
|