// React import { useState, useEffect, useMemo, useRef } from 'react'; import { View, Image, Alert, StyleSheet, TouchableOpacity } from 'react-native'; import MapView, { Marker, Circle, Polygon } from 'react-native-maps'; import LinearGradient from 'react-native-linear-gradient'; // Components import { DashedCircle, InvertedCircle, InvertedPolygon } from './layer'; // Contexts import { useTeamContext } from '../context/teamContext'; // Hooks import { useGame } from '../hook/useGame'; // Util import { GameState } from '../util/gameState'; import { ZoneTypes, InitialRegions } from '../util/constants'; export const CustomMap = () => { const {zoneType, zoneExtremities, location, gameState} = useTeamContext(); const {enemyLocation, startingArea, lastSentLocation, hasHandicap} = useGame(); const [centerMap, setCenterMap] = useState(true); const mapRef = useRef(null); // Center the map on user position useEffect(() => { if (centerMap && mapRef.current && location) { mapRef.current.animateToRegion({latitude: location[0], longitude: location[1], latitudeDelta: 0, longitudeDelta: 0.02}, 1000); } }, [centerMap, location]); // Map layers const latToLatitude = (pos) => ({latitude: pos.lat, longitude: pos.lng}); const startZone = useMemo(() => { if (gameState != GameState.PLACEMENT || !startingArea) return null; return ( ); }, [gameState, startingArea]); const gameZone = useMemo(() => { if (gameState !== GameState.PLAYING || !zoneExtremities) return null; const items = []; const nextZoneStrokeColor = "rgb(90, 90, 90)"; const zoneColor = "rgba(25, 83, 169, 0.4)"; const strokeWidth = 3; const lineDashPattern = [30, 10]; if (zoneType === ZoneTypes.circle) { if (zoneExtremities.begin) items.push( ); if (zoneExtremities.end) items.push( ); } else if (zoneType === ZoneTypes.polygon) { if (zoneExtremities.begin) items.push( latToLatitude(pos))} fillColor={zoneColor} /> ); if (zoneExtremities.end) items.push( latToLatitude(pos))} strokeColor={nextZoneStrokeColor} strokeWidth={strokeWidth} lineDashPattern={lineDashPattern} /> ); } return items.length ? items : null; }, [gameState, zoneType, zoneExtremities]); const currentPositionMarker = useMemo(() => { if (!location) return null; return ( Alert.alert("Position actuelle", "Ceci est votre position")}> ); }, [location]); const lastPositionMarker = useMemo(() => { if (gameState != GameState.PLAYING || !lastSentLocation || hasHandicap) return null; return ( Alert.alert("Position envoyée", "Ceci est votre dernière position connue par le serveur")}> ); }, [gameState, hasHandicap, lastSentLocation]); const enemyPositionMarker = useMemo(() => { if (gameState != GameState.PLAYING || !enemyLocation || hasHandicap) return null; return ( Alert.alert("Position ennemie", "Ceci est la dernière position de vos ennemis connue")}> ); }, [gameState, hasHandicap, enemyLocation]); return ( setCenterMap(false)} toolbarEnabled={false}> {startZone} {gameZone} {currentPositionMarker} {lastPositionMarker} {enemyPositionMarker} { !centerMap && setCenterMap(true)}> } ); }; const styles = StyleSheet.create({ container: { flex: 1, width: '100%', borderTopLeftRadius: 30, borderTopRightRadius: 30, overflow: 'hidden', }, centerMap: { position: 'absolute', right: 20, top: 20, width: 40, height: 40, borderRadius: 20, backgroundColor: 'white', borderWidth: 2, borderColor: 'black', alignItems: 'center', justifyContent: 'center', }, markerImage: { width: 24, height: 24 } });