import React, { useEffect, useRef, useState } from 'react'; import { Image, SafeAreaView, ScrollView, StatusBar, StyleSheet, Switch, View, Dimensions } from 'react-native'; import Mapbox, { Callout, Camera, MapView, PointAnnotation } from "@rnmapbox/maps"; import { useSelector } from 'react-redux'; import { useIsFocused } from '@react-navigation/core'; import { useTranslation } from 'react-i18next'; Mapbox.setAccessToken( "pk.eyJ1IjoibWFhcnRlbnZyOTgiLCJhIjoiY2x6ZDFqMGp1MGVyejJrczhqcXpvYm9iYiJ9.XvYcL62dWiJQiFmG6mOoug" ); import { ThemedText } from '@/src/components/themed/ThemedText'; import { ThemedView } from '@/src/components/themed/ThemedView'; import { Colors } from '@/src/constants/Colors'; import { useColorScheme } from '@/src/hooks/useColorScheme'; import List from '@/src/components/List'; import { Request } from '@/src/services/request'; export default function MapScreen() { const colorScheme = useColorScheme() ?? 'light'; const isFocused = useIsFocused(); const session = useSelector( (state: any) => state.data.session ); const { t } = useTranslation(); const mapRef = useRef( null ); const [ types, setTypes ] = useState( [] ); const [ typesSet, setTypesSet ] = useState( false ); const [ coordinates, setCoordinates ] = useState( [] ); const [ markers, setMarkers ] = useState( [] ); const [ activeCalloutId, setActiveCalloutId ] = useState( null ); // Load session useEffect( () => { setCoordinates( [ session.coordinates.longitude, session.coordinates.latitude ] ); }, [ session, isFocused ] ); // Setup mapbox useEffect( () => { Mapbox.setTelemetryEnabled( false ); }, [] ); // Load markers and types const loadMarkers = () => { handleCloseAllCallouts(); mapRef.current?.getVisibleBounds().then( (bounds) => { Request .post( 'locations', { topLeft: bounds[ 0 ], bottomRight: bounds[ 1 ], } ) .then( (response) => { const { locations, types } = response; // Set types if (!typesSet) { const typesList: any[] = []; types.forEach( (type: any) => { typesList.push( { name: type.name, image: type.image, isEnabled: false, type: type.config_name, } ); } ) setTypes( typesList ); setTypesSet( true ); } // Set markers setMarkers( locations ); } ) } ); } // Enable/disable type const toggleSwitch = (index: any) => { handleCloseAllCallouts(); const newData = types.map( (item: any, key: any) => key === index ? { ...item, isEnabled: !item.isEnabled } : item ); setTypes( newData ); }; // Get all types that are active const getActiveTypes = (): Array => { const list: any[] = []; types.forEach( (type: any) => { if (type.isEnabled) { list.push( type.type ); } } ); return list; } // Get all markers that needs to be visible const activeMarkers = () => { return markers.filter( (marker: any) => { return getActiveTypes().includes( marker.waste_type ); } ); } const handleCalloutPress = (id: any) => { console.log('set active', id); setActiveCalloutId( id ); }; const handleCloseAllCallouts = () => { setActiveCalloutId( null ); }; return ( {t( "garbage-bins" )} {t( "nearby" )} {activeMarkers().map( (marker: any, index: any) => ( handleCalloutPress( marker.id )} > <> {/*{activeCalloutId === marker.id && (*/} {/* */} {/* */} {/* {marker.description + ' - ' + marker.street}*/} {/* */} {/* */} {/*)}*/} ) )} ( {item.name} toggleSwitch( index )} /> )}/> ); } const styles = StyleSheet.create( { container: { marginTop: StatusBar.currentHeight, paddingTop: 25, flex: 1, }, titleContainer: { paddingLeft: 25, paddingRight: 25, flexDirection: 'row', alignItems: 'center', gap: 8, paddingBottom: 8, }, mapContainer: { marginTop: 15, height: Dimensions.get( 'window' ).height / 3, }, map: { width: Dimensions.get( 'window' ).width, height: Dimensions.get( 'window' ).height / 3, flex: 1, }, listContainer: { flex: 1, paddingTop: 20, paddingLeft: 25, paddingRight: 25, }, listItem: { flex: 1, display: 'flex', justifyContent: 'space-between', flexDirection: 'row', alignItems: 'center', paddingBottom: 20, marginBottom: 20, borderBottomWidth: 1, borderBottomColor: '#f2f2f2', }, listItemTitle: { flex: 1, flexDirection: 'row', alignItems: 'center', }, listImage: { width: 30, height: 30, borderRadius: 5, marginRight: 8, }, callout: { width: 200, padding: 5, }, } );