diff --git a/client/app/(tabs)/index.tsx b/client/app/(tabs)/index.tsx index d8fd3af..b0637d6 100644 --- a/client/app/(tabs)/index.tsx +++ b/client/app/(tabs)/index.tsx @@ -1,3 +1,58 @@ -import MapScreen from './map' +import { StyleSheet } from 'react-native' +import "maplibre-gl/dist/maplibre-gl.css" +import { useBackgroundPermissions } from 'expo-location' +import Map from '@/components/Map' +import { FAB, Surface, Text } from 'react-native-paper' +import { useGame } from '@/hooks/useGame' +import { FontAwesome6 } from '@expo/vector-icons' +import FreeChaseBanner from '@/components/FreeChaseBanner' -export default MapScreen +export default function MapScreen() { + const [backgroundStatus, requestBackgroundPermission] = useBackgroundPermissions() + if (!backgroundStatus?.granted && backgroundStatus?.canAskAgain) + requestBackgroundPermission() + + const game = useGame() + + return ( + + {backgroundStatus?.granted ? : La géolocalisation est requise pour utiliser la carte.} + 0} + icon={(props) => } + color='black' + label={`${game.money}`} /> + 0} + size='small' + color='black' + icon={game.currentRunner ? 'run-fast' : () => } + label={game.currentRunner ? "Coureuse" : "Poursuiveuse"} /> + + + ) +} + +const styles = StyleSheet.create({ + page: { + flex: 1, + }, + map: { + flex: 1, + alignSelf: 'stretch', + }, + moneyBadge: { + position: 'absolute', + top: 40, + right: 20, + backgroundColor: 'orange', + }, + statusBadge: { + position: 'absolute', + top: 40, + left: 20, + backgroundColor: 'pink', + }, +}) diff --git a/client/app/(tabs)/map.tsx b/client/app/(tabs)/map.tsx deleted file mode 100644 index 7960bc4..0000000 --- a/client/app/(tabs)/map.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { StyleSheet } from 'react-native' -import "maplibre-gl/dist/maplibre-gl.css" -import { useBackgroundPermissions } from 'expo-location' -import Map from '@/components/Map' -import { FAB, Surface, Text } from 'react-native-paper' -import { useGame } from '@/hooks/useGame' -import { FontAwesome6 } from '@expo/vector-icons' - -export default function MapScreen() { - const [backgroundStatus, requestBackgroundPermission] = useBackgroundPermissions() - if (!backgroundStatus?.granted && backgroundStatus?.canAskAgain) - requestBackgroundPermission() - - const game = useGame() - - return ( - - {backgroundStatus?.granted ? : La géolocalisation est requise pour utiliser la carte.} - 0} - icon={(props) => } - color='black' - label={`${game.money}`} /> - 0} - size='small' - color='black' - icon={game.currentRunner ? 'run-fast' : () => } - label={game.currentRunner ? "Coureuse" : "Poursuiveuse"} /> - - ) -} - -const styles = StyleSheet.create({ - page: { - flex: 1, - justifyContent: 'center', - alignItems: 'center' - }, - map: { - flex: 1, - alignSelf: 'stretch', - }, - moneyBadge: { - position: 'absolute', - top: 40, - right: 20, - backgroundColor: 'orange', - }, - statusBadge: { - position: 'absolute', - top: 40, - left: 20, - backgroundColor: 'pink', - }, -}) diff --git a/client/components/FreeChaseBanner.tsx b/client/components/FreeChaseBanner.tsx new file mode 100644 index 0000000..a0ff488 --- /dev/null +++ b/client/components/FreeChaseBanner.tsx @@ -0,0 +1,49 @@ +import { useGame } from "@/hooks/useGame" +import { FontAwesome6 } from "@expo/vector-icons" +import { useEffect, useMemo, useState } from "react" +import { View } from "react-native" +import { Banner, MD3Colors, ProgressBar, Text } from "react-native-paper" + +export default function FreeChaseBanner() { + const game = useGame() + const chaseFreeTime = game.chaseFreeTime + const stunChase = game.gameStarted && !game.currentRunner && chaseFreeTime !== null + const chaseFreeDate = useMemo(() => new Date(chaseFreeTime || 0), [chaseFreeTime]) + const chaseFreePretty = chaseFreeDate.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' }) + const [remainingTime, setRemainingTime] = useState(0) + const prettyRemainingTime = useMemo(() => `${Math.floor(remainingTime / 60).toString().padStart(2, '0')}:${Math.floor(remainingTime % 60).toString().padStart(2, '0')}`, [remainingTime]) + const iconName = useMemo(() => { + switch (Math.abs(remainingTime % 4)) { + case 0: return 'hourglass-empty' + case 1: return 'hourglass-end' + case 2: return 'hourglass-half' + case 3: return 'hourglass-start' + } + }, [remainingTime]) + + useEffect(() => { + if (!stunChase) + return + const interval = setInterval(() => setRemainingTime(Math.floor((chaseFreeDate.getTime() - new Date().getTime()) / 1000)), 1000) + return () => clearInterval(interval) + }, [stunChase, chaseFreeDate]) + + return ( + + + } + style={{ backgroundColor: MD3Colors.secondary40 }}> + + Vous pourrez vous mettre en chasse à {chaseFreePretty}. + Temps restant : {prettyRemainingTime} + + + + ) +}