@tastic/hud 0.22.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -14
- 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-N7A7W72S.mjs → chunk-BXG44LIA.mjs} +298 -19
- package/dist/index.d.mts +12 -81
- package/dist/index.d.ts +12 -81
- package/dist/index.js +27 -24
- package/dist/index.mjs +100 -364
- package/package.json +3 -2
- package/src/BaseSettingsDialog.tsx +13 -13
- package/src/chrome/index.ts +12 -4
package/dist/index.mjs
CHANGED
|
@@ -10,18 +10,24 @@ import {
|
|
|
10
10
|
ConfirmDialog,
|
|
11
11
|
ContentGutter,
|
|
12
12
|
CornerActionButtons,
|
|
13
|
+
InlineColorPicker,
|
|
13
14
|
LOCKED_BADGE_COLOR,
|
|
14
15
|
MONO_FONT,
|
|
16
|
+
PopoverBody,
|
|
17
|
+
PressAwayOverlay,
|
|
15
18
|
RotatedFrame,
|
|
16
19
|
StaggeredWord,
|
|
17
20
|
StatRow,
|
|
18
21
|
StatSection,
|
|
19
22
|
UpdateDialog,
|
|
20
23
|
WELL_SHADOW,
|
|
24
|
+
getInlineColorPickerContentSize,
|
|
21
25
|
getStaggeredWordDuration,
|
|
26
|
+
useAutoAlign,
|
|
22
27
|
useCompactDialog,
|
|
28
|
+
usePopoverHost,
|
|
23
29
|
useWellColors
|
|
24
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-BXG44LIA.mjs";
|
|
25
31
|
import {
|
|
26
32
|
COMPACT_DIALOG_HEIGHT,
|
|
27
33
|
DialogHeader,
|
|
@@ -85,132 +91,18 @@ import { Platform } from "react-native";
|
|
|
85
91
|
import { getBlendedColor, getColorRoles } from "@rific/auto-paper";
|
|
86
92
|
import { IconButton, TouchableRipple } from "@rific/feedback-press";
|
|
87
93
|
import { useRotation } from "@tastic/core";
|
|
88
|
-
import { ScrollView, StyleSheet as
|
|
94
|
+
import { ScrollView, StyleSheet as StyleSheet2, View as View2 } from "react-native";
|
|
89
95
|
import { Icon as Icon2, Text as Text2 } from "react-native-paper";
|
|
90
96
|
|
|
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
97
|
// src/TriggerGaugeHost.tsx
|
|
158
|
-
import { jsx as
|
|
98
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
159
99
|
var getTriggerGauge = () => import("./TriggerGauge-GIHKGAZE.mjs").then((mod) => ({ default: mod.TriggerGauge }));
|
|
160
100
|
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 };
|
|
101
|
+
return /* @__PURE__ */ jsx2(SkiaGate, { getComponent: getTriggerGauge, componentProps: props });
|
|
210
102
|
}
|
|
211
103
|
|
|
212
104
|
// src/SectionedDropdown.tsx
|
|
213
|
-
import { Fragment
|
|
105
|
+
import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
214
106
|
var MENU_BORDER_WIDTH = 1;
|
|
215
107
|
var TRIGGER_SIZE = 44;
|
|
216
108
|
var MENU_MIN_WIDTH = 200;
|
|
@@ -260,17 +152,17 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
|
|
|
260
152
|
}
|
|
261
153
|
gaugeOffset += section.options.length;
|
|
262
154
|
}
|
|
263
|
-
const anchorStyle = [
|
|
155
|
+
const anchorStyle = [styles2.anchor, open && styles2.anchorOpen];
|
|
264
156
|
const menuStyle = { backgroundColor: menuBg, borderColor: menuBorderColor, maxHeight };
|
|
265
157
|
const dividerStyle = { backgroundColor: menuBorderColor };
|
|
266
|
-
return /* @__PURE__ */
|
|
267
|
-
/* @__PURE__ */
|
|
268
|
-
/* @__PURE__ */
|
|
269
|
-
/* @__PURE__ */
|
|
158
|
+
return /* @__PURE__ */ jsxs2(View2, { style: anchorStyle, children: [
|
|
159
|
+
/* @__PURE__ */ jsxs2(View2, { ref: triggerRef, collapsable: false, style: styles2.triggerBox, children: [
|
|
160
|
+
/* @__PURE__ */ jsx3(TriggerGaugeHost, { segments: gaugeSegments, litIndices: gaugeLitIndices, size: TRIGGER_SIZE, accentColor, mutedColor }),
|
|
161
|
+
/* @__PURE__ */ jsx3(IconButton, { icon: triggerIcon, iconColor: triggerIconColor, size: triggerIconSize, accessibilityLabel, onPress: () => host.toggle(id) })
|
|
270
162
|
] }),
|
|
271
|
-
/* @__PURE__ */
|
|
272
|
-
sectionIndex > 0 && /* @__PURE__ */
|
|
273
|
-
section.kind === "single" ? /* @__PURE__ */
|
|
163
|
+
/* @__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: [
|
|
164
|
+
sectionIndex > 0 && /* @__PURE__ */ jsx3(View2, { style: [styles2.divider, dividerStyle] }),
|
|
165
|
+
section.kind === "single" ? /* @__PURE__ */ jsx3(
|
|
274
166
|
SingleSection,
|
|
275
167
|
{
|
|
276
168
|
section,
|
|
@@ -283,7 +175,7 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
|
|
|
283
175
|
if (autoDismiss) host.close();
|
|
284
176
|
}
|
|
285
177
|
}
|
|
286
|
-
) : /* @__PURE__ */
|
|
178
|
+
) : /* @__PURE__ */ jsx3(MultiSection, { section, accentColor, onAccentColor: resolvedOnAccentColor, mutedColor, labelFontFamily, allClearLabels })
|
|
287
179
|
] }, section.id)) }) })
|
|
288
180
|
] });
|
|
289
181
|
}
|
|
@@ -295,18 +187,18 @@ function SingleSection({
|
|
|
295
187
|
labelFontFamily,
|
|
296
188
|
onSelect
|
|
297
189
|
}) {
|
|
298
|
-
return /* @__PURE__ */
|
|
190
|
+
return /* @__PURE__ */ jsx3(Fragment, { children: section.options.map((option) => {
|
|
299
191
|
const selected = option.value === section.value;
|
|
300
192
|
const taken = !selected && option.value === section.takenValue;
|
|
301
193
|
const rowColor = selected ? onAccentColor : mutedColor;
|
|
302
|
-
const itemStyle = [
|
|
194
|
+
const itemStyle = [styles2.item, selected && { backgroundColor: accentColor }, taken && styles2.itemTaken];
|
|
303
195
|
const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
|
|
304
196
|
const descriptionStyle = { fontFamily: labelFontFamily, color: rowColor };
|
|
305
|
-
return /* @__PURE__ */
|
|
306
|
-
option.icon && /* @__PURE__ */
|
|
307
|
-
/* @__PURE__ */
|
|
308
|
-
/* @__PURE__ */
|
|
309
|
-
option.description && /* @__PURE__ */
|
|
197
|
+
return /* @__PURE__ */ jsx3(TouchableRipple, { disabled: taken, onPress: () => onSelect(option.value), style: itemStyle, children: /* @__PURE__ */ jsxs2(View2, { style: styles2.itemRow, children: [
|
|
198
|
+
option.icon && /* @__PURE__ */ jsx3(Icon2, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
|
|
199
|
+
/* @__PURE__ */ jsxs2(View2, { style: styles2.itemLabelColumn, children: [
|
|
200
|
+
/* @__PURE__ */ jsx3(Text2, { variant: "labelLarge", style: labelStyle, children: option.label }),
|
|
201
|
+
option.description && /* @__PURE__ */ jsx3(Text2, { variant: "labelSmall", style: descriptionStyle, children: option.description })
|
|
310
202
|
] })
|
|
311
203
|
] }) }, option.value);
|
|
312
204
|
}) });
|
|
@@ -320,23 +212,23 @@ function MultiSection({
|
|
|
320
212
|
allClearLabels
|
|
321
213
|
}) {
|
|
322
214
|
const allSelected = section.value.length === section.options.length;
|
|
323
|
-
return /* @__PURE__ */
|
|
215
|
+
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
324
216
|
section.options.map((option, i) => {
|
|
325
217
|
const selected = section.value.includes(option.value);
|
|
326
218
|
const rowColor = selected ? onAccentColor : mutedColor;
|
|
327
219
|
const prevSelected = selected && i > 0 && section.value.includes(section.options[i - 1].value);
|
|
328
220
|
const nextSelected = selected && i < section.options.length - 1 && section.value.includes(section.options[i + 1].value);
|
|
329
|
-
const itemStyle = [
|
|
221
|
+
const itemStyle = [styles2.item, selected && { backgroundColor: accentColor }, prevSelected && { borderTopLeftRadius: 0, borderTopRightRadius: 0 }, nextSelected && { borderBottomLeftRadius: 0, borderBottomRightRadius: 0 }];
|
|
330
222
|
const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
|
|
331
|
-
return /* @__PURE__ */
|
|
332
|
-
option.icon && /* @__PURE__ */
|
|
333
|
-
/* @__PURE__ */
|
|
223
|
+
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: [
|
|
224
|
+
option.icon && /* @__PURE__ */ jsx3(Icon2, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
|
|
225
|
+
/* @__PURE__ */ jsx3(Text2, { variant: "labelLarge", style: [styles2.itemLabelFlex, labelStyle], children: option.label })
|
|
334
226
|
] }) }, option.value);
|
|
335
227
|
}),
|
|
336
|
-
section.allClear && /* @__PURE__ */
|
|
228
|
+
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
229
|
] });
|
|
338
230
|
}
|
|
339
|
-
var
|
|
231
|
+
var styles2 = StyleSheet2.create({
|
|
340
232
|
allClearLabel: {
|
|
341
233
|
fontWeight: "bold",
|
|
342
234
|
textAlign: "center"
|
|
@@ -353,7 +245,7 @@ var styles3 = StyleSheet3.create({
|
|
|
353
245
|
zIndex: 100
|
|
354
246
|
},
|
|
355
247
|
divider: {
|
|
356
|
-
height:
|
|
248
|
+
height: StyleSheet2.hairlineWidth,
|
|
357
249
|
marginVertical: 4
|
|
358
250
|
},
|
|
359
251
|
item: {
|
|
@@ -406,30 +298,30 @@ var styles3 = StyleSheet3.create({
|
|
|
406
298
|
});
|
|
407
299
|
|
|
408
300
|
// src/ControlSchemePicker.tsx
|
|
409
|
-
import { jsx as
|
|
301
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
410
302
|
function ControlSchemePicker({ id, host, value, onChange, options, takenValue, accentColor, mutedColor, onAccentColor, dark, align, alignOverride, rotation, labelFontFamily }) {
|
|
411
303
|
const isTouchPrimary = useIsTouchPrimaryDevice();
|
|
412
304
|
if (Platform.OS !== "web" || isTouchPrimary) return null;
|
|
413
|
-
return /* @__PURE__ */
|
|
305
|
+
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
306
|
}
|
|
415
307
|
|
|
416
308
|
// src/CornerStatusBadges.tsx
|
|
417
|
-
import { StyleSheet as
|
|
309
|
+
import { StyleSheet as StyleSheet3, View as View3 } from "react-native";
|
|
418
310
|
import { Icon as Icon3 } from "react-native-paper";
|
|
419
|
-
import { Fragment as
|
|
311
|
+
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
420
312
|
var BADGE_SIZE = 30;
|
|
421
313
|
function StatusBadge({ icon }) {
|
|
422
|
-
return /* @__PURE__ */
|
|
314
|
+
return /* @__PURE__ */ jsx5(View3, { style: styles3.badge, children: icon && /* @__PURE__ */ jsx5(Icon3, { source: icon, size: 16, color: "rgba(255,255,255,0.85)" }) });
|
|
423
315
|
}
|
|
424
316
|
function CornerStatusBadges({ orientationMode, p1OnRight, p1, p2 }) {
|
|
425
317
|
const p1OnRightSide = orientationMode === "sideBySide" && p1OnRight;
|
|
426
318
|
const p2OnLeftSide = orientationMode === "sideBySide" && !p1OnRight;
|
|
427
|
-
return /* @__PURE__ */
|
|
428
|
-
p1 && /* @__PURE__ */
|
|
429
|
-
p2 && /* @__PURE__ */
|
|
319
|
+
return /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
320
|
+
p1 && /* @__PURE__ */ jsx5(View3, { pointerEvents: "none", style: p1OnRightSide ? styles3.bottomRight : styles3.bottomLeft, children: /* @__PURE__ */ jsx5(StatusBadge, { icon: p1.icon }) }),
|
|
321
|
+
p2 && /* @__PURE__ */ jsx5(View3, { pointerEvents: "none", style: p2OnLeftSide ? styles3.topLeft : styles3.topRight, children: /* @__PURE__ */ jsx5(StatusBadge, { icon: p2.icon }) })
|
|
430
322
|
] });
|
|
431
323
|
}
|
|
432
|
-
var
|
|
324
|
+
var styles3 = StyleSheet3.create({
|
|
433
325
|
badge: {
|
|
434
326
|
alignItems: "center",
|
|
435
327
|
backgroundColor: "rgba(0,0,0,0.28)",
|
|
@@ -447,149 +339,12 @@ var styles4 = StyleSheet4.create({
|
|
|
447
339
|
topRight: { position: "absolute", right: 12, top: 12 }
|
|
448
340
|
});
|
|
449
341
|
|
|
450
|
-
// src/
|
|
451
|
-
import {
|
|
342
|
+
// src/LabeledDropdown.tsx
|
|
343
|
+
import { getContrastColor as getContrastColor2 } from "@rific/auto-paper";
|
|
452
344
|
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";
|
|
345
|
+
import { ScrollView as ScrollView2, StyleSheet as StyleSheet4, View as View4 } from "react-native";
|
|
455
346
|
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";
|
|
347
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
593
348
|
var TRIGGER_HEIGHT = 28;
|
|
594
349
|
var POPOVER_WIDTH = 180;
|
|
595
350
|
var ROW_HEIGHT = 36;
|
|
@@ -612,22 +367,22 @@ function LabeledDropdown({ id, host, options, value, onChange, color, dark, alig
|
|
|
612
367
|
onChange(option.value);
|
|
613
368
|
host.close();
|
|
614
369
|
};
|
|
615
|
-
return /* @__PURE__ */
|
|
616
|
-
/* @__PURE__ */
|
|
617
|
-
/* @__PURE__ */
|
|
618
|
-
/* @__PURE__ */
|
|
370
|
+
return /* @__PURE__ */ jsxs4(View4, { style: [styles4.anchor, open && styles4.anchorOpen], children: [
|
|
371
|
+
/* @__PURE__ */ jsx6(TouchableRipple2, { onPress: () => host.toggle(id), style: styles4.trigger, children: /* @__PURE__ */ jsxs4(View4, { ref: triggerRef, collapsable: false, style: styles4.triggerInner, children: [
|
|
372
|
+
/* @__PURE__ */ jsx6(Text3, { style: [styles4.triggerLabel, { color }], numberOfLines: 1, children: (selected?.label ?? "").toUpperCase() }),
|
|
373
|
+
/* @__PURE__ */ jsx6(Icon4, { source: "menu-down", size: 16, color })
|
|
619
374
|
] }) }),
|
|
620
|
-
/* @__PURE__ */
|
|
375
|
+
/* @__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
376
|
const isSelected = option.value === value;
|
|
622
|
-
const onColor =
|
|
623
|
-
return /* @__PURE__ */
|
|
624
|
-
option.icon && /* @__PURE__ */
|
|
625
|
-
/* @__PURE__ */
|
|
377
|
+
const onColor = getContrastColor2(color);
|
|
378
|
+
return /* @__PURE__ */ jsx6(TouchableRipple2, { onPress: () => handleSelect(option), style: [styles4.row, isSelected && { backgroundColor: color }], children: /* @__PURE__ */ jsxs4(View4, { style: styles4.rowInner, children: [
|
|
379
|
+
option.icon && /* @__PURE__ */ jsx6(Icon4, { source: option.icon, size: 18, color: isSelected ? onColor : fg }),
|
|
380
|
+
/* @__PURE__ */ jsx6(Text3, { style: [styles4.rowLabel, { color: isSelected ? onColor : fg }], numberOfLines: 1, children: option.label })
|
|
626
381
|
] }) }, option.value);
|
|
627
382
|
}) }) })
|
|
628
383
|
] });
|
|
629
384
|
}
|
|
630
|
-
var
|
|
385
|
+
var styles4 = StyleSheet4.create({
|
|
631
386
|
anchor: {
|
|
632
387
|
position: "relative"
|
|
633
388
|
},
|
|
@@ -686,21 +441,21 @@ function loadSkiaWeb() {
|
|
|
686
441
|
|
|
687
442
|
// src/PlayerSetupPanel.tsx
|
|
688
443
|
import { getOptionPickerContentSize, getProfilePickerContentSize, OptionPicker, ProfilePicker } from "@tastic/profile";
|
|
689
|
-
import { StyleSheet as
|
|
690
|
-
import { Text as
|
|
444
|
+
import { StyleSheet as StyleSheet6, View as View5 } from "react-native";
|
|
445
|
+
import { Text as Text5 } from "react-native-paper";
|
|
691
446
|
|
|
692
447
|
// src/ReadyButton.tsx
|
|
693
|
-
import { TouchableRipple as
|
|
694
|
-
import { StyleSheet as
|
|
695
|
-
import { Text as
|
|
696
|
-
import { jsx as
|
|
448
|
+
import { TouchableRipple as TouchableRipple3 } from "@rific/feedback-press";
|
|
449
|
+
import { StyleSheet as StyleSheet5 } from "react-native";
|
|
450
|
+
import { Text as Text4 } from "react-native-paper";
|
|
451
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
697
452
|
function ReadyButton({ color, ready, onToggleReady, style, labelFontFamily = MONO_FONT }) {
|
|
698
|
-
const readyButtonStyle = [
|
|
453
|
+
const readyButtonStyle = [styles5.readyButton, { borderColor: color }, ready && { backgroundColor: color }, style];
|
|
699
454
|
const labelTextStyle = { fontFamily: labelFontFamily, fontWeight: "bold" };
|
|
700
455
|
const labelColorStyle = { color: ready ? "#000000" : color };
|
|
701
|
-
return /* @__PURE__ */
|
|
456
|
+
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
457
|
}
|
|
703
|
-
var
|
|
458
|
+
var styles5 = StyleSheet5.create({
|
|
704
459
|
readyButton: {
|
|
705
460
|
alignItems: "center",
|
|
706
461
|
borderRadius: 12,
|
|
@@ -712,41 +467,30 @@ var styles7 = StyleSheet7.create({
|
|
|
712
467
|
}
|
|
713
468
|
});
|
|
714
469
|
|
|
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
470
|
// src/useZoneClampedAlign.ts
|
|
727
471
|
import { useZoneBounds } from "@tastic/split-screen";
|
|
728
|
-
import { useEffect
|
|
729
|
-
import { useWindowDimensions
|
|
472
|
+
import { useEffect, useState } from "react";
|
|
473
|
+
import { useWindowDimensions } from "react-native";
|
|
730
474
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
731
|
-
var
|
|
475
|
+
var EDGE_MARGIN = 12;
|
|
732
476
|
function useZoneClampedAlign(open, contentWidth, contentHeight, rotation = 0) {
|
|
733
477
|
const auto = useAutoAlign(open, contentWidth, contentHeight, rotation);
|
|
734
478
|
const zone = useZoneBounds();
|
|
735
|
-
const { height: windowHeight } =
|
|
479
|
+
const { height: windowHeight } = useWindowDimensions();
|
|
736
480
|
const insets = useSafeAreaInsets();
|
|
737
481
|
const shouldMeasure = open && auto.measured && zone !== null;
|
|
738
|
-
const [ownBounds, setOwnBounds] =
|
|
739
|
-
const [prevShouldMeasure, setPrevShouldMeasure] =
|
|
482
|
+
const [ownBounds, setOwnBounds] = useState(null);
|
|
483
|
+
const [prevShouldMeasure, setPrevShouldMeasure] = useState(shouldMeasure);
|
|
740
484
|
if (shouldMeasure !== prevShouldMeasure) {
|
|
741
485
|
setPrevShouldMeasure(shouldMeasure);
|
|
742
486
|
setOwnBounds(null);
|
|
743
487
|
}
|
|
744
|
-
|
|
488
|
+
useEffect(() => {
|
|
745
489
|
if (!shouldMeasure) return;
|
|
746
490
|
auto.triggerRef.current?.measureInWindow((_x, y, _width, height) => {
|
|
747
491
|
const belowShared = zone.zoneSide === "belowShared";
|
|
748
|
-
const awayRoom = belowShared ? windowHeight - insets.bottom - (y + height) -
|
|
749
|
-
const towardRoom = belowShared ? y - zone.sharedEdgeY -
|
|
492
|
+
const awayRoom = belowShared ? windowHeight - insets.bottom - (y + height) - EDGE_MARGIN : y - insets.top - EDGE_MARGIN;
|
|
493
|
+
const towardRoom = belowShared ? y - zone.sharedEdgeY - EDGE_MARGIN : zone.sharedEdgeY - (y + height) - EDGE_MARGIN;
|
|
750
494
|
const useToward = contentHeight > awayRoom && towardRoom > awayRoom;
|
|
751
495
|
let awaySide = belowShared ? "below" : "above";
|
|
752
496
|
let towardSide = belowShared ? "above" : "below";
|
|
@@ -763,7 +507,7 @@ function useZoneClampedAlign(open, contentWidth, contentHeight, rotation = 0) {
|
|
|
763
507
|
}
|
|
764
508
|
|
|
765
509
|
// src/PlayerSetupPanel.tsx
|
|
766
|
-
import { jsx as
|
|
510
|
+
import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
767
511
|
function getColorPopoverId(idPrefix) {
|
|
768
512
|
return `${idPrefix}-color`;
|
|
769
513
|
}
|
|
@@ -786,16 +530,16 @@ function PlayerSetupPanel({ idPrefix, host, label, labelFontFamily, color, onCol
|
|
|
786
530
|
const seatPickerId = showProfilePicker ? getProfilePopoverId(idPrefix) : getCpuDifficultyPopoverId(idPrefix);
|
|
787
531
|
const seatPickerSize = showProfilePicker ? getProfilePickerContentSize(profiles.length, !!onManageProfiles, colorSection) : getOptionPickerContentSize(cpuDifficultyOptions?.length ?? 0, colorSection);
|
|
788
532
|
const seatPickerAlign = useZoneClampedAlign(seatButton && popover.openId === seatPickerId, seatPickerSize.width, seatPickerSize.height);
|
|
789
|
-
return /* @__PURE__ */
|
|
790
|
-
showProfilePicker ? /* @__PURE__ */
|
|
791
|
-
(!seatButton || secondPicker) && /* @__PURE__ */
|
|
792
|
-
!seatButton && /* @__PURE__ */
|
|
533
|
+
return /* @__PURE__ */ jsxs5(View5, { style: [styles6.panel, ownPopoverOpen && styles6.panelOpen], children: [
|
|
534
|
+
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 }),
|
|
535
|
+
(!seatButton || secondPicker) && /* @__PURE__ */ jsxs5(View5, { style: [styles6.pickerRow, pickerRowPopoverOpen && styles6.pickerRowOpen], children: [
|
|
536
|
+
!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
537
|
secondPicker
|
|
794
538
|
] }),
|
|
795
|
-
isHuman && showReadyButton && onToggleReady && /* @__PURE__ */
|
|
539
|
+
isHuman && showReadyButton && onToggleReady && /* @__PURE__ */ jsx8(ReadyButton, { color, ready: ready ?? false, onToggleReady })
|
|
796
540
|
] });
|
|
797
541
|
}
|
|
798
|
-
var
|
|
542
|
+
var styles6 = StyleSheet6.create({
|
|
799
543
|
panel: {
|
|
800
544
|
alignItems: "center",
|
|
801
545
|
gap: 12
|
|
@@ -826,30 +570,22 @@ var styles8 = StyleSheet8.create({
|
|
|
826
570
|
}
|
|
827
571
|
});
|
|
828
572
|
|
|
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
573
|
// src/SharedActionBand.tsx
|
|
838
574
|
import { IconButton as IconButton2 } from "@rific/feedback-press";
|
|
839
|
-
import { StyleSheet as
|
|
840
|
-
import { jsx as
|
|
575
|
+
import { StyleSheet as StyleSheet7, View as View6 } from "react-native";
|
|
576
|
+
import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
841
577
|
function SharedActionBand({ onBack, onSettings, onRandomize, onReset, fg, popoverOpen, children }) {
|
|
842
|
-
return /* @__PURE__ */
|
|
843
|
-
/* @__PURE__ */
|
|
844
|
-
/* @__PURE__ */
|
|
845
|
-
onRandomize && /* @__PURE__ */
|
|
846
|
-
onReset && /* @__PURE__ */
|
|
847
|
-
/* @__PURE__ */
|
|
578
|
+
return /* @__PURE__ */ jsxs6(View6, { style: [styles7.column, popoverOpen && styles7.columnOpen], children: [
|
|
579
|
+
/* @__PURE__ */ jsxs6(View6, { style: styles7.actionsRow, children: [
|
|
580
|
+
/* @__PURE__ */ jsx9(IconButton2, { icon: "arrow-left", iconColor: fg, size: 20, onPress: onBack, accessibilityLabel: "Back" }),
|
|
581
|
+
onRandomize && /* @__PURE__ */ jsx9(IconButton2, { icon: "dice-multiple", iconColor: fg, size: 18, onPress: onRandomize, accessibilityLabel: "Randomize match settings" }),
|
|
582
|
+
onReset && /* @__PURE__ */ jsx9(IconButton2, { icon: "restore", iconColor: fg, size: 18, onPress: onReset, accessibilityLabel: "Reset match settings to defaults" }),
|
|
583
|
+
/* @__PURE__ */ jsx9(IconButton2, { icon: "cog", iconColor: fg, size: 20, onPress: onSettings, accessibilityLabel: "Settings" })
|
|
848
584
|
] }),
|
|
849
585
|
children
|
|
850
586
|
] });
|
|
851
587
|
}
|
|
852
|
-
var
|
|
588
|
+
var styles7 = StyleSheet7.create({
|
|
853
589
|
actionsRow: {
|
|
854
590
|
alignItems: "center",
|
|
855
591
|
flexDirection: "row",
|
|
@@ -865,22 +601,22 @@ var styles9 = StyleSheet10.create({
|
|
|
865
601
|
});
|
|
866
602
|
|
|
867
603
|
// src/useQuitConfirmation.ts
|
|
868
|
-
import { useCallback
|
|
604
|
+
import { useCallback, useEffect as useEffect2, useRef, useState as useState2 } from "react";
|
|
869
605
|
function useQuitConfirmation(hasProgress, onConfirmedBack) {
|
|
870
|
-
const [confirmVisible, setConfirmVisible] =
|
|
871
|
-
const hasProgressRef =
|
|
872
|
-
|
|
606
|
+
const [confirmVisible, setConfirmVisible] = useState2(false);
|
|
607
|
+
const hasProgressRef = useRef(hasProgress);
|
|
608
|
+
useEffect2(() => {
|
|
873
609
|
hasProgressRef.current = hasProgress;
|
|
874
610
|
});
|
|
875
|
-
const onConfirmedBackRef =
|
|
876
|
-
|
|
611
|
+
const onConfirmedBackRef = useRef(onConfirmedBack);
|
|
612
|
+
useEffect2(() => {
|
|
877
613
|
onConfirmedBackRef.current = onConfirmedBack;
|
|
878
614
|
});
|
|
879
|
-
const requestBack =
|
|
615
|
+
const requestBack = useCallback(() => {
|
|
880
616
|
if (hasProgressRef.current()) setConfirmVisible(true);
|
|
881
617
|
else onConfirmedBackRef.current();
|
|
882
618
|
}, []);
|
|
883
|
-
const cancelBack =
|
|
619
|
+
const cancelBack = useCallback(() => setConfirmVisible(false), []);
|
|
884
620
|
return { confirmVisible, requestBack, cancelBack };
|
|
885
621
|
}
|
|
886
622
|
export {
|