// React import { useState, useEffect, useMemo, Fragment } from 'react'; import { ScrollView, View, Text, Image, StyleSheet, TouchableOpacity, TouchableHighlight, Alert } from 'react-native'; import Collapsible from 'react-native-collapsible'; import LinearGradient from 'react-native-linear-gradient'; // Components import { CustomImage } from './image'; import { CustomTextInput } from './input'; import { Stat } from './stat'; // Contexts import { useTeamContext } from '../context/teamContext'; import { useSocket } from '../context/socketContext'; // Hooks import { useTimeDifference } from '../hook/useTimeDifference'; import { useGame } from '../hook/useGame'; // Util import { GameState } from '../util/gameState'; import { Colors } from '../util/colors'; import { secondsToHHMMSS } from '../util/functions'; export const Drawer = ({ height }) => { const [collapsibleState, setCollapsibleState] = useState(true); const [enemyCaptureCode, setEnemyCaptureCode] = useState(""); const {SERVER_URL} = useSocket(); const {gameState, startDate} = useTeamContext(); const {capture, enemyName, captureCode, name, teamId, distance, finishDate, nCaptures, nSentLocation, hasHandicap} = useGame(); const [timeSinceStart] = useTimeDifference(startDate, 1000); const [enemyImageURI, setEnemyImageURI] = useState("../assets/images/missing_image.jpg"); const [captureStatus, setCaptureStatus] = useState(0); // 0 : no capture | 1 : waiting for response from server | 2 : capture failed | 3 : capture succesful const captureStatusColor = {0: "#777", 1: "#FFA500", 2: "#FF6B6B", 3: "#81C784"}; const avgSpeed = useMemo(() => { const hours = (finishDate ? (finishDate - startDate) : timeSinceStart*1000) / 1000 / 3600; if (hours <= 0 || distance <= 0) return 0; const km = distance / 1000; const speed = km / hours; return parseFloat(speed.toFixed(1)); }, [finishDate, startDate, timeSinceStart, distance]); // Capture state update useEffect(() => { if (captureStatus == 2 || captureStatus == 3) { const timeout = setTimeout(() => { setCaptureStatus(0); }, 3000); return () => clearTimeout(timeout); } }, [captureStatus]); // Refresh the image useEffect(() => { setEnemyImageURI(`${SERVER_URL}/photo/enemy?team=${teamId}&t=${new Date().getTime()}`); }, [SERVER_URL, enemyName, teamId]); const handleCapture = () => { if (captureStatus != 1) { setCaptureStatus(1); capture(enemyCaptureCode) .then((response) => { if (response.hasCaptured) { setCaptureStatus(3); } else { setCaptureStatus(2); } }) .catch(() => { Alert.alert("Échec", "La connexion au serveur a échoué."); setCaptureStatus(2); }); setEnemyCaptureCode(""); } }; return ( setCollapsibleState(!collapsibleState)} style={styles.collapsibleButton} underlayColor="#d9d9d9"> { gameState == GameState.PLAYING && Code de {(name ?? "Indisponible")} : {String(captureCode).padStart(4,"0")} } { gameState == GameState.PLAYING && !hasHandicap && {{"Cible (" + (enemyName ?? "Indisponible") + ")"}} {} } {Math.floor(distance / 100) / 10}km {secondsToHHMMSS((finishDate ? Math.floor((finishDate - startDate) / 1000) : timeSinceStart))} {avgSpeed}km/h {nCaptures} {nSentLocation} ); }; const styles = StyleSheet.create({ outerDrawerContainer: { position: 'absolute', bottom: 0, left: 0, right: 0, }, innerDrawerContainer: { width: "100%", backgroundColor: Colors.background, borderTopLeftRadius: 30, borderTopRightRadius: 30, overflow: 'hidden', }, collapsibleButton: { justifyContent: 'center', alignItems: 'center', width: "100%", height: 45 }, collapsibleWindow: { width: "100%", justifyContent: 'center', backgroundColor: Colors.background, }, collapsibleContent: { paddingHorizontal: 15, }, imageContainer: { width: "100%", alignItems: "center", justifyContent: "center", marginTop: 15 }, actionsContainer: { flexDirection: "row", width: "100%", alignItems: 'center', justifyContent: 'space-between', marginTop: 15 }, actionsLeftContainer: { flexGrow: 1, alignItems: 'center', justifyContent: 'center', marginRight: 15 }, actionsRightContainer: { width: 100, alignItems: 'center', justifyContent: 'center' }, button: { borderRadius: 12, width: '100%', height: 75, alignItems: 'center', justifyContent: 'center', backgroundColor: '#444' }, });