Skip to content

Commit

Permalink
Lock
Browse files Browse the repository at this point in the history
  • Loading branch information
wyne committed Nov 16, 2023
1 parent 49198a3 commit 1c7c2de
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 22 deletions.
1 change: 1 addition & 0 deletions redux/GamesSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface GameState {
roundCurrent: number;
roundTotal: number;
playerIds: string[];
locked?: boolean;
}

const gamesAdapter = createEntityAdapter({
Expand Down
67 changes: 54 additions & 13 deletions src/components/GameBottomSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import { NativeStackNavigationProp } from '@react-navigation/native-stack';
import { ParamListBase } from '@react-navigation/native';
import BottomSheet, { BottomSheetScrollView } from '@gorhom/bottom-sheet';

import { useAppSelector } from '../../redux/hooks';
import { useAppDispatch, useAppSelector } from '../../redux/hooks';
import Rounds from '../components/Rounds';
import { selectGameById } from '../../redux/GamesSlice';
import { selectGameById, updateGame } from '../../redux/GamesSlice';
import { systemBlue } from '../constants';
import Animated, { Extrapolate, interpolate, useAnimatedStyle, useSharedValue } from 'react-native-reanimated';
import { TouchableOpacity } from 'react-native-gesture-handler';
import { TouchableOpacity, TouchableWithoutFeedback } from 'react-native';
import { Icon } from 'react-native-elements';

/**
Expand Down Expand Up @@ -38,6 +38,20 @@ const GameBottomSheet: React.FunctionComponent<Props> = ({ navigation, container
// variables
const snapPoints = useMemo(() => [bottomSheetHeight, '60%', '100%'], []);

const dispatch = useAppDispatch();

/**
* Lock the game
*/
const setLock = () => dispatch(
updateGame({
id: currentGame.id,
changes: {
locked: !currentGame.locked,
}
})
);

// State variable for the current snap point index
const [, setSnapPointIndex] = useState(0);

Expand Down Expand Up @@ -100,12 +114,23 @@ const GameBottomSheet: React.FunctionComponent<Props> = ({ navigation, container
<BottomSheetScrollView >
<SafeAreaView edges={['right', 'left']}>
<View style={styles.sheetHeaderContainer}>
<Text style={[styles.sheetHeader]} numberOfLines={1} onPress={() => sheetTitlePress()}>
{currentGame.title}
</Text>
<Text style={styles.sheetHeaderButton} onPress={() => navigation.navigate('Settings')}>
Edit
</Text>
<TouchableWithoutFeedback onPress={() => sheetTitlePress()}>
<Text style={[styles.sheetTitle]} numberOfLines={1}>
{currentGame.title}
</Text>
</TouchableWithoutFeedback>
{currentGame.locked &&
<Text style={{ color: 'gray', fontSize: 20, paddingHorizontal: 10 }}
onPress={() => { bottomSheetRef.current?.snapToIndex(snapPoints.length - 1); }}
>
Locked
</Text>
}
{!currentGame.locked &&
<Text style={styles.editButton} onPress={() => navigation.navigate('Settings')}>
Edit
</Text>
}
</View>

<Animated.View style={[styles.sheetContent, animatedSheetStyle]}>
Expand All @@ -115,12 +140,27 @@ const GameBottomSheet: React.FunctionComponent<Props> = ({ navigation, container
</Text>

<View style={{ flexDirection: 'row', justifyContent: 'space-around', paddingVertical: 10 }}>
<TouchableOpacity onPress={() => navigation.navigate('Share')}>
<TouchableOpacity activeOpacity={.5} onPress={() => navigation.navigate('Share')}>
<View style={[styles.shareButton]}>
<Icon name="share-outline" type="ionicon" size={30} color={systemBlue} />
<Text style={{ color: systemBlue, fontSize: 15, paddingTop: 5 }}>Share</Text>
</View>
</TouchableOpacity>

<TouchableOpacity activeOpacity={.5} onPress={setLock}>
<View style={[styles.shareButton]}>
<Icon name={currentGame.locked ? "lock-closed-outline" : "lock-open-outline"}
type="ionicon" size={30}
color={currentGame.locked ? 'red' : 'green'}
/>
<Text style={{
color: currentGame.locked ? 'red' : 'green',
fontSize: 15, paddingTop: 5
}}>
{currentGame.locked ? "Unlock" : "Lock"}
</Text>
</View>
</TouchableOpacity>
</View>
</Animated.View>
</SafeAreaView>
Expand All @@ -135,15 +175,15 @@ const styles = StyleSheet.create({
justifyContent: 'space-between',
paddingHorizontal: 10,
},
sheetHeader: {
color: 'white',
sheetTitle: {
flex: 1,
color: 'white',
fontSize: 20,
fontWeight: 'bold',
paddingHorizontal: 10,
paddingTop: 0,
},
sheetHeaderButton: {
editButton: {
color: systemBlue,
fontSize: 20,
paddingHorizontal: 10,
Expand All @@ -153,6 +193,7 @@ const styles = StyleSheet.create({
paddingHorizontal: 20,
},
shareButton: {
width: 100,
margin: 5,
padding: 10,
paddingHorizontal: 20,
Expand Down
5 changes: 4 additions & 1 deletion src/components/GameListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,10 @@ const GameListItem: React.FunctionComponent<Props> = ({ navigation, game, index
actions={actions}>
<ListItem key={game.id} bottomDivider onPress={chooseGameHandler}>
<ListItem.Content>
<ListItem.Title>{game.title}</ListItem.Title>
<ListItem.Title style={{ alignItems: 'center' }}>
{game.title}
{game.locked && <Icon name="lock-closed-outline" type="ionicon" size={14} color='green' style={{ paddingHorizontal: 4 }} />}
</ListItem.Title>
<ListItem.Subtitle style={styles.gameSubtitle}>
<Text><Moment element={Text} fromNow>{game.dateCreated}</Moment></Text>
</ListItem.Subtitle>
Expand Down
25 changes: 18 additions & 7 deletions src/components/Headers/GameHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,35 +17,38 @@ import CustomHeader from './CustomHeader';

interface PrevRoundButtonProps {
prevRoundHandler: () => void;
roundCurrent: number;
visible: boolean;
}

const PrevRoundButton: React.FunctionComponent<PrevRoundButtonProps> = ({ prevRoundHandler, roundCurrent }) => {
const PrevRoundButton: React.FunctionComponent<PrevRoundButtonProps> = ({ prevRoundHandler, visible }) => {
return (
<TouchableOpacity style={[styles.headerButton]}
onPress={prevRoundHandler}>
<Icon name="chevron-left"
type="font-awesome-5"
size={20}
color={systemBlue}
style={{ opacity: roundCurrent == 0 ? 0 : 1 }}
style={{ opacity: visible ? 0 : 1 }}
/>
</TouchableOpacity>
);
};

interface NextRoundButtonProps {
nextRoundHandler: () => void;
visible: boolean;
}

const NextRoundButton: React.FunctionComponent<NextRoundButtonProps> = ({ nextRoundHandler }) => {
const NextRoundButton: React.FunctionComponent<NextRoundButtonProps> = ({ nextRoundHandler, visible }) => {
return (
<TouchableOpacity style={[styles.headerButton]}
onPress={nextRoundHandler}>
<Icon name="chevron-right"
type="font-awesome-5"
size={20}
color={systemBlue} />
color={systemBlue}
style={{ opacity: visible ? 0 : 1 }}
/>
</TouchableOpacity>
);
};
Expand All @@ -64,6 +67,7 @@ const GameHeader: React.FunctionComponent<Props> = ({ navigation }) => {
);
const currentGame = useAppSelector(state => selectGameById(state, currentGameId));
const roundCurrent = useAppSelector(state => selectGameById(state, currentGameId)?.roundCurrent || 0);
const lastRoundIndex = useAppSelector(state => selectGameById(state, currentGameId)?.roundTotal || 0);

if (currentGame == null) {
return <CustomHeader navigation={navigation}
Expand All @@ -72,7 +76,12 @@ const GameHeader: React.FunctionComponent<Props> = ({ navigation }) => {
/>;
}

const isFirstRound = roundCurrent == 0;
const isLastRound = roundCurrent >= lastRoundIndex;

const nextRoundHandler = async () => {
if (isLastRound && currentGame.locked) return;

dispatch(roundNext(currentGame.id));
await analytics().logEvent('round_change', {
game_id: currentGameId,
Expand All @@ -81,6 +90,8 @@ const GameHeader: React.FunctionComponent<Props> = ({ navigation }) => {
};

const prevRoundHandler = async () => {
if (isFirstRound) return;

dispatch(roundPrevious(currentGame.id));
await analytics().logEvent('round_change', {
game_id: currentGameId,
Expand All @@ -95,9 +106,9 @@ const GameHeader: React.FunctionComponent<Props> = ({ navigation }) => {
<FullscreenButton />
</>}
headerCenter={<>
<PrevRoundButton prevRoundHandler={prevRoundHandler} roundCurrent={roundCurrent} />
<PrevRoundButton prevRoundHandler={prevRoundHandler} visible={isFirstRound} />
<Text style={styles.title}>Round {roundCurrent + 1}</Text>
<NextRoundButton nextRoundHandler={nextRoundHandler} />
<NextRoundButton nextRoundHandler={nextRoundHandler} visible={isLastRound && currentGame.locked} />
</>}
headerRight={<MultiplierButton />}
/>
Expand Down
4 changes: 3 additions & 1 deletion src/components/PlayerTiles/AdditionTile/TouchSurface.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ export const TouchSurface: React.FunctionComponent<Props> = (
};

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

if (showPointParticles) {
addParticle();
}
Expand All @@ -63,7 +65,7 @@ export const TouchSurface: React.FunctionComponent<Props> = (
return (
<TouchableHighlight
style={[styles.surface, scoreType == 'increment' ? styles.surfaceAdd : styles.surfaceSubtract]}
underlayColor={fontColor + '30'}
underlayColor={currentGame.locked ? 'transparent' : fontColor + '30'}
activeOpacity={1}
onPress={scoreChangeHandler}>
<View style={[StyleSheet.absoluteFill]}>
Expand Down

0 comments on commit 1c7c2de

Please sign in to comment.