diff --git a/src/Navigation.tsx b/src/Navigation.tsx index 8f4c7d90..3bceb8de 100644 --- a/src/Navigation.tsx +++ b/src/Navigation.tsx @@ -107,6 +107,7 @@ export const Navigation = () => { headerBlurEffect: 'systemChromeMaterial', headerShadowVisible: false, headerBackButtonDisplayMode: 'minimal', + headerTitleAlign: 'center', }} listeners={{ focus: () => setShowGameSheetForActiveRoute(true), diff --git a/src/components/Headers/RoundHeaderTitle.tsx b/src/components/Headers/RoundHeaderTitle.tsx index 75fa6a8f..4d2f1eb2 100644 --- a/src/components/Headers/RoundHeaderTitle.tsx +++ b/src/components/Headers/RoundHeaderTitle.tsx @@ -1,12 +1,15 @@ import React from 'react'; +import { MenuAction, MenuView } from '@react-native-menu/menu'; +import { GlassView } from 'expo-glass-effect'; import * as Haptics from 'expo-haptics'; -import { StyleSheet, Text, TouchableOpacity, View } from 'react-native'; +import { Platform, Pressable, StyleSheet, Text, View } from 'react-native'; import { Icon } from 'react-native-elements/dist/icons/Icon'; -import { roundNext, roundPrevious, selectGameById } from '../../../redux/GamesSlice'; +import { roundNext, roundPrevious, selectGameById, updateGame } from '../../../redux/GamesSlice'; import { useAppDispatch, useAppSelector } from '../../../redux/hooks'; import { logEvent } from '../../Analytics'; +import { LIQUID_GLASS } from '../../platform'; import { useTheme } from '../../theme'; const RoundHeaderTitle: React.FunctionComponent = () => { @@ -54,30 +57,142 @@ const RoundHeaderTitle: React.FunctionComponent = () => { }; const isLocked = currentGame?.locked === true; + const previousDisabled = isLocked || isFirstRound; + const nextDisabled = isLocked || isLastRound && (currentGame?.locked ?? false); + const roundPickerEnabled = !isLocked && roundCount > 1; + const roundLabel = isLocked ? 'Final' : `Round ${currentRoundIndex + 1} of ${roundCount}`; + const roundPickerLabel = isLocked ? ( + + Final + + ) : ( + + + Round + + + {currentRoundIndex + 1} of {roundCount} + + + ); + const roundActions: MenuAction[] = Array.from({ length: roundCount }, (_, round) => ({ + id: round.toString(), + title: Platform.OS === 'android' && round === currentRoundIndex + ? `✓ Round ${round + 1}` + : `Round ${round + 1}`, + state: round === currentRoundIndex ? 'on' : 'off', + })); + + const selectRound = (event: string) => { + const round = Number(event); + if (!Number.isInteger(round) || round < 0 || round >= roundCount || round === currentRoundIndex) return; - return ( - - selectRound(nativeEvent.event)} + shouldOpenOnLongPress={false} + testID="round-picker-menu" + > + + {roundPickerLabel} + + + + + + ) : ( + + {roundPickerLabel} + + ); + + const controls = ( + <> + [ + styles.chevron, + { opacity: previousDisabled ? 0 : 1 }, + Platform.OS === 'ios' && pressed && styles.pressed, + ]} testID="previous-round-button" > - - - - {isLocked ? 'Final' : `Round ${currentRoundIndex + 1}${isLastRound ? '' : `/${roundCount}`}`} - - + + {roundPicker} + [ + styles.chevron, + { opacity: nextDisabled ? 0 : 1 }, + Platform.OS === 'ios' && pressed && styles.pressed, + ]} testID="next-round-button" > - - - + + + ); + + if (LIQUID_GLASS) { + return ( + + {controls} + + ); + } + + const backgroundColor = Platform.OS === 'android' + ? theme.backgroundSecondary + : theme.headerText === '#FFFFFF' + ? 'rgba(255,255,255,0.14)' + : 'rgba(118,118,128,0.12)'; + + return {controls}; }; const styles = StyleSheet.create({ @@ -85,18 +200,55 @@ const styles = StyleSheet.create({ flexDirection: 'row', alignItems: 'center', justifyContent: 'center', + borderRadius: Platform.OS === 'android' ? 24 : 22, + height: Platform.OS === 'android' ? 48 : 44, + width: Platform.OS === 'android' ? 192 : undefined, + }, + fallbackContainer: { + overflow: 'hidden', + }, + finalLabel: { + fontSize: Platform.OS === 'android' ? 17 : 16, + fontWeight: '600', + lineHeight: Platform.OS === 'android' ? 21 : 20, + fontVariant: ['tabular-nums'], + textAlign: 'center', + }, + roundDescriptor: { + fontSize: Platform.OS === 'android' ? 11 : 10, + fontWeight: '600', + lineHeight: Platform.OS === 'android' ? 13 : 12, + textAlign: 'center', + }, + roundLabel: { + alignItems: 'center', + justifyContent: 'center', }, - title: { - fontSize: 20, + roundValue: { + fontSize: Platform.OS === 'android' ? 15 : 14, + fontWeight: '600', + lineHeight: Platform.OS === 'android' ? 18 : 17, fontVariant: ['tabular-nums'], textAlign: 'center', - minWidth: 110, + }, + roundPicker: { + alignItems: 'center', + justifyContent: 'center', + position: 'relative', + width: Platform.OS === 'android' ? 104 : 96, + }, + menuIndicator: { + position: 'absolute', + right: 5, }, chevron: { - width: 32, + width: Platform.OS === 'android' ? 44 : 40, + height: Platform.OS === 'android' ? 48 : 44, alignItems: 'center', justifyContent: 'center', - padding: 8, + }, + pressed: { + opacity: 0.45, }, });