@tastic/shell 0.6.0 → 0.8.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 +10 -9
- package/dist/index.d.mts +10 -6
- package/dist/index.d.ts +10 -6
- package/dist/index.js +146 -128
- package/dist/index.mjs +118 -100
- package/package.json +9 -9
- package/src/components/MatchChips.tsx +12 -12
- package/src/components/OpponentPicker.tsx +112 -0
- package/src/components/SettingsDialog.tsx +8 -3
- package/src/hooks/useAtComputer.ts +13 -0
- package/src/index.ts +2 -1
- package/src/redux/opponentSlice.ts +1 -1
- package/src/screens/HomeScreen.tsx +1 -1
- package/src/screens/LoadoutScreen.tsx +86 -37
- package/src/types.ts +16 -4
- package/src/components/SeatTwoPanel.tsx +0 -144
package/README.md
CHANGED
|
@@ -102,6 +102,7 @@ the front of an in-app link, so a route starting with a game id equal to the bas
|
|
|
102
102
|
| `fonts?` | Fonts the pack's own art needs, loaded behind the splash screen beside the icon font. |
|
|
103
103
|
| `fontFamily?` | The typeface on every Paper text variant. Unset is Paper's own. |
|
|
104
104
|
| `otaVersion` | The version label in Settings. |
|
|
105
|
+
| `useSettingsRules?` | A hook returning what goes first in every Settings dialog, above the shell's rows: the rules of the game it's opened in. Null where there's nothing (Home). |
|
|
105
106
|
| `SettingsSections?` | The pack's own Settings sections, in every Settings dialog, under the shell's rows and any a play screen adds. |
|
|
106
107
|
| `reducers?` | The pack's own store keys (what `SettingsSections` saves), beside the shell's and the games'. Never a key either already mounts. |
|
|
107
108
|
| `StatsSections?` | A section across the pack's games (a calendar of play), first on the stats screen's Stats tab, handed its two filters (`PackStatsSectionsProps`: `profileId`, null for Everyone, and `gameId`, null for All Games). |
|
|
@@ -111,7 +112,7 @@ PuckTastic and DuelTastic draw what they always did:
|
|
|
111
112
|
|
|
112
113
|
| Field | |
|
|
113
114
|
| --- | --- |
|
|
114
|
-
| `Backdrop?` | A table drawn once behind the whole stack (Solitaire's felt). The stack's two layers go transparent (the screens' `contentStyle` and the navigation theme's `colors.background`, which React Navigation paints around every screen), the root window stays dark so light mode doesn't flash white on a push, Android's push and pop crossfade (its default holds the outgoing screen opaque), and Home, each loadout, the stats screen and Profiles draw transparent, with their buttons and tabs on the theme's surface. |
|
|
115
|
+
| `Backdrop?` | A table drawn once behind the whole stack (Solitaire's felt). The stack's two layers go transparent (the screens' `contentStyle` and the navigation theme's `colors.background`, which React Navigation paints around every screen), the root window stays dark so light mode doesn't flash white on a push, Android's push and pop crossfade (its default holds the outgoing screen opaque), and Home, each loadout, the stats screen and Profiles draw transparent, with their buttons and tabs on the theme's surface (a loadout's Ready buttons too, filled with the seat's color once ready). |
|
|
115
116
|
| `foreground?` | The color of what those screens draw straight on the background (the hero, the corner buttons, headers), and at half strength a loadout's muted options. Unset is black or white with the theme. |
|
|
116
117
|
| `Provider?` | Mounted once around How to Play and the stack, inside the store, the theme, profiles and every game's `Provider` (one stats context across the pack's games). |
|
|
117
118
|
| `useScreenOptions?` | A hook returning stack screen options (`StackScreenOptions`), merged after the shell's own (a status bar style of the pack's own, Reduce Motion's crossfade). The shell's already follow the app's theme, and stay dark over a `Backdrop`. |
|
|
@@ -135,8 +136,8 @@ PuckTastic and DuelTastic draw what they always did:
|
|
|
135
136
|
|
|
136
137
|
Each game is one object: its `id`, `title`, `blurb` and `icon` (a component drawn in the seats'
|
|
137
138
|
colors, or `imageGameIcon({ light, dark })` for a light and dark pair of pictures), its seat 2
|
|
138
|
-
choices (`seatTwo`: `'cpu'`, `'person'`, `'nobody'`)
|
|
139
|
-
|
|
139
|
+
choices (`seatTwo`: `'cpu'`, `'person'`, `'nobody'`), whether 2 Player seats its players side by side
|
|
140
|
+
at a computer (`sideBySideAtComputer`) and in a wide window (`sideBySideWhenWide`), the store `reducers` it mounts, its root `Provider`, its `useLoadout(mode)`, its
|
|
140
141
|
`PlayScreen`, its `StatsSections` and `AchievementList`, `resetStats`, and its How to Play `guide`.
|
|
141
142
|
See `src/types.ts` for every field.
|
|
142
143
|
|
|
@@ -144,9 +145,9 @@ What a game can leave out or add, each optional, so a two-seat game sets none of
|
|
|
144
145
|
|
|
145
146
|
| Field | |
|
|
146
147
|
| --- | --- |
|
|
147
|
-
| no `seatTwo` (nor `sideBySideWhenWide`) | A game for one player: its loadout has no
|
|
148
|
+
| no `seatTwo` (nor `sideBySideWhenWide`) | A game for one player: its loadout has no opponent button, every round is solo (`useActiveRound` falls back to `'solo'`), and its How to Play describes a solo round. |
|
|
148
149
|
| no `useLoadout` | Nothing to set up first: Home opens its play screen straight away, after its How to Play the first time, and a link to its loadout plays it. Its rule variants go in its play screen's Settings: `<SettingsDialog>` takes `children`. |
|
|
149
|
-
| no `cpuDifficulty` (in `GameLoadout`) | A CPU with no levels:
|
|
150
|
+
| no `cpuDifficulty` (in `GameLoadout`) | A CPU with no levels: player 1's opponent menu offers one plain CPU. |
|
|
150
151
|
| `resumable` | A cold launch drops the player back into its play screen if they left the app there rather than backing out of it. The shell remembers only which game (`lastActiveGame`); the game saves and restores its own board. |
|
|
151
152
|
| `Preview` | Drawn on Home in place of the icon (`GamePreviewProps`: `width`, `height`, the seats' colors, `dark`), in a box of `PREVIEW_ASPECT` (360:200), a frame after Home first paints. While any game has one, Home shows tiles: rows upright, and on a wide screen a grid beside the hero and seat 1's button. A game without one keeps its icon. |
|
|
152
153
|
| no `icon` | Only with a `Preview`, which Home draws in its place. |
|
|
@@ -205,10 +206,10 @@ screen right now) and `onBack`/`onSettings`, plus `centerLineY` when the line be
|
|
|
205
206
|
the window's middle.
|
|
206
207
|
|
|
207
208
|
- **Where:** the window's top corners; 2 Player face to face, the side edges at the line between the
|
|
208
|
-
players (the top corners are the far player's end);
|
|
209
|
-
|
|
209
|
+
players (the top corners are the far player's end); at a computer (`useAtComputer`: the web without
|
|
210
|
+
a touch-first screen), the page's top corners always.
|
|
210
211
|
- **When:** faded out over `MATCH_CHIPS_FADE_MS` (150) and not pressable while `playing`, back the moment
|
|
211
|
-
it stops; up all match
|
|
212
|
+
it stops; up all match at a computer.
|
|
212
213
|
- **Look:** a 24 icon in the theme's full contrast on a translucent chip of the page's color.
|
|
213
214
|
|
|
214
215
|
## Peer dependencies
|
|
@@ -233,7 +234,7 @@ became a package (the lower of the two where they differ).
|
|
|
233
234
|
| `@rific/feedback-press` | >=0.13.1 | haptic and sound settings, the UI sounds |
|
|
234
235
|
| `@rific/toaster` | >=0.10.1 | toasts (DuelTastic runs 0.12, PuckTastic 0.10) |
|
|
235
236
|
| `@tastic/core` | >=0.15.0 | the seat mode from the window's shape, the root background |
|
|
236
|
-
| `@tastic/hud` | >=0.
|
|
237
|
+
| `@tastic/hud` | >=0.29.0 | Settings, the stats screen, the loadout's panels (its Skia-free `/lobby` entry, new in 0.26.0; 0.27.1's options for a pack drawn on its own backdrop; 0.28.0's Ready pill; 0.29.0's leading Settings sections), How to Play |
|
|
237
238
|
| `@tastic/profile` | >=0.16.2 | profiles, the seat buttons, seat colors |
|
|
238
239
|
| `@tastic/achievements` | >=0.6.0 | `createGameStats`, `forgetProfileAchievements` |
|
|
239
240
|
| `@tastic/split-screen` | >=0.5.5 | the 2 Player loadout's two halves |
|
package/dist/index.d.mts
CHANGED
|
@@ -207,6 +207,7 @@ interface GameDefinition {
|
|
|
207
207
|
Preview?: ComponentType<GamePreviewProps>;
|
|
208
208
|
seatTwo?: readonly SeatTwo[];
|
|
209
209
|
sideBySideWhenWide?: boolean;
|
|
210
|
+
sideBySideAtComputer?: boolean;
|
|
210
211
|
reducers: Record<string, Reducer>;
|
|
211
212
|
Provider?: ComponentType<{
|
|
212
213
|
children: ReactNode;
|
|
@@ -279,6 +280,7 @@ interface PackDefinition {
|
|
|
279
280
|
fontFamily?: string;
|
|
280
281
|
otaVersion: number;
|
|
281
282
|
SettingsSections?: ComponentType;
|
|
283
|
+
useSettingsRules?: () => ReactNode;
|
|
282
284
|
reducers?: Record<string, Reducer>;
|
|
283
285
|
StatsSections?: ComponentType<PackStatsSectionsProps>;
|
|
284
286
|
Backdrop?: ComponentType;
|
|
@@ -399,17 +401,16 @@ declare function imageGameIcon(images: {
|
|
|
399
401
|
dark: ImageSourcePropType;
|
|
400
402
|
}): ComponentType<GameIconProps>;
|
|
401
403
|
|
|
402
|
-
declare const MATCH_CHIPS_DESKTOP_MIN_WIDTH = 768;
|
|
403
404
|
declare const MATCH_CHIPS_FADE_MS = 150;
|
|
404
405
|
interface MatchChipsProps {
|
|
405
406
|
/** Whether play is on right now (a live puck, a shot in flight, a round being ridden). While it is,
|
|
406
407
|
* the chips fade out and can't be pressed, so they never cover play; they come back the moment it
|
|
407
|
-
* stops (between points, a round's card, Game Over). Ignored
|
|
408
|
+
* stops (between points, a round's card, Game Over). Ignored at a computer, where they stay up. */
|
|
408
409
|
playing: boolean;
|
|
409
410
|
/** Two players at opposite ends of one screen right now (2 Player face to face). The chips then sit
|
|
410
411
|
* on the side edges at the line between the players, rather than in the top corners, which are the
|
|
411
|
-
* far player's end. False for one human (vs CPU, solo) and for side by side. Ignored
|
|
412
|
-
*
|
|
412
|
+
* far player's end. False for one human (vs CPU, solo) and for side by side. Ignored at a
|
|
413
|
+
* computer: both players share one upright screen there. */
|
|
413
414
|
faceToFace: boolean;
|
|
414
415
|
/** Where that line between the players is, as a y in the window. Defaults to the window's middle;
|
|
415
416
|
* pass it when the board isn't centered (a band of score above it, say). */
|
|
@@ -420,7 +421,8 @@ interface MatchChipsProps {
|
|
|
420
421
|
/** The back and settings chips over a match, in every game of every pack: one rule for where they sit
|
|
421
422
|
* and when they show. The window's top corners (the same spot as hud's CornerActionButtons on every
|
|
422
423
|
* other screen), except 2 Player face to face, which puts them on the side edges at the line between
|
|
423
|
-
* the players; faded out while play is on, except
|
|
424
|
+
* the players; faded out while play is on, except at a computer (useAtComputer: the web without a
|
|
425
|
+
* touch-first screen), where they stay up in the page's corners. */
|
|
424
426
|
declare function MatchChips({ playing, faceToFace, centerLineY, onBack, onSettings }: MatchChipsProps): react.JSX.Element;
|
|
425
427
|
|
|
426
428
|
interface SettingsDialogProps {
|
|
@@ -441,6 +443,8 @@ declare function useAppSettings(): {
|
|
|
441
443
|
setSettings: (patch: Partial<AppSettings>) => void;
|
|
442
444
|
};
|
|
443
445
|
|
|
446
|
+
declare function useAtComputer(): boolean;
|
|
447
|
+
|
|
444
448
|
declare function useOpponent(): {
|
|
445
449
|
seatTwo: SeatTwo;
|
|
446
450
|
setSeatTwo: (seatTwo: SeatTwo) => void;
|
|
@@ -575,5 +579,5 @@ declare function createPlayerSettings<S extends WithControls<C>, C>({ id, defaul
|
|
|
575
579
|
};
|
|
576
580
|
};
|
|
577
581
|
|
|
578
|
-
export { DEFAULT_APP_SETTINGS, DEFAULT_OPPONENT, GUEST_PLAYER_ID, HomeScreen, LoadoutRoute,
|
|
582
|
+
export { DEFAULT_APP_SETTINGS, DEFAULT_OPPONENT, GUEST_PLAYER_ID, HomeScreen, LoadoutRoute, MATCH_CHIPS_FADE_MS, MatchChips, PREVIEW_ASPECT, PackProvider, PlayRoute, ProfilesProvider, ProfilesRoute, RootLayout, SettingsDialog, StatsScreen, appSettingsActions, reducer$1 as appSettingsReducer, createGameGuideSlice, createGameStats, createPackStore, createPlayerSettings, createSeatColorsReducer, createShellReducers, defaultProfileSelectionState, defaultSeatColorsState, forgetProfileAchievements, humanSeatsFor, imageGameIcon, liveplayActions, reducer$3 as liveplayReducer, onProfileRemoved, opponentActions, reducer$2 as opponentReducer, profileSelectionActions, reducer as profileSelectionReducer, roundModeFor, seatColorsActions, seatPlayerKey, seatTwoFor, useActiveRound, useAppSettings, useAtComputer, useGameGuide, useOpponent, usePack, usePackGame, useProfiles, useSeatColors };
|
|
579
583
|
export type { ActiveRound, AppSettings, FeedbackSounds, GameDefinition, GameGuide, GameGuideState, GameIconProps, GameLoadout, GamePreviewProps, GameRulesProps, GuidelessGameDefinition, HeroTitleProps, HomeTab, LiveplaySliceState, LoadoutOptionsProps, MatchChipsProps, OpponentState, PackDefinition, PackGameDefinition, PackGuide, PackStatsReset, PackStatsSectionsProps, PackStatsTab, PackStore, PackStoreConfig, PackStoreSource, PickerAlign, PlayerControlsState, PlayerSettingsState, ProfileSelectionState, RecordResult, RoundMode, Seat, SeatColorsState, SeatControlLook, SeatTwo, SettingsDialogProps, ShellState, StackScreenOptions };
|
package/dist/index.d.ts
CHANGED
|
@@ -207,6 +207,7 @@ interface GameDefinition {
|
|
|
207
207
|
Preview?: ComponentType<GamePreviewProps>;
|
|
208
208
|
seatTwo?: readonly SeatTwo[];
|
|
209
209
|
sideBySideWhenWide?: boolean;
|
|
210
|
+
sideBySideAtComputer?: boolean;
|
|
210
211
|
reducers: Record<string, Reducer>;
|
|
211
212
|
Provider?: ComponentType<{
|
|
212
213
|
children: ReactNode;
|
|
@@ -279,6 +280,7 @@ interface PackDefinition {
|
|
|
279
280
|
fontFamily?: string;
|
|
280
281
|
otaVersion: number;
|
|
281
282
|
SettingsSections?: ComponentType;
|
|
283
|
+
useSettingsRules?: () => ReactNode;
|
|
282
284
|
reducers?: Record<string, Reducer>;
|
|
283
285
|
StatsSections?: ComponentType<PackStatsSectionsProps>;
|
|
284
286
|
Backdrop?: ComponentType;
|
|
@@ -399,17 +401,16 @@ declare function imageGameIcon(images: {
|
|
|
399
401
|
dark: ImageSourcePropType;
|
|
400
402
|
}): ComponentType<GameIconProps>;
|
|
401
403
|
|
|
402
|
-
declare const MATCH_CHIPS_DESKTOP_MIN_WIDTH = 768;
|
|
403
404
|
declare const MATCH_CHIPS_FADE_MS = 150;
|
|
404
405
|
interface MatchChipsProps {
|
|
405
406
|
/** Whether play is on right now (a live puck, a shot in flight, a round being ridden). While it is,
|
|
406
407
|
* the chips fade out and can't be pressed, so they never cover play; they come back the moment it
|
|
407
|
-
* stops (between points, a round's card, Game Over). Ignored
|
|
408
|
+
* stops (between points, a round's card, Game Over). Ignored at a computer, where they stay up. */
|
|
408
409
|
playing: boolean;
|
|
409
410
|
/** Two players at opposite ends of one screen right now (2 Player face to face). The chips then sit
|
|
410
411
|
* on the side edges at the line between the players, rather than in the top corners, which are the
|
|
411
|
-
* far player's end. False for one human (vs CPU, solo) and for side by side. Ignored
|
|
412
|
-
*
|
|
412
|
+
* far player's end. False for one human (vs CPU, solo) and for side by side. Ignored at a
|
|
413
|
+
* computer: both players share one upright screen there. */
|
|
413
414
|
faceToFace: boolean;
|
|
414
415
|
/** Where that line between the players is, as a y in the window. Defaults to the window's middle;
|
|
415
416
|
* pass it when the board isn't centered (a band of score above it, say). */
|
|
@@ -420,7 +421,8 @@ interface MatchChipsProps {
|
|
|
420
421
|
/** The back and settings chips over a match, in every game of every pack: one rule for where they sit
|
|
421
422
|
* and when they show. The window's top corners (the same spot as hud's CornerActionButtons on every
|
|
422
423
|
* other screen), except 2 Player face to face, which puts them on the side edges at the line between
|
|
423
|
-
* the players; faded out while play is on, except
|
|
424
|
+
* the players; faded out while play is on, except at a computer (useAtComputer: the web without a
|
|
425
|
+
* touch-first screen), where they stay up in the page's corners. */
|
|
424
426
|
declare function MatchChips({ playing, faceToFace, centerLineY, onBack, onSettings }: MatchChipsProps): react.JSX.Element;
|
|
425
427
|
|
|
426
428
|
interface SettingsDialogProps {
|
|
@@ -441,6 +443,8 @@ declare function useAppSettings(): {
|
|
|
441
443
|
setSettings: (patch: Partial<AppSettings>) => void;
|
|
442
444
|
};
|
|
443
445
|
|
|
446
|
+
declare function useAtComputer(): boolean;
|
|
447
|
+
|
|
444
448
|
declare function useOpponent(): {
|
|
445
449
|
seatTwo: SeatTwo;
|
|
446
450
|
setSeatTwo: (seatTwo: SeatTwo) => void;
|
|
@@ -575,5 +579,5 @@ declare function createPlayerSettings<S extends WithControls<C>, C>({ id, defaul
|
|
|
575
579
|
};
|
|
576
580
|
};
|
|
577
581
|
|
|
578
|
-
export { DEFAULT_APP_SETTINGS, DEFAULT_OPPONENT, GUEST_PLAYER_ID, HomeScreen, LoadoutRoute,
|
|
582
|
+
export { DEFAULT_APP_SETTINGS, DEFAULT_OPPONENT, GUEST_PLAYER_ID, HomeScreen, LoadoutRoute, MATCH_CHIPS_FADE_MS, MatchChips, PREVIEW_ASPECT, PackProvider, PlayRoute, ProfilesProvider, ProfilesRoute, RootLayout, SettingsDialog, StatsScreen, appSettingsActions, reducer$1 as appSettingsReducer, createGameGuideSlice, createGameStats, createPackStore, createPlayerSettings, createSeatColorsReducer, createShellReducers, defaultProfileSelectionState, defaultSeatColorsState, forgetProfileAchievements, humanSeatsFor, imageGameIcon, liveplayActions, reducer$3 as liveplayReducer, onProfileRemoved, opponentActions, reducer$2 as opponentReducer, profileSelectionActions, reducer as profileSelectionReducer, roundModeFor, seatColorsActions, seatPlayerKey, seatTwoFor, useActiveRound, useAppSettings, useAtComputer, useGameGuide, useOpponent, usePack, usePackGame, useProfiles, useSeatColors };
|
|
579
583
|
export type { ActiveRound, AppSettings, FeedbackSounds, GameDefinition, GameGuide, GameGuideState, GameIconProps, GameLoadout, GamePreviewProps, GameRulesProps, GuidelessGameDefinition, HeroTitleProps, HomeTab, LiveplaySliceState, LoadoutOptionsProps, MatchChipsProps, OpponentState, PackDefinition, PackGameDefinition, PackGuide, PackStatsReset, PackStatsSectionsProps, PackStatsTab, PackStore, PackStoreConfig, PackStoreSource, PickerAlign, PlayerControlsState, PlayerSettingsState, ProfileSelectionState, RecordResult, RoundMode, Seat, SeatColorsState, SeatControlLook, SeatTwo, SettingsDialogProps, ShellState, StackScreenOptions };
|