// React import { useState, useEffect, useMemo, Fragment } from 'react'; import { View, Text, Image, Alert, StyleSheet, TouchableOpacity } from 'react-native'; // Expo import { useRouter } from 'expo-router'; // Components import { CustomMap } from '../components/map'; import { Drawer } from '../components/drawer'; // Contexts import { useTeamConnexion } from '../context/teamConnexionContext'; import { useTeamContext } from '../context/teamContext'; // Hooks import { useGame } from '../hook/useGame'; import { useTimeDifference } from '../hook/useTimeDifference'; // Util import { GameState } from '../util/gameState'; import { TimerMMSS } from '../components/timer'; import { secondsToMMSS } from '../util/functions'; import { Colors } from '../util/colors'; const Interface = () => { const router = useRouter(); const {teamInfos, messages, nextZoneDate, isShrinking, startLocationTracking, stopLocationTracking, gameState} = useTeamContext(); const {name, ready, captured, locationSendDeadline, outOfZone, outOfZoneDeadline, hasHandicap, enemyHasHandicap} = teamInfos; const {loggedIn, logout} = useTeamConnexion(); const {sendCurrentPosition} = useGame(); const [timeLeftSendLocation] = useTimeDifference(locationSendDeadline, 1000); const [timeLeftNextZone] = useTimeDifference(nextZoneDate, 1000); const [timeLeftOutOfZone] = useTimeDifference(outOfZoneDeadline, 1000); const [bottomContainerHeight, setBottomContainerHeight] = useState(0); const statusMessage = useMemo(() => { switch (gameState) { case GameState.SETUP: return messages?.waiting || "Préparation de la partie"; case GameState.PLACEMENT: return "Phase de placement"; case GameState.PLAYING: if (captured) return messages?.captured || "Vous avez été éliminé..."; if (!outOfZone) return "La partie est en cours"; if (!hasHandicap) return `Veuillez retourner dans la zone\nHandicap dans ${secondsToMMSS(-timeLeftOutOfZone)}`; else return `Veuillez retourner dans la zone\nVotre position est révélée en continue`; case GameState.FINISHED: return `Vous avez ${captured ? (messages?.loser || "perdu...") : (messages?.winner || "gagné !")}`; default: return "Inconnue"; } }, [gameState, messages, outOfZone, hasHandicap, timeLeftOutOfZone, captured]); // Router useEffect(() => { if (!loggedIn) { router.replace("/"); } }, [router, loggedIn]); // Activating geolocation tracking useEffect(() => { if (loggedIn) { startLocationTracking(); } else { stopLocationTracking(); } }, [startLocationTracking, stopLocationTracking, loggedIn]); return ( Alert.alert("Settings")}> {(name ?? "Indisponible")} {statusMessage} { gameState == GameState.PLACEMENT && {ready ? "Placé" : "Non placé"} } { gameState == GameState.PLAYING && !captured && } { enemyHasHandicap && Position ennemie révélée en continue ! } setBottomContainerHeight(event.nativeEvent.layout.height)}> { gameState == GameState.PLAYING && !captured && !hasHandicap && } { gameState == GameState.PLAYING && !captured && } ); }; export default Interface; const styles = StyleSheet.create({ globalContainer: { backgroundColor: Colors.background, flex: 1, }, topContainer: { width: '100%', alignItems: 'center', padding: 15, }, topheadContainer: { width: "100%", flexDirection: "row", justifyContent: 'space-between' }, teamNameContainer: { width: '100%', alignItems: 'center', justifyContent: 'center' }, logContainer: { width: '100%', alignItems: 'center', justifyContent: 'center', marginTop: 15 }, gameState: { borderWidth: 2, borderRadius: 10, width: "100%", backgroundColor: 'white', padding: 10, }, infoContainer: { width: '100%', alignItems: 'center', justifyContent: 'center', flexDirection: 'row', marginTop: 15 }, readyIndicator: { width: "100%", maxWidth: 240, height: 61, alignItems: 'center', justifyContent: 'center', padding: 3, borderRadius: 10 }, bottomContainer: { flex: 1, }, updatePosition: { position: 'absolute', right: 30, bottom: 80, width: 60, height: 60, borderRadius: 30, backgroundColor: 'white', borderWidth: 4, borderColor: 'black', alignItems: 'center', justifyContent: 'center', }, });