@tastic/shell 0.6.0 → 0.7.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 +8 -8
- package/dist/index.d.mts +9 -6
- package/dist/index.d.ts +9 -6
- package/dist/index.js +142 -126
- package/dist/index.mjs +115 -99
- package/package.json +8 -8
- package/src/components/MatchChips.tsx +12 -12
- package/src/components/OpponentPicker.tsx +112 -0
- package/src/hooks/useAtComputer.ts +13 -0
- package/src/index.ts +2 -1
- package/src/redux/opponentSlice.ts +1 -1
- package/src/screens/HomeScreen.tsx +1 -1
- package/src/screens/LoadoutScreen.tsx +86 -37
- package/src/types.ts +11 -4
- package/src/components/SeatTwoPanel.tsx +0 -144
package/dist/index.js
CHANGED
|
@@ -35,7 +35,6 @@ __export(index_exports, {
|
|
|
35
35
|
GUEST_PLAYER_ID: () => GUEST_PLAYER_ID,
|
|
36
36
|
HomeScreen: () => HomeScreen,
|
|
37
37
|
LoadoutRoute: () => LoadoutRoute,
|
|
38
|
-
MATCH_CHIPS_DESKTOP_MIN_WIDTH: () => MATCH_CHIPS_DESKTOP_MIN_WIDTH,
|
|
39
38
|
MATCH_CHIPS_FADE_MS: () => MATCH_CHIPS_FADE_MS,
|
|
40
39
|
MatchChips: () => MatchChips,
|
|
41
40
|
PREVIEW_ASPECT: () => PREVIEW_ASPECT,
|
|
@@ -67,12 +66,13 @@ __export(index_exports, {
|
|
|
67
66
|
profileSelectionActions: () => profileSelectionActions,
|
|
68
67
|
profileSelectionReducer: () => profileSelectionSlice_default,
|
|
69
68
|
roundModeFor: () => roundModeFor,
|
|
70
|
-
safeBack: () =>
|
|
69
|
+
safeBack: () => import_core8.safeBack,
|
|
71
70
|
seatColorsActions: () => seatColorsActions,
|
|
72
71
|
seatPlayerKey: () => seatPlayerKey,
|
|
73
72
|
seatTwoFor: () => seatTwoFor,
|
|
74
73
|
useActiveRound: () => useActiveRound,
|
|
75
74
|
useAppSettings: () => useAppSettings,
|
|
75
|
+
useAtComputer: () => useAtComputer,
|
|
76
76
|
useGameGuide: () => useGameGuide,
|
|
77
77
|
useOpponent: () => useOpponent,
|
|
78
78
|
usePack: () => usePack,
|
|
@@ -525,7 +525,7 @@ var styles = import_react_native2.StyleSheet.create({
|
|
|
525
525
|
// src/screens/GameRoute.tsx
|
|
526
526
|
var import_expo_router5 = require("expo-router");
|
|
527
527
|
var import_react14 = require("react");
|
|
528
|
-
var
|
|
528
|
+
var import_react_native6 = require("react-native");
|
|
529
529
|
|
|
530
530
|
// src/routes.ts
|
|
531
531
|
var playHref = (game) => ({ pathname: "/play/[game]", params: { game } });
|
|
@@ -535,91 +535,66 @@ var PROFILES_HREF = "/profiles";
|
|
|
535
535
|
|
|
536
536
|
// src/screens/LoadoutScreen.tsx
|
|
537
537
|
var import_auto_paper4 = require("@rific/auto-paper");
|
|
538
|
-
var
|
|
538
|
+
var import_core10 = require("@tastic/core");
|
|
539
539
|
var import_chrome4 = require("@tastic/hud/chrome");
|
|
540
540
|
var import_lobby2 = require("@tastic/hud/lobby");
|
|
541
541
|
var import_split_screen = require("@tastic/split-screen");
|
|
542
542
|
var import_expo_router4 = require("expo-router");
|
|
543
543
|
var import_react13 = require("react");
|
|
544
|
-
var
|
|
544
|
+
var import_react_native5 = require("react-native");
|
|
545
545
|
var import_react_native_reanimated2 = __toESM(require("react-native-reanimated"));
|
|
546
546
|
var import_react_native_safe_area_context2 = require("react-native-safe-area-context");
|
|
547
547
|
var import_react_redux9 = require("react-redux");
|
|
548
548
|
|
|
549
|
-
// src/components/
|
|
549
|
+
// src/components/OpponentPicker.tsx
|
|
550
550
|
var import_lobby = require("@tastic/hud/lobby");
|
|
551
551
|
var import_profile4 = require("@tastic/profile");
|
|
552
552
|
var import_react9 = require("react");
|
|
553
553
|
var import_react_native3 = require("react-native");
|
|
554
554
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
555
555
|
var CPU_PREFIX = "cpu:";
|
|
556
|
-
var PROFILE_PREFIX = "profile:";
|
|
557
556
|
var NOBODY = "nobody";
|
|
558
|
-
var
|
|
559
|
-
var
|
|
557
|
+
var PERSON = "person";
|
|
558
|
+
var PERSON_ICON = "account-outline";
|
|
560
559
|
var NOBODY_ICON = "account-off-outline";
|
|
561
560
|
var CPU_ICON = "robot";
|
|
562
|
-
function
|
|
563
|
-
return `${idPrefix}-
|
|
561
|
+
function getOpponentPopoverId(idPrefix) {
|
|
562
|
+
return `${idPrefix}-opponent`;
|
|
564
563
|
}
|
|
565
|
-
function
|
|
566
|
-
const isPerson = seatTwo === "person";
|
|
564
|
+
function OpponentPicker({ idPrefix, host, choices, seatTwo, onSeatTwoChange, cpuDifficulty, color, onColorChange, swatches, takenColor, allowSwapTaken, dark, previewValue, triggerStyle, usePickerAlign }) {
|
|
567
565
|
const drawn = previewValue ? previewValue(color) : color;
|
|
568
|
-
const selectedProfile = isPerson ? profiles.find((p) => p.id === selectedProfileId) ?? null : null;
|
|
569
566
|
const cpuOptions = cpuDifficulty?.options;
|
|
570
567
|
const options = (0, import_react9.useMemo)(() => {
|
|
571
568
|
const list = [];
|
|
572
569
|
if (choices.includes("cpu")) list.push(...cpuOptions ? cpuOptions.map((o) => ({ value: `${CPU_PREFIX}${o.value}`, label: o.label, icon: o.icon })) : [{ value: CPU_PREFIX, label: "CPU", icon: CPU_ICON }]);
|
|
573
|
-
if (choices.includes("nobody")) list.push({ value: NOBODY, label: "
|
|
574
|
-
if (choices.includes("person")) {
|
|
575
|
-
list.push({ value: GUEST, label: "Player 2", icon: GUEST_ICON });
|
|
576
|
-
list.push(...[...profiles].sort((a, b) => a.name.localeCompare(b.name)).map((p) => ({ value: `${PROFILE_PREFIX}${p.id}`, label: p.name, icon: "account", color: previewValue ? previewValue(p.color) : p.color })));
|
|
577
|
-
}
|
|
570
|
+
if (choices.includes("nobody")) list.push({ value: NOBODY, label: "Solo", icon: NOBODY_ICON, dividerBefore: true });
|
|
571
|
+
if (choices.includes("person")) list.push({ value: PERSON, label: "Player", icon: PERSON_ICON, dividerBefore: true });
|
|
578
572
|
return list;
|
|
579
|
-
}, [choices, cpuOptions
|
|
580
|
-
const value = seatTwo === "cpu" ? `${CPU_PREFIX}${cpuDifficulty?.value ?? ""}` : seatTwo === "nobody" ? NOBODY :
|
|
581
|
-
const icon = seatTwo === "cpu" ? CPU_ICON : seatTwo === "nobody" ? NOBODY_ICON :
|
|
573
|
+
}, [choices, cpuOptions]);
|
|
574
|
+
const value = seatTwo === "cpu" ? `${CPU_PREFIX}${cpuDifficulty?.value ?? ""}` : seatTwo === "nobody" ? NOBODY : PERSON;
|
|
575
|
+
const icon = seatTwo === "cpu" ? CPU_ICON : seatTwo === "nobody" ? NOBODY_ICON : PERSON_ICON;
|
|
582
576
|
const handleChange = (next) => {
|
|
583
577
|
if (next.startsWith(CPU_PREFIX)) {
|
|
584
578
|
cpuDifficulty?.onChange(next.slice(CPU_PREFIX.length));
|
|
585
579
|
onSeatTwoChange("cpu");
|
|
586
|
-
} else if (next === NOBODY) {
|
|
587
|
-
onSeatTwoChange("nobody");
|
|
588
580
|
} else {
|
|
589
|
-
|
|
590
|
-
onSeatTwoChange("person");
|
|
581
|
+
onSeatTwoChange(next === NOBODY ? "nobody" : "person");
|
|
591
582
|
}
|
|
592
583
|
};
|
|
593
|
-
const colorSection = seatTwo === "
|
|
594
|
-
const pickerId =
|
|
595
|
-
const size = (0, import_profile4.getOptionPickerContentSize)(options
|
|
584
|
+
const colorSection = seatTwo === "cpu" ? { value: color, onChange: onColorChange, swatches, takenValue: takenColor, allowSwapTaken, previewValue } : void 0;
|
|
585
|
+
const pickerId = getOpponentPopoverId(idPrefix);
|
|
586
|
+
const size = (0, import_profile4.getOptionPickerContentSize)(options, colorSection);
|
|
596
587
|
const useAlign = usePickerAlign ?? import_lobby.useZoneClampedAlign;
|
|
597
588
|
const align = useAlign(host.openId === pickerId, size.width, size.height);
|
|
598
|
-
|
|
599
|
-
const pickerRowOpen = secondPickerId !== void 0 && host.openId === secondPickerId;
|
|
600
|
-
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native3.View, { style: [styles2.panel, ownPopoverOpen && styles2.panelOpen], children: [
|
|
601
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_profile4.OptionPicker, { id: pickerId, host, options, value, onChange: handleChange, color: drawn, dark, icon, colorSection, alignOverride: align, triggerStyle }),
|
|
602
|
-
isPerson && secondPicker && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native3.View, { style: [styles2.pickerRow, pickerRowOpen && styles2.pickerRowOpen], children: secondPicker }),
|
|
603
|
-
isPerson && showReadyButton && onToggleReady && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lobby.ReadyButton, { color: drawn, ready: ready ?? false, onToggleReady })
|
|
604
|
-
] });
|
|
589
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native3.View, { style: [styles2.button, host.openId === pickerId && styles2.buttonOpen], children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_profile4.OptionPicker, { id: pickerId, host, options, value, onChange: handleChange, color: drawn, dark, icon, colorSection, alignOverride: align, triggerStyle }) });
|
|
605
590
|
}
|
|
606
591
|
var styles2 = import_react_native3.StyleSheet.create({
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
},
|
|
611
|
-
// A popover escaping this panel needs the panel itself elevated to paint above a later sibling.
|
|
612
|
-
panelOpen: {
|
|
613
|
-
zIndex: 100
|
|
614
|
-
},
|
|
615
|
-
pickerRow: {
|
|
616
|
-
alignItems: "center",
|
|
617
|
-
flexDirection: "row",
|
|
618
|
-
gap: 12
|
|
592
|
+
// Its own column, so a row of seat buttons doesn't stretch the pill to the tallest of them.
|
|
593
|
+
button: {
|
|
594
|
+
alignItems: "center"
|
|
619
595
|
},
|
|
620
|
-
//
|
|
621
|
-
|
|
622
|
-
pickerRowOpen: {
|
|
596
|
+
// A popover escaping this button needs the button itself elevated to paint above a later sibling.
|
|
597
|
+
buttonOpen: {
|
|
623
598
|
zIndex: 100
|
|
624
599
|
}
|
|
625
600
|
});
|
|
@@ -671,14 +646,22 @@ function SettingsDialog({ visible, onDismiss, onShowHowToPlay, children }) {
|
|
|
671
646
|
] });
|
|
672
647
|
}
|
|
673
648
|
|
|
649
|
+
// src/hooks/useAtComputer.ts
|
|
650
|
+
var import_core6 = require("@tastic/core");
|
|
651
|
+
var import_react_native4 = require("react-native");
|
|
652
|
+
function useAtComputer() {
|
|
653
|
+
const touchPrimary = (0, import_core6.useIsTouchPrimaryDevice)();
|
|
654
|
+
return import_react_native4.Platform.OS === "web" && !touchPrimary;
|
|
655
|
+
}
|
|
656
|
+
|
|
674
657
|
// src/hooks/useOpponent.ts
|
|
675
658
|
var import_react11 = require("react");
|
|
676
659
|
var import_react_redux7 = require("react-redux");
|
|
677
660
|
|
|
678
661
|
// src/redux/opponentSlice.ts
|
|
679
|
-
var
|
|
662
|
+
var import_core7 = require("@rific/core");
|
|
680
663
|
var DEFAULT_OPPONENT = { seatTwo: "cpu" };
|
|
681
|
-
var { actions: actions4, reducer: reducer4 } = (0,
|
|
664
|
+
var { actions: actions4, reducer: reducer4 } = (0, import_core7.createSettingsSlice)("opponent", {
|
|
682
665
|
initialState: DEFAULT_OPPONENT
|
|
683
666
|
});
|
|
684
667
|
var opponentActions = actions4;
|
|
@@ -811,13 +794,13 @@ function useSeatColors(p2IsHuman) {
|
|
|
811
794
|
}
|
|
812
795
|
|
|
813
796
|
// src/navigation.ts
|
|
814
|
-
var
|
|
797
|
+
var import_core8 = require("@rific/core");
|
|
815
798
|
var import_expo_router3 = require("expo-router");
|
|
816
|
-
(0,
|
|
799
|
+
(0, import_core8.configureNavigation)({ router: import_expo_router3.router });
|
|
817
800
|
|
|
818
801
|
// src/redux/liveplaySlice.ts
|
|
819
|
-
var
|
|
820
|
-
var { actions: actions5, reducer: reducer5 } = (0,
|
|
802
|
+
var import_core9 = require("@rific/core");
|
|
803
|
+
var { actions: actions5, reducer: reducer5 } = (0, import_core9.createSettingsSlice)("liveplay", {
|
|
821
804
|
initialState: { activelyPlaying: false, activeRound: null }
|
|
822
805
|
});
|
|
823
806
|
var liveplayActions = actions5;
|
|
@@ -826,6 +809,8 @@ var liveplaySlice_default = reducer5;
|
|
|
826
809
|
// src/screens/LoadoutScreen.tsx
|
|
827
810
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
828
811
|
var PANEL_SWAP_FADE_MS = 180;
|
|
812
|
+
var P1_CONTROL_ID = "p1-control";
|
|
813
|
+
var P2_CONTROL_ID = "p2-control";
|
|
829
814
|
function LoadoutScreen({ game }) {
|
|
830
815
|
const pack = usePack();
|
|
831
816
|
const { seatTwo: savedSeatTwo, setSeatTwo } = useOpponent();
|
|
@@ -837,8 +822,10 @@ function LoadoutScreen({ game }) {
|
|
|
837
822
|
const loadout = game.useLoadout(mode);
|
|
838
823
|
const { openFor } = useGameGuide();
|
|
839
824
|
const { profiles, lastSelected, selectProfile } = useProfiles();
|
|
840
|
-
const { orientationMode } = (0,
|
|
841
|
-
const
|
|
825
|
+
const { orientationMode } = (0, import_core10.useOrientationState)();
|
|
826
|
+
const atComputer = useAtComputer();
|
|
827
|
+
const twoPlayerMode = game.sideBySideAtComputer && atComputer ? "sideBySide" : game.sideBySideWhenWide ? orientationMode : "faceToFace";
|
|
828
|
+
const panelMode = p2IsHuman ? twoPlayerMode : orientationMode;
|
|
842
829
|
const { panelLayout, panelFadeStyle } = (0, import_split_screen.useDualZoneLayout)(panelMode, false, true, false, PANEL_SWAP_FADE_MS);
|
|
843
830
|
const playersRowFade = panelFadeStyle;
|
|
844
831
|
const [settingsOpen, setSettingsOpen] = (0, import_react13.useState)(false);
|
|
@@ -847,7 +834,7 @@ function LoadoutScreen({ game }) {
|
|
|
847
834
|
const { p1Color, p2Color, handleP1ColorChange, handleP2ColorChange } = useSeatColors(p2IsHuman);
|
|
848
835
|
const dispatch = (0, import_react_redux9.useDispatch)();
|
|
849
836
|
const handleP1ProfileSelect = (0, import_react13.useCallback)((profile) => selectProfile(1, profile?.id ?? null), [selectProfile]);
|
|
850
|
-
const handleP2ProfileSelect = (0, import_react13.useCallback)((
|
|
837
|
+
const handleP2ProfileSelect = (0, import_react13.useCallback)((profile) => selectProfile(2, profile?.id ?? null), [selectProfile]);
|
|
851
838
|
const [ready, setReady] = (0, import_react13.useState)({ 1: false, 2: false });
|
|
852
839
|
(0, import_expo_router4.useFocusEffect)(
|
|
853
840
|
(0, import_react13.useCallback)(() => {
|
|
@@ -878,16 +865,16 @@ function LoadoutScreen({ game }) {
|
|
|
878
865
|
const p1Drawn = seatPreview ? seatPreview(p1Color) : p1Color;
|
|
879
866
|
const p2Drawn = seatPreview ? seatPreview(p2Color) : p2Color;
|
|
880
867
|
const triggerStyle = (0, import_react13.useMemo)(() => pack.Backdrop ? [styles3.pill, { backgroundColor: themeColors.surface }] : void 0, [pack.Backdrop, themeColors.surface]);
|
|
868
|
+
const readySurface = pack.Backdrop ? themeColors.surface : void 0;
|
|
881
869
|
const isPortrait = panelLayout.orientationMode === "faceToFace";
|
|
882
870
|
const showMetaInSharedBand = (0, import_split_screen.needsSharedNeutralZone)(panelLayout.orientationMode, humanSeats.length);
|
|
883
871
|
const p2ZoneStyle = p2IsHuman ? isPortrait ? styles3.p2ZoneTop : styles3.p2ZoneRight : null;
|
|
884
|
-
const showReadyButton = p2IsHuman;
|
|
885
872
|
const seatPickerAlign = p2IsHuman ? void 0 : pack.usePickerAlign;
|
|
886
873
|
const layoutKey = p2IsHuman ? "zones" : "row";
|
|
887
874
|
const controlsHost = (0, import_chrome4.usePopoverHost)();
|
|
888
|
-
const
|
|
889
|
-
const
|
|
890
|
-
const
|
|
875
|
+
const p2Host = (0, import_chrome4.usePopoverHost)();
|
|
876
|
+
const p1PickerOpen = controlsHost.openId?.startsWith("p1-") ?? false;
|
|
877
|
+
const p1ControlOpen = controlsHost.openId === P1_CONTROL_ID;
|
|
891
878
|
const optionsRow = loadout.options({
|
|
892
879
|
host: controlsHost,
|
|
893
880
|
accentColor: themeColors.tertiary,
|
|
@@ -899,36 +886,44 @@ function LoadoutScreen({ game }) {
|
|
|
899
886
|
onReset: showMetaInSharedBand ? void 0 : loadout.reset
|
|
900
887
|
});
|
|
901
888
|
const optionsPopoverOpen = controlsHost.openId !== null && loadout.optionIds.includes(controlsHost.openId);
|
|
902
|
-
const sharedControls = showMetaInSharedBand ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lobby2.SharedActionBand, { onBack:
|
|
889
|
+
const sharedControls = showMetaInSharedBand ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lobby2.SharedActionBand, { onBack: import_core8.safeBack, onSettings: () => setSettingsOpen(true), onRandomize: loadout.randomize, onReset: loadout.reset, fg, popoverOpen: optionsPopoverOpen, children: optionsRow }) : optionsRow;
|
|
903
890
|
const controlLook = { accentColor: themeColors.tertiary, mutedColor: fgMuted, dark };
|
|
904
891
|
const p1Control = loadout.seatControl(1, controlsHost, { ...controlLook, seatColor: p1Drawn });
|
|
905
|
-
const p1Panel = /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lobby2.PlayerSetupPanel, { idPrefix: "p1", host: controlsHost, color: p1Color, onColorChange: handleP1ColorChange, swatches: import_auto_paper4.defaultColors, takenColor: p2Exists ? p2Color : void 0, allowSwapTaken: mode === "vsCpu", colorCaption: pack.colorCaption, isHuman: true,
|
|
892
|
+
const p1Panel = /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lobby2.PlayerSetupPanel, { idPrefix: "p1", host: controlsHost, color: p1Color, onColorChange: handleP1ColorChange, swatches: import_auto_paper4.defaultColors, takenColor: p2Exists ? p2Color : void 0, allowSwapTaken: mode === "vsCpu", colorCaption: pack.colorCaption, isHuman: true, dark, showReadyButton: false, profiles, selectedProfileId: lastSelected[1], takenProfileId: p2IsHuman ? lastSelected[2] : null, guestLabel: pack.guestLabel ?? "P1", nullLabel: pack.nullLabel, onProfileSelect: handleP1ProfileSelect, onManageProfiles: () => import_expo_router4.router.push(PROFILES_HREF), previewValue: seatPreview, triggerStyle, useSeatPickerAlign: seatPickerAlign }, `p1-${layoutKey}`);
|
|
893
|
+
const opponentPicker = game.seatTwo && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(OpponentPicker, { idPrefix: "p1", host: controlsHost, choices: game.seatTwo, seatTwo, onSeatTwoChange: changeSeatTwo, cpuDifficulty: loadout.cpuDifficulty, color: p2Color, onColorChange: handleP2ColorChange, swatches: import_auto_paper4.defaultColors, takenColor: p1Color, allowSwapTaken: mode === "vsCpu", dark, previewValue: seatPreview, triggerStyle, usePickerAlign: seatPickerAlign }, `opponent-${layoutKey}`);
|
|
894
|
+
const toggleP1Ready = () => setReady((r) => ({ ...r, 1: !r[1] }));
|
|
895
|
+
const seatOne = /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native5.View, { style: [styles3.seatOne, !p2IsHuman && styles3.seatOneAlone, p1PickerOpen && styles3.raised], children: [
|
|
896
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native5.View, { style: [styles3.seatOneButtons, p1PickerOpen && styles3.raised], children: [
|
|
897
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native_reanimated2.default.View, { style: [styles3.playersRow, p1PickerOpen && styles3.raised, !p2IsHuman && playersRowFade], children: [
|
|
898
|
+
p1Panel,
|
|
899
|
+
opponentPicker
|
|
900
|
+
] }),
|
|
901
|
+
p1Control && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native5.View, { style: [styles3.controlRow, p1ControlOpen && styles3.raised], children: p1Control })
|
|
902
|
+
] }),
|
|
903
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lobby2.ReadyButton, { color: p1Drawn, ready: ready[1], onToggleReady: toggleP1Ready, surfaceColor: readySurface, dark, style: !p2IsHuman && p1PickerOpen && styles3.readyButtonHidden })
|
|
904
|
+
] });
|
|
906
905
|
const p2Control = p2IsHuman ? loadout.seatControl(2, p2Host, { ...controlLook, seatColor: p2Drawn }) : void 0;
|
|
907
|
-
const p2Panel =
|
|
908
|
-
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
909
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
906
|
+
const p2Panel = p2IsHuman && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lobby2.PlayerSetupPanel, { idPrefix: "p2", host: p2Host, color: p2Color, onColorChange: handleP2ColorChange, swatches: import_auto_paper4.defaultColors, takenColor: p1Color, colorCaption: pack.colorCaption, isHuman: true, ready: ready[2], onToggleReady: () => setReady((r) => ({ ...r, 2: !r[2] })), dark, secondPicker: p2Control, secondPickerId: p2Control ? P2_CONTROL_ID : void 0, profiles, selectedProfileId: lastSelected[2], takenProfileId: lastSelected[1], guestLabel: pack.guestLabel ?? "P2", nullLabel: pack.nullLabel, onProfileSelect: handleP2ProfileSelect, previewValue: seatPreview, triggerStyle, readySurfaceColor: readySurface }, "p2-zones");
|
|
907
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native5.View, { style: [styles3.container, { backgroundColor: bg }], children: [
|
|
908
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native5.View, { style: styles3.frame, children: [
|
|
910
909
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_chrome4.PressAwayOverlay, { active: controlsHost.openId !== null, onPress: controlsHost.close }),
|
|
911
910
|
p2ZoneStyle && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_chrome4.PressAwayOverlay, { active: controlsHost.openId !== null || p2Host.openId !== null, onPress: p2Host.close, style: p2ZoneStyle }),
|
|
912
|
-
!showMetaInSharedBand && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_chrome4.CornerActionButtons, { onBack:
|
|
911
|
+
!showMetaInSharedBand && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_chrome4.CornerActionButtons, { onBack: import_core8.safeBack, onSettings: () => setSettingsOpen(true), fg, insets }),
|
|
913
912
|
p2IsHuman ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
914
913
|
import_split_screen.DualZoneLayout,
|
|
915
914
|
{
|
|
916
915
|
panelLayout,
|
|
917
916
|
panelFadeStyle,
|
|
918
|
-
p1:
|
|
917
|
+
p1: seatOne,
|
|
919
918
|
p2: p2Panel,
|
|
920
919
|
shared: sharedControls,
|
|
921
|
-
p1Elevated:
|
|
920
|
+
p1Elevated: p1PickerOpen,
|
|
922
921
|
p2Elevated: p2Host.openId !== null,
|
|
923
922
|
sharedElevated: optionsPopoverOpen
|
|
924
923
|
}
|
|
925
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
924
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native5.View, { style: styles3.stackedZone, children: [
|
|
926
925
|
sharedControls,
|
|
927
|
-
|
|
928
|
-
p1Panel,
|
|
929
|
-
p2Panel
|
|
930
|
-
] }),
|
|
931
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lobby2.ReadyButton, { color: p1Drawn, ready: ready[1], onToggleReady: () => setReady((r) => ({ ...r, 1: !r[1] })), style: anyPlayerPickerOpen && styles3.readyButtonHidden })
|
|
926
|
+
seatOne
|
|
932
927
|
] })
|
|
933
928
|
] }),
|
|
934
929
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SettingsDialog, { visible: settingsOpen, onDismiss: () => setSettingsOpen(false), onShowHowToPlay: () => openFor(game.id) })
|
|
@@ -938,10 +933,16 @@ function halfOf(color) {
|
|
|
938
933
|
const rgb = (0, import_auto_paper4.getRgb)(color);
|
|
939
934
|
return rgb ? `rgba(${rgb.r},${rgb.g},${rgb.b},0.5)` : void 0;
|
|
940
935
|
}
|
|
941
|
-
var styles3 =
|
|
936
|
+
var styles3 = import_react_native5.StyleSheet.create({
|
|
942
937
|
container: {
|
|
943
938
|
flex: 1
|
|
944
939
|
},
|
|
940
|
+
// Player 1's controls, under their row of buttons.
|
|
941
|
+
controlRow: {
|
|
942
|
+
alignItems: "center",
|
|
943
|
+
flexDirection: "row",
|
|
944
|
+
gap: 12
|
|
945
|
+
},
|
|
945
946
|
// A real full-bleed box to size the absolutely-positioned children against.
|
|
946
947
|
frame: {
|
|
947
948
|
alignItems: "center",
|
|
@@ -968,21 +969,37 @@ var styles3 = import_react_native4.StyleSheet.create({
|
|
|
968
969
|
pill: {
|
|
969
970
|
borderRadius: 999
|
|
970
971
|
},
|
|
971
|
-
//
|
|
972
|
-
//
|
|
972
|
+
// Seat 1's button and the opponent button read as one evenly spaced row of buttons, at
|
|
973
|
+
// PlayerSetupPanel's own pickerRow gap (12).
|
|
973
974
|
playersRow: {
|
|
974
975
|
flexDirection: "row",
|
|
975
976
|
gap: 12
|
|
976
977
|
},
|
|
977
|
-
|
|
978
|
+
// Lifts whichever piece of player 1's has a menu open above its later siblings (each View is its
|
|
979
|
+
// own stacking context on the web).
|
|
980
|
+
raised: {
|
|
978
981
|
zIndex: 100
|
|
979
982
|
},
|
|
980
|
-
// See
|
|
983
|
+
// See p1PickerOpen: opacity 0 (not display:'none') keeps the button's layout space, and
|
|
981
984
|
// pointerEvents:'none' keeps the sliver an open menu doesn't cover from being a hidden tap target.
|
|
982
985
|
readyButtonHidden: {
|
|
983
986
|
opacity: 0,
|
|
984
987
|
pointerEvents: "none"
|
|
985
988
|
},
|
|
989
|
+
// Player 1's column: their row of buttons and controls, then Ready, at PlayerSetupPanel's own
|
|
990
|
+
// rhythm in their half of 2 Player.
|
|
991
|
+
seatOne: {
|
|
992
|
+
alignItems: "center",
|
|
993
|
+
gap: 12
|
|
994
|
+
},
|
|
995
|
+
// With one person, Ready sits as far under the buttons as the match options sit above them.
|
|
996
|
+
seatOneAlone: {
|
|
997
|
+
gap: 28
|
|
998
|
+
},
|
|
999
|
+
seatOneButtons: {
|
|
1000
|
+
alignItems: "center",
|
|
1001
|
+
gap: 12
|
|
1002
|
+
},
|
|
986
1003
|
stackedZone: {
|
|
987
1004
|
alignItems: "center",
|
|
988
1005
|
gap: 28
|
|
@@ -1015,7 +1032,7 @@ function useResumePoint(gameId) {
|
|
|
1015
1032
|
if (!gameId) return;
|
|
1016
1033
|
setLastActiveGame(gameId);
|
|
1017
1034
|
return () => {
|
|
1018
|
-
if (
|
|
1035
|
+
if (import_react_native6.AppState.currentState === "active") clearLastActiveGame();
|
|
1019
1036
|
};
|
|
1020
1037
|
}, [gameId, setLastActiveGame, clearLastActiveGame]);
|
|
1021
1038
|
}
|
|
@@ -1027,7 +1044,7 @@ var import_chrome5 = require("@tastic/hud/chrome");
|
|
|
1027
1044
|
var import_profile7 = require("@tastic/profile");
|
|
1028
1045
|
var import_expo_router6 = require("expo-router");
|
|
1029
1046
|
var import_react16 = require("react");
|
|
1030
|
-
var
|
|
1047
|
+
var import_react_native8 = require("react-native");
|
|
1031
1048
|
var import_react_native_paper = require("react-native-paper");
|
|
1032
1049
|
|
|
1033
1050
|
// src/hooks/useFrozenWhileHidden.ts
|
|
@@ -1047,8 +1064,8 @@ function useFrozenWhileHidden(value, hidden) {
|
|
|
1047
1064
|
}
|
|
1048
1065
|
|
|
1049
1066
|
// src/screens/homeLayout.ts
|
|
1050
|
-
var
|
|
1051
|
-
var
|
|
1067
|
+
var import_core11 = require("@tastic/core");
|
|
1068
|
+
var import_react_native7 = require("react-native");
|
|
1052
1069
|
var import_react_native_safe_area_context3 = require("react-native-safe-area-context");
|
|
1053
1070
|
var PREVIEW_ASPECT = 360 / 200;
|
|
1054
1071
|
var ROW_PREVIEW_WIDTH = 92;
|
|
@@ -1077,9 +1094,9 @@ function computeHomeLayout(windowWidth, windowHeight, insets) {
|
|
|
1077
1094
|
const inner = Math.max(0, usable - HOME_WIDE_EDGE_PADDING - HOME_WIDE_RIGHT_GUTTER);
|
|
1078
1095
|
const content = Math.min(inner, HOME_WIDE_MAX_CONTENT_WIDTH);
|
|
1079
1096
|
const slack = (inner - content) / 2;
|
|
1080
|
-
const leftPaneWidth = Math.min((0,
|
|
1097
|
+
const leftPaneWidth = Math.min((0, import_core11.clamp)(Math.round(HOME_LEFT_PANE_FRACTION * content), HOME_LEFT_PANE_MIN, HOME_LEFT_PANE_MAX), Math.max(0, content - HOME_WIDE_PANE_GAP - HOME_MIN_TILE_WIDTH));
|
|
1081
1098
|
const rightPaneWidth = Math.max(0, content - HOME_WIDE_PANE_GAP - leftPaneWidth);
|
|
1082
|
-
const columns = (0,
|
|
1099
|
+
const columns = (0, import_core11.clamp)(Math.floor((rightPaneWidth + HOME_GRID_GAP) / (HOME_MIN_TILE_WIDTH + HOME_GRID_GAP)), 1, HOME_MAX_COLUMNS);
|
|
1083
1100
|
const tileWidth = Math.max(0, Math.floor((rightPaneWidth - (columns - 1) * HOME_GRID_GAP) / columns));
|
|
1084
1101
|
const previewWidth = Math.max(0, tileWidth - 2 * HOME_TILE_PADDING);
|
|
1085
1102
|
const heroFit = {
|
|
@@ -1102,7 +1119,7 @@ function computeHomeLayout(windowWidth, windowHeight, insets) {
|
|
|
1102
1119
|
};
|
|
1103
1120
|
}
|
|
1104
1121
|
function useHomeLayout() {
|
|
1105
|
-
const { width, height } = (0,
|
|
1122
|
+
const { width, height } = (0, import_react_native7.useWindowDimensions)();
|
|
1106
1123
|
const insets = (0, import_react_native_safe_area_context3.useSafeAreaInsets)();
|
|
1107
1124
|
return computeHomeLayout(width, height, insets);
|
|
1108
1125
|
}
|
|
@@ -1132,9 +1149,9 @@ function HomeMenu() {
|
|
|
1132
1149
|
const [settingsOpen, setSettingsOpen] = (0, import_react16.useState)(false);
|
|
1133
1150
|
const [rulesGame, setRulesGame] = (0, import_react16.useState)(null);
|
|
1134
1151
|
const isFocused = (0, import_expo_router6.useIsFocused)();
|
|
1135
|
-
const [appState, setAppState] = (0, import_react16.useState)(
|
|
1152
|
+
const [appState, setAppState] = (0, import_react16.useState)(import_react_native8.AppState.currentState);
|
|
1136
1153
|
(0, import_react16.useEffect)(() => {
|
|
1137
|
-
const subscription =
|
|
1154
|
+
const subscription = import_react_native8.AppState.addEventListener("change", setAppState);
|
|
1138
1155
|
return () => subscription.remove();
|
|
1139
1156
|
}, []);
|
|
1140
1157
|
const heroActive = isFocused && appState === "active";
|
|
@@ -1176,24 +1193,24 @@ function HomeMenu() {
|
|
|
1176
1193
|
const picker = /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_profile7.ProfilePicker, { idPrefix: SEAT_ONE_PICKER, host: pickerHost, profiles, selectedId: lastSelected[1], color: p1Drawn, dark, guestLabel: pack.guestLabel ?? "P1", nullLabel: pack.nullLabel, onSelect: (profile) => selectProfile(1, profile?.id ?? null), onManage: () => import_expo_router6.router.push(PROFILES_HREF), colorSection, alignOverride: pickerAlign, triggerStyle });
|
|
1177
1194
|
const pressAway = /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_chrome5.PressAwayOverlay, { active: pickerHost.openId !== null, onPress: pickerHost.close, style: styles4.pressAway });
|
|
1178
1195
|
const RulesSheet = rulesGame?.Rules;
|
|
1179
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1180
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1196
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native8.View, { style: [styles4.container, { backgroundColor: bg }], children: [
|
|
1197
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native8.View, { style: styles4.frame, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(RulesHost, { enabled: pack.games.some((game) => game.Rules), children: [
|
|
1181
1198
|
isWide ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
1182
1199
|
pressAway,
|
|
1183
1200
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_auto_paper5.FadingScrollView, { ...tab && gridClamp, style: [styles4.wideRightPane, { left: layout.paddingLeft + layout.leftPaneWidth + HOME_WIDE_PANE_GAP }], contentContainerStyle: { paddingTop: 16 + insets.top, paddingBottom: 16 + insets.bottom, paddingRight: layout.paddingRight }, children: [
|
|
1184
|
-
tabBar && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1185
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1201
|
+
tabBar && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native8.View, { style: [styles4.wideTabs, { width: layout.rightPaneWidth }], children: tabBar }),
|
|
1202
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native8.View, { style: [styles4.grid, { width: layout.rightPaneWidth }], children: pack.games.map((game) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(GameTile, { game, hidden: isHidden(tab, game), width: layout.tileWidth, previewWidth: layout.previewWidth, previewRevealed: previewsRevealed, dark, p1Color, p2Color, onPress: () => openGame(game), onRules: hasRules(game) ? () => openRules(game) : void 0 }, game.id)) })
|
|
1186
1203
|
] }),
|
|
1187
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1204
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native8.View, { style: [styles4.wideLeftPane, { left: layout.paddingLeft, width: layout.leftPaneWidth, paddingTop: HOME_TOP_BAND + insets.top, paddingBottom: 16 + insets.bottom }, pickerHost.openId !== null && styles4.pickerOpen], children: [
|
|
1188
1205
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(pack.HeroTitle, { words: pack.wordmark, color: fg, p1Color, p2Color, active: heroActive, fit: layout.heroFit }),
|
|
1189
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1206
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native8.View, { style: styles4.widePicker, children: picker })
|
|
1190
1207
|
] })
|
|
1191
1208
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_auto_paper5.FadingScrollView, { ...tab && columnClamp, style: styles4.scroll, contentContainerStyle: [styles4.content, { paddingTop: 56 + insets.top, paddingBottom: 24 + insets.bottom, paddingLeft: 16 + insets.left, paddingRight: 16 + insets.right }], children: [
|
|
1192
1209
|
pressAway,
|
|
1193
1210
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(pack.HeroTitle, { words: pack.wordmark, color: fg, p1Color, p2Color, active: heroActive }),
|
|
1194
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1195
|
-
tabBar && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1196
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1211
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native8.View, { style: [styles4.picker, pickerHost.openId !== null && styles4.pickerOpen], children: picker }),
|
|
1212
|
+
tabBar && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native8.View, { style: styles4.listWidth, children: tabBar }),
|
|
1213
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native8.View, { style: styles4.list, children: pack.games.map((game) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(GameRow, { game, hidden: isHidden(tab, game), dark, p1Color, p2Color, previewRevealed: previewsRevealed, onPress: () => openGame(game), onRules: hasRules(game) ? () => openRules(game) : void 0 }, game.id)) })
|
|
1197
1214
|
] }),
|
|
1198
1215
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_feedback_press3.IconButton, { icon: "trophy", iconColor: fg, size: 24, style: [styles4.corner, { top: 8 + insets.top, left: 8 + insets.left }], onPress: () => import_expo_router6.router.push(STATS_HREF), accessibilityLabel: "Stats & Achievements" }),
|
|
1199
1216
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_feedback_press3.IconButton, { icon: "cog", iconColor: fg, size: 24, style: [styles4.corner, { top: 8 + insets.top, right: 8 + insets.right }], onPress: () => setSettingsOpen(true), accessibilityLabel: "Settings" }),
|
|
@@ -1244,10 +1261,10 @@ function GameRow({ game, hidden, dark, p1Color, p2Color, previewRevealed, onPres
|
|
|
1244
1261
|
return (
|
|
1245
1262
|
// The rules button sits beside the row's own button, laid over its end, not inside it: a button
|
|
1246
1263
|
// inside a button is invalid on the web.
|
|
1247
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1264
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native8.View, { style: hidden ? styles4.hidden : void 0, children: [
|
|
1248
1265
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_feedback_press3.Pressable, { onPress, style: [styles4.row, { backgroundColor: well.bg }], accessibilityRole: "button", accessibilityLabel: game.title, children: [
|
|
1249
|
-
game.Preview ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(PreviewBox, { game, width: ROW_PREVIEW_WIDTH, revealed: previewRevealed, dark, p1Color, p2Color }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1250
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1266
|
+
game.Preview ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(PreviewBox, { game, width: ROW_PREVIEW_WIDTH, revealed: previewRevealed, dark, p1Color, p2Color }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native8.View, { style: [styles4.rowIcon, { backgroundColor: dark ? ICON_DARK_BG : ICON_LIGHT_BG }], children: GameIcon && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(GameIcon, { size: ROW_ICON_SIZE, p1Color, p2Color, dark }) }),
|
|
1267
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native8.View, { style: styles4.rowText, children: [
|
|
1251
1268
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper.Text, { variant: "titleLarge", style: [styles4.rowTitle, { color: well.fg }], numberOfLines: 1, children: game.title }),
|
|
1252
1269
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper.Text, { variant: "bodyMedium", style: { color: well.fgMuted }, numberOfLines: 2, children: game.blurb })
|
|
1253
1270
|
] })
|
|
@@ -1258,7 +1275,7 @@ function GameRow({ game, hidden, dark, p1Color, p2Color, previewRevealed, onPres
|
|
|
1258
1275
|
}
|
|
1259
1276
|
function GameTile({ game, hidden, width, previewWidth, dark, p1Color, p2Color, previewRevealed, onPress, onRules }) {
|
|
1260
1277
|
const well = (0, import_chrome5.useWellColors)();
|
|
1261
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1278
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native8.View, { style: [{ width }, hidden && styles4.hidden], children: [
|
|
1262
1279
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_feedback_press3.Pressable, { onPress, style: [styles4.tile, { backgroundColor: well.bg }], accessibilityRole: "button", accessibilityLabel: game.title, children: [
|
|
1263
1280
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(PreviewBox, { game, width: previewWidth, revealed: previewRevealed, dark, p1Color, p2Color }),
|
|
1264
1281
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper.Text, { variant: "titleMedium", style: [styles4.rowTitle, { color: well.fg }], numberOfLines: 1, children: game.title }),
|
|
@@ -1271,13 +1288,13 @@ function PreviewBox({ game, width, revealed, dark, p1Color, p2Color }) {
|
|
|
1271
1288
|
const height = Math.round(width / PREVIEW_ASPECT);
|
|
1272
1289
|
const { Preview, icon: GameIcon } = game;
|
|
1273
1290
|
const iconSize = Math.min(height, ROW_ICON_SIZE);
|
|
1274
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1291
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native8.View, { style: [styles4.preview, { width, height, backgroundColor: dark ? ICON_DARK_BG : ICON_LIGHT_BG }], children: Preview ? revealed && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Preview, { width, height, p1Color, p2Color, dark }) : GameIcon && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native8.View, { style: [styles4.previewIcon, { width: iconSize, height: iconSize, borderRadius: iconSize * 0.22 }], children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(GameIcon, { size: iconSize, p1Color, p2Color, dark }) }) });
|
|
1275
1292
|
}
|
|
1276
1293
|
var ROW_ICON_SIZE = 56;
|
|
1277
1294
|
var ICON_LIGHT_BG = "#FAFAFA";
|
|
1278
1295
|
var ICON_DARK_BG = "#050505";
|
|
1279
1296
|
var RULES_BUTTON_SPACE = 44;
|
|
1280
|
-
var styles4 =
|
|
1297
|
+
var styles4 = import_react_native8.StyleSheet.create({
|
|
1281
1298
|
container: {
|
|
1282
1299
|
flex: 1
|
|
1283
1300
|
},
|
|
@@ -1433,7 +1450,7 @@ function useRosterAlign(open, contentWidth, contentHeight) {
|
|
|
1433
1450
|
function ProfilesRoute() {
|
|
1434
1451
|
const { profiles, createProfile, updateProfile, deleteProfile } = useProfiles();
|
|
1435
1452
|
const { Backdrop, foreground, newProfileColor, usePickerAlign } = usePack();
|
|
1436
|
-
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_chrome6.RotatedFrame, { rotatedSafeArea: true, portalHost: true, maxContentWidth: ROSTER_MAX_WIDTH, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_profile8.ProfilesScreen, { profiles, defaultColor: newProfileColor ?? import_auto_paper6.defaultColors[0].value, onCreate: (patch) => createProfile(patch), onSave: (id, patch) => updateProfile(id, patch), onDelete: deleteProfile, onBack:
|
|
1453
|
+
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_chrome6.RotatedFrame, { rotatedSafeArea: true, portalHost: true, maxContentWidth: ROSTER_MAX_WIDTH, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_profile8.ProfilesScreen, { profiles, defaultColor: newProfileColor ?? import_auto_paper6.defaultColors[0].value, onCreate: (patch) => createProfile(patch), onSave: (id, patch) => updateProfile(id, patch), onDelete: deleteProfile, onBack: import_core8.safeBack, fg: foreground, bg: Backdrop ? "transparent" : void 0, useColorPickerAlign: usePickerAlign ? useRosterAlign : void 0 }) });
|
|
1437
1454
|
}
|
|
1438
1455
|
|
|
1439
1456
|
// src/screens/StatsScreen.tsx
|
|
@@ -1441,7 +1458,7 @@ var import_auto_paper7 = require("@rific/auto-paper");
|
|
|
1441
1458
|
var import_chrome7 = require("@tastic/hud/chrome");
|
|
1442
1459
|
var import_profile9 = require("@tastic/profile");
|
|
1443
1460
|
var import_react17 = require("react");
|
|
1444
|
-
var
|
|
1461
|
+
var import_react_native9 = require("react-native");
|
|
1445
1462
|
var import_react_native_paper2 = require("react-native-paper");
|
|
1446
1463
|
var import_react_native_safe_area_context4 = require("react-native-safe-area-context");
|
|
1447
1464
|
var import_react_redux10 = require("react-redux");
|
|
@@ -1464,7 +1481,7 @@ function StatsScreen() {
|
|
|
1464
1481
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(StatsPressAway, { host: pickerHost, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_chrome7.RotatedFrame, { rotatedSafeArea: true, portalHost: true, maxContentWidth: STATS_MAX_WIDTH, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(StatsContent, { pickerHost }) }) });
|
|
1465
1482
|
}
|
|
1466
1483
|
function StatsPressAway({ host, children }) {
|
|
1467
|
-
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1484
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native9.View, { testID: "stats-press-away", style: styles5.screen, onStartShouldSetResponder: () => host.openId !== null, onResponderRelease: host.close, children });
|
|
1468
1485
|
}
|
|
1469
1486
|
var useNoPackReset = () => null;
|
|
1470
1487
|
var noPickerAlign2 = () => void 0;
|
|
@@ -1498,10 +1515,10 @@ function StatsContent({ pickerHost }) {
|
|
|
1498
1515
|
const surface = pack.Backdrop ? { backgroundColor: colors.surface } : void 0;
|
|
1499
1516
|
const triggerStyle = pack.Backdrop ? [styles5.pill, surface] : void 0;
|
|
1500
1517
|
const PackTabContent = packTab?.Content;
|
|
1501
|
-
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_chrome7.BaseStatsScreen, { title, onBack:
|
|
1518
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_chrome7.BaseStatsScreen, { title, onBack: import_core8.safeBack, insets, onReset: reset.onReset, resetLabel: reset.label, resetConfirmTitle: reset.title, resetConfirmBody: reset.body, fg: pack.foreground, bg: pack.Backdrop ? "transparent" : void 0, rotation: 0, children: [
|
|
1502
1519
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_chrome7.PressAwayOverlay, { active: pickerHost.openId !== null, onPress: pickerHost.close, style: styles5.pressAway }),
|
|
1503
1520
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native_paper2.SegmentedButtons, { value: tab, onValueChange: setTab, buttons: tabButtons, style: [styles5.tabs, surface] }),
|
|
1504
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
1521
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native9.View, { style: [styles5.filters, pickerHost.openId !== null && styles5.filtersOpen], onStartShouldSetResponder: () => pickerHost.openId !== null, children: [
|
|
1505
1522
|
profiles.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_profile9.OptionPicker, { id: PLAYER_PICKER_ID, host: pickerHost, options: playerOptions, value: profileId ?? EVERYONE, onChange: (value) => setSelectedProfileId(value === EVERYONE ? null : value), color: colors.primary, dark, icon: profileId ? "account" : "account-group", alignOverride: playerAlign, triggerStyle }),
|
|
1506
1523
|
showGamePicker && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_profile9.OptionPicker, { id: GAME_PICKER_ID, host: pickerHost, options: gameOptions, value: gameId, onChange: setGameId, color: colors.primary, dark, icon: "view-grid-outline", alignOverride: gameAlign, triggerStyle })
|
|
1507
1524
|
] }),
|
|
@@ -1522,12 +1539,12 @@ function GameStats({ game, tab, profileId, showTitle, titleColor }) {
|
|
|
1522
1539
|
const { StatsSections, AchievementList } = game;
|
|
1523
1540
|
const Sections = tab === STATS ? StatsSections : AchievementList;
|
|
1524
1541
|
if (!Sections) return null;
|
|
1525
|
-
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
1542
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native9.View, { style: styles5.game, children: [
|
|
1526
1543
|
showTitle && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native_paper2.Text, { variant: "titleLarge", style: [styles5.gameTitle, { color: titleColor }], children: game.title }),
|
|
1527
1544
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Sections, { profileId })
|
|
1528
1545
|
] });
|
|
1529
1546
|
}
|
|
1530
|
-
var styles5 =
|
|
1547
|
+
var styles5 = import_react_native9.StyleSheet.create({
|
|
1531
1548
|
filters: {
|
|
1532
1549
|
flexDirection: "row",
|
|
1533
1550
|
flexWrap: "wrap",
|
|
@@ -1561,11 +1578,11 @@ var styles5 = import_react_native8.StyleSheet.create({
|
|
|
1561
1578
|
});
|
|
1562
1579
|
|
|
1563
1580
|
// src/components/imageGameIcon.tsx
|
|
1564
|
-
var
|
|
1581
|
+
var import_react_native10 = require("react-native");
|
|
1565
1582
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
1566
1583
|
function imageGameIcon(images) {
|
|
1567
1584
|
return function ImageGameIcon({ size, dark }) {
|
|
1568
|
-
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1585
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native10.Image, { source: dark ? images.dark : images.light, style: { height: size, width: size }, accessibilityIgnoresInvertColors: true });
|
|
1569
1586
|
};
|
|
1570
1587
|
}
|
|
1571
1588
|
|
|
@@ -1573,20 +1590,19 @@ function imageGameIcon(images) {
|
|
|
1573
1590
|
var import_auto_paper8 = require("@rific/auto-paper");
|
|
1574
1591
|
var import_feedback_press4 = require("@rific/feedback-press");
|
|
1575
1592
|
var import_react18 = require("react");
|
|
1576
|
-
var
|
|
1593
|
+
var import_react_native11 = require("react-native");
|
|
1577
1594
|
var import_react_native_reanimated3 = __toESM(require("react-native-reanimated"));
|
|
1578
1595
|
var import_react_native_safe_area_context5 = require("react-native-safe-area-context");
|
|
1579
1596
|
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
1580
|
-
var MATCH_CHIPS_DESKTOP_MIN_WIDTH = 768;
|
|
1581
1597
|
var MATCH_CHIPS_FADE_MS = 150;
|
|
1582
1598
|
var CHIP_SIZE = 48;
|
|
1583
1599
|
var EDGE_PAD = 8;
|
|
1584
1600
|
function MatchChips({ playing, faceToFace, centerLineY, onBack, onSettings }) {
|
|
1585
|
-
const {
|
|
1601
|
+
const { height } = (0, import_react_native11.useWindowDimensions)();
|
|
1586
1602
|
const insets = (0, import_react_native_safe_area_context5.useSafeAreaInsets)();
|
|
1587
1603
|
const { dark } = (0, import_auto_paper8.useAutoPaperTheme)();
|
|
1588
|
-
const
|
|
1589
|
-
const visible =
|
|
1604
|
+
const atComputer = useAtComputer();
|
|
1605
|
+
const visible = atComputer || !playing;
|
|
1590
1606
|
const opacity = (0, import_react_native_reanimated3.useSharedValue)(visible ? 1 : 0);
|
|
1591
1607
|
(0, import_react18.useEffect)(() => {
|
|
1592
1608
|
opacity.value = (0, import_react_native_reanimated3.withTiming)(visible ? 1 : 0, { duration: MATCH_CHIPS_FADE_MS });
|
|
@@ -1594,7 +1610,7 @@ function MatchChips({ playing, faceToFace, centerLineY, onBack, onSettings }) {
|
|
|
1594
1610
|
const fadeStyle = (0, import_react_native_reanimated3.useAnimatedStyle)(() => ({ opacity: opacity.value }));
|
|
1595
1611
|
const iconColor = dark ? "#FFFFFF" : "#000000";
|
|
1596
1612
|
const containerColor = dark ? "rgba(0,0,0,0.55)" : "rgba(255,255,255,0.55)";
|
|
1597
|
-
const between = faceToFace && !
|
|
1613
|
+
const between = faceToFace && !atComputer;
|
|
1598
1614
|
const top = between ? (centerLineY ?? height / 2) - CHIP_SIZE / 2 : EDGE_PAD + insets.top;
|
|
1599
1615
|
const backSlot = { top, left: EDGE_PAD + insets.left };
|
|
1600
1616
|
const settingsSlot = { top, right: EDGE_PAD + insets.right };
|
|
@@ -1604,7 +1620,7 @@ function MatchChips({ playing, faceToFace, centerLineY, onBack, onSettings }) {
|
|
|
1604
1620
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native_reanimated3.default.View, { pointerEvents, style: [styles6.slot, settingsSlot, fadeStyle], testID: "match-chips-settings", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_feedback_press4.IconButton, { icon: "cog", iconColor, containerColor, style: styles6.chip, size: 24, onPress: onSettings, accessibilityLabel: "Settings" }) })
|
|
1605
1621
|
] });
|
|
1606
1622
|
}
|
|
1607
|
-
var styles6 =
|
|
1623
|
+
var styles6 = import_react_native11.StyleSheet.create({
|
|
1608
1624
|
chip: { margin: 0 },
|
|
1609
1625
|
slot: { position: "absolute" }
|
|
1610
1626
|
});
|
|
@@ -1625,7 +1641,7 @@ var import_redux_persist = require("redux-persist");
|
|
|
1625
1641
|
|
|
1626
1642
|
// src/redux/shellState.ts
|
|
1627
1643
|
var import_auto_paper9 = require("@rific/auto-paper");
|
|
1628
|
-
var
|
|
1644
|
+
var import_core12 = require("@rific/core");
|
|
1629
1645
|
var import_feedback_press5 = require("@rific/feedback-press");
|
|
1630
1646
|
var import_profile10 = require("@tastic/profile");
|
|
1631
1647
|
var initialSoundSettings = { ...import_feedback_press5.defaultSoundSettings, enabled: !__DEV__ };
|
|
@@ -1646,7 +1662,7 @@ function createShellReducers({ seatColors, appearance = "system", seatTheme }) {
|
|
|
1646
1662
|
sound: appSoundReducer,
|
|
1647
1663
|
// @rific/core's Keep Awake setting (see Providers.tsx's KeepAwakeBridge), under the namespace its
|
|
1648
1664
|
// REHYDRATE handling expects.
|
|
1649
|
-
keepAwake:
|
|
1665
|
+
keepAwake: import_core12.keepAwakeReducer,
|
|
1650
1666
|
// The shared App Group roster (see @tastic/profile's resolveInitialProfiles/
|
|
1651
1667
|
// useSharedProfilesSync, wired in hooks/useProfiles.tsx) is layered on top of this as a separate
|
|
1652
1668
|
// sync target - this slice persisting normally via redux-persist is what gives it local-fallback
|
|
@@ -1865,7 +1881,6 @@ function createPlayerSettings({ id, defaults, distinctControls }) {
|
|
|
1865
1881
|
GUEST_PLAYER_ID,
|
|
1866
1882
|
HomeScreen,
|
|
1867
1883
|
LoadoutRoute,
|
|
1868
|
-
MATCH_CHIPS_DESKTOP_MIN_WIDTH,
|
|
1869
1884
|
MATCH_CHIPS_FADE_MS,
|
|
1870
1885
|
MatchChips,
|
|
1871
1886
|
PREVIEW_ASPECT,
|
|
@@ -1903,6 +1918,7 @@ function createPlayerSettings({ id, defaults, distinctControls }) {
|
|
|
1903
1918
|
seatTwoFor,
|
|
1904
1919
|
useActiveRound,
|
|
1905
1920
|
useAppSettings,
|
|
1921
|
+
useAtComputer,
|
|
1906
1922
|
useGameGuide,
|
|
1907
1923
|
useOpponent,
|
|
1908
1924
|
usePack,
|