@tastic/shell 0.1.1 → 0.2.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 +71 -12
- package/dist/index.d.mts +86 -14
- package/dist/index.d.ts +86 -14
- package/dist/index.js +317 -148
- package/dist/index.mjs +321 -153
- package/package.json +9 -9
- package/src/PackContext.tsx +2 -2
- package/src/RootLayout.tsx +110 -28
- package/src/components/GuideHost.tsx +62 -23
- package/src/components/Providers.tsx +17 -7
- package/src/components/SeatTwoPanel.tsx +2 -1
- package/src/components/SettingsDialog.tsx +6 -4
- package/src/components/UpdateDialog.tsx +1 -1
- package/src/hooks/useSeatColors.ts +54 -27
- package/src/index.ts +1 -1
- package/src/redux/createPackStore.ts +16 -6
- package/src/redux/shellState.ts +4 -2
- package/src/routes.ts +10 -0
- package/src/screens/GameRoute.tsx +4 -3
- package/src/screens/HomeScreen.tsx +145 -76
- package/src/screens/LoadoutScreen.tsx +13 -7
- package/src/screens/ProfilesRoute.tsx +26 -1
- package/src/screens/StatsScreen.tsx +138 -56
- package/src/types.ts +143 -10
package/dist/index.js
CHANGED
|
@@ -32,6 +32,7 @@ var index_exports = {};
|
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
DEFAULT_APP_SETTINGS: () => DEFAULT_APP_SETTINGS,
|
|
34
34
|
DEFAULT_OPPONENT: () => DEFAULT_OPPONENT,
|
|
35
|
+
GUEST_PLAYER_ID: () => GUEST_PLAYER_ID,
|
|
35
36
|
HomeScreen: () => HomeScreen,
|
|
36
37
|
LoadoutRoute: () => LoadoutRoute,
|
|
37
38
|
PREVIEW_ASPECT: () => PREVIEW_ASPECT,
|
|
@@ -99,7 +100,8 @@ var import_auto_paper2 = require("@rific/auto-paper");
|
|
|
99
100
|
var import_feedback_press2 = require("@rific/feedback-press");
|
|
100
101
|
var import_toaster2 = require("@rific/toaster");
|
|
101
102
|
var import_core6 = require("@tastic/core");
|
|
102
|
-
var
|
|
103
|
+
var import_chrome2 = require("@tastic/hud/chrome");
|
|
104
|
+
var import_profile3 = require("@tastic/profile");
|
|
103
105
|
var Haptics = __toESM(require("expo-haptics"));
|
|
104
106
|
var import_expo_router = require("expo-router");
|
|
105
107
|
var import_expo_sensors = require("expo-sensors");
|
|
@@ -148,24 +150,35 @@ function seatTwoFor(saved, choices) {
|
|
|
148
150
|
function humanSeatsFor(mode) {
|
|
149
151
|
return mode === "twoPlayer" ? [1, 2] : [1];
|
|
150
152
|
}
|
|
153
|
+
var GUEST_PLAYER_ID = "guest";
|
|
151
154
|
|
|
152
155
|
// src/components/GuideHost.tsx
|
|
153
156
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
157
|
+
var PACK_GUIDE = "__pack__";
|
|
158
|
+
var NO_INPUT = {};
|
|
154
159
|
var GameGuideContext = (0, import_react2.createContext)(null);
|
|
155
160
|
function GuideHost({ children }) {
|
|
156
161
|
const pack = usePack();
|
|
157
|
-
const [
|
|
158
|
-
const
|
|
162
|
+
const [subject, setSubject] = (0, import_react2.useState)(() => pack.guide ? PACK_GUIDE : pack.games.find((g) => g.guide)?.id ?? null);
|
|
163
|
+
const packGuide = subject === PACK_GUIDE ? pack.guide : void 0;
|
|
164
|
+
const game = subject === PACK_GUIDE ? void 0 : pack.games.find((g) => g.id === subject);
|
|
165
|
+
const gameGuide = game?.guide;
|
|
159
166
|
const rotation = (0, import_core.useRotation)();
|
|
160
167
|
const touch = (0, import_core.useIsTouchPrimaryDevice)();
|
|
161
168
|
const seatTwo = (0, import_react_redux.useSelector)((state) => state.opponent.seatTwo);
|
|
162
|
-
const input = (0, import_react_redux.useSelector)((state) =>
|
|
163
|
-
const seenVersion = (0, import_react_redux.useSelector)((state) =>
|
|
169
|
+
const input = (0, import_react_redux.useSelector)((state) => gameGuide ? gameGuide.selectInput(state) : NO_INPUT, import_react_redux.shallowEqual);
|
|
170
|
+
const seenVersion = (0, import_react_redux.useSelector)((state) => (packGuide ?? gameGuide)?.selectVersionSeen(state) ?? 0);
|
|
164
171
|
const dispatch = (0, import_react_redux.useDispatch)();
|
|
165
|
-
const mode = roundModeFor(seatTwoFor(seatTwo, game
|
|
166
|
-
const steps = (0, import_react2.useMemo)(() =>
|
|
167
|
-
const onSeen = (0, import_react2.useCallback)(
|
|
168
|
-
|
|
172
|
+
const mode = roundModeFor(seatTwoFor(seatTwo, game?.seatTwo));
|
|
173
|
+
const steps = (0, import_react2.useMemo)(() => packGuide ? packGuide.getSteps({ touch }) : gameGuide ? gameGuide.getSteps(input, { touch, mode }) : [], [packGuide, gameGuide, input, touch, mode]);
|
|
174
|
+
const onSeen = (0, import_react2.useCallback)(
|
|
175
|
+
(version) => {
|
|
176
|
+
const guide = packGuide ?? gameGuide;
|
|
177
|
+
if (guide) dispatch(guide.markSeen(version));
|
|
178
|
+
},
|
|
179
|
+
[dispatch, packGuide, gameGuide]
|
|
180
|
+
);
|
|
181
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_guide.GuideProvider, { steps, currentVersion: (packGuide ?? gameGuide)?.version ?? 0, seenVersion, onSeen, rotation, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(GameGuideBridge, { onPick: setSubject, children }) });
|
|
169
182
|
}
|
|
170
183
|
function GameGuideBridge({ onPick, children }) {
|
|
171
184
|
const pack = usePack();
|
|
@@ -173,6 +186,7 @@ function GameGuideBridge({ onPick, children }) {
|
|
|
173
186
|
const { isOpen, open } = (0, import_guide.useGuide)();
|
|
174
187
|
const pendingNext = (0, import_react2.useRef)(null);
|
|
175
188
|
const wasOpen = (0, import_react2.useRef)(false);
|
|
189
|
+
const packAutoShown = (0, import_react2.useRef)(false);
|
|
176
190
|
(0, import_react2.useEffect)(() => {
|
|
177
191
|
if (wasOpen.current && !isOpen && pendingNext.current) {
|
|
178
192
|
const next = pendingNext.current;
|
|
@@ -183,15 +197,16 @@ function GameGuideBridge({ onPick, children }) {
|
|
|
183
197
|
}, [isOpen]);
|
|
184
198
|
const openFor = (0, import_react2.useCallback)(
|
|
185
199
|
(gameId) => {
|
|
200
|
+
if (!pack.games.find((g) => g.id === gameId)?.guide) return;
|
|
186
201
|
onPick(gameId);
|
|
187
202
|
open();
|
|
188
203
|
},
|
|
189
|
-
[onPick, open]
|
|
204
|
+
[pack, onPick, open]
|
|
190
205
|
);
|
|
191
206
|
const openFirstTime = (0, import_react2.useCallback)(
|
|
192
207
|
(gameId, next) => {
|
|
193
|
-
const
|
|
194
|
-
if (!
|
|
208
|
+
const guide = pack.games.find((g) => g.id === gameId)?.guide;
|
|
209
|
+
if (!guide || guide.selectVersionSeen(store.getState()) >= guide.version) {
|
|
195
210
|
next();
|
|
196
211
|
return;
|
|
197
212
|
}
|
|
@@ -200,7 +215,18 @@ function GameGuideBridge({ onPick, children }) {
|
|
|
200
215
|
},
|
|
201
216
|
[pack, store, openFor]
|
|
202
217
|
);
|
|
203
|
-
const
|
|
218
|
+
const openPack = (0, import_react2.useCallback)(() => {
|
|
219
|
+
if (!pack.guide) return;
|
|
220
|
+
onPick(PACK_GUIDE);
|
|
221
|
+
open();
|
|
222
|
+
}, [pack, onPick, open]);
|
|
223
|
+
const autoShowPack = (0, import_react2.useCallback)(() => {
|
|
224
|
+
const guide = pack.guide;
|
|
225
|
+
if (!guide || packAutoShown.current || guide.selectVersionSeen(store.getState()) >= guide.version) return;
|
|
226
|
+
packAutoShown.current = true;
|
|
227
|
+
openPack();
|
|
228
|
+
}, [pack, store, openPack]);
|
|
229
|
+
const value = (0, import_react2.useMemo)(() => ({ openFirstTime, openFor, openPack, autoShowPack }), [openFirstTime, openFor, openPack, autoShowPack]);
|
|
204
230
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(GameGuideContext.Provider, { value, children });
|
|
205
231
|
}
|
|
206
232
|
function useGameGuide() {
|
|
@@ -220,15 +246,20 @@ var RNPaper = __toESM(require("react-native-paper"));
|
|
|
220
246
|
var import_react_redux2 = require("react-redux");
|
|
221
247
|
var import_react4 = require("redux-persist/integration/react");
|
|
222
248
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
249
|
+
function useShellFeedbackSounds() {
|
|
250
|
+
const selection = (0, import_audio.useAudioPool)(require("./select-MLBNNA4N.wav"));
|
|
251
|
+
const notification = (0, import_audio.useAudioPool)(require("./notification-CGGFPYK7.wav"));
|
|
252
|
+
return { selection, notification };
|
|
253
|
+
}
|
|
223
254
|
var FeedbackBridge = ({ children }) => {
|
|
224
255
|
const haptic = (0, import_react_redux2.useSelector)((state) => state.haptic);
|
|
225
256
|
const sound = (0, import_react_redux2.useSelector)((state) => state.sound);
|
|
226
257
|
const dispatch = (0, import_react_redux2.useDispatch)();
|
|
227
258
|
const onChange = (0, import_react3.useCallback)((next) => dispatch(import_feedback_press.hapticActions.initialize(next)), [dispatch]);
|
|
228
259
|
const onSoundChange = (0, import_react3.useCallback)((next) => dispatch(import_feedback_press.soundActions.initialize(next)), [dispatch]);
|
|
229
|
-
const
|
|
230
|
-
const
|
|
231
|
-
const bridgeProps = (0, import_feedback_press.useFeedbackBridgeProps)({ initialValue: haptic, onChange, soundInitialValue: sound, onSoundChange, sound:
|
|
260
|
+
const { useFeedbackSounds = useShellFeedbackSounds } = usePack();
|
|
261
|
+
const sounds = useFeedbackSounds();
|
|
262
|
+
const bridgeProps = (0, import_feedback_press.useFeedbackBridgeProps)({ initialValue: haptic, onChange, soundInitialValue: sound, onSoundChange, sound: sounds });
|
|
232
263
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_feedback_press.FeedbackPressProvider, { ...bridgeProps, paper: RNPaper, children });
|
|
233
264
|
};
|
|
234
265
|
var EdgeGuardBridge = ({ children }) => {
|
|
@@ -271,12 +302,12 @@ function Theme({ children }) {
|
|
|
271
302
|
// src/components/UpdateDialog.tsx
|
|
272
303
|
var import_toaster = require("@rific/toaster");
|
|
273
304
|
var import_core3 = require("@tastic/core");
|
|
274
|
-
var
|
|
305
|
+
var import_chrome = require("@tastic/hud/chrome");
|
|
275
306
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
276
307
|
function UpdateDialog() {
|
|
277
308
|
const onError = (0, import_toaster.useUpdateErrorToast)();
|
|
278
309
|
const rotation = (0, import_core3.useRotation)();
|
|
279
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
310
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_chrome.UpdateDialog, { onError, rotation });
|
|
280
311
|
}
|
|
281
312
|
|
|
282
313
|
// src/hooks/useAppSettings.ts
|
|
@@ -446,18 +477,39 @@ function useProfiles() {
|
|
|
446
477
|
// src/RootLayout.tsx
|
|
447
478
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
448
479
|
var PLAY_OPTIONS = { statusBarHidden: true };
|
|
480
|
+
var KEEP_STATUS_BAR_OPTIONS = {};
|
|
481
|
+
var TRANSPARENT_CONTENT = { backgroundColor: "transparent" };
|
|
482
|
+
var noScreenOptions = () => ({});
|
|
449
483
|
function AppStack() {
|
|
484
|
+
const pack = usePack();
|
|
485
|
+
const { Backdrop } = pack;
|
|
450
486
|
const { dark } = (0, import_auto_paper2.useAutoPaperTheme)();
|
|
451
|
-
const rootBackground = (0, import_core6.useThemedRootBackground)(dark, false);
|
|
487
|
+
const rootBackground = (0, import_core6.useThemedRootBackground)(Backdrop ? true : dark, false);
|
|
452
488
|
const statusBar = (0, import_core6.useRotationAwareStatusBar)();
|
|
453
|
-
|
|
489
|
+
const packOptions = (pack.useScreenOptions ?? noScreenOptions)();
|
|
490
|
+
const backdropOptions = Backdrop ? { contentStyle: TRANSPARENT_CONTENT, animation: import_react_native2.Platform.select({ android: "fade" }) } : void 0;
|
|
491
|
+
const playOptions = (0, import_react9.useCallback)(
|
|
492
|
+
({ route }) => {
|
|
493
|
+
const id = route.params?.game;
|
|
494
|
+
return pack.games.some((g) => g.id === id && g.keepStatusBar) ? KEEP_STATUS_BAR_OPTIONS : PLAY_OPTIONS;
|
|
495
|
+
},
|
|
496
|
+
[pack.games]
|
|
497
|
+
);
|
|
498
|
+
const navigationTheme = (0, import_react9.useMemo)(() => Backdrop ? { ...import_expo_router.DarkTheme, colors: { ...import_expo_router.DarkTheme.colors, background: "transparent" } } : null, [Backdrop]);
|
|
499
|
+
const stack = /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_expo_router.Stack, { screenOptions: { ...rootBackground, ...statusBar, ...backdropOptions, ...packOptions }, children: [
|
|
454
500
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_expo_router.Stack.Screen, { name: "index" }),
|
|
455
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_expo_router.Stack.Screen, { name: "play/[game]", options:
|
|
501
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_expo_router.Stack.Screen, { name: "play/[game]", options: playOptions })
|
|
502
|
+
] });
|
|
503
|
+
if (!Backdrop || !navigationTheme) return stack;
|
|
504
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native2.View, { style: styles.root, children: [
|
|
505
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Backdrop, {}),
|
|
506
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_expo_router.ThemeProvider, { value: navigationTheme, children: stack })
|
|
456
507
|
] });
|
|
457
508
|
}
|
|
458
509
|
function OrientationBridge({ children }) {
|
|
459
510
|
const { settings, setSettings } = useAppSettings();
|
|
460
|
-
|
|
511
|
+
const { portraitWhileKeyboard } = usePack();
|
|
512
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_core6.OrientationProvider, { deviceMotion: import_expo_sensors.DeviceMotion, freezeWhileLocked: true, lockInitialValue: { locked: settings.lockOrientation, rotation: settings.lockedRotation }, onLockChange: (next) => setSettings({ lockOrientation: next.locked, lockedRotation: next.rotation }), portraitWhileKeyboard, children });
|
|
461
513
|
}
|
|
462
514
|
function GatedApp({ children }) {
|
|
463
515
|
const { loaded } = useProfiles();
|
|
@@ -465,24 +517,38 @@ function GatedApp({ children }) {
|
|
|
465
517
|
}
|
|
466
518
|
function HapticGatedToastProvider({ children }) {
|
|
467
519
|
const { settings } = (0, import_feedback_press2.useHapticSettings)();
|
|
468
|
-
|
|
520
|
+
const { Toaster: PackToasterComponent } = usePack();
|
|
521
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_toaster2.ToastProvider, { haptics: settings.vibrate ? Haptics : void 0, paper: PackToasterComponent ? void 0 : RNPaper2, children });
|
|
469
522
|
}
|
|
470
523
|
function RotatingToaster() {
|
|
471
524
|
const renderFrame = (0, import_react9.useCallback)(
|
|
472
|
-
(toasts) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
525
|
+
(toasts) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_chrome2.RotatedFrame, { rotatedSafeArea: true, passThrough: true, children: toasts }),
|
|
473
526
|
[]
|
|
474
527
|
);
|
|
475
528
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_toaster2.Toaster, { historyButton: null, clearButton: null, limit: 3, renderFrame });
|
|
476
529
|
}
|
|
530
|
+
function PackToaster({ Toaster: PackToasterComponent }) {
|
|
531
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native2.View, { style: import_react_native2.StyleSheet.absoluteFill, pointerEvents: "box-none", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_chrome2.RotatedFrame, { rotatedSafeArea: true, passThrough: true, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(PackToasterComponent, {}) }) });
|
|
532
|
+
}
|
|
477
533
|
function GameProviders({ games, children }) {
|
|
478
|
-
return games.reduceRight((inner, game) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(game.Provider, { children: inner }, game.id), children);
|
|
534
|
+
return games.reduceRight((inner, game) => game.Provider ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(game.Provider, { children: inner }, game.id) : inner, children);
|
|
535
|
+
}
|
|
536
|
+
function PreviewColors({ previewColor, children }) {
|
|
537
|
+
const { dark } = (0, import_auto_paper2.useAutoPaperTheme)();
|
|
538
|
+
const preview = (0, import_react9.useCallback)((hex) => previewColor(hex, dark), [previewColor, dark]);
|
|
539
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_profile3.ProfileColorProvider, { preview, children });
|
|
540
|
+
}
|
|
541
|
+
function PackRoot({ pack, children }) {
|
|
542
|
+
const { Provider, previewColor } = pack;
|
|
543
|
+
const inner = Provider ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Provider, { children }) : children;
|
|
544
|
+
return previewColor ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(PreviewColors, { previewColor, children: inner }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_jsx_runtime9.Fragment, { children: inner });
|
|
479
545
|
}
|
|
480
546
|
function RootLayout({ pack, store, persistor }) {
|
|
481
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_gesture_handler.GestureHandlerRootView, { style: styles.root, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_safe_area_context.SafeAreaProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(PackProvider, { pack, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Fonts, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Providers, { store, persistor, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Theme, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ProfilesProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(LastActiveGameProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(GameProviders, { games: pack.games, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(GatedApp, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(OrientationBridge, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(HapticGatedToastProvider, { children: [
|
|
547
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_gesture_handler.GestureHandlerRootView, { style: styles.root, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_safe_area_context.SafeAreaProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(PackProvider, { pack, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Fonts, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Providers, { store, persistor, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Theme, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ProfilesProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(LastActiveGameProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(GameProviders, { games: pack.games, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(PackRoot, { pack, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(GatedApp, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(OrientationBridge, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(HapticGatedToastProvider, { children: [
|
|
482
548
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(GuideHost, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(AppStack, {}) }),
|
|
483
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(RotatingToaster, {}),
|
|
549
|
+
pack.Toaster ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(PackToaster, { Toaster: pack.Toaster }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(RotatingToaster, {}),
|
|
484
550
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(UpdateDialog, {})
|
|
485
|
-
] }) }) }) }) }) }) }) }) }) }) }) });
|
|
551
|
+
] }) }) }) }) }) }) }) }) }) }) }) }) });
|
|
486
552
|
}
|
|
487
553
|
var styles = import_react_native2.StyleSheet.create({
|
|
488
554
|
root: { flex: 1 }
|
|
@@ -492,10 +558,17 @@ var styles = import_react_native2.StyleSheet.create({
|
|
|
492
558
|
var import_expo_router5 = require("expo-router");
|
|
493
559
|
var import_react14 = require("react");
|
|
494
560
|
|
|
561
|
+
// src/routes.ts
|
|
562
|
+
var playHref = (game) => ({ pathname: "/play/[game]", params: { game } });
|
|
563
|
+
var loadoutHref = (game) => ({ pathname: "/loadout/[game]", params: { game } });
|
|
564
|
+
var STATS_HREF = "/stats";
|
|
565
|
+
var PROFILES_HREF = "/profiles";
|
|
566
|
+
|
|
495
567
|
// src/screens/LoadoutScreen.tsx
|
|
496
568
|
var import_auto_paper4 = require("@rific/auto-paper");
|
|
497
569
|
var import_core10 = require("@tastic/core");
|
|
498
|
-
var
|
|
570
|
+
var import_chrome4 = require("@tastic/hud/chrome");
|
|
571
|
+
var import_lobby2 = require("@tastic/hud/lobby");
|
|
499
572
|
var import_split_screen = require("@tastic/split-screen");
|
|
500
573
|
var import_expo_router4 = require("expo-router");
|
|
501
574
|
var import_react13 = require("react");
|
|
@@ -505,8 +578,8 @@ var import_react_native_safe_area_context2 = require("react-native-safe-area-con
|
|
|
505
578
|
var import_react_redux9 = require("react-redux");
|
|
506
579
|
|
|
507
580
|
// src/components/SeatTwoPanel.tsx
|
|
508
|
-
var
|
|
509
|
-
var
|
|
581
|
+
var import_lobby = require("@tastic/hud/lobby");
|
|
582
|
+
var import_profile4 = require("@tastic/profile");
|
|
510
583
|
var import_react10 = require("react");
|
|
511
584
|
var import_react_native3 = require("react-native");
|
|
512
585
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
@@ -549,14 +622,14 @@ function SeatTwoPanel({ idPrefix, host, choices, seatTwo, onSeatTwoChange, cpuDi
|
|
|
549
622
|
};
|
|
550
623
|
const colorSection = seatTwo === "nobody" ? void 0 : { value: color, onChange: onColorChange, swatches, takenValue: takenColor, allowSwapTaken, caption: selectedProfile ? colorCaption : void 0 };
|
|
551
624
|
const pickerId = getSeatTwoPopoverId(idPrefix);
|
|
552
|
-
const size = (0,
|
|
553
|
-
const align = (0,
|
|
625
|
+
const size = (0, import_profile4.getOptionPickerContentSize)(options.length, colorSection);
|
|
626
|
+
const align = (0, import_lobby.useZoneClampedAlign)(host.openId === pickerId, size.width, size.height);
|
|
554
627
|
const ownPopoverOpen = host.openId?.startsWith(`${idPrefix}-`) ?? false;
|
|
555
628
|
const pickerRowOpen = secondPickerId !== void 0 && host.openId === secondPickerId;
|
|
556
629
|
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native3.View, { style: [styles2.panel, ownPopoverOpen && styles2.panelOpen], children: [
|
|
557
|
-
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
630
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_profile4.OptionPicker, { id: pickerId, host, options, value, onChange: handleChange, color, dark, icon, colorSection, alignOverride: align }),
|
|
558
631
|
isPerson && secondPicker && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native3.View, { style: [styles2.pickerRow, pickerRowOpen && styles2.pickerRowOpen], children: secondPicker }),
|
|
559
|
-
isPerson && showReadyButton && onToggleReady && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
632
|
+
isPerson && showReadyButton && onToggleReady && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lobby.ReadyButton, { color, ready: ready ?? false, onToggleReady })
|
|
560
633
|
] });
|
|
561
634
|
}
|
|
562
635
|
var styles2 = import_react_native3.StyleSheet.create({
|
|
@@ -582,13 +655,14 @@ var styles2 = import_react_native3.StyleSheet.create({
|
|
|
582
655
|
|
|
583
656
|
// src/components/SettingsDialog.tsx
|
|
584
657
|
var import_toaster3 = require("@rific/toaster");
|
|
585
|
-
var
|
|
658
|
+
var import_chrome3 = require("@tastic/hud/chrome");
|
|
586
659
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
587
660
|
function SettingsDialog({ visible, onDismiss, rotation = 0, onShowHowToPlay, children }) {
|
|
588
661
|
const onUpdateError = (0, import_toaster3.useUpdateErrorToast)();
|
|
589
662
|
const { settings, setSettings } = useAppSettings();
|
|
590
|
-
const { otaVersion, SettingsSections } = usePack();
|
|
591
|
-
|
|
663
|
+
const { otaVersion, SettingsSections, edgeGuard = true } = usePack();
|
|
664
|
+
const edgeGuardProps = edgeGuard ? { deferBottomEdgeGestures: settings.deferBottomEdgeGestures, onDeferBottomEdgeGestures: (value) => setSettings({ deferBottomEdgeGestures: value }) } : {};
|
|
665
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_chrome3.BaseSettingsDialog, { visible, onDismiss, rotation, version: otaVersion, lockOrientation: settings.lockOrientation, onLockOrientationChange: (value) => setSettings({ lockOrientation: value }), ...edgeGuardProps, onUpdateError, onShowHowToPlay, children: [
|
|
592
666
|
children,
|
|
593
667
|
SettingsSections && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SettingsSections, {})
|
|
594
668
|
] });
|
|
@@ -617,29 +691,33 @@ function useOpponent() {
|
|
|
617
691
|
|
|
618
692
|
// src/hooks/useSeatColors.ts
|
|
619
693
|
var import_auto_paper3 = require("@rific/auto-paper");
|
|
620
|
-
var
|
|
694
|
+
var import_profile6 = require("@tastic/profile");
|
|
621
695
|
var import_expo_router2 = require("expo-router");
|
|
622
696
|
var import_react12 = require("react");
|
|
623
697
|
var import_react_redux8 = require("react-redux");
|
|
624
698
|
|
|
625
699
|
// src/redux/seatColorsSlice.ts
|
|
626
|
-
var
|
|
700
|
+
var import_profile5 = require("@tastic/profile");
|
|
627
701
|
function defaultSeatColorsState(seatColors) {
|
|
628
702
|
return { lastGuestColor: { 1: seatColors[1], 2: seatColors[2] }, lastCpuColor: seatColors[2], profileColors: {} };
|
|
629
703
|
}
|
|
630
704
|
function createSeatColorsReducer(seatColors) {
|
|
631
|
-
return (0,
|
|
705
|
+
return (0, import_profile5.createSeatColorsSlice)("pack", defaultSeatColorsState(seatColors)).reducer;
|
|
632
706
|
}
|
|
633
|
-
var seatColorsActions = (0,
|
|
707
|
+
var seatColorsActions = (0, import_profile5.createSeatColorsSlice)("pack", defaultSeatColorsState({ 1: "", 2: "" })).actions;
|
|
634
708
|
|
|
635
709
|
// src/hooks/useSeatColors.ts
|
|
710
|
+
function sameTheme(current, next) {
|
|
711
|
+
const a = current.color;
|
|
712
|
+
const b = next.color;
|
|
713
|
+
const sameColor = typeof a === "string" || typeof b === "string" ? typeof a === typeof b && String(a).toLowerCase() === String(b).toLowerCase() : !!a && !!b && a.primary.toLowerCase() === b.primary.toLowerCase() && a.secondary.toLowerCase() === b.secondary.toLowerCase();
|
|
714
|
+
return sameColor && (next.harmony === void 0 || next.harmony === current.harmony);
|
|
715
|
+
}
|
|
636
716
|
function useSeatColors(p2IsHuman) {
|
|
637
|
-
const { colors: themeColors } = (0, import_auto_paper3.useAutoPaperTheme)();
|
|
638
|
-
const { set: setThemeColor } = (0, import_auto_paper3.useThemeSettings)();
|
|
639
|
-
const p1Color = themeColors.primary;
|
|
640
|
-
const p2Color = themeColors.secondary;
|
|
717
|
+
const { dark, colors: themeColors } = (0, import_auto_paper3.useAutoPaperTheme)();
|
|
718
|
+
const { settings: themeSettings, set: setThemeColor } = (0, import_auto_paper3.useThemeSettings)();
|
|
641
719
|
const { profiles, lastSelected } = useProfiles();
|
|
642
|
-
const { seatColors } = usePack();
|
|
720
|
+
const { seatColors, seatTheme } = usePack();
|
|
643
721
|
const seatDefaultColors = [seatColors[1], seatColors[2]];
|
|
644
722
|
const dispatch = (0, import_react_redux8.useDispatch)();
|
|
645
723
|
const guestColors = (0, import_react_redux8.useSelector)((state) => state.seatColors.lastGuestColor);
|
|
@@ -647,11 +725,21 @@ function useSeatColors(p2IsHuman) {
|
|
|
647
725
|
const profileColors = (0, import_react_redux8.useSelector)((state) => state.seatColors.profileColors);
|
|
648
726
|
const p1Profile = profiles.find((p) => p.id === lastSelected[1]) ?? null;
|
|
649
727
|
const p2Profile = p2IsHuman ? profiles.find((p) => p.id === lastSelected[2]) ?? null : null;
|
|
728
|
+
const rememberedColors = (p1Prof, p2Prof, picks, guest, cpu) => {
|
|
729
|
+
const p1 = p1Prof ? (0, import_profile6.profileSeatColor)(p1Prof, picks) : guest[1];
|
|
730
|
+
const p2 = (0, import_profile6.avoidSeatColorClash)(p1, p2Prof ? (0, import_profile6.profileSeatColor)(p2Prof, picks) : p2IsHuman ? guest[2] : cpu, seatDefaultColors);
|
|
731
|
+
return { p1, p2 };
|
|
732
|
+
};
|
|
733
|
+
const remembered = rememberedColors(p1Profile, p2Profile, profileColors, guestColors, cpuColor);
|
|
734
|
+
const p1Color = seatTheme ? remembered.p1 : themeColors.primary;
|
|
735
|
+
const p2Color = seatTheme ? remembered.p2 : themeColors.secondary;
|
|
736
|
+
const themeFor = (0, import_react12.useCallback)((p1, p2) => seatTheme ? seatTheme({ 1: p1, 2: p2 }, dark) : { color: { primary: p1, secondary: p2, tertiary: (0, import_auto_paper3.getThirdColor)(p1, p2) } }, [seatTheme, dark]);
|
|
650
737
|
const p1ProfileRef = (0, import_react12.useRef)(p1Profile);
|
|
651
738
|
const p2ProfileRef = (0, import_react12.useRef)(p2Profile);
|
|
652
739
|
const guestColorsRef = (0, import_react12.useRef)(guestColors);
|
|
653
740
|
const cpuColorRef = (0, import_react12.useRef)(cpuColor);
|
|
654
741
|
const profileColorsRef = (0, import_react12.useRef)(profileColors);
|
|
742
|
+
const themeForRef = (0, import_react12.useRef)(themeFor);
|
|
655
743
|
(0, import_react12.useEffect)(() => {
|
|
656
744
|
p1ProfileRef.current = p1Profile;
|
|
657
745
|
}, [p1Profile]);
|
|
@@ -668,21 +756,17 @@ function useSeatColors(p2IsHuman) {
|
|
|
668
756
|
profileColorsRef.current = profileColors;
|
|
669
757
|
}, [profileColors]);
|
|
670
758
|
(0, import_react12.useEffect)(() => {
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
759
|
+
themeForRef.current = themeFor;
|
|
760
|
+
}, [themeFor]);
|
|
761
|
+
(0, import_react12.useEffect)(() => {
|
|
762
|
+
const next = themeFor(remembered.p1, remembered.p2);
|
|
763
|
+
if (sameTheme(themeSettings, next)) return;
|
|
764
|
+
setThemeColor(next);
|
|
765
|
+
}, [lastSelected[1], lastSelected[2], p2IsHuman, guestColors, cpuColor, profileColors, profiles.length, dark]);
|
|
676
766
|
(0, import_expo_router2.useFocusEffect)(
|
|
677
767
|
(0, import_react12.useCallback)(() => {
|
|
678
|
-
const
|
|
679
|
-
|
|
680
|
-
const p1Prof = p1ProfileRef.current;
|
|
681
|
-
const p2Prof = p2ProfileRef.current;
|
|
682
|
-
const picks = profileColorsRef.current;
|
|
683
|
-
const nextP1 = p1Prof ? (0, import_profile5.profileSeatColor)(p1Prof, picks) : guest[1];
|
|
684
|
-
const nextP2 = (0, import_profile5.avoidSeatColorClash)(nextP1, p2Prof ? (0, import_profile5.profileSeatColor)(p2Prof, picks) : p2IsHuman ? guest[2] : cpu, seatDefaultColors);
|
|
685
|
-
setThemeColor({ color: { primary: nextP1, secondary: nextP2, tertiary: (0, import_auto_paper3.getThirdColor)(nextP1, nextP2) } });
|
|
768
|
+
const next = rememberedColors(p1ProfileRef.current, p2ProfileRef.current, profileColorsRef.current, guestColorsRef.current, cpuColorRef.current);
|
|
769
|
+
setThemeColor(themeForRef.current(next.p1, next.p2));
|
|
686
770
|
}, [lastSelected[1], lastSelected[2], p2IsHuman, setThemeColor])
|
|
687
771
|
);
|
|
688
772
|
const persistSeatColor = (0, import_react12.useCallback)(
|
|
@@ -704,21 +788,21 @@ function useSeatColors(p2IsHuman) {
|
|
|
704
788
|
(hex) => {
|
|
705
789
|
const swapped = hex.toLowerCase() === p2Color.toLowerCase();
|
|
706
790
|
const nextP2 = swapped ? p1Color : p2Color;
|
|
707
|
-
setThemeColor(
|
|
791
|
+
setThemeColor(themeFor(hex, nextP2));
|
|
708
792
|
persistSeatColor(1, hex);
|
|
709
793
|
if (swapped) persistSeatColor(2, nextP2);
|
|
710
794
|
},
|
|
711
|
-
[setThemeColor, p1Color, p2Color, persistSeatColor]
|
|
795
|
+
[setThemeColor, themeFor, p1Color, p2Color, persistSeatColor]
|
|
712
796
|
);
|
|
713
797
|
const handleP2ColorChange = (0, import_react12.useCallback)(
|
|
714
798
|
(hex) => {
|
|
715
799
|
const swapped = hex.toLowerCase() === p1Color.toLowerCase();
|
|
716
800
|
const nextP1 = swapped ? p2Color : p1Color;
|
|
717
|
-
setThemeColor(
|
|
801
|
+
setThemeColor(themeFor(nextP1, hex));
|
|
718
802
|
persistSeatColor(2, hex);
|
|
719
803
|
if (swapped) persistSeatColor(1, nextP1);
|
|
720
804
|
},
|
|
721
|
-
[setThemeColor, p1Color, p2Color, persistSeatColor]
|
|
805
|
+
[setThemeColor, themeFor, p1Color, p2Color, persistSeatColor]
|
|
722
806
|
);
|
|
723
807
|
return { p1Color, p2Color, handleP1ColorChange, handleP2ColorChange };
|
|
724
808
|
}
|
|
@@ -754,6 +838,7 @@ function LoadoutScreen({ game }) {
|
|
|
754
838
|
const fixedSeats = p2IsHuman && (!!game.twoPlayerSeats?.faceToFaceOnWeb || import_react_native4.Platform.OS !== "web");
|
|
755
839
|
const fixedUpsideDown = !!game.twoPlayerSeats?.followUpsideDown && orientationMode === "faceToFace" && upsideDown;
|
|
756
840
|
const { panelLayout, panelFadeStyle } = (0, import_split_screen.useDualZoneLayout)(fixedSeats ? "faceToFace" : orientationMode, fixedSeats ? true : p1OnRight, fixedSeats || p1OnRightResolved, fixedSeats ? fixedUpsideDown : upsideDown, PANEL_SWAP_FADE_MS);
|
|
841
|
+
const playersRowFade = panelFadeStyle;
|
|
757
842
|
const [settingsOpen, setSettingsOpen] = (0, import_react13.useState)(false);
|
|
758
843
|
const rotation = (0, import_core10.getViewRotation)(panelLayout.orientationMode, panelLayout.p1OnRight, panelLayout.upsideDown);
|
|
759
844
|
const insets = (0, import_core10.rotateInsets)((0, import_react_native_safe_area_context2.useSafeAreaInsets)(), rotation);
|
|
@@ -782,7 +867,7 @@ function LoadoutScreen({ game }) {
|
|
|
782
867
|
(0, import_react13.useEffect)(() => {
|
|
783
868
|
if (!humanSeats.every((s) => ready[s])) return;
|
|
784
869
|
dispatch(liveplayActions.setActiveRound({ game: game.id, mode, settings: roundSettingsRef.current }));
|
|
785
|
-
import_expo_router4.router.push(
|
|
870
|
+
import_expo_router4.router.push(playHref(game.id));
|
|
786
871
|
}, [ready, humanSeats, game.id, mode, dispatch]);
|
|
787
872
|
const bg = dark ? "#000000" : "#FFFFFF";
|
|
788
873
|
const fg = dark ? "#FFFFFF" : "#000000";
|
|
@@ -791,8 +876,8 @@ function LoadoutScreen({ game }) {
|
|
|
791
876
|
const showMetaInSharedBand = (0, import_split_screen.needsSharedNeutralZone)(panelLayout.orientationMode, humanSeats.length);
|
|
792
877
|
const p2ZoneStyle = p2IsHuman ? isPortrait ? styles3.p2ZoneTop : panelLayout.p1OnRight ? styles3.p2ZoneLeft : styles3.p2ZoneRight : null;
|
|
793
878
|
const showReadyButton = p2IsHuman;
|
|
794
|
-
const controlsHost = (0,
|
|
795
|
-
const p2PanelHost = (0,
|
|
879
|
+
const controlsHost = (0, import_chrome4.usePopoverHost)();
|
|
880
|
+
const p2PanelHost = (0, import_chrome4.usePopoverHost)();
|
|
796
881
|
const p2Host = p2IsHuman ? p2PanelHost : controlsHost;
|
|
797
882
|
const anyPlayerPickerOpen = !!(controlsHost.openId?.startsWith("p1-") || controlsHost.openId?.startsWith("p2-"));
|
|
798
883
|
const optionsRow = loadout.options({
|
|
@@ -807,17 +892,17 @@ function LoadoutScreen({ game }) {
|
|
|
807
892
|
onReset: showMetaInSharedBand ? void 0 : loadout.reset
|
|
808
893
|
});
|
|
809
894
|
const optionsPopoverOpen = controlsHost.openId !== null && loadout.optionIds.includes(controlsHost.openId);
|
|
810
|
-
const sharedControls = showMetaInSharedBand ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
895
|
+
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;
|
|
811
896
|
const controlLook = { accentColor: themeColors.tertiary, mutedColor: fgMuted, dark, rotation };
|
|
812
897
|
const p1Control = loadout.seatControl(1, controlsHost, { ...controlLook, seatColor: p1Color });
|
|
813
|
-
const p1Panel = /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
898
|
+
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, ready: ready[1], onToggleReady: () => setReady((r) => ({ ...r, 1: !r[1] })), dark, showReadyButton, secondPicker: p1Control, secondPickerId: p1Control ? "p1-control" : void 0, profiles, selectedProfileId: lastSelected[1], takenProfileId: p2IsHuman ? lastSelected[2] : null, guestLabel: "P1", onProfileSelect: handleP1ProfileSelect, onManageProfiles: () => import_expo_router4.router.push(PROFILES_HREF) });
|
|
814
899
|
const p2Control = p2IsHuman ? loadout.seatControl(2, p2Host, { ...controlLook, seatColor: p2Color }) : void 0;
|
|
815
900
|
const p2Panel = game.seatTwo && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SeatTwoPanel, { idPrefix: "p2", host: p2Host, choices: game.seatTwo, seatTwo, onSeatTwoChange: changeSeatTwo, cpuDifficulty: loadout.cpuDifficulty, profiles, selectedProfileId: lastSelected[2], onProfileSelect: handleP2ProfileSelect, color: p2Color, onColorChange: handleP2ColorChange, swatches: import_auto_paper4.defaultColors, takenColor: p1Color, allowSwapTaken: mode === "vsCpu", colorCaption: pack.colorCaption, dark, secondPicker: p2Control, secondPickerId: p2Control ? "p2-control" : void 0, ready: ready[2], onToggleReady: () => setReady((r) => ({ ...r, 2: !r[2] })), showReadyButton });
|
|
816
901
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native4.View, { style: [styles3.container, { backgroundColor: bg }], children: [
|
|
817
902
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_core10.FakeLandscapeView, { orientationMode: panelLayout.orientationMode, p1OnRight: panelLayout.p1OnRight, upsideDown: panelLayout.upsideDown, style: styles3.rotatable, children: [
|
|
818
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
819
|
-
p2ZoneStyle && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
820
|
-
!showMetaInSharedBand && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
903
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_chrome4.PressAwayOverlay, { active: controlsHost.openId !== null, onPress: controlsHost.close }),
|
|
904
|
+
p2ZoneStyle && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_chrome4.PressAwayOverlay, { active: controlsHost.openId !== null || p2Host.openId !== null, onPress: p2Host.close, style: p2ZoneStyle }),
|
|
905
|
+
!showMetaInSharedBand && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_chrome4.CornerActionButtons, { onBack: import_core8.safeBack, onSettings: () => setSettingsOpen(true), fg, insets }),
|
|
821
906
|
p2IsHuman ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
822
907
|
import_split_screen.DualZoneLayout,
|
|
823
908
|
{
|
|
@@ -832,11 +917,11 @@ function LoadoutScreen({ game }) {
|
|
|
832
917
|
}
|
|
833
918
|
) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native4.View, { style: styles3.stackedZone, children: [
|
|
834
919
|
sharedControls,
|
|
835
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native_reanimated2.default.View, { style: [styles3.playersRow, anyPlayerPickerOpen && styles3.playersRowOpen,
|
|
920
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native_reanimated2.default.View, { style: [styles3.playersRow, anyPlayerPickerOpen && styles3.playersRowOpen, playersRowFade], children: [
|
|
836
921
|
!isPortrait && panelLayout.p1OnRight ? p2Panel : p1Panel,
|
|
837
922
|
!isPortrait && panelLayout.p1OnRight ? p1Panel : p2Panel
|
|
838
923
|
] }),
|
|
839
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
924
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lobby2.ReadyButton, { color: p1Color, ready: ready[1], onToggleReady: () => setReady((r) => ({ ...r, 1: !r[1] })), style: anyPlayerPickerOpen && styles3.readyButtonHidden })
|
|
840
925
|
] })
|
|
841
926
|
] }),
|
|
842
927
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SettingsDialog, { visible: settingsOpen, onDismiss: () => setSettingsOpen(false), rotation, onShowHowToPlay: () => openFor(game.id) })
|
|
@@ -902,7 +987,7 @@ function LoadoutRoute() {
|
|
|
902
987
|
const { game: id } = (0, import_expo_router5.useLocalSearchParams)();
|
|
903
988
|
const game = usePackGame(id);
|
|
904
989
|
if (!game) return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_expo_router5.Redirect, { href: "/" });
|
|
905
|
-
if (!hasLoadout(game)) return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_expo_router5.Redirect, { href:
|
|
990
|
+
if (!hasLoadout(game)) return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_expo_router5.Redirect, { href: playHref(game.id) });
|
|
906
991
|
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(LoadoutScreen, { game }, game.id);
|
|
907
992
|
}
|
|
908
993
|
function hasLoadout(game) {
|
|
@@ -929,8 +1014,8 @@ function useResumePoint(gameId) {
|
|
|
929
1014
|
var import_auto_paper5 = require("@rific/auto-paper");
|
|
930
1015
|
var import_feedback_press3 = require("@rific/feedback-press");
|
|
931
1016
|
var import_core12 = require("@tastic/core");
|
|
932
|
-
var
|
|
933
|
-
var
|
|
1017
|
+
var import_chrome5 = require("@tastic/hud/chrome");
|
|
1018
|
+
var import_profile7 = require("@tastic/profile");
|
|
934
1019
|
var import_expo_router6 = require("expo-router");
|
|
935
1020
|
var import_react16 = require("react");
|
|
936
1021
|
var import_react_native5 = require("react-native");
|
|
@@ -1018,11 +1103,15 @@ var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
|
1018
1103
|
function HomeScreen() {
|
|
1019
1104
|
const pack = usePack();
|
|
1020
1105
|
const { consumeResumeGame } = useLastActiveGame();
|
|
1106
|
+
const { autoShowPack } = useGameGuide();
|
|
1021
1107
|
const [resumeGame] = (0, import_react16.useState)(() => {
|
|
1022
1108
|
const id = consumeResumeGame();
|
|
1023
1109
|
return pack.games.find((g) => g.id === id && g.resumable) ?? null;
|
|
1024
1110
|
});
|
|
1025
|
-
|
|
1111
|
+
(0, import_react16.useEffect)(() => {
|
|
1112
|
+
if (!resumeGame) autoShowPack();
|
|
1113
|
+
}, [resumeGame, autoShowPack]);
|
|
1114
|
+
if (resumeGame) return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_expo_router6.Redirect, { href: playHref(resumeGame.id) });
|
|
1026
1115
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(HomeMenu, {});
|
|
1027
1116
|
}
|
|
1028
1117
|
function HomeMenu() {
|
|
@@ -1030,9 +1119,10 @@ function HomeMenu() {
|
|
|
1030
1119
|
const rotation = (0, import_core12.useRotation)();
|
|
1031
1120
|
const layout = useHomeLayout();
|
|
1032
1121
|
const { insets } = layout;
|
|
1033
|
-
const { dark } = (0, import_auto_paper5.useAutoPaperTheme)();
|
|
1034
|
-
const { openFirstTime, openFor } = useGameGuide();
|
|
1122
|
+
const { dark, colors } = (0, import_auto_paper5.useAutoPaperTheme)();
|
|
1123
|
+
const { openFirstTime, openFor, openPack } = useGameGuide();
|
|
1035
1124
|
const [settingsOpen, setSettingsOpen] = (0, import_react16.useState)(false);
|
|
1125
|
+
const [rulesGame, setRulesGame] = (0, import_react16.useState)(null);
|
|
1036
1126
|
const isFocused = (0, import_expo_router6.useIsFocused)();
|
|
1037
1127
|
const [appState, setAppState] = (0, import_react16.useState)(import_react_native5.AppState.currentState);
|
|
1038
1128
|
(0, import_react16.useEffect)(() => {
|
|
@@ -1043,7 +1133,7 @@ function HomeMenu() {
|
|
|
1043
1133
|
const { profiles, lastSelected, selectProfile } = useProfiles();
|
|
1044
1134
|
const { seatTwo } = useOpponent();
|
|
1045
1135
|
const { p1Color, p2Color, handleP1ColorChange } = useSeatColors(seatTwo === "person");
|
|
1046
|
-
const pickerHost = (0,
|
|
1136
|
+
const pickerHost = (0, import_chrome5.usePopoverHost)();
|
|
1047
1137
|
const selectedProfile = profiles.find((p) => p.id === lastSelected[1]) ?? null;
|
|
1048
1138
|
const tiled = pack.games.some((game) => game.Preview);
|
|
1049
1139
|
const isWide = useFrozenWhileHidden(tiled && layout.isWide, !isFocused);
|
|
@@ -1056,65 +1146,85 @@ function HomeMenu() {
|
|
|
1056
1146
|
const closePicker = pickerHost.close;
|
|
1057
1147
|
(0, import_react16.useEffect)(() => {
|
|
1058
1148
|
closePicker();
|
|
1059
|
-
}, [isWide, closePicker]);
|
|
1060
|
-
const bg = dark ? "#000000" : "#FFFFFF";
|
|
1061
|
-
const fg = dark ? "#FFFFFF" : "#000000";
|
|
1062
|
-
const
|
|
1063
|
-
const
|
|
1149
|
+
}, [isWide, rotation, layout.windowWidth, layout.windowHeight, closePicker]);
|
|
1150
|
+
const bg = pack.Backdrop ? "transparent" : dark ? "#000000" : "#FFFFFF";
|
|
1151
|
+
const fg = pack.foreground ?? (dark ? "#FFFFFF" : "#000000");
|
|
1152
|
+
const { previewColor } = pack;
|
|
1153
|
+
const p1Drawn = previewColor ? previewColor(p1Color, dark) : p1Color;
|
|
1154
|
+
const triggerStyle = (0, import_react16.useMemo)(() => pack.Backdrop ? [styles4.pill, { backgroundColor: colors.surface }] : void 0, [pack.Backdrop, colors.surface]);
|
|
1155
|
+
const openGame = (0, import_react16.useCallback)((game) => openFirstTime(game.id, () => import_expo_router6.router.push(game.useLoadout ? loadoutHref(game.id) : playHref(game.id))), [openFirstTime]);
|
|
1156
|
+
const openRules = (0, import_react16.useCallback)((game) => game.Rules ? setRulesGame(game) : openFor(game.id), [openFor]);
|
|
1157
|
+
const colorSection = { value: p1Color, onChange: handleP1ColorChange, swatches: import_auto_paper5.defaultColors, caption: selectedProfile ? pack.colorCaption : void 0, previewValue: previewColor ? (hex) => previewColor(hex, dark) : void 0 };
|
|
1158
|
+
const usePickerAlign = pack.usePickerAlign ?? noPickerAlign;
|
|
1159
|
+
const pickerSize = (0, import_profile7.getProfilePickerContentSize)(profiles.length, true, colorSection);
|
|
1160
|
+
const pickerAlign = usePickerAlign(pickerHost.openId === `${SEAT_ONE_PICKER}-profile`, pickerSize.width, pickerSize.height);
|
|
1161
|
+
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 });
|
|
1162
|
+
const pressAway = /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_chrome5.PressAwayOverlay, { active: pickerHost.openId !== null, onPress: pickerHost.close, style: styles4.pressAway });
|
|
1163
|
+
const RulesSheet = rulesGame?.Rules;
|
|
1064
1164
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native5.View, { style: [styles4.container, { backgroundColor: bg }], children: [
|
|
1065
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.
|
|
1066
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_hud6.PressAwayOverlay, { active: pickerHost.openId !== null, onPress: pickerHost.close }),
|
|
1165
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_core12.FakeLandscapeView, { style: styles4.rotatable, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(RulesHost, { enabled: pack.games.some((game) => game.Rules), children: [
|
|
1067
1166
|
isWide ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
1068
|
-
|
|
1167
|
+
pressAway,
|
|
1168
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_auto_paper5.FadingScrollView, { 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: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native5.View, { style: [styles4.grid, { width: layout.rightPaneWidth }], children: pack.games.map((game) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(GameTile, { game, width: layout.tileWidth, previewWidth: layout.previewWidth, previewRevealed: previewsRevealed, dark, p1Color, p2Color, onPress: () => openGame(game), onRules: hasRules(game) ? () => openRules(game) : void 0 }, game.id)) }) }),
|
|
1069
1169
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native5.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: [
|
|
1070
1170
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(pack.HeroTitle, { words: pack.wordmark, color: fg, p1Color, p2Color, active: heroActive, fit: layout.heroFit }),
|
|
1071
1171
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native5.View, { style: styles4.widePicker, children: picker })
|
|
1072
1172
|
] })
|
|
1073
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1173
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_auto_paper5.FadingScrollView, { style: styles4.scroll, contentContainerStyle: [styles4.content, { paddingTop: 56 + insets.top, paddingBottom: 24 + insets.bottom, paddingLeft: 16 + insets.left, paddingRight: 16 + insets.right }], children: [
|
|
1174
|
+
pressAway,
|
|
1074
1175
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(pack.HeroTitle, { words: pack.wordmark, color: fg, p1Color, p2Color, active: heroActive }),
|
|
1075
1176
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native5.View, { style: [styles4.picker, pickerHost.openId !== null && styles4.pickerOpen], children: picker }),
|
|
1076
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native5.View, { style: styles4.list, children: pack.games.map((game) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(GameRow, { game, dark, p1Color, p2Color, previewRevealed: previewsRevealed, onPress: () => openGame(game), onRules: () =>
|
|
1177
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native5.View, { style: styles4.list, children: pack.games.map((game) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(GameRow, { game, dark, p1Color, p2Color, previewRevealed: previewsRevealed, onPress: () => openGame(game), onRules: hasRules(game) ? () => openRules(game) : void 0 }, game.id)) })
|
|
1077
1178
|
] }),
|
|
1078
|
-
/* @__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(
|
|
1079
|
-
/* @__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" })
|
|
1080
|
-
|
|
1081
|
-
|
|
1179
|
+
/* @__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" }),
|
|
1180
|
+
/* @__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" }),
|
|
1181
|
+
RulesSheet && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(RulesSheet, { visible: true, onDismiss: () => setRulesGame(null) })
|
|
1182
|
+
] }) }),
|
|
1183
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SettingsDialog, { visible: settingsOpen, onDismiss: () => setSettingsOpen(false), rotation, onShowHowToPlay: pack.guide ? openPack : void 0 })
|
|
1082
1184
|
] });
|
|
1083
1185
|
}
|
|
1186
|
+
var SEAT_ONE_PICKER = "home-p1";
|
|
1187
|
+
var noPickerAlign = () => void 0;
|
|
1188
|
+
function hasRules(game) {
|
|
1189
|
+
return !!(game.Rules || game.guide);
|
|
1190
|
+
}
|
|
1191
|
+
function RulesHost({ enabled, children }) {
|
|
1192
|
+
return enabled ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper.Portal.Host, { children }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_jsx_runtime14.Fragment, { children });
|
|
1193
|
+
}
|
|
1084
1194
|
function GameRow({ game, dark, p1Color, p2Color, previewRevealed, onPress, onRules }) {
|
|
1085
|
-
const well = (0,
|
|
1195
|
+
const well = (0, import_chrome5.useWellColors)();
|
|
1086
1196
|
const GameIcon = game.icon;
|
|
1087
1197
|
return (
|
|
1088
1198
|
// The rules button sits beside the row's own button, laid over its end, not inside it: a button
|
|
1089
1199
|
// inside a button is invalid on the web.
|
|
1090
1200
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native5.View, { children: [
|
|
1091
1201
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_feedback_press3.Pressable, { onPress, style: [styles4.row, { backgroundColor: well.bg }], accessibilityRole: "button", accessibilityLabel: game.title, children: [
|
|
1092
|
-
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_native5.View, { style: [styles4.rowIcon, { backgroundColor: dark ? ICON_DARK_BG : ICON_LIGHT_BG }], children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(GameIcon, { size: ROW_ICON_SIZE, p1Color, p2Color, dark }) }),
|
|
1202
|
+
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_native5.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 }) }),
|
|
1093
1203
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native5.View, { style: styles4.rowText, children: [
|
|
1094
1204
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper.Text, { variant: "titleLarge", style: [styles4.rowTitle, { color: well.fg }], numberOfLines: 1, children: game.title }),
|
|
1095
1205
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper.Text, { variant: "bodyMedium", style: { color: well.fgMuted }, numberOfLines: 2, children: game.blurb })
|
|
1096
1206
|
] })
|
|
1097
1207
|
] }),
|
|
1098
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_feedback_press3.Pressable, { onPress: onRules, style: styles4.rulesButton, hitSlop: 12, accessibilityRole: "button", accessibilityLabel: `${game.title} rules`, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper.Icon, { source: "information-outline", size: 22, color: well.fgMuted }) })
|
|
1208
|
+
onRules && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_feedback_press3.Pressable, { onPress: onRules, style: styles4.rulesButton, hitSlop: 12, accessibilityRole: "button", accessibilityLabel: `${game.title} rules`, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper.Icon, { source: "information-outline", size: 22, color: well.fgMuted }) })
|
|
1099
1209
|
] })
|
|
1100
1210
|
);
|
|
1101
1211
|
}
|
|
1102
1212
|
function GameTile({ game, width, previewWidth, dark, p1Color, p2Color, previewRevealed, onPress, onRules }) {
|
|
1103
|
-
const well = (0,
|
|
1213
|
+
const well = (0, import_chrome5.useWellColors)();
|
|
1104
1214
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native5.View, { style: { width }, children: [
|
|
1105
1215
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_feedback_press3.Pressable, { onPress, style: [styles4.tile, { backgroundColor: well.bg }], accessibilityRole: "button", accessibilityLabel: game.title, children: [
|
|
1106
1216
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(PreviewBox, { game, width: previewWidth, revealed: previewRevealed, dark, p1Color, p2Color }),
|
|
1107
1217
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper.Text, { variant: "titleMedium", style: [styles4.rowTitle, { color: well.fg }], numberOfLines: 1, children: game.title }),
|
|
1108
1218
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper.Text, { variant: "bodySmall", style: { color: well.fgMuted }, numberOfLines: 3, children: game.blurb })
|
|
1109
1219
|
] }),
|
|
1110
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_feedback_press3.Pressable, { onPress: onRules, style: styles4.tileRulesButton, hitSlop: 12, accessibilityRole: "button", accessibilityLabel: `${game.title} rules`, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper.Icon, { source: "information-outline", size: 20, color: "#FFFFFF" }) })
|
|
1220
|
+
onRules && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_feedback_press3.Pressable, { onPress: onRules, style: styles4.tileRulesButton, hitSlop: 12, accessibilityRole: "button", accessibilityLabel: `${game.title} rules`, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper.Icon, { source: "information-outline", size: 20, color: "#FFFFFF" }) })
|
|
1111
1221
|
] });
|
|
1112
1222
|
}
|
|
1113
1223
|
function PreviewBox({ game, width, revealed, dark, p1Color, p2Color }) {
|
|
1114
1224
|
const height = Math.round(width / PREVIEW_ASPECT);
|
|
1115
1225
|
const { Preview, icon: GameIcon } = game;
|
|
1116
1226
|
const iconSize = Math.min(height, ROW_ICON_SIZE);
|
|
1117
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native5.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 }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native5.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 }) }) });
|
|
1227
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native5.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_native5.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 }) }) });
|
|
1118
1228
|
}
|
|
1119
1229
|
var ROW_ICON_SIZE = 56;
|
|
1120
1230
|
var ICON_LIGHT_BG = "#FAFAFA";
|
|
@@ -1149,6 +1259,15 @@ var styles4 = import_react_native5.StyleSheet.create({
|
|
|
1149
1259
|
pickerOpen: {
|
|
1150
1260
|
zIndex: 100
|
|
1151
1261
|
},
|
|
1262
|
+
// Seat 1's button on the theme's surface (over a backdrop), the same pill as the tiles' wells.
|
|
1263
|
+
pill: {
|
|
1264
|
+
borderRadius: 999
|
|
1265
|
+
},
|
|
1266
|
+
// Over the rows (and, wide, the grid), whose own stacking is unset, so a press on them reaches it on
|
|
1267
|
+
// the web too, and under the raised button and left pane, so the menu's rows stay pressable.
|
|
1268
|
+
pressAway: {
|
|
1269
|
+
zIndex: 5
|
|
1270
|
+
},
|
|
1152
1271
|
// The preview's own rounding, clipping whatever it draws to the box.
|
|
1153
1272
|
preview: {
|
|
1154
1273
|
alignItems: "center",
|
|
@@ -1167,7 +1286,7 @@ var styles4 = import_react_native5.StyleSheet.create({
|
|
|
1167
1286
|
row: {
|
|
1168
1287
|
alignItems: "center",
|
|
1169
1288
|
borderRadius: 12,
|
|
1170
|
-
boxShadow:
|
|
1289
|
+
boxShadow: import_chrome5.WELL_SHADOW,
|
|
1171
1290
|
flexDirection: "row",
|
|
1172
1291
|
gap: 14,
|
|
1173
1292
|
padding: 14,
|
|
@@ -1199,7 +1318,7 @@ var styles4 = import_react_native5.StyleSheet.create({
|
|
|
1199
1318
|
// The same well as a row, turned on its side.
|
|
1200
1319
|
tile: {
|
|
1201
1320
|
borderRadius: 12,
|
|
1202
|
-
boxShadow:
|
|
1321
|
+
boxShadow: import_chrome5.WELL_SHADOW,
|
|
1203
1322
|
gap: 6,
|
|
1204
1323
|
padding: HOME_TILE_PADDING
|
|
1205
1324
|
},
|
|
@@ -1239,66 +1358,109 @@ var styles4 = import_react_native5.StyleSheet.create({
|
|
|
1239
1358
|
|
|
1240
1359
|
// src/screens/ProfilesRoute.tsx
|
|
1241
1360
|
var import_auto_paper6 = require("@rific/auto-paper");
|
|
1242
|
-
var
|
|
1361
|
+
var import_chrome6 = require("@tastic/hud/chrome");
|
|
1362
|
+
var import_profile8 = require("@tastic/profile");
|
|
1243
1363
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
1364
|
+
var ROSTER_MAX_WIDTH = 640;
|
|
1365
|
+
function useRosterAlign(open, contentWidth, contentHeight) {
|
|
1366
|
+
const { usePickerAlign } = usePack();
|
|
1367
|
+
return usePickerAlign(open, contentWidth, contentHeight, { maxContentWidth: ROSTER_MAX_WIDTH });
|
|
1368
|
+
}
|
|
1244
1369
|
function ProfilesRoute() {
|
|
1245
1370
|
const { profiles, createProfile, updateProfile, deleteProfile } = useProfiles();
|
|
1246
|
-
|
|
1371
|
+
const { Backdrop, foreground, newProfileColor, usePickerAlign } = usePack();
|
|
1372
|
+
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 }) });
|
|
1247
1373
|
}
|
|
1248
1374
|
|
|
1249
1375
|
// src/screens/StatsScreen.tsx
|
|
1250
1376
|
var import_auto_paper7 = require("@rific/auto-paper");
|
|
1251
|
-
var
|
|
1252
|
-
var
|
|
1253
|
-
var import_profile8 = require("@tastic/profile");
|
|
1377
|
+
var import_chrome7 = require("@tastic/hud/chrome");
|
|
1378
|
+
var import_profile9 = require("@tastic/profile");
|
|
1254
1379
|
var import_react17 = require("react");
|
|
1255
1380
|
var import_react_native6 = require("react-native");
|
|
1256
1381
|
var import_react_native_paper2 = require("react-native-paper");
|
|
1257
1382
|
var import_react_native_safe_area_context4 = require("react-native-safe-area-context");
|
|
1258
1383
|
var import_react_redux10 = require("react-redux");
|
|
1259
1384
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
1385
|
+
var STATS = "stats";
|
|
1386
|
+
var ACHIEVEMENTS = "achievements";
|
|
1260
1387
|
var TABS = [
|
|
1261
|
-
{ value:
|
|
1262
|
-
{ value:
|
|
1388
|
+
{ value: STATS, label: "Stats", icon: "chart-box-outline" },
|
|
1389
|
+
{ value: ACHIEVEMENTS, label: "Achievements", icon: "trophy-outline" }
|
|
1263
1390
|
];
|
|
1391
|
+
var LABEL_WIDE_TAB = { flexBasis: "auto", flexGrow: 1, flexShrink: 1 };
|
|
1392
|
+
var NO_PACK_TABS = [];
|
|
1264
1393
|
var EVERYONE = "__everyone__";
|
|
1265
1394
|
var ALL_GAMES = "__all__";
|
|
1266
1395
|
var PLAYER_PICKER_ID = "stats-player";
|
|
1267
1396
|
var GAME_PICKER_ID = "stats-game";
|
|
1397
|
+
var STATS_MAX_WIDTH = 640;
|
|
1268
1398
|
function StatsScreen() {
|
|
1399
|
+
const pickerHost = (0, import_chrome7.usePopoverHost)();
|
|
1400
|
+
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 }) }) });
|
|
1401
|
+
}
|
|
1402
|
+
function StatsPressAway({ host, children }) {
|
|
1403
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native6.View, { testID: "stats-press-away", style: styles5.screen, onStartShouldSetResponder: () => host.openId !== null, onResponderRelease: host.close, children });
|
|
1404
|
+
}
|
|
1405
|
+
var useNoPackReset = () => null;
|
|
1406
|
+
var noPickerAlign2 = () => void 0;
|
|
1407
|
+
function StatsContent({ pickerHost }) {
|
|
1269
1408
|
const pack = usePack();
|
|
1270
1409
|
const { dark, colors } = (0, import_auto_paper7.useAutoPaperTheme)();
|
|
1271
|
-
const
|
|
1272
|
-
const
|
|
1273
|
-
const { profiles } = useProfiles();
|
|
1410
|
+
const insets = (0, import_react_native_safe_area_context4.useSafeAreaInsets)();
|
|
1411
|
+
const { profiles, lastSelected } = useProfiles();
|
|
1274
1412
|
const dispatch = (0, import_react_redux10.useDispatch)();
|
|
1275
|
-
const
|
|
1276
|
-
const [tab, setTab] = (0, import_react17.useState)(
|
|
1413
|
+
const fg = pack.foreground ?? colors.onBackground;
|
|
1414
|
+
const [tab, setTab] = (0, import_react17.useState)(STATS);
|
|
1277
1415
|
const [gameId, setGameId] = (0, import_react17.useState)(ALL_GAMES);
|
|
1278
|
-
const [selectedProfileId, setSelectedProfileId] = (0, import_react17.useState)(null);
|
|
1279
|
-
const profileId = selectedProfileId && profiles.some((p) => p.id === selectedProfileId) ? selectedProfileId : null;
|
|
1416
|
+
const [selectedProfileId, setSelectedProfileId] = (0, import_react17.useState)(() => pack.guestStats ? lastSelected[1] ?? GUEST_PLAYER_ID : null);
|
|
1417
|
+
const profileId = selectedProfileId && profiles.length > 0 && (pack.guestStats && selectedProfileId === GUEST_PLAYER_ID || profiles.some((p) => p.id === selectedProfileId)) ? selectedProfileId : null;
|
|
1280
1418
|
const games = gameId === ALL_GAMES ? pack.games : pack.games.filter((g) => g.id === gameId);
|
|
1281
|
-
const
|
|
1419
|
+
const packTabs = pack.statsTabs ?? NO_PACK_TABS;
|
|
1420
|
+
const packTab = packTabs.find((t) => t.value === tab);
|
|
1421
|
+
const showGamePicker = !(tab === ACHIEVEMENTS && pack.AchievementList);
|
|
1422
|
+
const playerOptions = (0, import_react17.useMemo)(() => [{ value: EVERYONE, label: "Everyone", icon: "account-group" }, ...pack.guestStats ? [{ value: GUEST_PLAYER_ID, label: "Guest", icon: "account-outline" }] : [], ...profiles.map((p) => ({ value: p.id, label: p.name, icon: "account", color: pack.previewColor ? pack.previewColor(p.color, dark) : p.color }))], [profiles, pack, dark]);
|
|
1282
1423
|
const gameOptions = (0, import_react17.useMemo)(() => [{ value: ALL_GAMES, label: "All Games", icon: "view-grid-outline" }, ...pack.games.map((g) => ({ value: g.id, label: g.title }))], [pack.games]);
|
|
1283
|
-
const
|
|
1284
|
-
const
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1424
|
+
const tabButtons = (0, import_react17.useMemo)(() => packTabs.length > 0 ? [{ value: STATS, label: "Stats" }, ...packTabs.map(({ value, label }) => ({ value, label })), { value: ACHIEVEMENTS, label: "Achievements" }].map((button) => ({ ...button, style: LABEL_WIDE_TAB })) : TABS, [packTabs]);
|
|
1425
|
+
const title = tab === STATS ? "Stats" : tab === ACHIEVEMENTS ? "Achievements" : packTab?.label ?? "";
|
|
1426
|
+
const usePackReset = pack.resetStats?.useReset ?? useNoPackReset;
|
|
1427
|
+
const packReset = usePackReset();
|
|
1428
|
+
const reset = resetFor(pack, packReset, profileId, profiles, games, () => games.forEach((g) => g.resetStats && dispatch(g.resetStats())));
|
|
1429
|
+
const usePickerAlign = pack.usePickerAlign ?? noPickerAlign2;
|
|
1430
|
+
const playerSize = (0, import_profile9.getOptionPickerContentSize)(playerOptions.length);
|
|
1431
|
+
const gameSize = (0, import_profile9.getOptionPickerContentSize)(gameOptions.length);
|
|
1432
|
+
const playerAlign = usePickerAlign(pickerHost.openId === PLAYER_PICKER_ID, playerSize.width, playerSize.height);
|
|
1433
|
+
const gameAlign = usePickerAlign(pickerHost.openId === GAME_PICKER_ID, gameSize.width, gameSize.height);
|
|
1434
|
+
const surface = pack.Backdrop ? { backgroundColor: colors.surface } : void 0;
|
|
1435
|
+
const triggerStyle = pack.Backdrop ? [styles5.pill, surface] : void 0;
|
|
1436
|
+
const PackTabContent = packTab?.Content;
|
|
1437
|
+
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: [
|
|
1438
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_chrome7.PressAwayOverlay, { active: pickerHost.openId !== null, onPress: pickerHost.close, style: styles5.pressAway }),
|
|
1439
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native_paper2.SegmentedButtons, { value: tab, onValueChange: setTab, buttons: tabButtons, style: [styles5.tabs, surface] }),
|
|
1440
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native6.View, { style: [styles5.filters, pickerHost.openId !== null && styles5.filtersOpen], onStartShouldSetResponder: () => pickerHost.openId !== null, children: [
|
|
1441
|
+
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 }),
|
|
1442
|
+
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 })
|
|
1291
1443
|
] }),
|
|
1292
|
-
tab ===
|
|
1293
|
-
|
|
1294
|
-
|
|
1444
|
+
tab === STATS && pack.StatsSections && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(pack.StatsSections, { profileId, gameId: gameId === ALL_GAMES ? null : gameId }),
|
|
1445
|
+
PackTabContent && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(PackTabContent, { profileId, gameId: gameId === ALL_GAMES ? null : gameId }),
|
|
1446
|
+
tab === ACHIEVEMENTS && pack.AchievementList ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(pack.AchievementList, { profileId }) : (tab === STATS || tab === ACHIEVEMENTS) && games.map((game) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(GameStats, { game, tab, profileId, showTitle: games.length > 1 && pack.statsGameTitles !== false, titleColor: fg }, game.id))
|
|
1447
|
+
] });
|
|
1448
|
+
}
|
|
1449
|
+
function resetFor(pack, packReset, profileId, profiles, games, resetGames) {
|
|
1450
|
+
if (pack.resetStats && packReset) {
|
|
1451
|
+
const name = profileId === GUEST_PLAYER_ID ? "Guest" : profileId ? profiles.find((p) => p.id === profileId)?.name ?? null : null;
|
|
1452
|
+
return { onReset: () => packReset(profileId), ...pack.resetStats.labels(name) };
|
|
1453
|
+
}
|
|
1454
|
+
const scope = games.length === 1 ? games[0].title : "every game";
|
|
1455
|
+
return { onReset: resetGames, label: games.length === 1 ? `Reset ${scope} Stats` : "Reset All Stats", title: "Reset Stats?", body: `Erases every player's stats and achievements in ${scope}. This cannot be undone.` };
|
|
1295
1456
|
}
|
|
1296
|
-
function GameStats({ game, tab, profileId, showTitle }) {
|
|
1297
|
-
const { colors } = (0, import_auto_paper7.useAutoPaperTheme)();
|
|
1457
|
+
function GameStats({ game, tab, profileId, showTitle, titleColor }) {
|
|
1298
1458
|
const { StatsSections, AchievementList } = game;
|
|
1459
|
+
const Sections = tab === STATS ? StatsSections : AchievementList;
|
|
1460
|
+
if (!Sections) return null;
|
|
1299
1461
|
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native6.View, { style: styles5.game, children: [
|
|
1300
|
-
showTitle && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native_paper2.Text, { variant: "titleLarge", style: [styles5.gameTitle, { color:
|
|
1301
|
-
|
|
1462
|
+
showTitle && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native_paper2.Text, { variant: "titleLarge", style: [styles5.gameTitle, { color: titleColor }], children: game.title }),
|
|
1463
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Sections, { profileId })
|
|
1302
1464
|
] });
|
|
1303
1465
|
}
|
|
1304
1466
|
var styles5 = import_react_native6.StyleSheet.create({
|
|
@@ -1318,14 +1480,17 @@ var styles5 = import_react_native6.StyleSheet.create({
|
|
|
1318
1480
|
fontWeight: "bold",
|
|
1319
1481
|
marginTop: 8
|
|
1320
1482
|
},
|
|
1483
|
+
// A picker's button on the theme's surface (over a backdrop), the same pill as Home's.
|
|
1484
|
+
pill: {
|
|
1485
|
+
borderRadius: 999
|
|
1486
|
+
},
|
|
1321
1487
|
pressAway: {
|
|
1322
1488
|
zIndex: 50
|
|
1323
1489
|
},
|
|
1324
|
-
|
|
1325
|
-
rotatable: {
|
|
1490
|
+
screen: {
|
|
1326
1491
|
flex: 1
|
|
1327
1492
|
},
|
|
1328
|
-
// SegmentedButtons' own rounding.
|
|
1493
|
+
// SegmentedButtons' own rounding, so a surface behind it is the same pill.
|
|
1329
1494
|
tabs: {
|
|
1330
1495
|
borderRadius: 20
|
|
1331
1496
|
}
|
|
@@ -1356,12 +1521,12 @@ var import_redux_persist = require("redux-persist");
|
|
|
1356
1521
|
|
|
1357
1522
|
// src/redux/shellState.ts
|
|
1358
1523
|
var import_auto_paper8 = require("@rific/auto-paper");
|
|
1359
|
-
var
|
|
1524
|
+
var import_core13 = require("@rific/core");
|
|
1360
1525
|
var import_feedback_press4 = require("@rific/feedback-press");
|
|
1361
|
-
var
|
|
1526
|
+
var import_profile10 = require("@tastic/profile");
|
|
1362
1527
|
var initialSoundSettings = { ...import_feedback_press4.defaultSoundSettings, enabled: !__DEV__ };
|
|
1363
1528
|
var appSoundReducer = (state = initialSoundSettings, action) => (0, import_feedback_press4.soundReducer)(state, action);
|
|
1364
|
-
function createShellReducers({ seatColors, appearance = "system" }) {
|
|
1529
|
+
function createShellReducers({ seatColors, appearance = "system", seatTheme }) {
|
|
1365
1530
|
return {
|
|
1366
1531
|
// Explicit primary/secondary triad (rather than a single seed expanded via harmony) so the pack's
|
|
1367
1532
|
// identity is pinned exactly instead of drifting with whatever hue math a harmony offset would
|
|
@@ -1370,17 +1535,19 @@ function createShellReducers({ seatColors, appearance = "system" }) {
|
|
|
1370
1535
|
// derived, not picked, via getThirdColor: the hue maximally distant from both (see
|
|
1371
1536
|
// @rific/auto-paper's README "Explicit triad" section). The appearance is the pack's ('system',
|
|
1372
1537
|
// createThemeReducer's own default, when it sets none).
|
|
1373
|
-
|
|
1538
|
+
// A pack with its own seatTheme starts from what seat 1's default color makes of it instead (dark
|
|
1539
|
+
// only when the pack's appearance is; hooks/useSeatColors.ts re-applies it with the live mode).
|
|
1540
|
+
theme: (0, import_auto_paper8.createThemeReducer)(seatTheme ? { appearance, ...seatTheme(seatColors, appearance === "dark") } : { appearance, color: { primary: seatColors[1], secondary: seatColors[2], tertiary: (0, import_auto_paper8.getThirdColor)(seatColors[1], seatColors[2]) } }),
|
|
1374
1541
|
haptic: import_feedback_press4.hapticReducer,
|
|
1375
1542
|
sound: appSoundReducer,
|
|
1376
1543
|
// @rific/core's Keep Awake setting (see Providers.tsx's KeepAwakeBridge), under the namespace its
|
|
1377
1544
|
// REHYDRATE handling expects.
|
|
1378
|
-
keepAwake:
|
|
1545
|
+
keepAwake: import_core13.keepAwakeReducer,
|
|
1379
1546
|
// The shared App Group roster (see @tastic/profile's resolveInitialProfiles/
|
|
1380
1547
|
// useSharedProfilesSync, wired in hooks/useProfiles.tsx) is layered on top of this as a separate
|
|
1381
1548
|
// sync target - this slice persisting normally via redux-persist is what gives it local-fallback
|
|
1382
1549
|
// behavior where the shared store isn't available, with no separate AsyncStorage path.
|
|
1383
|
-
profiles:
|
|
1550
|
+
profiles: import_profile10.profilesReducer,
|
|
1384
1551
|
profileSelection: profileSelectionSlice_default,
|
|
1385
1552
|
// The loadout's "remember this color for next time" memory (guest, CPU, and each profile's pick
|
|
1386
1553
|
// in this pack) - separate from `theme` above, which always reflects whatever's live right now.
|
|
@@ -1398,7 +1565,7 @@ var errorMiddleware = () => (next) => (action) => {
|
|
|
1398
1565
|
if (!hasError(action)) return next(action);
|
|
1399
1566
|
return action;
|
|
1400
1567
|
};
|
|
1401
|
-
function createPackStore(pack, { keyPrefix, migrate }) {
|
|
1568
|
+
function createPackStore(pack, { keyPrefix, migrate, blacklist = [], serializableIgnoredPaths = [], middleware = [] }) {
|
|
1402
1569
|
const gameReducers = Object.assign({}, ...pack.games.map((game) => game.reducers));
|
|
1403
1570
|
const resumeReducers = pack.games.some((game) => game.resumable) ? { lastActiveGame: lastActiveGameSlice_default } : {};
|
|
1404
1571
|
const rootReducer = (0, import_toolkit.combineReducers)({ ...createShellReducers(pack), ...resumeReducers, ...pack.reducers, ...gameReducers });
|
|
@@ -1416,7 +1583,7 @@ function createPackStore(pack, { keyPrefix, migrate }) {
|
|
|
1416
1583
|
// failing to ever resolve at all isn't a failure mode worth a 5s failsafe for.
|
|
1417
1584
|
timeout: 0,
|
|
1418
1585
|
// liveplay is per-round state that must never survive a relaunch (see liveplaySlice.ts).
|
|
1419
|
-
blacklist: ["liveplay"],
|
|
1586
|
+
blacklist: ["liveplay", ...blacklist],
|
|
1420
1587
|
migrate
|
|
1421
1588
|
},
|
|
1422
1589
|
rootReducer
|
|
@@ -1426,10 +1593,11 @@ function createPackStore(pack, { keyPrefix, migrate }) {
|
|
|
1426
1593
|
const defaultMiddleware = getDefaultMiddleware({
|
|
1427
1594
|
immutableCheck: false,
|
|
1428
1595
|
serializableCheck: {
|
|
1429
|
-
ignoredActions: [import_redux_persist.FLUSH, import_redux_persist.REHYDRATE, import_redux_persist.PAUSE, import_redux_persist.PERSIST, import_redux_persist.PURGE, import_redux_persist.REGISTER]
|
|
1596
|
+
ignoredActions: [import_redux_persist.FLUSH, import_redux_persist.REHYDRATE, import_redux_persist.PAUSE, import_redux_persist.PERSIST, import_redux_persist.PURGE, import_redux_persist.REGISTER],
|
|
1597
|
+
ignoredPaths: [...serializableIgnoredPaths]
|
|
1430
1598
|
}
|
|
1431
1599
|
});
|
|
1432
|
-
return defaultMiddleware.concat(errorMiddleware);
|
|
1600
|
+
return defaultMiddleware.concat(errorMiddleware, ...middleware);
|
|
1433
1601
|
},
|
|
1434
1602
|
reducer: persistedReducer
|
|
1435
1603
|
});
|
|
@@ -1463,11 +1631,11 @@ function createGameGuideSlice(mountKey) {
|
|
|
1463
1631
|
|
|
1464
1632
|
// src/redux/onProfileRemoved.ts
|
|
1465
1633
|
var import_achievements = require("@tastic/achievements");
|
|
1466
|
-
var
|
|
1634
|
+
var import_profile11 = require("@tastic/profile");
|
|
1467
1635
|
function onProfileRemoved(reducer6, forget) {
|
|
1468
1636
|
return (state, action) => {
|
|
1469
1637
|
const next = reducer6(state, action);
|
|
1470
|
-
return
|
|
1638
|
+
return import_profile11.profilesActions.remove.match(action) ? forget(next, action.payload) : next;
|
|
1471
1639
|
};
|
|
1472
1640
|
}
|
|
1473
1641
|
function forgetProfileAchievements(dropStats) {
|
|
@@ -1590,6 +1758,7 @@ function createPlayerSettings({ id, defaults, distinctControls }) {
|
|
|
1590
1758
|
0 && (module.exports = {
|
|
1591
1759
|
DEFAULT_APP_SETTINGS,
|
|
1592
1760
|
DEFAULT_OPPONENT,
|
|
1761
|
+
GUEST_PLAYER_ID,
|
|
1593
1762
|
HomeScreen,
|
|
1594
1763
|
LoadoutRoute,
|
|
1595
1764
|
PREVIEW_ASPECT,
|