@tastic/hud 0.22.0 → 0.24.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 +85 -15
- package/dist/chrome/index.d.mts +87 -18
- package/dist/chrome/index.d.ts +87 -18
- package/dist/chrome/index.js +309 -22
- package/dist/chrome/index.mjs +13 -1
- package/dist/chunk-3TCJHMJP.mjs +14 -0
- package/dist/{chunk-N7A7W72S.mjs → chunk-BXG44LIA.mjs} +298 -19
- package/dist/index.d.mts +13 -84
- package/dist/index.d.ts +13 -84
- package/dist/index.js +120 -127
- package/dist/index.mjs +107 -374
- package/dist/skia/index.d.mts +5 -0
- package/dist/skia/index.d.ts +5 -0
- package/dist/{SkiaGate.js → skia/index.js} +17 -21
- package/dist/skia/index.mjs +8 -0
- package/package.json +9 -8
- package/src/BaseSettingsDialog.tsx +13 -13
- package/src/TriggerGaugeHost.tsx +20 -14
- package/src/chrome/index.ts +12 -4
- package/src/guide/index.ts +1 -1
- package/src/index.ts +2 -2
- package/src/loadSkiaWeb.web.ts +7 -4
- package/src/locateSkiaWebFile.ts +16 -0
- package/src/skia/index.ts +12 -0
- package/dist/SkiaGate.d.mts +0 -13
- package/dist/SkiaGate.d.ts +0 -13
- package/dist/SkiaGate.mjs +0 -6
- package/dist/chunk-XEOFR236.mjs +0 -21
- package/src/SkiaGate.tsx +0 -45
- package/src/SkiaGate.web.tsx +0 -9
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
SkiaGate
|
|
3
|
-
} from "./chunk-XEOFR236.mjs";
|
|
4
1
|
import {
|
|
5
2
|
AchievementCatalogSection,
|
|
6
3
|
AchievementRow,
|
|
@@ -10,18 +7,24 @@ import {
|
|
|
10
7
|
ConfirmDialog,
|
|
11
8
|
ContentGutter,
|
|
12
9
|
CornerActionButtons,
|
|
10
|
+
InlineColorPicker,
|
|
13
11
|
LOCKED_BADGE_COLOR,
|
|
14
12
|
MONO_FONT,
|
|
13
|
+
PopoverBody,
|
|
14
|
+
PressAwayOverlay,
|
|
15
15
|
RotatedFrame,
|
|
16
16
|
StaggeredWord,
|
|
17
17
|
StatRow,
|
|
18
18
|
StatSection,
|
|
19
19
|
UpdateDialog,
|
|
20
20
|
WELL_SHADOW,
|
|
21
|
+
getInlineColorPickerContentSize,
|
|
21
22
|
getStaggeredWordDuration,
|
|
23
|
+
useAutoAlign,
|
|
22
24
|
useCompactDialog,
|
|
25
|
+
usePopoverHost,
|
|
23
26
|
useWellColors
|
|
24
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-BXG44LIA.mjs";
|
|
25
28
|
import {
|
|
26
29
|
COMPACT_DIALOG_HEIGHT,
|
|
27
30
|
DialogHeader,
|
|
@@ -32,6 +35,10 @@ import {
|
|
|
32
35
|
overlayStyles,
|
|
33
36
|
useOverlayCardColors
|
|
34
37
|
} from "./chunk-PUF6TABL.mjs";
|
|
38
|
+
import {
|
|
39
|
+
loadSkiaWeb,
|
|
40
|
+
locateSkiaWebFile
|
|
41
|
+
} from "./chunk-3TCJHMJP.mjs";
|
|
35
42
|
|
|
36
43
|
// src/AchievementUnlockList.tsx
|
|
37
44
|
import { getContrastColor, useAutoPaperTheme } from "@rific/auto-paper";
|
|
@@ -85,132 +92,19 @@ import { Platform } from "react-native";
|
|
|
85
92
|
import { getBlendedColor, getColorRoles } from "@rific/auto-paper";
|
|
86
93
|
import { IconButton, TouchableRipple } from "@rific/feedback-press";
|
|
87
94
|
import { useRotation } from "@tastic/core";
|
|
88
|
-
import { ScrollView, StyleSheet as
|
|
95
|
+
import { ScrollView, StyleSheet as StyleSheet2, View as View2 } from "react-native";
|
|
89
96
|
import { Icon as Icon2, Text as Text2 } from "react-native-paper";
|
|
90
97
|
|
|
91
|
-
// src/PopoverBody.tsx
|
|
92
|
-
import { StyleSheet as StyleSheet2, View as View2 } from "react-native";
|
|
93
|
-
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
94
|
-
var CARET_SIZE = 7;
|
|
95
|
-
var CARET_RING_OFFSET = 2;
|
|
96
|
-
var CARET_DIP = 1;
|
|
97
|
-
function PopoverBody({ visible, children, align = "center", verticalAlign = "below", caretColor, caretBorderColor, caretBorderWidth = 1, triggerSize = 0 }) {
|
|
98
|
-
if (!visible) return null;
|
|
99
|
-
const above = verticalAlign === "above";
|
|
100
|
-
const alignStyle = align === "left" ? styles2.contentLeft : align === "right" ? styles2.contentRight : styles2.contentCenter;
|
|
101
|
-
const verticalStyle = above ? styles2.contentAbove : styles2.contentBelow;
|
|
102
|
-
const ringSize = CARET_SIZE + caretBorderWidth;
|
|
103
|
-
const caretOffset = (halfFootprint) => align === "right" ? { right: triggerSize / 2 - halfFootprint } : { left: triggerSize / 2 - halfFootprint };
|
|
104
|
-
const caretFill = above ? "borderTopColor" : "borderBottomColor";
|
|
105
|
-
const caretWidthProp = above ? "borderTopWidth" : "borderBottomWidth";
|
|
106
|
-
const caretEdge = (size) => above ? { bottom: -size + CARET_DIP } : { top: -size + CARET_DIP };
|
|
107
|
-
return /* @__PURE__ */ jsxs2(View2, { style: [styles2.content, alignStyle, verticalStyle], children: [
|
|
108
|
-
children,
|
|
109
|
-
caretColor && /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
110
|
-
/* @__PURE__ */ jsx2(View2, { style: [styles2.caret, caretOffset(ringSize), caretEdge(ringSize), { [caretFill]: caretBorderColor ?? caretColor, [caretWidthProp]: ringSize, borderLeftWidth: ringSize, borderRightWidth: ringSize }] }),
|
|
111
|
-
/* @__PURE__ */ jsx2(View2, { style: [styles2.caret, caretOffset(CARET_SIZE), caretEdge(CARET_SIZE - CARET_RING_OFFSET), { [caretFill]: caretColor, [caretWidthProp]: CARET_SIZE, borderLeftWidth: CARET_SIZE, borderRightWidth: CARET_SIZE }] })
|
|
112
|
-
] })
|
|
113
|
-
] });
|
|
114
|
-
}
|
|
115
|
-
var styles2 = StyleSheet2.create({
|
|
116
|
-
caret: {
|
|
117
|
-
borderLeftColor: "transparent",
|
|
118
|
-
borderRightColor: "transparent",
|
|
119
|
-
height: 0,
|
|
120
|
-
position: "absolute",
|
|
121
|
-
width: 0,
|
|
122
|
-
// Explicit, not left to DOM order - the box it dips into is itself a position:'relative' view,
|
|
123
|
-
// which React Native Web always gives an implicit zIndex:0 (see PopoverBody's stacking-context
|
|
124
|
-
// notes elsewhere in this codebase), so painting on top needs a real zIndex to beat that
|
|
125
|
-
// reliably rather than relying on being the later sibling.
|
|
126
|
-
zIndex: 1
|
|
127
|
-
},
|
|
128
|
-
content: {
|
|
129
|
-
position: "absolute",
|
|
130
|
-
zIndex: 50
|
|
131
|
-
},
|
|
132
|
-
contentAbove: {
|
|
133
|
-
bottom: "100%",
|
|
134
|
-
marginBottom: 8
|
|
135
|
-
},
|
|
136
|
-
contentBelow: {
|
|
137
|
-
marginTop: 8,
|
|
138
|
-
top: "100%"
|
|
139
|
-
},
|
|
140
|
-
// Stretched to the anchor's own (trigger) width, with alignItems centering the actual (usually
|
|
141
|
-
// much wider) popover box inside via plain flexbox - not `left:'50%'` plus a percentage
|
|
142
|
-
// `transform`, which depends on native resolving the box's own auto width before applying the
|
|
143
|
-
// transform and has proven unreliable there, visibly shifting the box off-center.
|
|
144
|
-
contentCenter: {
|
|
145
|
-
alignItems: "center",
|
|
146
|
-
left: 0,
|
|
147
|
-
right: 0
|
|
148
|
-
},
|
|
149
|
-
contentLeft: {
|
|
150
|
-
left: 0
|
|
151
|
-
},
|
|
152
|
-
contentRight: {
|
|
153
|
-
right: 0
|
|
154
|
-
}
|
|
155
|
-
});
|
|
156
|
-
|
|
157
98
|
// src/TriggerGaugeHost.tsx
|
|
158
|
-
import {
|
|
159
|
-
|
|
99
|
+
import { lazy, Suspense } from "react";
|
|
100
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
101
|
+
var LazyTriggerGauge = lazy(() => loadSkiaWeb().then(() => import("./TriggerGauge-GIHKGAZE.mjs").then((mod) => ({ default: mod.TriggerGauge }))));
|
|
160
102
|
function TriggerGaugeHost(props) {
|
|
161
|
-
return /* @__PURE__ */
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// src/useAutoAlign.ts
|
|
165
|
-
import { useCallback, useEffect, useRef, useState } from "react";
|
|
166
|
-
import { useWindowDimensions } from "react-native";
|
|
167
|
-
var EDGE_MARGIN = 12;
|
|
168
|
-
function rotateRect(x, y, width, height, rotation, windowWidth, windowHeight) {
|
|
169
|
-
if (rotation === 0) return { x, y, width, height };
|
|
170
|
-
const cx = windowWidth / 2;
|
|
171
|
-
const cy = windowHeight / 2;
|
|
172
|
-
const dx = x + width / 2 - cx;
|
|
173
|
-
const dy = y + height / 2 - cy;
|
|
174
|
-
const [newDx, newDy, newWidth, newHeight] = rotation === 180 ? [-dx, -dy, width, height] : rotation === 90 ? [-dy, dx, height, width] : [dy, -dx, height, width];
|
|
175
|
-
return { x: cx + newDx - newWidth / 2, y: cy + newDy - newHeight / 2, width: newWidth, height: newHeight };
|
|
176
|
-
}
|
|
177
|
-
function useAutoAlign(open, contentWidth, contentHeight, rotation = 0) {
|
|
178
|
-
const triggerRef = useRef(null);
|
|
179
|
-
const { width: windowWidth, height: windowHeight } = useWindowDimensions();
|
|
180
|
-
const [align, setAlign] = useState("center");
|
|
181
|
-
const [verticalAlign, setVerticalAlign] = useState("below");
|
|
182
|
-
const [maxHeight, setMaxHeight] = useState(contentHeight);
|
|
183
|
-
const [measured, setMeasured] = useState(false);
|
|
184
|
-
const [prevOpen, setPrevOpen] = useState(open);
|
|
185
|
-
if (open !== prevOpen) {
|
|
186
|
-
setPrevOpen(open);
|
|
187
|
-
if (open) setMeasured(false);
|
|
188
|
-
}
|
|
189
|
-
const measure = useCallback(() => {
|
|
190
|
-
triggerRef.current?.measureInWindow((rawX, rawY, rawWidth, rawHeight) => {
|
|
191
|
-
const { x, y, width: triggerWidth, height: triggerHeight } = rotateRect(rawX, rawY, rawWidth, rawHeight, rotation, windowWidth, windowHeight);
|
|
192
|
-
const centerX = x + triggerWidth / 2;
|
|
193
|
-
const overflowsRight = centerX + contentWidth / 2 > windowWidth - EDGE_MARGIN;
|
|
194
|
-
const overflowsLeft = centerX - contentWidth / 2 < EDGE_MARGIN;
|
|
195
|
-
if (overflowsRight && !overflowsLeft) setAlign("right");
|
|
196
|
-
else if (overflowsLeft && !overflowsRight) setAlign("left");
|
|
197
|
-
else setAlign("center");
|
|
198
|
-
const roomBelow = windowHeight - (y + triggerHeight) - EDGE_MARGIN;
|
|
199
|
-
const roomAbove = y - EDGE_MARGIN;
|
|
200
|
-
const above = contentHeight > roomBelow && roomAbove > roomBelow;
|
|
201
|
-
setVerticalAlign(above ? "above" : "below");
|
|
202
|
-
setMaxHeight(Math.max(above ? roomAbove : roomBelow, 0));
|
|
203
|
-
setMeasured(true);
|
|
204
|
-
});
|
|
205
|
-
}, [contentWidth, contentHeight, windowWidth, windowHeight, rotation]);
|
|
206
|
-
useEffect(() => {
|
|
207
|
-
if (open) measure();
|
|
208
|
-
}, [open, measure]);
|
|
209
|
-
return { align, maxHeight, measured, triggerRef, verticalAlign };
|
|
103
|
+
return /* @__PURE__ */ jsx2(Suspense, { fallback: null, children: /* @__PURE__ */ jsx2(LazyTriggerGauge, { ...props }) });
|
|
210
104
|
}
|
|
211
105
|
|
|
212
106
|
// src/SectionedDropdown.tsx
|
|
213
|
-
import { Fragment
|
|
107
|
+
import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
214
108
|
var MENU_BORDER_WIDTH = 1;
|
|
215
109
|
var TRIGGER_SIZE = 44;
|
|
216
110
|
var MENU_MIN_WIDTH = 200;
|
|
@@ -260,17 +154,17 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
|
|
|
260
154
|
}
|
|
261
155
|
gaugeOffset += section.options.length;
|
|
262
156
|
}
|
|
263
|
-
const anchorStyle = [
|
|
157
|
+
const anchorStyle = [styles2.anchor, open && styles2.anchorOpen];
|
|
264
158
|
const menuStyle = { backgroundColor: menuBg, borderColor: menuBorderColor, maxHeight };
|
|
265
159
|
const dividerStyle = { backgroundColor: menuBorderColor };
|
|
266
|
-
return /* @__PURE__ */
|
|
267
|
-
/* @__PURE__ */
|
|
268
|
-
/* @__PURE__ */
|
|
269
|
-
/* @__PURE__ */
|
|
160
|
+
return /* @__PURE__ */ jsxs2(View2, { style: anchorStyle, children: [
|
|
161
|
+
/* @__PURE__ */ jsxs2(View2, { ref: triggerRef, collapsable: false, style: styles2.triggerBox, children: [
|
|
162
|
+
/* @__PURE__ */ jsx3(TriggerGaugeHost, { segments: gaugeSegments, litIndices: gaugeLitIndices, size: TRIGGER_SIZE, accentColor, mutedColor }),
|
|
163
|
+
/* @__PURE__ */ jsx3(IconButton, { icon: triggerIcon, iconColor: triggerIconColor, size: triggerIconSize, accessibilityLabel, onPress: () => host.toggle(id) })
|
|
270
164
|
] }),
|
|
271
|
-
/* @__PURE__ */
|
|
272
|
-
sectionIndex > 0 && /* @__PURE__ */
|
|
273
|
-
section.kind === "single" ? /* @__PURE__ */
|
|
165
|
+
/* @__PURE__ */ jsx3(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: menuBorderColor, caretBorderWidth: MENU_BORDER_WIDTH, triggerSize: TRIGGER_SIZE, children: /* @__PURE__ */ jsx3(ScrollView, { style: [styles2.menu, menuStyle], contentContainerStyle: styles2.menuContent, showsVerticalScrollIndicator: false, children: sections.map((section, sectionIndex) => /* @__PURE__ */ jsxs2(View2, { children: [
|
|
166
|
+
sectionIndex > 0 && /* @__PURE__ */ jsx3(View2, { style: [styles2.divider, dividerStyle] }),
|
|
167
|
+
section.kind === "single" ? /* @__PURE__ */ jsx3(
|
|
274
168
|
SingleSection,
|
|
275
169
|
{
|
|
276
170
|
section,
|
|
@@ -283,7 +177,7 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
|
|
|
283
177
|
if (autoDismiss) host.close();
|
|
284
178
|
}
|
|
285
179
|
}
|
|
286
|
-
) : /* @__PURE__ */
|
|
180
|
+
) : /* @__PURE__ */ jsx3(MultiSection, { section, accentColor, onAccentColor: resolvedOnAccentColor, mutedColor, labelFontFamily, allClearLabels })
|
|
287
181
|
] }, section.id)) }) })
|
|
288
182
|
] });
|
|
289
183
|
}
|
|
@@ -295,18 +189,18 @@ function SingleSection({
|
|
|
295
189
|
labelFontFamily,
|
|
296
190
|
onSelect
|
|
297
191
|
}) {
|
|
298
|
-
return /* @__PURE__ */
|
|
192
|
+
return /* @__PURE__ */ jsx3(Fragment, { children: section.options.map((option) => {
|
|
299
193
|
const selected = option.value === section.value;
|
|
300
194
|
const taken = !selected && option.value === section.takenValue;
|
|
301
195
|
const rowColor = selected ? onAccentColor : mutedColor;
|
|
302
|
-
const itemStyle = [
|
|
196
|
+
const itemStyle = [styles2.item, selected && { backgroundColor: accentColor }, taken && styles2.itemTaken];
|
|
303
197
|
const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
|
|
304
198
|
const descriptionStyle = { fontFamily: labelFontFamily, color: rowColor };
|
|
305
|
-
return /* @__PURE__ */
|
|
306
|
-
option.icon && /* @__PURE__ */
|
|
307
|
-
/* @__PURE__ */
|
|
308
|
-
/* @__PURE__ */
|
|
309
|
-
option.description && /* @__PURE__ */
|
|
199
|
+
return /* @__PURE__ */ jsx3(TouchableRipple, { disabled: taken, onPress: () => onSelect(option.value), style: itemStyle, children: /* @__PURE__ */ jsxs2(View2, { style: styles2.itemRow, children: [
|
|
200
|
+
option.icon && /* @__PURE__ */ jsx3(Icon2, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
|
|
201
|
+
/* @__PURE__ */ jsxs2(View2, { style: styles2.itemLabelColumn, children: [
|
|
202
|
+
/* @__PURE__ */ jsx3(Text2, { variant: "labelLarge", style: labelStyle, children: option.label }),
|
|
203
|
+
option.description && /* @__PURE__ */ jsx3(Text2, { variant: "labelSmall", style: descriptionStyle, children: option.description })
|
|
310
204
|
] })
|
|
311
205
|
] }) }, option.value);
|
|
312
206
|
}) });
|
|
@@ -320,23 +214,23 @@ function MultiSection({
|
|
|
320
214
|
allClearLabels
|
|
321
215
|
}) {
|
|
322
216
|
const allSelected = section.value.length === section.options.length;
|
|
323
|
-
return /* @__PURE__ */
|
|
217
|
+
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
324
218
|
section.options.map((option, i) => {
|
|
325
219
|
const selected = section.value.includes(option.value);
|
|
326
220
|
const rowColor = selected ? onAccentColor : mutedColor;
|
|
327
221
|
const prevSelected = selected && i > 0 && section.value.includes(section.options[i - 1].value);
|
|
328
222
|
const nextSelected = selected && i < section.options.length - 1 && section.value.includes(section.options[i + 1].value);
|
|
329
|
-
const itemStyle = [
|
|
223
|
+
const itemStyle = [styles2.item, selected && { backgroundColor: accentColor }, prevSelected && { borderTopLeftRadius: 0, borderTopRightRadius: 0 }, nextSelected && { borderBottomLeftRadius: 0, borderBottomRightRadius: 0 }];
|
|
330
224
|
const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
|
|
331
|
-
return /* @__PURE__ */
|
|
332
|
-
option.icon && /* @__PURE__ */
|
|
333
|
-
/* @__PURE__ */
|
|
225
|
+
return /* @__PURE__ */ jsx3(TouchableRipple, { onPress: () => section.onChange(selected ? section.value.filter((v) => v !== option.value) : [...section.value, option.value]), style: itemStyle, children: /* @__PURE__ */ jsxs2(View2, { style: styles2.itemRow, children: [
|
|
226
|
+
option.icon && /* @__PURE__ */ jsx3(Icon2, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
|
|
227
|
+
/* @__PURE__ */ jsx3(Text2, { variant: "labelLarge", style: [styles2.itemLabelFlex, labelStyle], children: option.label })
|
|
334
228
|
] }) }, option.value);
|
|
335
229
|
}),
|
|
336
|
-
section.allClear && /* @__PURE__ */
|
|
230
|
+
section.allClear && /* @__PURE__ */ jsx3(TouchableRipple, { onPress: () => section.onChange(allSelected ? [] : section.options.map((o) => o.value)), style: styles2.item, children: /* @__PURE__ */ jsx3(Text2, { variant: "labelLarge", style: [styles2.allClearLabel, { fontFamily: labelFontFamily, color: accentColor }], children: allSelected ? allClearLabels.clear : allClearLabels.all }) })
|
|
337
231
|
] });
|
|
338
232
|
}
|
|
339
|
-
var
|
|
233
|
+
var styles2 = StyleSheet2.create({
|
|
340
234
|
allClearLabel: {
|
|
341
235
|
fontWeight: "bold",
|
|
342
236
|
textAlign: "center"
|
|
@@ -353,7 +247,7 @@ var styles3 = StyleSheet3.create({
|
|
|
353
247
|
zIndex: 100
|
|
354
248
|
},
|
|
355
249
|
divider: {
|
|
356
|
-
height:
|
|
250
|
+
height: StyleSheet2.hairlineWidth,
|
|
357
251
|
marginVertical: 4
|
|
358
252
|
},
|
|
359
253
|
item: {
|
|
@@ -406,30 +300,30 @@ var styles3 = StyleSheet3.create({
|
|
|
406
300
|
});
|
|
407
301
|
|
|
408
302
|
// src/ControlSchemePicker.tsx
|
|
409
|
-
import { jsx as
|
|
303
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
410
304
|
function ControlSchemePicker({ id, host, value, onChange, options, takenValue, accentColor, mutedColor, onAccentColor, dark, align, alignOverride, rotation, labelFontFamily }) {
|
|
411
305
|
const isTouchPrimary = useIsTouchPrimaryDevice();
|
|
412
306
|
if (Platform.OS !== "web" || isTouchPrimary) return null;
|
|
413
|
-
return /* @__PURE__ */
|
|
307
|
+
return /* @__PURE__ */ jsx4(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 });
|
|
414
308
|
}
|
|
415
309
|
|
|
416
310
|
// src/CornerStatusBadges.tsx
|
|
417
|
-
import { StyleSheet as
|
|
311
|
+
import { StyleSheet as StyleSheet3, View as View3 } from "react-native";
|
|
418
312
|
import { Icon as Icon3 } from "react-native-paper";
|
|
419
|
-
import { Fragment as
|
|
313
|
+
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
420
314
|
var BADGE_SIZE = 30;
|
|
421
315
|
function StatusBadge({ icon }) {
|
|
422
|
-
return /* @__PURE__ */
|
|
316
|
+
return /* @__PURE__ */ jsx5(View3, { style: styles3.badge, children: icon && /* @__PURE__ */ jsx5(Icon3, { source: icon, size: 16, color: "rgba(255,255,255,0.85)" }) });
|
|
423
317
|
}
|
|
424
318
|
function CornerStatusBadges({ orientationMode, p1OnRight, p1, p2 }) {
|
|
425
319
|
const p1OnRightSide = orientationMode === "sideBySide" && p1OnRight;
|
|
426
320
|
const p2OnLeftSide = orientationMode === "sideBySide" && !p1OnRight;
|
|
427
|
-
return /* @__PURE__ */
|
|
428
|
-
p1 && /* @__PURE__ */
|
|
429
|
-
p2 && /* @__PURE__ */
|
|
321
|
+
return /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
322
|
+
p1 && /* @__PURE__ */ jsx5(View3, { pointerEvents: "none", style: p1OnRightSide ? styles3.bottomRight : styles3.bottomLeft, children: /* @__PURE__ */ jsx5(StatusBadge, { icon: p1.icon }) }),
|
|
323
|
+
p2 && /* @__PURE__ */ jsx5(View3, { pointerEvents: "none", style: p2OnLeftSide ? styles3.topLeft : styles3.topRight, children: /* @__PURE__ */ jsx5(StatusBadge, { icon: p2.icon }) })
|
|
430
324
|
] });
|
|
431
325
|
}
|
|
432
|
-
var
|
|
326
|
+
var styles3 = StyleSheet3.create({
|
|
433
327
|
badge: {
|
|
434
328
|
alignItems: "center",
|
|
435
329
|
backgroundColor: "rgba(0,0,0,0.28)",
|
|
@@ -447,149 +341,12 @@ var styles4 = StyleSheet4.create({
|
|
|
447
341
|
topRight: { position: "absolute", right: 12, top: 12 }
|
|
448
342
|
});
|
|
449
343
|
|
|
450
|
-
// src/
|
|
451
|
-
import {
|
|
344
|
+
// src/LabeledDropdown.tsx
|
|
345
|
+
import { getContrastColor as getContrastColor2 } from "@rific/auto-paper";
|
|
452
346
|
import { TouchableRipple as TouchableRipple2 } from "@rific/feedback-press";
|
|
453
|
-
import {
|
|
454
|
-
import { ScrollView as ScrollView2, StyleSheet as StyleSheet5, useWindowDimensions as useWindowDimensions2, View as View6 } from "react-native";
|
|
347
|
+
import { ScrollView as ScrollView2, StyleSheet as StyleSheet4, View as View4 } from "react-native";
|
|
455
348
|
import { Icon as Icon4, Text as Text3 } from "react-native-paper";
|
|
456
|
-
import { jsx as
|
|
457
|
-
var EMOJI_PATTERN = /\p{Extended_Pictographic}/u;
|
|
458
|
-
var DEFAULT_SIZE = 48;
|
|
459
|
-
var SWATCH_SIZE = 28;
|
|
460
|
-
var SWATCHES_PADDING = 8;
|
|
461
|
-
var SWATCHES_GAP = 6;
|
|
462
|
-
var SWATCHES_BORDER_WIDTH = 2;
|
|
463
|
-
var MIN_COLUMNS = 4;
|
|
464
|
-
var MAX_COLUMNS = 5;
|
|
465
|
-
var SCREEN_MARGIN = 40;
|
|
466
|
-
function widthForColumns(columns) {
|
|
467
|
-
return SWATCHES_BORDER_WIDTH * 2 + SWATCHES_PADDING * 2 + SWATCH_SIZE * columns + SWATCHES_GAP * (columns - 1);
|
|
468
|
-
}
|
|
469
|
-
function getInlineColorPickerContentSize(swatchCount, windowWidth, columns) {
|
|
470
|
-
const autoColumns = clamp(Math.floor((windowWidth - 2 * SCREEN_MARGIN + SWATCHES_GAP) / (SWATCH_SIZE + SWATCHES_GAP)), MIN_COLUMNS, MAX_COLUMNS);
|
|
471
|
-
const resolvedColumns = columns ?? autoColumns;
|
|
472
|
-
const width = widthForColumns(resolvedColumns);
|
|
473
|
-
const rows = Math.ceil(swatchCount / resolvedColumns);
|
|
474
|
-
const height = SWATCHES_BORDER_WIDTH * 2 + SWATCHES_PADDING * 2 + SWATCH_SIZE * rows + SWATCHES_GAP * (rows - 1);
|
|
475
|
-
return { width, height };
|
|
476
|
-
}
|
|
477
|
-
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 }) {
|
|
478
|
-
const ambientRotation = useRotation2();
|
|
479
|
-
const rotation = rotationOverride ?? ambientRotation;
|
|
480
|
-
const menuBg = dark ? "#000000" : "#FFFFFF";
|
|
481
|
-
const { width: windowWidth } = useWindowDimensions2();
|
|
482
|
-
const { width: swatchesWidth, height: swatchesHeight } = getInlineColorPickerContentSize(swatches.length, windowWidth, columns);
|
|
483
|
-
const open = host.openId === id;
|
|
484
|
-
const auto = useAutoAlign(open, swatchesWidth, swatchesHeight, rotation);
|
|
485
|
-
const placement = alignOverride ?? auto;
|
|
486
|
-
const { maxHeight, measured, triggerRef, verticalAlign } = placement;
|
|
487
|
-
const align = forcedAlign ?? placement.align;
|
|
488
|
-
const displayFor = previewValue ?? ((hex) => hex);
|
|
489
|
-
const displayValue = displayFor(value);
|
|
490
|
-
const contrastColor = getContrastColor2(displayValue);
|
|
491
|
-
const tagFontSize = size * (tag && EMOJI_PATTERN.test(tag) ? 0.6 : 0.4);
|
|
492
|
-
return /* @__PURE__ */ jsxs5(View6, { style: [styles5.anchor, open && styles5.anchorOpen], children: [
|
|
493
|
-
/* @__PURE__ */ jsx7(TouchableRipple2, { onPress: () => host.toggle(id), borderless: true, style: [styles5.trigger, { backgroundColor: displayValue, borderRadius: size / 2, height: size, width: size }], children: /* @__PURE__ */ jsx7(View6, { ref: triggerRef, collapsable: false, style: styles5.triggerMeasure, children: tag ? /* @__PURE__ */ jsx7(Text3, { style: [styles5.tagLabel, { color: contrastColor, fontFamily: labelFontFamily, fontSize: tagFontSize }], numberOfLines: 1, adjustsFontSizeToFit: true, children: tag }) : /* @__PURE__ */ jsx7(Icon4, { source: icon, size: size * 0.6, color: contrastColor }) }) }),
|
|
494
|
-
/* @__PURE__ */ jsx7(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: displayValue, caretBorderWidth: SWATCHES_BORDER_WIDTH, triggerSize: size, children: /* @__PURE__ */ jsx7(ScrollView2, { style: [styles5.swatches, { backgroundColor: menuBg, borderColor: displayValue, width: swatchesWidth, maxHeight }], contentContainerStyle: styles5.swatchesContent, showsVerticalScrollIndicator: false, children: swatches.map((swatch) => {
|
|
495
|
-
const selected = swatch.value.toLowerCase() === value.toLowerCase();
|
|
496
|
-
const taken = !selected && !!takenValue && swatch.value.toLowerCase() === takenValue.toLowerCase();
|
|
497
|
-
const swappable = taken && allowSwapTaken;
|
|
498
|
-
const swatchDisplay = displayFor(swatch.value);
|
|
499
|
-
return /* @__PURE__ */ jsx7(
|
|
500
|
-
TouchableRipple2,
|
|
501
|
-
{
|
|
502
|
-
disabled: taken && !swappable,
|
|
503
|
-
onPress: () => {
|
|
504
|
-
onChange(swatch.value);
|
|
505
|
-
if (autoDismiss) host.close();
|
|
506
|
-
},
|
|
507
|
-
borderless: true,
|
|
508
|
-
style: [styles5.swatch, { backgroundColor: swatchDisplay }, selected && styles5.swatchSelected, taken && !swappable && styles5.swatchTaken],
|
|
509
|
-
children: selected ? /* @__PURE__ */ jsx7(Icon4, { source: "check", size: 16, color: getContrastColor2(swatchDisplay) }) : swappable ? /* @__PURE__ */ jsx7(Icon4, { source: "swap-horizontal", size: 16, color: getContrastColor2(swatchDisplay) }) : taken ? /* @__PURE__ */ jsx7(Icon4, { source: "close", size: 16, color: getContrastColor2(swatchDisplay) }) : /* @__PURE__ */ jsx7(View6, {})
|
|
510
|
-
},
|
|
511
|
-
swatch.value
|
|
512
|
-
);
|
|
513
|
-
}) }) })
|
|
514
|
-
] });
|
|
515
|
-
}
|
|
516
|
-
var styles5 = StyleSheet5.create({
|
|
517
|
-
anchor: {
|
|
518
|
-
position: "relative"
|
|
519
|
-
},
|
|
520
|
-
// See SectionedDropdown's identical comment - React Native Web gives every position:'relative' view
|
|
521
|
-
// its own stacking context, so the elevation has to live on the anchor itself, not just the
|
|
522
|
-
// popover content nested inside it, to correctly paint above this anchor's own later siblings.
|
|
523
|
-
anchorOpen: {
|
|
524
|
-
zIndex: 100
|
|
525
|
-
},
|
|
526
|
-
swatch: {
|
|
527
|
-
alignItems: "center",
|
|
528
|
-
borderRadius: SWATCH_SIZE / 2,
|
|
529
|
-
height: SWATCH_SIZE,
|
|
530
|
-
justifyContent: "center",
|
|
531
|
-
width: SWATCH_SIZE
|
|
532
|
-
},
|
|
533
|
-
swatchSelected: {
|
|
534
|
-
borderColor: "#ffffff",
|
|
535
|
-
borderWidth: 2
|
|
536
|
-
},
|
|
537
|
-
swatchTaken: {
|
|
538
|
-
opacity: 0.35
|
|
539
|
-
},
|
|
540
|
-
swatches: {
|
|
541
|
-
borderRadius: 12,
|
|
542
|
-
borderWidth: SWATCHES_BORDER_WIDTH,
|
|
543
|
-
elevation: 8,
|
|
544
|
-
shadowColor: "#000000",
|
|
545
|
-
shadowOffset: { height: 2, width: 0 },
|
|
546
|
-
shadowOpacity: 0.3,
|
|
547
|
-
shadowRadius: 8
|
|
548
|
-
// width is set inline above - border-box sizing means it has to include the border too
|
|
549
|
-
// (2*SWATCHES_BORDER_WIDTH), not just padding+content, or exactly enough room goes missing that
|
|
550
|
-
// the last column silently wraps to a new row. Anything wider than the exact sum just shows as
|
|
551
|
-
// dead space on the right edge of each row instead.
|
|
552
|
-
},
|
|
553
|
-
// Separate from `swatches` itself - see SectionedDropdown's identical menu/menuContent split.
|
|
554
|
-
// The scroll frame's own bounds (including maxHeight) live on the ScrollView; the actual grid
|
|
555
|
-
// wrapping belongs to its contentContainerStyle, which sizes to the unclamped content instead.
|
|
556
|
-
swatchesContent: {
|
|
557
|
-
flexDirection: "row",
|
|
558
|
-
flexWrap: "wrap",
|
|
559
|
-
gap: SWATCHES_GAP,
|
|
560
|
-
padding: SWATCHES_PADDING
|
|
561
|
-
},
|
|
562
|
-
tagLabel: {
|
|
563
|
-
fontWeight: "700",
|
|
564
|
-
letterSpacing: 0.5
|
|
565
|
-
},
|
|
566
|
-
// borderRadius/height/width come from the `size` prop instead (see render-site override) - no
|
|
567
|
-
// fixed default here, since this style object is shared by every caller regardless of size.
|
|
568
|
-
trigger: {
|
|
569
|
-
alignItems: "center",
|
|
570
|
-
alignSelf: "flex-start",
|
|
571
|
-
justifyContent: "center"
|
|
572
|
-
},
|
|
573
|
-
// Wraps just the icon/tag, inside the TouchableRipple, purely so useAutoAlign has a plain View
|
|
574
|
-
// to attach its measurement ref to - TouchableRipple itself doesn't forward a ref to a
|
|
575
|
-
// measurable native node. Padded horizontally so a multi-character tag doesn't butt right up
|
|
576
|
-
// against the trigger's own circular edge (an icon alone doesn't need it, but this style is
|
|
577
|
-
// shared by both).
|
|
578
|
-
triggerMeasure: {
|
|
579
|
-
alignItems: "center",
|
|
580
|
-
height: "100%",
|
|
581
|
-
justifyContent: "center",
|
|
582
|
-
paddingHorizontal: 4,
|
|
583
|
-
width: "100%"
|
|
584
|
-
}
|
|
585
|
-
});
|
|
586
|
-
|
|
587
|
-
// src/LabeledDropdown.tsx
|
|
588
|
-
import { getContrastColor as getContrastColor3 } from "@rific/auto-paper";
|
|
589
|
-
import { TouchableRipple as TouchableRipple3 } from "@rific/feedback-press";
|
|
590
|
-
import { ScrollView as ScrollView3, StyleSheet as StyleSheet6, View as View7 } from "react-native";
|
|
591
|
-
import { Icon as Icon5, Text as Text4 } from "react-native-paper";
|
|
592
|
-
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
349
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
593
350
|
var TRIGGER_HEIGHT = 28;
|
|
594
351
|
var POPOVER_WIDTH = 180;
|
|
595
352
|
var ROW_HEIGHT = 36;
|
|
@@ -612,22 +369,22 @@ function LabeledDropdown({ id, host, options, value, onChange, color, dark, alig
|
|
|
612
369
|
onChange(option.value);
|
|
613
370
|
host.close();
|
|
614
371
|
};
|
|
615
|
-
return /* @__PURE__ */
|
|
616
|
-
/* @__PURE__ */
|
|
617
|
-
/* @__PURE__ */
|
|
618
|
-
/* @__PURE__ */
|
|
372
|
+
return /* @__PURE__ */ jsxs4(View4, { style: [styles4.anchor, open && styles4.anchorOpen], children: [
|
|
373
|
+
/* @__PURE__ */ jsx6(TouchableRipple2, { onPress: () => host.toggle(id), style: styles4.trigger, children: /* @__PURE__ */ jsxs4(View4, { ref: triggerRef, collapsable: false, style: styles4.triggerInner, children: [
|
|
374
|
+
/* @__PURE__ */ jsx6(Text3, { style: [styles4.triggerLabel, { color }], numberOfLines: 1, children: (selected?.label ?? "").toUpperCase() }),
|
|
375
|
+
/* @__PURE__ */ jsx6(Icon4, { source: "menu-down", size: 16, color })
|
|
619
376
|
] }) }),
|
|
620
|
-
/* @__PURE__ */
|
|
377
|
+
/* @__PURE__ */ jsx6(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: color, caretBorderWidth: 2, triggerSize: TRIGGER_HEIGHT, children: /* @__PURE__ */ jsx6(ScrollView2, { style: [styles4.menu, { backgroundColor: menuBg, borderColor: color, width: POPOVER_WIDTH, maxHeight }], contentContainerStyle: styles4.menuContent, showsVerticalScrollIndicator: false, children: options.map((option) => {
|
|
621
378
|
const isSelected = option.value === value;
|
|
622
|
-
const onColor =
|
|
623
|
-
return /* @__PURE__ */
|
|
624
|
-
option.icon && /* @__PURE__ */
|
|
625
|
-
/* @__PURE__ */
|
|
379
|
+
const onColor = getContrastColor2(color);
|
|
380
|
+
return /* @__PURE__ */ jsx6(TouchableRipple2, { onPress: () => handleSelect(option), style: [styles4.row, isSelected && { backgroundColor: color }], children: /* @__PURE__ */ jsxs4(View4, { style: styles4.rowInner, children: [
|
|
381
|
+
option.icon && /* @__PURE__ */ jsx6(Icon4, { source: option.icon, size: 18, color: isSelected ? onColor : fg }),
|
|
382
|
+
/* @__PURE__ */ jsx6(Text3, { style: [styles4.rowLabel, { color: isSelected ? onColor : fg }], numberOfLines: 1, children: option.label })
|
|
626
383
|
] }) }, option.value);
|
|
627
384
|
}) }) })
|
|
628
385
|
] });
|
|
629
386
|
}
|
|
630
|
-
var
|
|
387
|
+
var styles4 = StyleSheet4.create({
|
|
631
388
|
anchor: {
|
|
632
389
|
position: "relative"
|
|
633
390
|
},
|
|
@@ -679,28 +436,23 @@ var styles6 = StyleSheet6.create({
|
|
|
679
436
|
}
|
|
680
437
|
});
|
|
681
438
|
|
|
682
|
-
// src/loadSkiaWeb.ts
|
|
683
|
-
function loadSkiaWeb() {
|
|
684
|
-
return Promise.resolve();
|
|
685
|
-
}
|
|
686
|
-
|
|
687
439
|
// src/PlayerSetupPanel.tsx
|
|
688
440
|
import { getOptionPickerContentSize, getProfilePickerContentSize, OptionPicker, ProfilePicker } from "@tastic/profile";
|
|
689
|
-
import { StyleSheet as
|
|
690
|
-
import { Text as
|
|
441
|
+
import { StyleSheet as StyleSheet6, View as View5 } from "react-native";
|
|
442
|
+
import { Text as Text5 } from "react-native-paper";
|
|
691
443
|
|
|
692
444
|
// src/ReadyButton.tsx
|
|
693
|
-
import { TouchableRipple as
|
|
694
|
-
import { StyleSheet as
|
|
695
|
-
import { Text as
|
|
696
|
-
import { jsx as
|
|
445
|
+
import { TouchableRipple as TouchableRipple3 } from "@rific/feedback-press";
|
|
446
|
+
import { StyleSheet as StyleSheet5 } from "react-native";
|
|
447
|
+
import { Text as Text4 } from "react-native-paper";
|
|
448
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
697
449
|
function ReadyButton({ color, ready, onToggleReady, style, labelFontFamily = MONO_FONT }) {
|
|
698
|
-
const readyButtonStyle = [
|
|
450
|
+
const readyButtonStyle = [styles5.readyButton, { borderColor: color }, ready && { backgroundColor: color }, style];
|
|
699
451
|
const labelTextStyle = { fontFamily: labelFontFamily, fontWeight: "bold" };
|
|
700
452
|
const labelColorStyle = { color: ready ? "#000000" : color };
|
|
701
|
-
return /* @__PURE__ */
|
|
453
|
+
return /* @__PURE__ */ jsx7(TouchableRipple3, { onPress: onToggleReady, borderless: true, style: readyButtonStyle, children: /* @__PURE__ */ jsx7(Text4, { variant: "labelLarge", style: [labelTextStyle, labelColorStyle], children: ready ? "READY \u2713" : "READY?" }) });
|
|
702
454
|
}
|
|
703
|
-
var
|
|
455
|
+
var styles5 = StyleSheet5.create({
|
|
704
456
|
readyButton: {
|
|
705
457
|
alignItems: "center",
|
|
706
458
|
borderRadius: 12,
|
|
@@ -712,41 +464,30 @@ var styles7 = StyleSheet7.create({
|
|
|
712
464
|
}
|
|
713
465
|
});
|
|
714
466
|
|
|
715
|
-
// src/usePopoverHost.ts
|
|
716
|
-
import { useCallback as useCallback2, useState as useState2 } from "react";
|
|
717
|
-
function usePopoverHost() {
|
|
718
|
-
const [openId, setOpenId] = useState2(null);
|
|
719
|
-
const toggle = useCallback2((id) => {
|
|
720
|
-
setOpenId((prev) => prev === id ? null : id);
|
|
721
|
-
}, []);
|
|
722
|
-
const close = useCallback2(() => setOpenId(null), []);
|
|
723
|
-
return { openId, toggle, close };
|
|
724
|
-
}
|
|
725
|
-
|
|
726
467
|
// src/useZoneClampedAlign.ts
|
|
727
468
|
import { useZoneBounds } from "@tastic/split-screen";
|
|
728
|
-
import { useEffect
|
|
729
|
-
import { useWindowDimensions
|
|
469
|
+
import { useEffect, useState } from "react";
|
|
470
|
+
import { useWindowDimensions } from "react-native";
|
|
730
471
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
731
|
-
var
|
|
472
|
+
var EDGE_MARGIN = 12;
|
|
732
473
|
function useZoneClampedAlign(open, contentWidth, contentHeight, rotation = 0) {
|
|
733
474
|
const auto = useAutoAlign(open, contentWidth, contentHeight, rotation);
|
|
734
475
|
const zone = useZoneBounds();
|
|
735
|
-
const { height: windowHeight } =
|
|
476
|
+
const { height: windowHeight } = useWindowDimensions();
|
|
736
477
|
const insets = useSafeAreaInsets();
|
|
737
478
|
const shouldMeasure = open && auto.measured && zone !== null;
|
|
738
|
-
const [ownBounds, setOwnBounds] =
|
|
739
|
-
const [prevShouldMeasure, setPrevShouldMeasure] =
|
|
479
|
+
const [ownBounds, setOwnBounds] = useState(null);
|
|
480
|
+
const [prevShouldMeasure, setPrevShouldMeasure] = useState(shouldMeasure);
|
|
740
481
|
if (shouldMeasure !== prevShouldMeasure) {
|
|
741
482
|
setPrevShouldMeasure(shouldMeasure);
|
|
742
483
|
setOwnBounds(null);
|
|
743
484
|
}
|
|
744
|
-
|
|
485
|
+
useEffect(() => {
|
|
745
486
|
if (!shouldMeasure) return;
|
|
746
487
|
auto.triggerRef.current?.measureInWindow((_x, y, _width, height) => {
|
|
747
488
|
const belowShared = zone.zoneSide === "belowShared";
|
|
748
|
-
const awayRoom = belowShared ? windowHeight - insets.bottom - (y + height) -
|
|
749
|
-
const towardRoom = belowShared ? y - zone.sharedEdgeY -
|
|
489
|
+
const awayRoom = belowShared ? windowHeight - insets.bottom - (y + height) - EDGE_MARGIN : y - insets.top - EDGE_MARGIN;
|
|
490
|
+
const towardRoom = belowShared ? y - zone.sharedEdgeY - EDGE_MARGIN : zone.sharedEdgeY - (y + height) - EDGE_MARGIN;
|
|
750
491
|
const useToward = contentHeight > awayRoom && towardRoom > awayRoom;
|
|
751
492
|
let awaySide = belowShared ? "below" : "above";
|
|
752
493
|
let towardSide = belowShared ? "above" : "below";
|
|
@@ -763,7 +504,7 @@ function useZoneClampedAlign(open, contentWidth, contentHeight, rotation = 0) {
|
|
|
763
504
|
}
|
|
764
505
|
|
|
765
506
|
// src/PlayerSetupPanel.tsx
|
|
766
|
-
import { jsx as
|
|
507
|
+
import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
767
508
|
function getColorPopoverId(idPrefix) {
|
|
768
509
|
return `${idPrefix}-color`;
|
|
769
510
|
}
|
|
@@ -786,16 +527,16 @@ function PlayerSetupPanel({ idPrefix, host, label, labelFontFamily, color, onCol
|
|
|
786
527
|
const seatPickerId = showProfilePicker ? getProfilePopoverId(idPrefix) : getCpuDifficultyPopoverId(idPrefix);
|
|
787
528
|
const seatPickerSize = showProfilePicker ? getProfilePickerContentSize(profiles.length, !!onManageProfiles, colorSection) : getOptionPickerContentSize(cpuDifficultyOptions?.length ?? 0, colorSection);
|
|
788
529
|
const seatPickerAlign = useZoneClampedAlign(seatButton && popover.openId === seatPickerId, seatPickerSize.width, seatPickerSize.height);
|
|
789
|
-
return /* @__PURE__ */
|
|
790
|
-
showProfilePicker ? /* @__PURE__ */
|
|
791
|
-
(!seatButton || secondPicker) && /* @__PURE__ */
|
|
792
|
-
!seatButton && /* @__PURE__ */
|
|
530
|
+
return /* @__PURE__ */ jsxs5(View5, { style: [styles6.panel, ownPopoverOpen && styles6.panelOpen], children: [
|
|
531
|
+
showProfilePicker ? /* @__PURE__ */ jsx8(ProfilePicker, { idPrefix, host: popover, profiles, selectedId: selectedProfileId ?? null, takenId: takenProfileId, color, dark, guestLabel: guestLabel ?? "GUEST", onSelect: (profile) => onProfileSelect?.(profile), onManage: onManageProfiles, colorSection, alignOverride: seatPickerAlign }) : showCpuDifficulty ? /* @__PURE__ */ jsx8(OptionPicker, { id: getCpuDifficultyPopoverId(idPrefix), host: popover, options: cpuDifficultyOptions, value: cpuDifficulty, onChange: onCpuDifficultyChange, color, dark, icon: cpuIcon, colorSection, alignOverride: seatPickerAlign }) : label && /* @__PURE__ */ jsx8(Text5, { variant: "labelSmall", style: { color, fontFamily: labelFontFamily }, children: label }),
|
|
532
|
+
(!seatButton || secondPicker) && /* @__PURE__ */ jsxs5(View5, { style: [styles6.pickerRow, pickerRowPopoverOpen && styles6.pickerRowOpen], children: [
|
|
533
|
+
!seatButton && /* @__PURE__ */ jsx8(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 }),
|
|
793
534
|
secondPicker
|
|
794
535
|
] }),
|
|
795
|
-
isHuman && showReadyButton && onToggleReady && /* @__PURE__ */
|
|
536
|
+
isHuman && showReadyButton && onToggleReady && /* @__PURE__ */ jsx8(ReadyButton, { color, ready: ready ?? false, onToggleReady })
|
|
796
537
|
] });
|
|
797
538
|
}
|
|
798
|
-
var
|
|
539
|
+
var styles6 = StyleSheet6.create({
|
|
799
540
|
panel: {
|
|
800
541
|
alignItems: "center",
|
|
801
542
|
gap: 12
|
|
@@ -826,30 +567,22 @@ var styles8 = StyleSheet8.create({
|
|
|
826
567
|
}
|
|
827
568
|
});
|
|
828
569
|
|
|
829
|
-
// src/PressAwayOverlay.tsx
|
|
830
|
-
import { Pressable, StyleSheet as StyleSheet9 } from "react-native";
|
|
831
|
-
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
832
|
-
function PressAwayOverlay({ active, onPress, style }) {
|
|
833
|
-
if (!active) return null;
|
|
834
|
-
return /* @__PURE__ */ jsx11(Pressable, { accessibilityLabel: "Dismiss", accessibilityRole: "button", onPress, style: [StyleSheet9.absoluteFill, style] });
|
|
835
|
-
}
|
|
836
|
-
|
|
837
570
|
// src/SharedActionBand.tsx
|
|
838
571
|
import { IconButton as IconButton2 } from "@rific/feedback-press";
|
|
839
|
-
import { StyleSheet as
|
|
840
|
-
import { jsx as
|
|
572
|
+
import { StyleSheet as StyleSheet7, View as View6 } from "react-native";
|
|
573
|
+
import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
841
574
|
function SharedActionBand({ onBack, onSettings, onRandomize, onReset, fg, popoverOpen, children }) {
|
|
842
|
-
return /* @__PURE__ */
|
|
843
|
-
/* @__PURE__ */
|
|
844
|
-
/* @__PURE__ */
|
|
845
|
-
onRandomize && /* @__PURE__ */
|
|
846
|
-
onReset && /* @__PURE__ */
|
|
847
|
-
/* @__PURE__ */
|
|
575
|
+
return /* @__PURE__ */ jsxs6(View6, { style: [styles7.column, popoverOpen && styles7.columnOpen], children: [
|
|
576
|
+
/* @__PURE__ */ jsxs6(View6, { style: styles7.actionsRow, children: [
|
|
577
|
+
/* @__PURE__ */ jsx9(IconButton2, { icon: "arrow-left", iconColor: fg, size: 20, onPress: onBack, accessibilityLabel: "Back" }),
|
|
578
|
+
onRandomize && /* @__PURE__ */ jsx9(IconButton2, { icon: "dice-multiple", iconColor: fg, size: 18, onPress: onRandomize, accessibilityLabel: "Randomize match settings" }),
|
|
579
|
+
onReset && /* @__PURE__ */ jsx9(IconButton2, { icon: "restore", iconColor: fg, size: 18, onPress: onReset, accessibilityLabel: "Reset match settings to defaults" }),
|
|
580
|
+
/* @__PURE__ */ jsx9(IconButton2, { icon: "cog", iconColor: fg, size: 20, onPress: onSettings, accessibilityLabel: "Settings" })
|
|
848
581
|
] }),
|
|
849
582
|
children
|
|
850
583
|
] });
|
|
851
584
|
}
|
|
852
|
-
var
|
|
585
|
+
var styles7 = StyleSheet7.create({
|
|
853
586
|
actionsRow: {
|
|
854
587
|
alignItems: "center",
|
|
855
588
|
flexDirection: "row",
|
|
@@ -865,22 +598,22 @@ var styles9 = StyleSheet10.create({
|
|
|
865
598
|
});
|
|
866
599
|
|
|
867
600
|
// src/useQuitConfirmation.ts
|
|
868
|
-
import { useCallback
|
|
601
|
+
import { useCallback, useEffect as useEffect2, useRef, useState as useState2 } from "react";
|
|
869
602
|
function useQuitConfirmation(hasProgress, onConfirmedBack) {
|
|
870
|
-
const [confirmVisible, setConfirmVisible] =
|
|
871
|
-
const hasProgressRef =
|
|
872
|
-
|
|
603
|
+
const [confirmVisible, setConfirmVisible] = useState2(false);
|
|
604
|
+
const hasProgressRef = useRef(hasProgress);
|
|
605
|
+
useEffect2(() => {
|
|
873
606
|
hasProgressRef.current = hasProgress;
|
|
874
607
|
});
|
|
875
|
-
const onConfirmedBackRef =
|
|
876
|
-
|
|
608
|
+
const onConfirmedBackRef = useRef(onConfirmedBack);
|
|
609
|
+
useEffect2(() => {
|
|
877
610
|
onConfirmedBackRef.current = onConfirmedBack;
|
|
878
611
|
});
|
|
879
|
-
const requestBack =
|
|
612
|
+
const requestBack = useCallback(() => {
|
|
880
613
|
if (hasProgressRef.current()) setConfirmVisible(true);
|
|
881
614
|
else onConfirmedBackRef.current();
|
|
882
615
|
}, []);
|
|
883
|
-
const cancelBack =
|
|
616
|
+
const cancelBack = useCallback(() => setConfirmVisible(false), []);
|
|
884
617
|
return { confirmVisible, requestBack, cancelBack };
|
|
885
618
|
}
|
|
886
619
|
export {
|
|
@@ -911,7 +644,6 @@ export {
|
|
|
911
644
|
RotatedFrame,
|
|
912
645
|
SectionedDropdown,
|
|
913
646
|
SharedActionBand,
|
|
914
|
-
SkiaGate,
|
|
915
647
|
StaggeredWord,
|
|
916
648
|
StatRow,
|
|
917
649
|
StatSection,
|
|
@@ -926,6 +658,7 @@ export {
|
|
|
926
658
|
getStaggeredWordDuration,
|
|
927
659
|
isCompactDialogHeight,
|
|
928
660
|
loadSkiaWeb,
|
|
661
|
+
locateSkiaWebFile,
|
|
929
662
|
overlayActionStyles,
|
|
930
663
|
overlayStyles,
|
|
931
664
|
useAutoAlign,
|