diff --git a/redux/GamesSlice.ts b/redux/GamesSlice.ts index 9d86791f..f9e4855f 100644 --- a/redux/GamesSlice.ts +++ b/redux/GamesSlice.ts @@ -31,7 +31,7 @@ const gamesAdapter = createEntityAdapter({ const initialState = gamesAdapter.getInitialState({ }); -const gameDefaults = { +export const gameDefaults = { roundCurrent: 0, roundTotal: 1, locked: false, diff --git a/redux/SettingsSlice.ts b/redux/SettingsSlice.ts index 8212e2cc..fa4e5198 100644 --- a/redux/SettingsSlice.ts +++ b/redux/SettingsSlice.ts @@ -14,7 +14,6 @@ export interface SettingsState { onboarded: string | undefined; showPointParticles: boolean; showPlayerIndex: boolean; - showColorPalettes?: boolean; interactionType: InteractionType; lastStoreReviewPrompt: number; devMenuEnabled?: boolean; @@ -23,7 +22,7 @@ export interface SettingsState { rollingGameCounter?: number; }; -const initialState: SettingsState = { +export const initialState: SettingsState = { home_fullscreen: false, multiplier: 1, addendOne: 1, @@ -32,7 +31,6 @@ const initialState: SettingsState = { onboarded: undefined, showPointParticles: false, showPlayerIndex: false, - showColorPalettes: false, interactionType: InteractionType.SwipeVertical, lastStoreReviewPrompt: 0, appOpens: 0, @@ -57,9 +55,6 @@ const settingsSlice = createSlice({ toggleShowPlayerIndex(state) { state.showPlayerIndex = !state.showPlayerIndex; }, - toggleShowColorPalettes(state) { - state.showColorPalettes = !state.showColorPalettes; - }, setMultiplier(state, action: PayloadAction) { state.multiplier = action.payload; }, @@ -107,7 +102,6 @@ export const { setOnboardedVersion, toggleShowPointParticles, toggleShowPlayerIndex, - toggleShowColorPalettes, setInteractionType, setLastStoreReviewPrompt, toggleDevMenuEnabled, diff --git a/redux/store.ts b/redux/store.ts index 59ea18a1..217b8002 100644 --- a/redux/store.ts +++ b/redux/store.ts @@ -19,7 +19,6 @@ const settingsPersistConfig = { 'onboarded', 'showPointParticles', 'showPlayerIndex', - 'showColorPalettes', 'interactionType', 'lastStoreReviewPrompt', 'devMenuEnabled', diff --git a/src/components/Buttons/CheckButton.test.tsx b/src/components/Buttons/CheckButton.test.tsx index 33bce360..22ed94a8 100644 --- a/src/components/Buttons/CheckButton.test.tsx +++ b/src/components/Buttons/CheckButton.test.tsx @@ -1,5 +1,9 @@ +import { configureStore } from '@reduxjs/toolkit'; import { fireEvent, render, waitFor } from '@testing-library/react-native'; +import { Provider } from 'react-redux'; +import gamesReducer, { gameDefaults } from '../../../redux/GamesSlice'; +import settingsReducer, { initialState as settingsState } from '../../../redux/SettingsSlice'; import { useNavigationMock } from '../../../test/test-helpers'; import { logEvent } from '../../Analytics'; @@ -7,35 +11,84 @@ import CheckButton from './CheckButton'; jest.mock('../../Analytics'); +const mockStore = () => { + return configureStore({ + reducer: { + settings: settingsReducer, + games: gamesReducer, + }, + preloadedState: { + settings: { + ...settingsState, + currentGameId: '123' + }, + games: { + entities: { + '123': { + ...gameDefaults, + id: '123', + title: 'Game', + dateCreated: 1, + playerIds: [], + } + }, + ids: ['123'] + } + } + }); +}; + describe('CheckButton', () => { const navigation = useNavigationMock(); - it.skip('should navigate to Game screen when pressed', async () => { - const { getByRole } = render(); + it('should navigate to Game screen when pressed', async () => { + const store = mockStore(); + + const { getByRole } = render( + + + + ); + const button = getByRole('button'); + fireEvent.press(button); + await waitFor(() => { - fireEvent.press(button); expect(navigation.navigate).toHaveBeenCalledWith('Game'); }); - }); + }, 10000); + + it('should navigate back a screen when pressed', async () => { + const store = mockStore(); + + const { getByRole } = render( + + + + ); - it.skip('should navigate back a screen when pressed', async () => { - const { getByRole } = render(); const button = getByRole('button'); + fireEvent.press(button); + await waitFor(() => { - fireEvent.press(button); - expect(navigation.goBack).toHaveBeenCalled(); + expect(navigation.navigate).toHaveBeenCalledWith('List'); }); - }); + }, 10000); it('should log an analytics event when pressed', async () => { - const { getByRole } = render(); - const button = getByRole('button'); + const store = mockStore(); + + const { getByRole } = render( + + + + ); + const button = getByRole('button'); fireEvent.press(button); await waitFor(() => { - expect(logEvent).toHaveBeenCalledWith('save_game'); + expect(logEvent).toHaveBeenCalledWith('save_game', expect.any(Object)); }); - }); + }, 10000); }); diff --git a/src/components/Buttons/CheckButton.tsx b/src/components/Buttons/CheckButton.tsx index a37acd32..88e73667 100644 --- a/src/components/Buttons/CheckButton.tsx +++ b/src/components/Buttons/CheckButton.tsx @@ -4,6 +4,8 @@ import { ParamListBase, RouteProp } from '@react-navigation/native'; import { NativeStackNavigationProp } from '@react-navigation/native-stack'; import { Text } from 'react-native'; +import { useAppSelector } from '../../../redux/hooks'; +import { selectCurrentGame } from '../../../redux/selectors'; import { logEvent } from '../../Analytics'; import { systemBlue } from '../../constants'; @@ -20,10 +22,18 @@ interface Props { } const CheckButton: React.FunctionComponent = ({ navigation, route }) => { + const currentGame = useAppSelector(state => selectCurrentGame(state)); + if (typeof currentGame == 'undefined') return null; return ( { - await logEvent('save_game'); + await logEvent('save_game', { + source: route?.params?.source, + gameId: currentGame?.id, + palette: currentGame.palette, + player_count: currentGame.playerIds.length, + }); + if (route?.params?.source === 'list_screen') { navigation.navigate('List'); } else { diff --git a/src/components/ColorPalettes/ColorSelector.tsx b/src/components/ColorPalettes/ColorSelector.tsx index 8ce441ae..6b969bc6 100644 --- a/src/components/ColorPalettes/ColorSelector.tsx +++ b/src/components/ColorPalettes/ColorSelector.tsx @@ -5,6 +5,7 @@ import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'; import { useAppDispatch, useAppSelector } from '../../../redux/hooks'; import { updatePlayer } from '../../../redux/PlayersSlice'; import { selectCurrentGame } from '../../../redux/selectors'; +import { logEvent } from '../../Analytics'; import { getPalette, getPalettes } from '../../ColorPalette'; interface ColorSelectorProps { @@ -27,6 +28,7 @@ const ColorButton: React.FC<{ color: string, playerColor: string | undefined; }> const ColorSelector: React.FC = ({ playerId }) => { const colorPalettes = getPalettes(); const currentGameId = useAppSelector(state => selectCurrentGame(state)?.id); + const currentGame = useAppSelector(state => selectCurrentGame(state)); const currentPalette = useAppSelector(state => selectCurrentGame(state)?.palette); const playerColor = useAppSelector(state => state.players.entities[playerId]?.color); @@ -34,11 +36,17 @@ const ColorSelector: React.FC = ({ playerId }) => { const dispatch = useAppDispatch(); - const tapColorHandler = (color: string) => { + const tapColorHandler = (color: string, inCurrentPalette: boolean = false) => { dispatch(updatePlayer({ id: playerId, changes: { color: color } })); + logEvent('set_player_color', { + gameId: currentGameId, + palette: currentGame?.palette, + color, + inCurrentPalette, + }); }; return ( @@ -55,7 +63,7 @@ const ColorSelector: React.FC = ({ playerId }) => { getPalette(currentPalette).map((color, i) => ( tapColorHandler(color)} + onPress={() => tapColorHandler(color, true)} > diff --git a/src/components/ColorPalettes/PaletteSelector.tsx b/src/components/ColorPalettes/PaletteSelector.tsx index 88db0c09..eda63e95 100644 --- a/src/components/ColorPalettes/PaletteSelector.tsx +++ b/src/components/ColorPalettes/PaletteSelector.tsx @@ -5,6 +5,7 @@ import { ScrollView, StyleSheet, TouchableOpacity } from 'react-native'; import { asyncSetGamePalette } from '../../../redux/GamesSlice'; import { useAppDispatch, useAppSelector } from '../../../redux/hooks'; import { selectCurrentGame } from '../../../redux/selectors'; +import { logEvent } from '../../Analytics'; import { getPalette, getPalettes } from '../../ColorPalette'; import PalettePreview from './PalettePreview'; @@ -27,6 +28,10 @@ const PaletteSelector: React.FunctionComponent = () => { palette: palette, }) ); + logEvent('set_game_palette', { + game_id: currentGameId, + palette, + }); }; return ( diff --git a/src/components/EditGame.tsx b/src/components/EditGame.tsx index ef3192c0..11f1bde2 100644 --- a/src/components/EditGame.tsx +++ b/src/components/EditGame.tsx @@ -50,8 +50,6 @@ const EditGame = ({ }) => { })); }; - const showColorPalettes = useAppSelector(state => state.settings.showColorPalettes); - return ( <> @@ -75,9 +73,7 @@ const EditGame = ({ }) => { - {showColorPalettes && - - } + ); diff --git a/src/components/Sheets/GameSheet.tsx b/src/components/Sheets/GameSheet.tsx index b24f5878..8d866500 100644 --- a/src/components/Sheets/GameSheet.tsx +++ b/src/components/Sheets/GameSheet.tsx @@ -274,7 +274,7 @@ const GameSheet: React.FunctionComponent = ({ navigation, containerHeight logEvent('edit_game', { game_id: currentGameId }); - navigation.navigate('Settings'); + navigation.navigate('Settings', { source: 'edit_game' }); } } /> diff --git a/src/screens/AppInfoScreen.tsx b/src/screens/AppInfoScreen.tsx index 6039f390..3620dd92 100644 --- a/src/screens/AppInfoScreen.tsx +++ b/src/screens/AppInfoScreen.tsx @@ -7,7 +7,7 @@ import { Alert, Linking, Platform, ScrollView, StyleSheet, Switch, Text, View } import { Button } from 'react-native-elements'; import { useAppDispatch, useAppSelector } from '../../redux/hooks'; -import { toggleShowColorPalettes, toggleShowPlayerIndex, toggleShowPointParticles } from '../../redux/SettingsSlice'; +import { toggleShowPlayerIndex, toggleShowPointParticles } from '../../redux/SettingsSlice'; import { logEvent } from '../Analytics'; import RotatingIcon from '../components/AppInfo/RotatingIcon'; @@ -41,7 +41,6 @@ const AppInfoScreen: React.FunctionComponent = ({ navigation }) => { const showPointParticles = useAppSelector(state => state.settings.showPointParticles); const showPlayerIndex = useAppSelector(state => state.settings.showPlayerIndex); - const showColorPalettes = useAppSelector(state => state.settings.showColorPalettes); const devMenuEnabled = useAppSelector(state => state.settings.devMenuEnabled); const installId = useAppSelector(state => state.settings.installId); @@ -62,14 +61,6 @@ const AppInfoScreen: React.FunctionComponent = ({ navigation }) => { installId }); }; - const toggleColorPalettesSwitch = () => { - dispatch(toggleShowColorPalettes()); - logEvent('toggle_feature', { - feature: 'color_palettes', - value: !showColorPalettes, - installId - }); - }; const alertWithVersion = async () => { Alert.alert('ScorePad with Rounds\n' + @@ -94,22 +85,18 @@ const AppInfoScreen: React.FunctionComponent = ({ navigation }) => {
- + - - + + {devMenuEnabled && ( <> - - - - )}
diff --git a/src/screens/EditPlayerScreen.tsx b/src/screens/EditPlayerScreen.tsx index cacb4461..c7ef1703 100644 --- a/src/screens/EditPlayerScreen.tsx +++ b/src/screens/EditPlayerScreen.tsx @@ -83,7 +83,6 @@ const EditPlayerScreen: React.FC = ({ }; const inputRef = React.useRef(null); - const showColorPalettes = useAppSelector(state => state.settings.showColorPalettes); return ( @@ -119,12 +118,9 @@ const EditPlayerScreen: React.FC = ({ value={localPlayerName} /> - { - showColorPalettes && - - - - } + + + );