@tastic/shell 0.3.1 → 0.5.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 +27 -15
- package/dist/index.d.mts +10 -14
- package/dist/index.d.ts +10 -14
- package/dist/index.js +203 -167
- package/dist/index.mjs +161 -125
- package/package.json +16 -18
- package/src/RootLayout.tsx +27 -66
- package/src/components/GuideHost.tsx +4 -6
- package/src/components/SettingsDialog.tsx +4 -10
- package/src/components/Theme.tsx +3 -2
- package/src/components/UpdateDialog.tsx +1 -3
- package/src/hooks/useFrozenWhileHidden.ts +2 -2
- package/src/index.ts +1 -1
- package/src/redux/appSettingsSlice.ts +0 -11
- package/src/screens/HomeScreen.tsx +98 -30
- package/src/screens/LoadoutScreen.tsx +35 -53
- package/src/screens/ProfilesRoute.tsx +5 -5
- package/src/screens/StatsScreen.tsx +4 -5
- package/src/screens/homeLayout.ts +15 -19
- package/src/types.ts +24 -21
package/dist/index.js
CHANGED
|
@@ -64,7 +64,7 @@ __export(index_exports, {
|
|
|
64
64
|
profileSelectionActions: () => profileSelectionActions,
|
|
65
65
|
profileSelectionReducer: () => profileSelectionSlice_default,
|
|
66
66
|
roundModeFor: () => roundModeFor,
|
|
67
|
-
safeBack: () =>
|
|
67
|
+
safeBack: () => import_core7.safeBack,
|
|
68
68
|
seatColorsActions: () => seatColorsActions,
|
|
69
69
|
seatPlayerKey: () => seatPlayerKey,
|
|
70
70
|
seatTwoFor: () => seatTwoFor,
|
|
@@ -99,13 +99,12 @@ function usePackGame(id) {
|
|
|
99
99
|
var import_auto_paper2 = require("@rific/auto-paper");
|
|
100
100
|
var import_feedback_press2 = require("@rific/feedback-press");
|
|
101
101
|
var import_toaster2 = require("@rific/toaster");
|
|
102
|
-
var
|
|
102
|
+
var import_core4 = require("@tastic/core");
|
|
103
103
|
var import_chrome2 = require("@tastic/hud/chrome");
|
|
104
104
|
var import_profile3 = require("@tastic/profile");
|
|
105
105
|
var Haptics = __toESM(require("expo-haptics"));
|
|
106
106
|
var import_expo_router = require("expo-router");
|
|
107
|
-
var
|
|
108
|
-
var import_react9 = require("react");
|
|
107
|
+
var import_react8 = require("react");
|
|
109
108
|
var import_react_native2 = require("react-native");
|
|
110
109
|
var import_react_native_gesture_handler = require("react-native-gesture-handler");
|
|
111
110
|
var RNPaper2 = __toESM(require("react-native-paper"));
|
|
@@ -163,7 +162,6 @@ function GuideHost({ children }) {
|
|
|
163
162
|
const packGuide = subject === PACK_GUIDE ? pack.guide : void 0;
|
|
164
163
|
const game = subject === PACK_GUIDE ? void 0 : pack.games.find((g) => g.id === subject);
|
|
165
164
|
const gameGuide = game?.guide;
|
|
166
|
-
const rotation = (0, import_core.useRotation)();
|
|
167
165
|
const touch = (0, import_core.useIsTouchPrimaryDevice)();
|
|
168
166
|
const seatTwo = (0, import_react_redux.useSelector)((state) => state.opponent.seatTwo);
|
|
169
167
|
const input = (0, import_react_redux.useSelector)((state) => gameGuide ? gameGuide.selectInput(state) : NO_INPUT, import_react_redux.shallowEqual);
|
|
@@ -178,7 +176,7 @@ function GuideHost({ children }) {
|
|
|
178
176
|
},
|
|
179
177
|
[dispatch, packGuide, gameGuide]
|
|
180
178
|
);
|
|
181
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_guide.GuideProvider, { steps, currentVersion: (packGuide ?? gameGuide)?.version ?? 0, seenVersion, onSeen,
|
|
179
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_guide.GuideProvider, { steps, currentVersion: (packGuide ?? gameGuide)?.version ?? 0, seenVersion, onSeen, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(GameGuideBridge, { onPick: setSubject, children }) });
|
|
182
180
|
}
|
|
183
181
|
function GameGuideBridge({ onPick, children }) {
|
|
184
182
|
const pack = usePack();
|
|
@@ -301,66 +299,33 @@ function Theme({ children }) {
|
|
|
301
299
|
|
|
302
300
|
// src/components/UpdateDialog.tsx
|
|
303
301
|
var import_toaster = require("@rific/toaster");
|
|
304
|
-
var import_core3 = require("@tastic/core");
|
|
305
302
|
var import_chrome = require("@tastic/hud/chrome");
|
|
306
303
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
307
304
|
function UpdateDialog() {
|
|
308
305
|
const onError = (0, import_toaster.useUpdateErrorToast)();
|
|
309
|
-
|
|
310
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_chrome.UpdateDialog, { onError, rotation });
|
|
306
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_chrome.UpdateDialog, { onError });
|
|
311
307
|
}
|
|
312
308
|
|
|
313
|
-
// src/hooks/
|
|
309
|
+
// src/hooks/useLastActiveGame.tsx
|
|
314
310
|
var import_react6 = require("react");
|
|
315
311
|
var import_react_redux4 = require("react-redux");
|
|
316
312
|
|
|
317
|
-
// src/redux/appSettingsSlice.ts
|
|
318
|
-
var import_core4 = require("@rific/core");
|
|
319
|
-
var DEFAULT_APP_SETTINGS = {
|
|
320
|
-
lockOrientation: false,
|
|
321
|
-
deferBottomEdgeGestures: false
|
|
322
|
-
};
|
|
323
|
-
var { actions, reducer } = (0, import_core4.createSettingsSlice)("appSettings", {
|
|
324
|
-
initialState: DEFAULT_APP_SETTINGS,
|
|
325
|
-
initializeMode: "merge",
|
|
326
|
-
fieldSetters: []
|
|
327
|
-
});
|
|
328
|
-
var appSettingsActions = actions;
|
|
329
|
-
var appSettingsSlice_default = reducer;
|
|
330
|
-
|
|
331
|
-
// src/hooks/useAppSettings.ts
|
|
332
|
-
function useAppSettings() {
|
|
333
|
-
const settings = (0, import_react_redux4.useSelector)((state) => state.appSettings);
|
|
334
|
-
const dispatch = (0, import_react_redux4.useDispatch)();
|
|
335
|
-
const setSettings = (0, import_react6.useCallback)(
|
|
336
|
-
(patch) => {
|
|
337
|
-
dispatch(appSettingsActions.initialize(patch));
|
|
338
|
-
},
|
|
339
|
-
[dispatch]
|
|
340
|
-
);
|
|
341
|
-
return { settings, setSettings };
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
// src/hooks/useLastActiveGame.tsx
|
|
345
|
-
var import_react7 = require("react");
|
|
346
|
-
var import_react_redux5 = require("react-redux");
|
|
347
|
-
|
|
348
313
|
// src/redux/lastActiveGameSlice.ts
|
|
349
|
-
var
|
|
350
|
-
var { actions
|
|
351
|
-
var lastActiveGameActions =
|
|
352
|
-
var lastActiveGameSlice_default =
|
|
314
|
+
var import_core3 = require("@rific/core");
|
|
315
|
+
var { actions, reducer } = (0, import_core3.createSettingsSlice)("lastActiveGame", { initialState: { gameId: null } });
|
|
316
|
+
var lastActiveGameActions = actions;
|
|
317
|
+
var lastActiveGameSlice_default = reducer;
|
|
353
318
|
|
|
354
319
|
// src/hooks/useLastActiveGame.tsx
|
|
355
320
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
356
|
-
var LastActiveGameContext = (0,
|
|
321
|
+
var LastActiveGameContext = (0, import_react6.createContext)(null);
|
|
357
322
|
function LastActiveGameProvider({ children }) {
|
|
358
|
-
const store = (0,
|
|
359
|
-
const dispatch = (0,
|
|
360
|
-
const [initial] = (0,
|
|
361
|
-
const pendingResume = (0,
|
|
362
|
-
const persisted = (0,
|
|
363
|
-
const value = (0,
|
|
323
|
+
const store = (0, import_react_redux4.useStore)();
|
|
324
|
+
const dispatch = (0, import_react_redux4.useDispatch)();
|
|
325
|
+
const [initial] = (0, import_react6.useState)(() => store.getState().lastActiveGame?.gameId ?? null);
|
|
326
|
+
const pendingResume = (0, import_react6.useRef)(initial);
|
|
327
|
+
const persisted = (0, import_react6.useRef)(initial);
|
|
328
|
+
const value = (0, import_react6.useMemo)(
|
|
364
329
|
() => ({
|
|
365
330
|
consumeResumeGame: () => {
|
|
366
331
|
const game = pendingResume.current;
|
|
@@ -388,33 +353,33 @@ function LastActiveGameProvider({ children }) {
|
|
|
388
353
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(LastActiveGameContext.Provider, { value, children });
|
|
389
354
|
}
|
|
390
355
|
function useLastActiveGame() {
|
|
391
|
-
const ctx = (0,
|
|
356
|
+
const ctx = (0, import_react6.useContext)(LastActiveGameContext);
|
|
392
357
|
if (!ctx) throw new Error("useLastActiveGame must be used within a LastActiveGameProvider");
|
|
393
358
|
return ctx;
|
|
394
359
|
}
|
|
395
360
|
|
|
396
361
|
// src/hooks/useProfiles.tsx
|
|
397
362
|
var import_profile2 = require("@tastic/profile");
|
|
398
|
-
var
|
|
399
|
-
var
|
|
363
|
+
var import_react7 = require("react");
|
|
364
|
+
var import_react_redux5 = require("react-redux");
|
|
400
365
|
|
|
401
366
|
// src/redux/profileSelectionSlice.ts
|
|
402
367
|
var import_profile = require("@tastic/profile");
|
|
403
368
|
var defaultProfileSelectionState = { 1: null, 2: null };
|
|
404
|
-
var { actions:
|
|
405
|
-
var profileSelectionActions =
|
|
406
|
-
var profileSelectionSlice_default =
|
|
369
|
+
var { actions: actions2, reducer: reducer2 } = (0, import_profile.createProfileSelectionSlice)("pack", defaultProfileSelectionState);
|
|
370
|
+
var profileSelectionActions = actions2;
|
|
371
|
+
var profileSelectionSlice_default = reducer2;
|
|
407
372
|
|
|
408
373
|
// src/hooks/useProfiles.tsx
|
|
409
374
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
410
375
|
var SHARED_GROUP_ID = "group.com.infinitetoken.tastic";
|
|
411
|
-
var ProfilesContext = (0,
|
|
376
|
+
var ProfilesContext = (0, import_react7.createContext)(null);
|
|
412
377
|
function ProfilesProvider({ children }) {
|
|
413
|
-
const profiles = (0,
|
|
414
|
-
const lastSelected = (0,
|
|
415
|
-
const dispatch = (0,
|
|
416
|
-
const [loaded, setLoaded] = (0,
|
|
417
|
-
(0,
|
|
378
|
+
const profiles = (0, import_react_redux5.useSelector)((state) => state.profiles);
|
|
379
|
+
const lastSelected = (0, import_react_redux5.useSelector)((state) => state.profileSelection);
|
|
380
|
+
const dispatch = (0, import_react_redux5.useDispatch)();
|
|
381
|
+
const [loaded, setLoaded] = (0, import_react7.useState)(false);
|
|
382
|
+
(0, import_react7.useEffect)(() => {
|
|
418
383
|
let cancelled = false;
|
|
419
384
|
(0, import_profile2.resolveInitialProfiles)(SHARED_GROUP_ID, profiles).then((resolved) => {
|
|
420
385
|
if (cancelled) return;
|
|
@@ -428,7 +393,7 @@ function ProfilesProvider({ children }) {
|
|
|
428
393
|
}, []);
|
|
429
394
|
const { syncToShared } = (0, import_profile2.useSharedProfilesSync)({
|
|
430
395
|
groupId: SHARED_GROUP_ID,
|
|
431
|
-
onRemoteChange: (0,
|
|
396
|
+
onRemoteChange: (0, import_react7.useCallback)(
|
|
432
397
|
(remote) => {
|
|
433
398
|
dispatch(import_profile2.profilesActions.setAll(remote));
|
|
434
399
|
dispatch(profileSelectionActions.pruneToRoster(remote.map((p) => p.id)));
|
|
@@ -436,7 +401,7 @@ function ProfilesProvider({ children }) {
|
|
|
436
401
|
[dispatch]
|
|
437
402
|
)
|
|
438
403
|
});
|
|
439
|
-
const createProfile = (0,
|
|
404
|
+
const createProfile = (0, import_react7.useCallback)(
|
|
440
405
|
(input) => {
|
|
441
406
|
const record = (0, import_profile2.createProfileRecord)(input);
|
|
442
407
|
dispatch(import_profile2.profilesActions.add(record));
|
|
@@ -445,14 +410,14 @@ function ProfilesProvider({ children }) {
|
|
|
445
410
|
},
|
|
446
411
|
[profiles, dispatch, syncToShared]
|
|
447
412
|
);
|
|
448
|
-
const updateProfile = (0,
|
|
413
|
+
const updateProfile = (0, import_react7.useCallback)(
|
|
449
414
|
(id, patch) => {
|
|
450
415
|
dispatch(import_profile2.profilesActions.update({ id, patch }));
|
|
451
416
|
syncToShared(profiles.map((p) => p.id === id ? { ...p, ...patch, updatedAt: Date.now() } : p));
|
|
452
417
|
},
|
|
453
418
|
[profiles, dispatch, syncToShared]
|
|
454
419
|
);
|
|
455
|
-
const deleteProfile = (0,
|
|
420
|
+
const deleteProfile = (0, import_react7.useCallback)(
|
|
456
421
|
(id) => {
|
|
457
422
|
dispatch(import_profile2.profilesActions.remove(id));
|
|
458
423
|
syncToShared(profiles.filter((p) => p.id !== id));
|
|
@@ -460,7 +425,7 @@ function ProfilesProvider({ children }) {
|
|
|
460
425
|
},
|
|
461
426
|
[profiles, dispatch, syncToShared]
|
|
462
427
|
);
|
|
463
|
-
const selectProfile = (0,
|
|
428
|
+
const selectProfile = (0, import_react7.useCallback)(
|
|
464
429
|
(seat, profileId) => {
|
|
465
430
|
dispatch(profileSelectionActions.select({ profileId, seat }));
|
|
466
431
|
},
|
|
@@ -469,7 +434,7 @@ function ProfilesProvider({ children }) {
|
|
|
469
434
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ProfilesContext.Provider, { value: { profiles, lastSelected, loaded, createProfile, updateProfile, deleteProfile, selectProfile }, children });
|
|
470
435
|
}
|
|
471
436
|
function useProfiles() {
|
|
472
|
-
const ctx = (0,
|
|
437
|
+
const ctx = (0, import_react7.useContext)(ProfilesContext);
|
|
473
438
|
if (!ctx) throw new Error("useProfiles must be used within a ProfilesProvider");
|
|
474
439
|
return ctx;
|
|
475
440
|
}
|
|
@@ -485,11 +450,11 @@ function AppStack() {
|
|
|
485
450
|
const { Backdrop } = pack;
|
|
486
451
|
const { dark } = (0, import_auto_paper2.useAutoPaperTheme)();
|
|
487
452
|
const darkRoot = Backdrop ? true : dark;
|
|
488
|
-
const rootBackground = (0,
|
|
489
|
-
const
|
|
453
|
+
const rootBackground = (0, import_core4.useThemedRootBackground)(darkRoot, false);
|
|
454
|
+
const statusBarStyle = darkRoot ? "light" : "dark";
|
|
490
455
|
const packOptions = (pack.useScreenOptions ?? noScreenOptions)();
|
|
491
456
|
const backdropOptions = Backdrop ? { contentStyle: TRANSPARENT_CONTENT, animation: import_react_native2.Platform.select({ android: "fade" }) } : void 0;
|
|
492
|
-
const playOptions = (0,
|
|
457
|
+
const playOptions = (0, import_react8.useCallback)(
|
|
493
458
|
({ route }) => {
|
|
494
459
|
const id = route.params?.game;
|
|
495
460
|
return pack.games.some((g) => g.id === id && g.keepStatusBar) ? KEEP_STATUS_BAR_OPTIONS : PLAY_OPTIONS;
|
|
@@ -497,11 +462,11 @@ function AppStack() {
|
|
|
497
462
|
[pack.games]
|
|
498
463
|
);
|
|
499
464
|
const navigationBackground = Backdrop ? TRANSPARENT_CONTENT.backgroundColor : rootBackground.contentStyle.backgroundColor;
|
|
500
|
-
const navigationTheme = (0,
|
|
465
|
+
const navigationTheme = (0, import_react8.useMemo)(() => {
|
|
501
466
|
const base = darkRoot ? import_expo_router.DarkTheme : import_expo_router.DefaultTheme;
|
|
502
467
|
return { ...base, colors: { ...base.colors, background: navigationBackground } };
|
|
503
468
|
}, [darkRoot, navigationBackground]);
|
|
504
|
-
const stack = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_expo_router.ThemeProvider, { value: navigationTheme, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_expo_router.Stack, { screenOptions: { ...rootBackground,
|
|
469
|
+
const stack = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_expo_router.ThemeProvider, { value: navigationTheme, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_expo_router.Stack, { screenOptions: { ...rootBackground, statusBarStyle, ...backdropOptions, ...packOptions }, children: [
|
|
505
470
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_expo_router.Stack.Screen, { name: "index" }),
|
|
506
471
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_expo_router.Stack.Screen, { name: "play/[game]", options: playOptions })
|
|
507
472
|
] }) });
|
|
@@ -511,11 +476,6 @@ function AppStack() {
|
|
|
511
476
|
stack
|
|
512
477
|
] });
|
|
513
478
|
}
|
|
514
|
-
function OrientationBridge({ children }) {
|
|
515
|
-
const { settings, setSettings } = useAppSettings();
|
|
516
|
-
const { portraitWhileKeyboard } = usePack();
|
|
517
|
-
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 });
|
|
518
|
-
}
|
|
519
479
|
function GatedApp({ children }) {
|
|
520
480
|
const { loaded } = useProfiles();
|
|
521
481
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SplashGate, { gate: "profiles", ready: loaded, children });
|
|
@@ -526,7 +486,7 @@ function HapticGatedToastProvider({ children }) {
|
|
|
526
486
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_toaster2.ToastProvider, { haptics: settings.vibrate ? Haptics : void 0, paper: PackToasterComponent ? void 0 : RNPaper2, children });
|
|
527
487
|
}
|
|
528
488
|
function RotatingToaster() {
|
|
529
|
-
const renderFrame = (0,
|
|
489
|
+
const renderFrame = (0, import_react8.useCallback)(
|
|
530
490
|
(toasts) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_chrome2.RotatedFrame, { rotatedSafeArea: true, passThrough: true, children: toasts }),
|
|
531
491
|
[]
|
|
532
492
|
);
|
|
@@ -540,7 +500,7 @@ function GameProviders({ games, children }) {
|
|
|
540
500
|
}
|
|
541
501
|
function PreviewColors({ previewColor, children }) {
|
|
542
502
|
const { dark } = (0, import_auto_paper2.useAutoPaperTheme)();
|
|
543
|
-
const preview = (0,
|
|
503
|
+
const preview = (0, import_react8.useCallback)((hex) => previewColor(hex, dark), [previewColor, dark]);
|
|
544
504
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_profile3.ProfileColorProvider, { preview, children });
|
|
545
505
|
}
|
|
546
506
|
function PackRoot({ pack, children }) {
|
|
@@ -549,11 +509,11 @@ function PackRoot({ pack, children }) {
|
|
|
549
509
|
return previewColor ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(PreviewColors, { previewColor, children: inner }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_jsx_runtime9.Fragment, { children: inner });
|
|
550
510
|
}
|
|
551
511
|
function RootLayout({ pack, store, persistor }) {
|
|
552
|
-
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.
|
|
512
|
+
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.jsxs)(HapticGatedToastProvider, { children: [
|
|
553
513
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(GuideHost, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(AppStack, {}) }),
|
|
554
514
|
pack.Toaster ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(PackToaster, { Toaster: pack.Toaster }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(RotatingToaster, {}),
|
|
555
515
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(UpdateDialog, {})
|
|
556
|
-
] }) }) }) }) }) }) }) }) }) }) }) })
|
|
516
|
+
] }) }) }) }) }) }) }) }) }) }) }) });
|
|
557
517
|
}
|
|
558
518
|
var styles = import_react_native2.StyleSheet.create({
|
|
559
519
|
root: { flex: 1 }
|
|
@@ -572,7 +532,7 @@ var PROFILES_HREF = "/profiles";
|
|
|
572
532
|
|
|
573
533
|
// src/screens/LoadoutScreen.tsx
|
|
574
534
|
var import_auto_paper4 = require("@rific/auto-paper");
|
|
575
|
-
var
|
|
535
|
+
var import_core9 = require("@tastic/core");
|
|
576
536
|
var import_chrome4 = require("@tastic/hud/chrome");
|
|
577
537
|
var import_lobby2 = require("@tastic/hud/lobby");
|
|
578
538
|
var import_split_screen = require("@tastic/split-screen");
|
|
@@ -586,7 +546,7 @@ var import_react_redux9 = require("react-redux");
|
|
|
586
546
|
// src/components/SeatTwoPanel.tsx
|
|
587
547
|
var import_lobby = require("@tastic/hud/lobby");
|
|
588
548
|
var import_profile4 = require("@tastic/profile");
|
|
589
|
-
var
|
|
549
|
+
var import_react9 = require("react");
|
|
590
550
|
var import_react_native3 = require("react-native");
|
|
591
551
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
592
552
|
var CPU_PREFIX = "cpu:";
|
|
@@ -604,7 +564,7 @@ function SeatTwoPanel({ idPrefix, host, choices, seatTwo, onSeatTwoChange, cpuDi
|
|
|
604
564
|
const drawn = previewValue ? previewValue(color) : color;
|
|
605
565
|
const selectedProfile = isPerson ? profiles.find((p) => p.id === selectedProfileId) ?? null : null;
|
|
606
566
|
const cpuOptions = cpuDifficulty?.options;
|
|
607
|
-
const options = (0,
|
|
567
|
+
const options = (0, import_react9.useMemo)(() => {
|
|
608
568
|
const list = [];
|
|
609
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 }]);
|
|
610
570
|
if (choices.includes("nobody")) list.push({ value: NOBODY, label: "Nobody", icon: NOBODY_ICON });
|
|
@@ -664,13 +624,45 @@ var styles2 = import_react_native3.StyleSheet.create({
|
|
|
664
624
|
// src/components/SettingsDialog.tsx
|
|
665
625
|
var import_toaster3 = require("@rific/toaster");
|
|
666
626
|
var import_chrome3 = require("@tastic/hud/chrome");
|
|
627
|
+
|
|
628
|
+
// src/hooks/useAppSettings.ts
|
|
629
|
+
var import_react10 = require("react");
|
|
630
|
+
var import_react_redux6 = require("react-redux");
|
|
631
|
+
|
|
632
|
+
// src/redux/appSettingsSlice.ts
|
|
633
|
+
var import_core5 = require("@rific/core");
|
|
634
|
+
var DEFAULT_APP_SETTINGS = {
|
|
635
|
+
deferBottomEdgeGestures: false
|
|
636
|
+
};
|
|
637
|
+
var { actions: actions3, reducer: reducer3 } = (0, import_core5.createSettingsSlice)("appSettings", {
|
|
638
|
+
initialState: DEFAULT_APP_SETTINGS,
|
|
639
|
+
initializeMode: "merge",
|
|
640
|
+
fieldSetters: []
|
|
641
|
+
});
|
|
642
|
+
var appSettingsActions = actions3;
|
|
643
|
+
var appSettingsSlice_default = reducer3;
|
|
644
|
+
|
|
645
|
+
// src/hooks/useAppSettings.ts
|
|
646
|
+
function useAppSettings() {
|
|
647
|
+
const settings = (0, import_react_redux6.useSelector)((state) => state.appSettings);
|
|
648
|
+
const dispatch = (0, import_react_redux6.useDispatch)();
|
|
649
|
+
const setSettings = (0, import_react10.useCallback)(
|
|
650
|
+
(patch) => {
|
|
651
|
+
dispatch(appSettingsActions.initialize(patch));
|
|
652
|
+
},
|
|
653
|
+
[dispatch]
|
|
654
|
+
);
|
|
655
|
+
return { settings, setSettings };
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
// src/components/SettingsDialog.tsx
|
|
667
659
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
668
|
-
function SettingsDialog({ visible, onDismiss,
|
|
660
|
+
function SettingsDialog({ visible, onDismiss, onShowHowToPlay, children }) {
|
|
669
661
|
const onUpdateError = (0, import_toaster3.useUpdateErrorToast)();
|
|
670
662
|
const { settings, setSettings } = useAppSettings();
|
|
671
663
|
const { otaVersion, SettingsSections, edgeGuard = true } = usePack();
|
|
672
664
|
const edgeGuardProps = edgeGuard ? { deferBottomEdgeGestures: settings.deferBottomEdgeGestures, onDeferBottomEdgeGestures: (value) => setSettings({ deferBottomEdgeGestures: value }) } : {};
|
|
673
|
-
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_chrome3.BaseSettingsDialog, { visible, onDismiss,
|
|
665
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_chrome3.BaseSettingsDialog, { visible, onDismiss, version: otaVersion, ...edgeGuardProps, onUpdateError, onShowHowToPlay, children: [
|
|
674
666
|
children,
|
|
675
667
|
SettingsSections && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SettingsSections, {})
|
|
676
668
|
] });
|
|
@@ -681,9 +673,9 @@ var import_react11 = require("react");
|
|
|
681
673
|
var import_react_redux7 = require("react-redux");
|
|
682
674
|
|
|
683
675
|
// src/redux/opponentSlice.ts
|
|
684
|
-
var
|
|
676
|
+
var import_core6 = require("@rific/core");
|
|
685
677
|
var DEFAULT_OPPONENT = { seatTwo: "cpu" };
|
|
686
|
-
var { actions: actions4, reducer: reducer4 } = (0,
|
|
678
|
+
var { actions: actions4, reducer: reducer4 } = (0, import_core6.createSettingsSlice)("opponent", {
|
|
687
679
|
initialState: DEFAULT_OPPONENT
|
|
688
680
|
});
|
|
689
681
|
var opponentActions = actions4;
|
|
@@ -816,13 +808,13 @@ function useSeatColors(p2IsHuman) {
|
|
|
816
808
|
}
|
|
817
809
|
|
|
818
810
|
// src/navigation.ts
|
|
819
|
-
var
|
|
811
|
+
var import_core7 = require("@rific/core");
|
|
820
812
|
var import_expo_router3 = require("expo-router");
|
|
821
|
-
(0,
|
|
813
|
+
(0, import_core7.configureNavigation)({ router: import_expo_router3.router });
|
|
822
814
|
|
|
823
815
|
// src/redux/liveplaySlice.ts
|
|
824
|
-
var
|
|
825
|
-
var { actions: actions5, reducer: reducer5 } = (0,
|
|
816
|
+
var import_core8 = require("@rific/core");
|
|
817
|
+
var { actions: actions5, reducer: reducer5 } = (0, import_core8.createSettingsSlice)("liveplay", {
|
|
826
818
|
initialState: { activelyPlaying: false, activeRound: null }
|
|
827
819
|
});
|
|
828
820
|
var liveplayActions = actions5;
|
|
@@ -842,14 +834,12 @@ function LoadoutScreen({ game }) {
|
|
|
842
834
|
const loadout = game.useLoadout(mode);
|
|
843
835
|
const { openFor } = useGameGuide();
|
|
844
836
|
const { profiles, lastSelected, selectProfile } = useProfiles();
|
|
845
|
-
const { orientationMode
|
|
846
|
-
const
|
|
847
|
-
const
|
|
848
|
-
const { panelLayout, panelFadeStyle } = (0, import_split_screen.useDualZoneLayout)(fixedSeats ? "faceToFace" : orientationMode, fixedSeats ? true : p1OnRight, fixedSeats || p1OnRightResolved, fixedSeats ? fixedUpsideDown : upsideDown, PANEL_SWAP_FADE_MS);
|
|
837
|
+
const { orientationMode } = (0, import_core9.useOrientationState)();
|
|
838
|
+
const panelMode = p2IsHuman && !game.sideBySideWhenWide ? "faceToFace" : orientationMode;
|
|
839
|
+
const { panelLayout, panelFadeStyle } = (0, import_split_screen.useDualZoneLayout)(panelMode, false, true, false, PANEL_SWAP_FADE_MS);
|
|
849
840
|
const playersRowFade = panelFadeStyle;
|
|
850
841
|
const [settingsOpen, setSettingsOpen] = (0, import_react13.useState)(false);
|
|
851
|
-
const
|
|
852
|
-
const insets = (0, import_core10.rotateInsets)((0, import_react_native_safe_area_context2.useSafeAreaInsets)(), rotation);
|
|
842
|
+
const insets = (0, import_react_native_safe_area_context2.useSafeAreaInsets)();
|
|
853
843
|
const { colors: themeColors, dark } = (0, import_auto_paper4.useAutoPaperTheme)();
|
|
854
844
|
const { p1Color, p2Color, handleP1ColorChange, handleP2ColorChange } = useSeatColors(p2IsHuman);
|
|
855
845
|
const dispatch = (0, import_react_redux9.useDispatch)();
|
|
@@ -887,7 +877,7 @@ function LoadoutScreen({ game }) {
|
|
|
887
877
|
const triggerStyle = (0, import_react13.useMemo)(() => pack.Backdrop ? [styles3.pill, { backgroundColor: themeColors.surface }] : void 0, [pack.Backdrop, themeColors.surface]);
|
|
888
878
|
const isPortrait = panelLayout.orientationMode === "faceToFace";
|
|
889
879
|
const showMetaInSharedBand = (0, import_split_screen.needsSharedNeutralZone)(panelLayout.orientationMode, humanSeats.length);
|
|
890
|
-
const p2ZoneStyle = p2IsHuman ? isPortrait ? styles3.p2ZoneTop :
|
|
880
|
+
const p2ZoneStyle = p2IsHuman ? isPortrait ? styles3.p2ZoneTop : styles3.p2ZoneRight : null;
|
|
891
881
|
const showReadyButton = p2IsHuman;
|
|
892
882
|
const seatPickerAlign = p2IsHuman ? void 0 : pack.usePickerAlign;
|
|
893
883
|
const layoutKey = p2IsHuman ? "zones" : "row";
|
|
@@ -897,7 +887,6 @@ function LoadoutScreen({ game }) {
|
|
|
897
887
|
const anyPlayerPickerOpen = !!(controlsHost.openId?.startsWith("p1-") || controlsHost.openId?.startsWith("p2-"));
|
|
898
888
|
const optionsRow = loadout.options({
|
|
899
889
|
host: controlsHost,
|
|
900
|
-
rotation,
|
|
901
890
|
accentColor: themeColors.tertiary,
|
|
902
891
|
mutedColor: fgMuted,
|
|
903
892
|
onAccentColor: themeColors.onTertiary,
|
|
@@ -907,17 +896,17 @@ function LoadoutScreen({ game }) {
|
|
|
907
896
|
onReset: showMetaInSharedBand ? void 0 : loadout.reset
|
|
908
897
|
});
|
|
909
898
|
const optionsPopoverOpen = controlsHost.openId !== null && loadout.optionIds.includes(controlsHost.openId);
|
|
910
|
-
const sharedControls = showMetaInSharedBand ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lobby2.SharedActionBand, { onBack:
|
|
911
|
-
const controlLook = { accentColor: themeColors.tertiary, mutedColor: fgMuted, dark
|
|
899
|
+
const sharedControls = showMetaInSharedBand ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lobby2.SharedActionBand, { onBack: import_core7.safeBack, onSettings: () => setSettingsOpen(true), onRandomize: loadout.randomize, onReset: loadout.reset, fg, popoverOpen: optionsPopoverOpen, children: optionsRow }) : optionsRow;
|
|
900
|
+
const controlLook = { accentColor: themeColors.tertiary, mutedColor: fgMuted, dark };
|
|
912
901
|
const p1Control = loadout.seatControl(1, controlsHost, { ...controlLook, seatColor: p1Drawn });
|
|
913
902
|
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: pack.guestLabel ?? "P1", nullLabel: pack.nullLabel, onProfileSelect: handleP1ProfileSelect, onManageProfiles: () => import_expo_router4.router.push(PROFILES_HREF), previewValue: seatPreview, triggerStyle, useSeatPickerAlign: seatPickerAlign }, `p1-${layoutKey}`);
|
|
914
903
|
const p2Control = p2IsHuman ? loadout.seatControl(2, p2Host, { ...controlLook, seatColor: p2Drawn }) : void 0;
|
|
915
904
|
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, previewValue: seatPreview, triggerStyle, usePickerAlign: seatPickerAlign }, `p2-${layoutKey}`);
|
|
916
905
|
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native4.View, { style: [styles3.container, { backgroundColor: bg }], children: [
|
|
917
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
906
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native4.View, { style: styles3.frame, children: [
|
|
918
907
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_chrome4.PressAwayOverlay, { active: controlsHost.openId !== null, onPress: controlsHost.close }),
|
|
919
908
|
p2ZoneStyle && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_chrome4.PressAwayOverlay, { active: controlsHost.openId !== null || p2Host.openId !== null, onPress: p2Host.close, style: p2ZoneStyle }),
|
|
920
|
-
!showMetaInSharedBand && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_chrome4.CornerActionButtons, { onBack:
|
|
909
|
+
!showMetaInSharedBand && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_chrome4.CornerActionButtons, { onBack: import_core7.safeBack, onSettings: () => setSettingsOpen(true), fg, insets }),
|
|
921
910
|
p2IsHuman ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
922
911
|
import_split_screen.DualZoneLayout,
|
|
923
912
|
{
|
|
@@ -933,13 +922,13 @@ function LoadoutScreen({ game }) {
|
|
|
933
922
|
) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native4.View, { style: styles3.stackedZone, children: [
|
|
934
923
|
sharedControls,
|
|
935
924
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native_reanimated2.default.View, { style: [styles3.playersRow, anyPlayerPickerOpen && styles3.playersRowOpen, playersRowFade], children: [
|
|
936
|
-
|
|
937
|
-
|
|
925
|
+
p1Panel,
|
|
926
|
+
p2Panel
|
|
938
927
|
] }),
|
|
939
928
|
/* @__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 })
|
|
940
929
|
] })
|
|
941
930
|
] }),
|
|
942
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SettingsDialog, { visible: settingsOpen, onDismiss: () => setSettingsOpen(false),
|
|
931
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SettingsDialog, { visible: settingsOpen, onDismiss: () => setSettingsOpen(false), onShowHowToPlay: () => openFor(game.id) })
|
|
943
932
|
] });
|
|
944
933
|
}
|
|
945
934
|
function halfOf(color) {
|
|
@@ -950,12 +939,13 @@ var styles3 = import_react_native4.StyleSheet.create({
|
|
|
950
939
|
container: {
|
|
951
940
|
flex: 1
|
|
952
941
|
},
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
942
|
+
// A real full-bleed box to size the absolutely-positioned children against.
|
|
943
|
+
frame: {
|
|
944
|
+
alignItems: "center",
|
|
945
|
+
flex: 1,
|
|
946
|
+
gap: 32,
|
|
947
|
+
justifyContent: "center",
|
|
948
|
+
paddingHorizontal: 16
|
|
959
949
|
},
|
|
960
950
|
p2ZoneRight: {
|
|
961
951
|
bottom: 0,
|
|
@@ -990,14 +980,6 @@ var styles3 = import_react_native4.StyleSheet.create({
|
|
|
990
980
|
opacity: 0,
|
|
991
981
|
pointerEvents: "none"
|
|
992
982
|
},
|
|
993
|
-
// A real full-bleed box for FakeLandscapeView to size its absolutely-positioned children against.
|
|
994
|
-
rotatable: {
|
|
995
|
-
alignItems: "center",
|
|
996
|
-
flex: 1,
|
|
997
|
-
gap: 32,
|
|
998
|
-
justifyContent: "center",
|
|
999
|
-
paddingHorizontal: 16
|
|
1000
|
-
},
|
|
1001
983
|
stackedZone: {
|
|
1002
984
|
alignItems: "center",
|
|
1003
985
|
gap: 28
|
|
@@ -1038,12 +1020,11 @@ function useResumePoint(gameId) {
|
|
|
1038
1020
|
// src/screens/HomeScreen.tsx
|
|
1039
1021
|
var import_auto_paper5 = require("@rific/auto-paper");
|
|
1040
1022
|
var import_feedback_press3 = require("@rific/feedback-press");
|
|
1041
|
-
var import_core12 = require("@tastic/core");
|
|
1042
1023
|
var import_chrome5 = require("@tastic/hud/chrome");
|
|
1043
1024
|
var import_profile7 = require("@tastic/profile");
|
|
1044
1025
|
var import_expo_router6 = require("expo-router");
|
|
1045
1026
|
var import_react16 = require("react");
|
|
1046
|
-
var
|
|
1027
|
+
var import_react_native7 = require("react-native");
|
|
1047
1028
|
var import_react_native_paper = require("react-native-paper");
|
|
1048
1029
|
|
|
1049
1030
|
// src/hooks/useFrozenWhileHidden.ts
|
|
@@ -1063,7 +1044,8 @@ function useFrozenWhileHidden(value, hidden) {
|
|
|
1063
1044
|
}
|
|
1064
1045
|
|
|
1065
1046
|
// src/screens/homeLayout.ts
|
|
1066
|
-
var
|
|
1047
|
+
var import_core10 = require("@tastic/core");
|
|
1048
|
+
var import_react_native6 = require("react-native");
|
|
1067
1049
|
var import_react_native_safe_area_context3 = require("react-native-safe-area-context");
|
|
1068
1050
|
var PREVIEW_ASPECT = 360 / 200;
|
|
1069
1051
|
var ROW_PREVIEW_WIDTH = 92;
|
|
@@ -1092,9 +1074,9 @@ function computeHomeLayout(windowWidth, windowHeight, insets) {
|
|
|
1092
1074
|
const inner = Math.max(0, usable - HOME_WIDE_EDGE_PADDING - HOME_WIDE_RIGHT_GUTTER);
|
|
1093
1075
|
const content = Math.min(inner, HOME_WIDE_MAX_CONTENT_WIDTH);
|
|
1094
1076
|
const slack = (inner - content) / 2;
|
|
1095
|
-
const leftPaneWidth = Math.min((0,
|
|
1077
|
+
const leftPaneWidth = Math.min((0, import_core10.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));
|
|
1096
1078
|
const rightPaneWidth = Math.max(0, content - HOME_WIDE_PANE_GAP - leftPaneWidth);
|
|
1097
|
-
const columns = (0,
|
|
1079
|
+
const columns = (0, import_core10.clamp)(Math.floor((rightPaneWidth + HOME_GRID_GAP) / (HOME_MIN_TILE_WIDTH + HOME_GRID_GAP)), 1, HOME_MAX_COLUMNS);
|
|
1098
1080
|
const tileWidth = Math.max(0, Math.floor((rightPaneWidth - (columns - 1) * HOME_GRID_GAP) / columns));
|
|
1099
1081
|
const previewWidth = Math.max(0, tileWidth - 2 * HOME_TILE_PADDING);
|
|
1100
1082
|
const heroFit = {
|
|
@@ -1117,9 +1099,8 @@ function computeHomeLayout(windowWidth, windowHeight, insets) {
|
|
|
1117
1099
|
};
|
|
1118
1100
|
}
|
|
1119
1101
|
function useHomeLayout() {
|
|
1120
|
-
const { width, height } = (0,
|
|
1121
|
-
const
|
|
1122
|
-
const insets = (0, import_core11.rotateInsets)((0, import_react_native_safe_area_context3.useSafeAreaInsets)(), rotation);
|
|
1102
|
+
const { width, height } = (0, import_react_native6.useWindowDimensions)();
|
|
1103
|
+
const insets = (0, import_react_native_safe_area_context3.useSafeAreaInsets)();
|
|
1123
1104
|
return computeHomeLayout(width, height, insets);
|
|
1124
1105
|
}
|
|
1125
1106
|
|
|
@@ -1141,7 +1122,6 @@ function HomeScreen() {
|
|
|
1141
1122
|
}
|
|
1142
1123
|
function HomeMenu() {
|
|
1143
1124
|
const pack = usePack();
|
|
1144
|
-
const rotation = (0, import_core12.useRotation)();
|
|
1145
1125
|
const layout = useHomeLayout();
|
|
1146
1126
|
const { insets } = layout;
|
|
1147
1127
|
const { dark, colors } = (0, import_auto_paper5.useAutoPaperTheme)();
|
|
@@ -1149,9 +1129,9 @@ function HomeMenu() {
|
|
|
1149
1129
|
const [settingsOpen, setSettingsOpen] = (0, import_react16.useState)(false);
|
|
1150
1130
|
const [rulesGame, setRulesGame] = (0, import_react16.useState)(null);
|
|
1151
1131
|
const isFocused = (0, import_expo_router6.useIsFocused)();
|
|
1152
|
-
const [appState, setAppState] = (0, import_react16.useState)(
|
|
1132
|
+
const [appState, setAppState] = (0, import_react16.useState)(import_react_native7.AppState.currentState);
|
|
1153
1133
|
(0, import_react16.useEffect)(() => {
|
|
1154
|
-
const subscription =
|
|
1134
|
+
const subscription = import_react_native7.AppState.addEventListener("change", setAppState);
|
|
1155
1135
|
return () => subscription.remove();
|
|
1156
1136
|
}, []);
|
|
1157
1137
|
const heroActive = isFocused && appState === "active";
|
|
@@ -1171,12 +1151,19 @@ function HomeMenu() {
|
|
|
1171
1151
|
const closePicker = pickerHost.close;
|
|
1172
1152
|
(0, import_react16.useEffect)(() => {
|
|
1173
1153
|
closePicker();
|
|
1174
|
-
}, [isWide,
|
|
1154
|
+
}, [isWide, layout.windowWidth, layout.windowHeight, closePicker]);
|
|
1175
1155
|
const bg = pack.Backdrop ? "transparent" : dark ? "#000000" : "#FFFFFF";
|
|
1176
1156
|
const fg = pack.foreground ?? (dark ? "#FFFFFF" : "#000000");
|
|
1177
1157
|
const { previewColor } = pack;
|
|
1178
1158
|
const p1Drawn = previewColor ? previewColor(p1Color, dark) : p1Color;
|
|
1179
1159
|
const triggerStyle = (0, import_react16.useMemo)(() => pack.Backdrop ? [styles4.pill, { backgroundColor: colors.surface }] : void 0, [pack.Backdrop, colors.surface]);
|
|
1160
|
+
const tabs = pack.homeTabs && pack.homeTabs.length > 1 ? pack.homeTabs : null;
|
|
1161
|
+
const [tabLabel, setTabLabel] = (0, import_react16.useState)(() => tabs?.[0].label ?? null);
|
|
1162
|
+
const tab = tabs ? tabs.find((t) => t.label === tabLabel) ?? tabs[0] : null;
|
|
1163
|
+
const tabButtons = (0, import_react16.useMemo)(() => tabs?.map(({ label }) => ({ value: label, label })) ?? [], [tabs]);
|
|
1164
|
+
const tabBar = tab && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper.SegmentedButtons, { value: tab.label, onValueChange: setTabLabel, buttons: tabButtons, style: [styles4.tabs, pack.Backdrop && { backgroundColor: colors.surface }] });
|
|
1165
|
+
const columnClamp = useClampOnShrink();
|
|
1166
|
+
const gridClamp = useClampOnShrink();
|
|
1180
1167
|
const openGame = (0, import_react16.useCallback)((game) => openFirstTime(game.id, () => import_expo_router6.router.push(game.useLoadout ? loadoutHref(game.id) : playHref(game.id))), [openFirstTime]);
|
|
1181
1168
|
const openRules = (0, import_react16.useCallback)((game) => game.Rules ? setRulesGame(game) : openFor(game.id), [openFor]);
|
|
1182
1169
|
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 };
|
|
@@ -1186,46 +1173,78 @@ function HomeMenu() {
|
|
|
1186
1173
|
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 });
|
|
1187
1174
|
const pressAway = /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_chrome5.PressAwayOverlay, { active: pickerHost.openId !== null, onPress: pickerHost.close, style: styles4.pressAway });
|
|
1188
1175
|
const RulesSheet = rulesGame?.Rules;
|
|
1189
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1190
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1176
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native7.View, { style: [styles4.container, { backgroundColor: bg }], children: [
|
|
1177
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native7.View, { style: styles4.frame, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(RulesHost, { enabled: pack.games.some((game) => game.Rules), children: [
|
|
1191
1178
|
isWide ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
1192
1179
|
pressAway,
|
|
1193
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.
|
|
1194
|
-
|
|
1180
|
+
/* @__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: [
|
|
1181
|
+
tabBar && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native7.View, { style: [styles4.wideTabs, { width: layout.rightPaneWidth }], children: tabBar }),
|
|
1182
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native7.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)) })
|
|
1183
|
+
] }),
|
|
1184
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native7.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: [
|
|
1195
1185
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(pack.HeroTitle, { words: pack.wordmark, color: fg, p1Color, p2Color, active: heroActive, fit: layout.heroFit }),
|
|
1196
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1186
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native7.View, { style: styles4.widePicker, children: picker })
|
|
1197
1187
|
] })
|
|
1198
|
-
] }) : /* @__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: [
|
|
1188
|
+
] }) : /* @__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: [
|
|
1199
1189
|
pressAway,
|
|
1200
1190
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(pack.HeroTitle, { words: pack.wordmark, color: fg, p1Color, p2Color, active: heroActive }),
|
|
1201
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1202
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1191
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native7.View, { style: [styles4.picker, pickerHost.openId !== null && styles4.pickerOpen], children: picker }),
|
|
1192
|
+
tabBar && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native7.View, { style: styles4.listWidth, children: tabBar }),
|
|
1193
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native7.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)) })
|
|
1203
1194
|
] }),
|
|
1204
1195
|
/* @__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" }),
|
|
1205
1196
|
/* @__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" }),
|
|
1206
1197
|
RulesSheet && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(RulesSheet, { visible: true, onDismiss: () => setRulesGame(null) })
|
|
1207
1198
|
] }) }),
|
|
1208
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SettingsDialog, { visible: settingsOpen, onDismiss: () => setSettingsOpen(false),
|
|
1199
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(SettingsDialog, { visible: settingsOpen, onDismiss: () => setSettingsOpen(false), onShowHowToPlay: pack.guide ? openPack : void 0 })
|
|
1209
1200
|
] });
|
|
1210
1201
|
}
|
|
1211
1202
|
var SEAT_ONE_PICKER = "home-p1";
|
|
1212
1203
|
var noPickerAlign = () => void 0;
|
|
1204
|
+
function isHidden(tab, game) {
|
|
1205
|
+
return !!tab && !tab.includes(game);
|
|
1206
|
+
}
|
|
1207
|
+
function useClampOnShrink() {
|
|
1208
|
+
const view = (0, import_react16.useRef)(null);
|
|
1209
|
+
const sizes = (0, import_react16.useRef)({ viewport: 0, offset: 0 });
|
|
1210
|
+
return (0, import_react16.useMemo)(
|
|
1211
|
+
() => ({
|
|
1212
|
+
ref: (instance) => {
|
|
1213
|
+
view.current = instance;
|
|
1214
|
+
sizes.current.offset = 0;
|
|
1215
|
+
},
|
|
1216
|
+
onLayout: (e) => {
|
|
1217
|
+
sizes.current.viewport = e.nativeEvent.layout.height;
|
|
1218
|
+
},
|
|
1219
|
+
onScroll: (e) => {
|
|
1220
|
+
sizes.current.offset = e.nativeEvent.contentOffset.y;
|
|
1221
|
+
},
|
|
1222
|
+
onContentSizeChange: (_width, height) => {
|
|
1223
|
+
const end = Math.max(0, height - sizes.current.viewport);
|
|
1224
|
+
if (sizes.current.offset <= end) return;
|
|
1225
|
+
sizes.current.offset = end;
|
|
1226
|
+
view.current?.scrollTo({ y: end, animated: false });
|
|
1227
|
+
}
|
|
1228
|
+
}),
|
|
1229
|
+
[]
|
|
1230
|
+
);
|
|
1231
|
+
}
|
|
1213
1232
|
function hasRules(game) {
|
|
1214
1233
|
return !!(game.Rules || game.guide);
|
|
1215
1234
|
}
|
|
1216
1235
|
function RulesHost({ enabled, children }) {
|
|
1217
1236
|
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 });
|
|
1218
1237
|
}
|
|
1219
|
-
function GameRow({ game, dark, p1Color, p2Color, previewRevealed, onPress, onRules }) {
|
|
1238
|
+
function GameRow({ game, hidden, dark, p1Color, p2Color, previewRevealed, onPress, onRules }) {
|
|
1220
1239
|
const well = (0, import_chrome5.useWellColors)();
|
|
1221
1240
|
const GameIcon = game.icon;
|
|
1222
1241
|
return (
|
|
1223
1242
|
// The rules button sits beside the row's own button, laid over its end, not inside it: a button
|
|
1224
1243
|
// inside a button is invalid on the web.
|
|
1225
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1244
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native7.View, { style: hidden ? styles4.hidden : void 0, children: [
|
|
1226
1245
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_feedback_press3.Pressable, { onPress, style: [styles4.row, { backgroundColor: well.bg }], accessibilityRole: "button", accessibilityLabel: game.title, children: [
|
|
1227
|
-
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)(
|
|
1228
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1246
|
+
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_native7.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 }) }),
|
|
1247
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native7.View, { style: styles4.rowText, children: [
|
|
1229
1248
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper.Text, { variant: "titleLarge", style: [styles4.rowTitle, { color: well.fg }], numberOfLines: 1, children: game.title }),
|
|
1230
1249
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper.Text, { variant: "bodyMedium", style: { color: well.fgMuted }, numberOfLines: 2, children: game.blurb })
|
|
1231
1250
|
] })
|
|
@@ -1234,9 +1253,9 @@ function GameRow({ game, dark, p1Color, p2Color, previewRevealed, onPress, onRul
|
|
|
1234
1253
|
] })
|
|
1235
1254
|
);
|
|
1236
1255
|
}
|
|
1237
|
-
function GameTile({ game, width, previewWidth, dark, p1Color, p2Color, previewRevealed, onPress, onRules }) {
|
|
1256
|
+
function GameTile({ game, hidden, width, previewWidth, dark, p1Color, p2Color, previewRevealed, onPress, onRules }) {
|
|
1238
1257
|
const well = (0, import_chrome5.useWellColors)();
|
|
1239
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
1258
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native7.View, { style: [{ width }, hidden && styles4.hidden], children: [
|
|
1240
1259
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_feedback_press3.Pressable, { onPress, style: [styles4.tile, { backgroundColor: well.bg }], accessibilityRole: "button", accessibilityLabel: game.title, children: [
|
|
1241
1260
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(PreviewBox, { game, width: previewWidth, revealed: previewRevealed, dark, p1Color, p2Color }),
|
|
1242
1261
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native_paper.Text, { variant: "titleMedium", style: [styles4.rowTitle, { color: well.fg }], numberOfLines: 1, children: game.title }),
|
|
@@ -1249,13 +1268,13 @@ function PreviewBox({ game, width, revealed, dark, p1Color, p2Color }) {
|
|
|
1249
1268
|
const height = Math.round(width / PREVIEW_ASPECT);
|
|
1250
1269
|
const { Preview, icon: GameIcon } = game;
|
|
1251
1270
|
const iconSize = Math.min(height, ROW_ICON_SIZE);
|
|
1252
|
-
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
1271
|
+
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_react_native7.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_native7.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 }) }) });
|
|
1253
1272
|
}
|
|
1254
1273
|
var ROW_ICON_SIZE = 56;
|
|
1255
1274
|
var ICON_LIGHT_BG = "#FAFAFA";
|
|
1256
1275
|
var ICON_DARK_BG = "#050505";
|
|
1257
1276
|
var RULES_BUTTON_SPACE = 44;
|
|
1258
|
-
var styles4 =
|
|
1277
|
+
var styles4 = import_react_native7.StyleSheet.create({
|
|
1259
1278
|
container: {
|
|
1260
1279
|
flex: 1
|
|
1261
1280
|
},
|
|
@@ -1266,18 +1285,30 @@ var styles4 = import_react_native6.StyleSheet.create({
|
|
|
1266
1285
|
corner: {
|
|
1267
1286
|
position: "absolute"
|
|
1268
1287
|
},
|
|
1288
|
+
frame: {
|
|
1289
|
+
flex: 1
|
|
1290
|
+
},
|
|
1269
1291
|
// The wide layout's tiles: wrapped rows of tiles the layout sizes to fill the pane's width.
|
|
1270
1292
|
grid: {
|
|
1271
1293
|
flexDirection: "row",
|
|
1272
1294
|
flexWrap: "wrap",
|
|
1273
1295
|
gap: HOME_GRID_GAP
|
|
1274
1296
|
},
|
|
1297
|
+
// Out of the layout (a grid closes up around it) and hidden from screen readers.
|
|
1298
|
+
hidden: {
|
|
1299
|
+
display: "none"
|
|
1300
|
+
},
|
|
1275
1301
|
// Solitaire's list: one column, never wider than a phone's, centred on a wide screen.
|
|
1276
1302
|
list: {
|
|
1277
1303
|
gap: 14,
|
|
1278
1304
|
maxWidth: 480,
|
|
1279
1305
|
width: "100%"
|
|
1280
1306
|
},
|
|
1307
|
+
// The list's width, for the tabs over it.
|
|
1308
|
+
listWidth: {
|
|
1309
|
+
maxWidth: 480,
|
|
1310
|
+
width: "100%"
|
|
1311
|
+
},
|
|
1281
1312
|
picker: {
|
|
1282
1313
|
alignItems: "center"
|
|
1283
1314
|
},
|
|
@@ -1303,9 +1334,6 @@ var styles4 = import_react_native6.StyleSheet.create({
|
|
|
1303
1334
|
previewIcon: {
|
|
1304
1335
|
overflow: "hidden"
|
|
1305
1336
|
},
|
|
1306
|
-
rotatable: {
|
|
1307
|
-
flex: 1
|
|
1308
|
-
},
|
|
1309
1337
|
// A well (@tastic/hud's wellSurface): the theme's surface on MD3's level-1 shadow, the same surface
|
|
1310
1338
|
// as Solitaire's game rows, the stats screen's sections and every dialog.
|
|
1311
1339
|
row: {
|
|
@@ -1340,6 +1368,10 @@ var styles4 = import_react_native6.StyleSheet.create({
|
|
|
1340
1368
|
scroll: {
|
|
1341
1369
|
flex: 1
|
|
1342
1370
|
},
|
|
1371
|
+
// SegmentedButtons' own rounding, so a surface behind it is the same pill (the stats screen's tabs).
|
|
1372
|
+
tabs: {
|
|
1373
|
+
borderRadius: 20
|
|
1374
|
+
},
|
|
1343
1375
|
// The same well as a row, turned on its side.
|
|
1344
1376
|
tile: {
|
|
1345
1377
|
borderRadius: 12,
|
|
@@ -1378,6 +1410,10 @@ var styles4 = import_react_native6.StyleSheet.create({
|
|
|
1378
1410
|
position: "absolute",
|
|
1379
1411
|
right: 0,
|
|
1380
1412
|
top: 0
|
|
1413
|
+
},
|
|
1414
|
+
// The tabs over the grid, a little further from it than the tiles are from each other.
|
|
1415
|
+
wideTabs: {
|
|
1416
|
+
marginBottom: 16
|
|
1381
1417
|
}
|
|
1382
1418
|
});
|
|
1383
1419
|
|
|
@@ -1394,7 +1430,7 @@ function useRosterAlign(open, contentWidth, contentHeight) {
|
|
|
1394
1430
|
function ProfilesRoute() {
|
|
1395
1431
|
const { profiles, createProfile, updateProfile, deleteProfile } = useProfiles();
|
|
1396
1432
|
const { Backdrop, foreground, newProfileColor, usePickerAlign } = usePack();
|
|
1397
|
-
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:
|
|
1433
|
+
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_core7.safeBack, fg: foreground, bg: Backdrop ? "transparent" : void 0, useColorPickerAlign: usePickerAlign ? useRosterAlign : void 0 }) });
|
|
1398
1434
|
}
|
|
1399
1435
|
|
|
1400
1436
|
// src/screens/StatsScreen.tsx
|
|
@@ -1402,7 +1438,7 @@ var import_auto_paper7 = require("@rific/auto-paper");
|
|
|
1402
1438
|
var import_chrome7 = require("@tastic/hud/chrome");
|
|
1403
1439
|
var import_profile9 = require("@tastic/profile");
|
|
1404
1440
|
var import_react17 = require("react");
|
|
1405
|
-
var
|
|
1441
|
+
var import_react_native8 = require("react-native");
|
|
1406
1442
|
var import_react_native_paper2 = require("react-native-paper");
|
|
1407
1443
|
var import_react_native_safe_area_context4 = require("react-native-safe-area-context");
|
|
1408
1444
|
var import_react_redux10 = require("react-redux");
|
|
@@ -1425,7 +1461,7 @@ function StatsScreen() {
|
|
|
1425
1461
|
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 }) }) });
|
|
1426
1462
|
}
|
|
1427
1463
|
function StatsPressAway({ host, children }) {
|
|
1428
|
-
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1464
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native8.View, { testID: "stats-press-away", style: styles5.screen, onStartShouldSetResponder: () => host.openId !== null, onResponderRelease: host.close, children });
|
|
1429
1465
|
}
|
|
1430
1466
|
var useNoPackReset = () => null;
|
|
1431
1467
|
var noPickerAlign2 = () => void 0;
|
|
@@ -1459,10 +1495,10 @@ function StatsContent({ pickerHost }) {
|
|
|
1459
1495
|
const surface = pack.Backdrop ? { backgroundColor: colors.surface } : void 0;
|
|
1460
1496
|
const triggerStyle = pack.Backdrop ? [styles5.pill, surface] : void 0;
|
|
1461
1497
|
const PackTabContent = packTab?.Content;
|
|
1462
|
-
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_chrome7.BaseStatsScreen, { title, onBack:
|
|
1498
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_chrome7.BaseStatsScreen, { title, onBack: import_core7.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: [
|
|
1463
1499
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_chrome7.PressAwayOverlay, { active: pickerHost.openId !== null, onPress: pickerHost.close, style: styles5.pressAway }),
|
|
1464
1500
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native_paper2.SegmentedButtons, { value: tab, onValueChange: setTab, buttons: tabButtons, style: [styles5.tabs, surface] }),
|
|
1465
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
1501
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native8.View, { style: [styles5.filters, pickerHost.openId !== null && styles5.filtersOpen], onStartShouldSetResponder: () => pickerHost.openId !== null, children: [
|
|
1466
1502
|
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 }),
|
|
1467
1503
|
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 })
|
|
1468
1504
|
] }),
|
|
@@ -1483,12 +1519,12 @@ function GameStats({ game, tab, profileId, showTitle, titleColor }) {
|
|
|
1483
1519
|
const { StatsSections, AchievementList } = game;
|
|
1484
1520
|
const Sections = tab === STATS ? StatsSections : AchievementList;
|
|
1485
1521
|
if (!Sections) return null;
|
|
1486
|
-
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
1522
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_react_native8.View, { style: styles5.game, children: [
|
|
1487
1523
|
showTitle && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_react_native_paper2.Text, { variant: "titleLarge", style: [styles5.gameTitle, { color: titleColor }], children: game.title }),
|
|
1488
1524
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Sections, { profileId })
|
|
1489
1525
|
] });
|
|
1490
1526
|
}
|
|
1491
|
-
var styles5 =
|
|
1527
|
+
var styles5 = import_react_native8.StyleSheet.create({
|
|
1492
1528
|
filters: {
|
|
1493
1529
|
flexDirection: "row",
|
|
1494
1530
|
flexWrap: "wrap",
|
|
@@ -1522,11 +1558,11 @@ var styles5 = import_react_native7.StyleSheet.create({
|
|
|
1522
1558
|
});
|
|
1523
1559
|
|
|
1524
1560
|
// src/components/imageGameIcon.tsx
|
|
1525
|
-
var
|
|
1561
|
+
var import_react_native9 = require("react-native");
|
|
1526
1562
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
1527
1563
|
function imageGameIcon(images) {
|
|
1528
1564
|
return function ImageGameIcon({ size, dark }) {
|
|
1529
|
-
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
1565
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native9.Image, { source: dark ? images.dark : images.light, style: { height: size, width: size }, accessibilityIgnoresInvertColors: true });
|
|
1530
1566
|
};
|
|
1531
1567
|
}
|
|
1532
1568
|
|
|
@@ -1546,7 +1582,7 @@ var import_redux_persist = require("redux-persist");
|
|
|
1546
1582
|
|
|
1547
1583
|
// src/redux/shellState.ts
|
|
1548
1584
|
var import_auto_paper8 = require("@rific/auto-paper");
|
|
1549
|
-
var
|
|
1585
|
+
var import_core11 = require("@rific/core");
|
|
1550
1586
|
var import_feedback_press4 = require("@rific/feedback-press");
|
|
1551
1587
|
var import_profile10 = require("@tastic/profile");
|
|
1552
1588
|
var initialSoundSettings = { ...import_feedback_press4.defaultSoundSettings, enabled: !__DEV__ };
|
|
@@ -1567,7 +1603,7 @@ function createShellReducers({ seatColors, appearance = "system", seatTheme }) {
|
|
|
1567
1603
|
sound: appSoundReducer,
|
|
1568
1604
|
// @rific/core's Keep Awake setting (see Providers.tsx's KeepAwakeBridge), under the namespace its
|
|
1569
1605
|
// REHYDRATE handling expects.
|
|
1570
|
-
keepAwake:
|
|
1606
|
+
keepAwake: import_core11.keepAwakeReducer,
|
|
1571
1607
|
// The shared App Group roster (see @tastic/profile's resolveInitialProfiles/
|
|
1572
1608
|
// useSharedProfilesSync, wired in hooks/useProfiles.tsx) is layered on top of this as a separate
|
|
1573
1609
|
// sync target - this slice persisting normally via redux-persist is what gives it local-fallback
|