Skip to content

Commit

Permalink
Merge pull request #414 from wyne/reorder-players
Browse files Browse the repository at this point in the history
Reorder players
  • Loading branch information
wyne authored Apr 13, 2024
2 parents 241d0dc + 945c940 commit e303fa2
Show file tree
Hide file tree
Showing 21 changed files with 531 additions and 224 deletions.
14 changes: 14 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,13 @@
"expo-device": "~5.9.3",
"expo-haptics": "~12.8.1",
"expo-image": "~1.10.6",
"expo-linking": "~6.2.2",
"expo-screen-orientation": "~6.4.1",
"expo-sensors": "~12.9.1",
"expo-sharing": "~11.10.0",
"expo-splash-screen": "~0.26.4",
"expo-status-bar": "~1.11.1",
"expo-store-review": "~6.8.3",
"expo-system-ui": "~2.9.3",
"expo-updates": "~0.24.12",
"firebase": "^9.17.1",
Expand All @@ -52,6 +54,7 @@
"react-moment": "^1.1.3",
"react-native": "0.73.6",
"react-native-animated-pagination-dots": "^0.1.73",
"react-native-draggable-flatlist": "^4.0.1",
"react-native-elements": "^3.4.2",
"react-native-gesture-handler": "~2.14.0",
"react-native-get-random-values": "~1.11.0",
Expand All @@ -73,9 +76,7 @@
"react-redux": "^8.0.2",
"redux-persist": "^6.0.0",
"semver": "^7.6.0",
"typescript": "^5.4.3",
"expo-store-review": "~6.8.3",
"expo-linking": "~6.2.2"
"typescript": "^5.4.3"
},
"devDependencies": {
"@babel/core": "^7.19.3",
Expand Down
12 changes: 12 additions & 0 deletions redux/GamesSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,17 @@ const gamesSlice = createSlice({
},
gameDelete(state, action: PayloadAction<string>) {
gamesAdapter.removeOne(state, action.payload);
},
reorderPlayers(state, action: PayloadAction<{ gameId: string, playerIds: string[]; }>) {
const game = state.entities[action.payload.gameId];
if (!game) { return; }

gamesAdapter.updateOne(state, {
id: action.payload.gameId,
changes: {
playerIds: action.payload.playerIds,
}
});
}
}
});
Expand Down Expand Up @@ -179,6 +190,7 @@ export const {
roundPrevious,
gameSave,
gameDelete,
reorderPlayers,
} = gamesSlice.actions;

export default gamesSlice.reducer;
Expand Down
16 changes: 16 additions & 0 deletions src/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ import ListScreen from "../src/screens/ListScreen";
import OnboardingScreen from '../src/screens/OnboardingScreen';
import SettingsScreen from "../src/screens/SettingsScreen";

import EditPlayerHeader from './components/Headers/EditPlayerHeader';
import ShareHeader from './components/Headers/ShareHeader';
import { getOnboardingSemVer } from './components/Onboarding/Onboarding';
import logger from './Logger';
import EditPlayerScreen from './screens/EditPlayerScreen';
import ShareScreen from './screens/ShareScreen';

export type OnboardingScreenParamList = {
Expand All @@ -35,6 +37,10 @@ export type RootStackParamList = {
Share: undefined;
Onboarding: OnboardingScreenParamList;
Tutorial: OnboardingScreenParamList;
EditPlayer: {
index: number | undefined;
playerId: string | undefined;
};
};

const Stack = createNativeStackNavigator<RootStackParamList>();
Expand Down Expand Up @@ -116,6 +122,16 @@ export const Navigation = () => {
},
}}
/>
<Stack.Screen name="EditPlayer" component={EditPlayerScreen}
initialParams={{ index: 0, playerId: '' }}
options={({ route }) => ({
orientation: 'portrait',
title: "Edit Player",
header: ({ navigation }) => {
return <EditPlayerHeader navigation={navigation} route={route} />;
},
})}
/>
<Stack.Screen name="Tutorial" component={OnboardingScreen}
initialParams={{ onboarding: false }}
options={{
Expand Down
12 changes: 4 additions & 8 deletions src/components/Boards/FlexboxBoard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,18 @@ interface FlexboxBoardProps {
}

const FlexboxBoard: React.FC<FlexboxBoardProps> = () => {
const currentGameId = useAppSelector(state => state.settings.currentGameId);
if (typeof currentGameId == 'undefined') return null;
const fullscreen = useAppSelector(state => state.settings.home_fullscreen);
const playerIds = useAppSelector(state => selectCurrentGame(state)?.playerIds);

if (playerIds == null || playerIds.length == 0) return null;

const palette = ["01497c", "c25858", "f5c800", "275436", "dc902c", "62516a", "755647", "925561"];
const [rows, setRows] = useState<number>(0);
const [cols, setCols] = useState<number>(0);
const fullscreen = useAppSelector(state => state.settings.home_fullscreen);
const currentGame = useAppSelector(selectCurrentGame);

const [width, setWidth] = useState<number | null>(null);
const [height, setHeight] = useState<number | null>(null);

if (currentGame == undefined) return null;

const playerIds = currentGame.playerIds;

const playerCount = playerIds.length;

const desiredAspectRatio = 0.8;
Expand Down
5 changes: 1 addition & 4 deletions src/components/Boards/FlexboxTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { DimensionValue, StyleSheet } from 'react-native';
import Animated, { Easing, FadeIn } from 'react-native-reanimated';

import { useAppSelector } from '../../../redux/hooks';
import { selectCurrentGame, selectInteractionType } from '../../../redux/selectors';
import { selectInteractionType } from '../../../redux/selectors';
import { interactionComponents } from '../Interactions/InteractionComponents';
import { InteractionType } from '../Interactions/InteractionType';
import AdditionTile from '../PlayerTiles/AdditionTile/AdditionTile';
Expand Down Expand Up @@ -34,9 +34,6 @@ const FlexboxTile: React.FunctionComponent<Props> = ({
if (!(width > 0 && height > 0)) return null;
if (Number.isNaN(width) || Number.isNaN(height)) return null;

const currentGame = useAppSelector(selectCurrentGame);
if (typeof currentGame == 'undefined') return null;

const widthPerc: DimensionValue = `${(100 / cols)}%`;
const heightPerc: DimensionValue = `${(100 / rows)}%`;

Expand Down
4 changes: 2 additions & 2 deletions src/components/Buttons/NewGameButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Icon } from 'react-native-elements';

import { asyncCreateGame, selectAllGames } from '../../../redux/GamesSlice';
import { useAppSelector, useAppDispatch } from '../../../redux/hooks';
import { systemBlue } from '../../constants';
import { MAX_PLAYERS, systemBlue } from '../../constants';

interface Props {
navigation: NativeStackNavigationProp<ParamListBase, string, undefined>;
Expand All @@ -18,7 +18,7 @@ const NewGameButton: React.FunctionComponent<Props> = ({ navigation }) => {

const gameList = useAppSelector(selectAllGames);

const playerNumberOptions = [...Array.from(Array(12).keys(), n => n + 1)];
const playerNumberOptions = [...Array.from(Array(MAX_PLAYERS).keys(), n => n + 1)];

const menuActions: MenuAction[] = playerNumberOptions.map((number) => {
return {
Expand Down
33 changes: 21 additions & 12 deletions src/components/EditGame.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,27 @@ const EditGame = ({ }) => {

const [localTitle, setLocalTitle] = useState(currentGame.title);

const setGameTitleHandler = (title: string) => {
const onEndEditingHandler = (e: NativeSyntheticEvent<TextInputEndEditingEventData>) => {
const text = e.nativeEvent.text;

if (text == "") {
setLocalTitle(UNTITLED);
saveGameTitle(UNTITLED);
} else {
saveGameTitle(text);
}
};

const onChangeTextHandler = (text: string) => {
if (text == "") {
saveGameTitle(UNTITLED);
} else {
saveGameTitle(text);
}
setLocalTitle(text);
};

const saveGameTitle = (title: string) => {
setLocalTitle(title);

dispatch(updateGame({
Expand All @@ -28,16 +48,6 @@ const EditGame = ({ }) => {
}));
};

const onEndEditingHandler = (e: NativeSyntheticEvent<TextInputEndEditingEventData>) => {
if (e.nativeEvent.text == "") {
setGameTitleHandler(UNTITLED);
}
};

const onChangeTextHandler = (text: string) => {
setGameTitleHandler(text);
};

return (
<>
<View style={styles.inputContainer}>
Expand All @@ -49,7 +59,6 @@ const EditGame = ({ }) => {
onBlur={onEndEditingHandler}
placeholder={UNTITLED}
renderErrorMessage={false}
selectTextOnFocus={true}
style={styles.input}
inputContainerStyle={{ borderBottomWidth: 0 }}
/>
Expand Down
49 changes: 49 additions & 0 deletions src/components/Headers/EditPlayerHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React from 'react';

import { getAnalytics } from '@react-native-firebase/analytics';
import { ParamListBase, RouteProp } from '@react-navigation/native';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { StyleSheet, Text } from 'react-native';

import { systemBlue } from '../../constants';
import HeaderButton from '../Buttons/HeaderButton';

import CustomHeader from './CustomHeader';

type RouteParams = {
EditPlayer: {
index: number | undefined;
playerId: string | undefined;
};
};

interface EditPlayerScreenProps {
navigation: NativeStackNavigationProp<ParamListBase, string, undefined>;
route: RouteProp<RouteParams, 'EditPlayer'>;
}

const EditPlayerHeader: React.FunctionComponent<EditPlayerScreenProps> = ({ navigation }) => {
return (
<CustomHeader navigation={navigation}
headerLeft={
<HeaderButton accessibilityLabel='EditPlayerBack' onPress={async () => {
navigation.goBack();
await getAnalytics().logEvent('edit_player_back');
}}>
<Text style={{ color: systemBlue, fontSize: 20 }}>Back</Text>
</HeaderButton>
}
headerCenter={<Text style={styles.title}>Edit Player</Text>}
/>
);
};

const styles = StyleSheet.create({
title: {
color: 'white',
fontSize: 20,
fontVariant: ['tabular-nums'],
},
});

export default EditPlayerHeader;
7 changes: 3 additions & 4 deletions src/components/Interactions/Swipe/Swipe.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,9 @@ const SwipeVertical: React.FC<HalfTapProps> = ({
//#region Selector setup

const currentGameId = useAppSelector(state => state.settings.currentGameId);
const currentGame = useAppSelector(selectCurrentGame);
if (typeof currentGame == 'undefined') return null;
const roundCurrent = useAppSelector(state => selectCurrentGame(state)?.roundCurrent) || 0;
const currentGameLocked = useAppSelector(state => selectCurrentGame(state)?.locked);

const roundCurrent = currentGame.roundCurrent;
const dispatch = useAppDispatch();

const addendOne = useAppSelector(state => state.settings.addendOne);
Expand Down Expand Up @@ -230,7 +229,7 @@ const SwipeVertical: React.FC<HalfTapProps> = ({
</Animated.View>

<PanGestureHandler
enabled={!currentGame.locked}
enabled={!currentGameLocked}
minDist={0}
onGestureEvent={onGestureEvent}
onHandlerStateChange={onHandlerStateChange}
Expand Down
Loading

0 comments on commit e303fa2

Please sign in to comment.