Skip to content

Commit

Permalink
Merge pull request #344 from wyne/SCORE-75-long-press-add
Browse files Browse the repository at this point in the history
SCORE-75 Long Press Addend
  • Loading branch information
wyne authored Nov 17, 2023
2 parents f437465 + 6921979 commit a824200
Show file tree
Hide file tree
Showing 14 changed files with 319 additions and 81 deletions.
15 changes: 9 additions & 6 deletions App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Navigation } from './src/Navigation';
import { View } from 'react-native';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import analytics from '@react-native-firebase/analytics';
import { PointSelectModalContextProvider } from './src/contexts/PointSelectModalContext';

if (process.env.EXPO_PUBLIC_FIREBASE_ANALYTICS == "false") {
analytics().setAnalyticsCollectionEnabled(false);
Expand All @@ -16,12 +17,14 @@ export default function App() {
return (
<View style={{ flex: 1, backgroundColor: '#fff' }}>
<GestureHandlerRootView style={{ flex: 1 }}>
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<StatusBar />
<Navigation />
</PersistGate>
</Provider>
<PointSelectModalContextProvider>
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<StatusBar />
<Navigation />
</PersistGate>
</Provider>
</PointSelectModalContextProvider>
</GestureHandlerRootView>
</View>
);
Expand Down
10 changes: 10 additions & 0 deletions package-lock.json

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

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@
"react-redux": "^8.0.2",
"redux-persist": "^6.0.0",
"semver": "^7.5.4",
"typescript": "^5.1.6"
"typescript": "^5.1.6",
"@react-native-picker/picker": "2.4.10"
},
"devDependencies": {
"@babel/core": "^7.19.3",
Expand Down
12 changes: 12 additions & 0 deletions redux/SettingsSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import * as Application from 'expo-application';
export interface SettingsState {
home_fullscreen: boolean;
multiplier: number;
addendOne: number;
addendTwo: number;
currentGameId: string | undefined;
onboarded: string | undefined;
showPointParticles: boolean;
Expand All @@ -13,6 +15,8 @@ export interface SettingsState {
const initialState: SettingsState = {
home_fullscreen: false,
multiplier: 1,
addendOne: 1,
addendTwo: 10,
currentGameId: undefined,
onboarded: undefined,
showPointParticles: false,
Expand All @@ -34,6 +38,12 @@ const settingsSlice = createSlice({
setMultiplier(state, action: PayloadAction<number>) {
state.multiplier = action.payload;
},
setAddendOne(state, action: PayloadAction<number>) {
state.addendOne = action.payload;
},
setAddendTwo(state, action: PayloadAction<number>) {
state.addendTwo = action.payload;
},
setOnboardedVersion(state) {
const appVersion = new SemVer(Application.nativeApplicationVersion || '0.0.0');
console.log(`Setting Onboarded Version: ${appVersion}`);
Expand All @@ -46,6 +56,8 @@ export const {
setCurrentGameId,
toggleHomeFullscreen,
setMultiplier,
setAddendOne,
setAddendTwo,
setOnboardedVersion,
toggleshowPointParticles,
} = settingsSlice.actions;
Expand Down
45 changes: 45 additions & 0 deletions src/components/BigButtons/BigButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from "react";
import { StyleSheet, Text, TouchableOpacity, View } from "react-native";
import { Icon } from "react-native-elements";

interface Props {
onPress: () => void;
icon: string;
text: string;
color: string;
}

const BigButton: React.FunctionComponent<Props> = ({ icon, text, color, onPress }) => {
return (
<TouchableOpacity activeOpacity={.5} onPress={onPress}>
<View style={[styles.bigButton]}>
<Icon name={icon}
type="ionicon" size={30}
color={color}
/>
<Text style={{
color: color,
fontSize: 15,
paddingTop: 5,
textAlign: 'center',
}}>
{text}
</Text>
</View>
</TouchableOpacity>
);
};

export default BigButton;

const styles = StyleSheet.create({
bigButton: {
width: 100,
margin: 5,
padding: 10,
paddingHorizontal: 20,
backgroundColor: 'rgba(0,0,0,.2)',
borderRadius: 10,
alignItems: 'center'
},
});
4 changes: 2 additions & 2 deletions src/components/Buttons/AppInfoButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ const AppInfoButton: React.FunctionComponent<Props> = ({ navigation }) => {
navigation.navigate('AppInfo');
await analytics().logEvent('app_info');
}}>
<Icon name="info-circle"
type="font-awesome-5"
<Icon name="gear"
type="font-awesome"
size={20}
color={systemBlue} />
</HeaderButton >
Expand Down
43 changes: 16 additions & 27 deletions src/components/Buttons/MultiplierButton.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,30 @@
import React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import analytics from '@react-native-firebase/analytics';
import { Text, View, StyleSheet, TouchableHighlight } from 'react-native';

import { useAppSelector, useAppDispatch } from '../../../redux/hooks';
import { useAppSelector } from '../../../redux/hooks';
import { systemBlue } from '../../constants';
import { setMultiplier } from '../../../redux/SettingsSlice';
import { MenuView, MenuAction } from '@react-native-menu/menu';
import { usePointSelectModalContext } from '../../contexts/PointSelectModalContext';

const MultiplierButton: React.FunctionComponent = ({ }) => {
const dispatch = useAppDispatch();
const multiplier = useAppSelector(state => state.settings.multiplier);
const currentGameId = useAppSelector(state => state.settings.currentGameId);
const addendOne = useAppSelector(state => state.settings.addendOne);
const addendTwo = useAppSelector(state => state.settings.addendTwo);

const addends = [1, 5, 10, 20, 50];
const pointSelectorModalRef = usePointSelectModalContext();

const actions: MenuAction[] = addends.map(addend => {
return {
id: addend.toString(),
title: `${addend} point${addend === 1 ? '' : 's'} per tap`,
state: multiplier === addend ? 'on' : 'off',
};
});
const handlePress = () => {
if (pointSelectorModalRef == null) {
return;
}

pointSelectorModalRef.current?.present();
};

return (
<MenuView
onPressAction={async ({ nativeEvent }) => {
dispatch(setMultiplier(parseInt(nativeEvent.event)));
await analytics().logEvent('multiplier_change', {
multiplier: multiplier,
game_id: currentGameId,
});
}}
actions={actions}>
<TouchableHighlight onPress={handlePress}>
<View style={styles.button}>
<Text style={styles.buttonText}>{multiplier} pt</Text>
<Text style={styles.buttonText}>{addendOne}, {addendTwo}</Text>
</View>
</MenuView>
</TouchableHighlight>
);
};

Expand Down
32 changes: 25 additions & 7 deletions src/components/GameBottomSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { View, StyleSheet, Text } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { ParamListBase } from '@react-navigation/native';
import BottomSheet, { BottomSheetScrollView } from '@gorhom/bottom-sheet';
import BottomSheet, { BottomSheetBackdrop, BottomSheetBackdropProps, BottomSheetScrollView } from '@gorhom/bottom-sheet';

import { useAppDispatch, useAppSelector } from '../../redux/hooks';
import Rounds from '../components/Rounds';
Expand Down Expand Up @@ -101,23 +101,39 @@ const GameBottomSheet: React.FunctionComponent<Props> = ({ navigation, container
};
});

const renderBackdrop = useCallback(
(props: BottomSheetBackdropProps) => (
<BottomSheetBackdrop
{...props}
disappearsOnIndex={0}
appearsOnIndex={1}
pressBehavior={0}
/>
),
[]
);

return (
<BottomSheet
ref={bottomSheetRef}
index={0}
onChange={onSheetChange}
snapPoints={snapPoints}
backdropComponent={renderBackdrop}
backgroundStyle={{ backgroundColor: 'rgb(30,40,50)' }}
handleIndicatorStyle={{ backgroundColor: 'white' }}
animatedPosition={animatedPosition}
enablePanDownToClose={false}
>
<BottomSheetScrollView >
<SafeAreaView edges={['right', 'left']}>
<View style={styles.sheetHeaderContainer}>
<TouchableWithoutFeedback onPress={() => sheetTitlePress()}>
<Text style={[styles.sheetTitle]} numberOfLines={1}>
{currentGame.title}
</Text>
<View style={[styles.sheetTitleView]}>
<Text style={[styles.sheetTitle]} numberOfLines={1}>
{currentGame.title}
</Text>
</View>
</TouchableWithoutFeedback>
{currentGame.locked &&
<Text style={{ color: 'gray', fontSize: 20, paddingHorizontal: 10 }}
Expand Down Expand Up @@ -175,13 +191,15 @@ const styles = StyleSheet.create({
justifyContent: 'space-between',
paddingHorizontal: 10,
},
sheetTitle: {
sheetTitleView: {
flex: 1,
paddingHorizontal: 10,
paddingTop: 0,
},
sheetTitle: {
color: 'white',
fontSize: 20,
fontWeight: 'bold',
paddingHorizontal: 10,
paddingTop: 0,
},
editButton: {
color: systemBlue,
Expand Down
2 changes: 1 addition & 1 deletion src/components/Headers/AppInfoHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const AppInfoHeader: React.FunctionComponent<Props> = ({ navigation }: Props) =>
return (
<CustomHeader navigation={navigation}
headerLeft={<MenuButton navigation={navigation} />}
headerCenter={<Text style={styles.title}>Info</Text>}
headerCenter={<Text style={styles.title}>Settings</Text>}
/>
);
};
Expand Down
1 change: 0 additions & 1 deletion src/components/PlayerTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ const PlayerTile: React.FunctionComponent<Props> = ({
{
borderRadius: 20,
borderWidth: 3,
padding: 5,
backgroundColor: color,
width: widthPerc,
height: heightPerc
Expand Down
19 changes: 11 additions & 8 deletions src/components/PlayerTiles/AdditionTile/TouchSurface.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,46 +28,49 @@ export const TouchSurface: React.FunctionComponent<Props> = (

const [particles, setParticles] = useState<ScoreParticleProps[]>([]);

const multiplier = useAppSelector(state => state.settings.multiplier);
const addendOne = useAppSelector(state => state.settings.addendOne);
const addendTwo = useAppSelector(state => state.settings.addendTwo);

const currentGameId = useAppSelector(state => state.settings.currentGameId);
const currentGame = useAppSelector(state => selectGameById(state, currentGameId));
if (typeof currentGame == 'undefined') return null;

const roundCurrent = currentGame.roundCurrent;

const addParticle = () => {
const addParticle = (addend: number) => {
const key = Math.random().toString(36).substring(7);
const value = `${scoreType == 'increment' ? '+' : '-'}${multiplier}`;
const value = `${scoreType == 'increment' ? '+' : '-'}${addend}`;

setTimeout(() => {
setParticles((particles) => particles.filter((p) => p.key !== key));
}, 800);
setParticles((particles) => [...particles, { key, value }]);
};

const scoreChangeHandler = () => {
const scoreChangeHandler = (addend: number) => {
if (currentGame.locked) return;

if (showPointParticles) {
addParticle();
addParticle(addend);
}
Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
analytics().logEvent('score_change', {
player_index: playerIndex,
game_id: currentGameId,
multiplier: multiplier,
addend: addend,
round: roundCurrent,
type: scoreType,
});
dispatch(playerRoundScoreIncrement(playerId, roundCurrent, scoreType == 'increment' ? multiplier : -multiplier));
dispatch(playerRoundScoreIncrement(playerId, roundCurrent, scoreType == 'increment' ? addend : -addend));
};

return (
<TouchableHighlight
style={[styles.surface, scoreType == 'increment' ? styles.surfaceAdd : styles.surfaceSubtract]}
underlayColor={currentGame.locked ? 'transparent' : fontColor + '30'}
activeOpacity={1}
onPress={scoreChangeHandler}>
onPress={() => scoreChangeHandler(addendOne)}
onLongPress={() => scoreChangeHandler(addendTwo)}>
<View style={[StyleSheet.absoluteFill]}>
{particles.map((particle) => (
<ScoreParticle key={particle.key} id={particle.key} value={particle.value} />
Expand Down
Loading

0 comments on commit a824200

Please sign in to comment.