123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- import React, { useEffect, useState } from 'react';
- import { View, Platform, SafeAreaView, Text } from 'react-native';
- import MapView, { Geojson, UrlTile } from 'react-native-maps';
- import kye from '../../../../../assets/geojson/kye.json';
- import { Header } from 'src/components';
- import { useGetKyeQuery, usePostSetKye } from '@api/travels';
- import { StoreType, storage } from 'src/storage';
- import { FeatureCollection } from '@turf/turf';
- import { MAP_HOST } from 'src/constants';
- import { styles } from './styles';
- interface PropertiesData {
- id: number;
- tt: string;
- mega: string;
- name: string;
- fill?: string;
- }
- const EarthScreen = () => {
- const token = storage.get('token', StoreType.STRING) as string;
- const [geojson, setGeojson] = useState<FeatureCollection>(kye as FeatureCollection);
- const { data } = useGetKyeQuery(token, true);
- const { mutateAsync } = usePostSetKye();
- const [visited, setVisited] = useState<number[]>([]);
- const [score, setScore] = useState({ base: 0, percentage: 0 });
- const [quadrantsAll, setQuadrantsAll] = useState<number>(1);
- useEffect(() => {
- if (!data || !data.regions) return;
- setQuadrantsAll(data.regions?.length);
- token && setVisited(data.visited);
- }, [data]);
- useEffect(() => {
- const updatedGeojson = updateGeojsonStyles(geojson);
- setGeojson(updatedGeojson);
- showScore();
- }, [visited]);
- const getFeatureStyle = (properties: PropertiesData) => {
- const style = {
- fill: 'transparent'
- };
- if (properties.tt == '1') {
- if (properties.id > 612) {
- if (Math.max(...visited) > 612) {
- style.fill = 'rgba(132, 138, 68, 0.5)';
- } else {
- style.fill = 'rgba(21, 99, 123, 0.5)';
- }
- } else {
- if (visited.includes(properties.id)) {
- style.fill = 'rgba(132, 138, 68, 0.5)';
- } else {
- style.fill = 'rgba(21, 99, 123, 0.5)';
- }
- }
- } else {
- style.fill = 'rgba(230, 230, 230, 0.5)';
- }
- return style;
- };
- const updateGeojsonStyles = (geojson: FeatureCollection) => {
- const updatedFeatures = geojson.features.map((feature) => {
- const style = getFeatureStyle(feature.properties as PropertiesData);
- return { ...feature, properties: { ...feature.properties, ...style } };
- });
- return { ...geojson, features: updatedFeatures };
- };
- const markQuadrant = async (qid: number) => {
- if (!token) return;
- let vis: 0 | 1 = 1;
- if (qid > 612) {
- if (Math.max(...visited) > 612) {
- vis = 0;
- }
- } else {
- if (visited.includes(qid)) {
- vis = 0;
- }
- }
- try {
- await mutateAsync(
- { token, qid, visited: vis },
- {
- onSuccess: () => {
- if (vis == 0) {
- quadRemove(qid);
- } else {
- quadAdd(qid);
- }
- }
- }
- );
- } catch (error) {
- console.error('Failed to update kye state', error);
- }
- };
- const quadAdd = (qid: number) => {
- setVisited((prevVisited) => {
- if (qid > 612) {
- const newVisited = [...prevVisited];
- for (let i = 613; i < 649; i++) {
- if (!newVisited.includes(i)) {
- newVisited.push(i);
- }
- }
- return newVisited;
- } else {
- if (!prevVisited.includes(qid)) {
- return [...prevVisited, qid];
- }
- return prevVisited;
- }
- });
- };
- const quadRemove = (qid: number) => {
- setVisited((prevVisited) => {
- if (qid > 612) {
- return prevVisited.filter((id) => id < 613 || id > 648);
- } else {
- return prevVisited.filter((id) => id !== qid);
- }
- });
- };
- const showScore = () => {
- let baseList = visited.filter((id) => id < 613);
- let score = baseList.length;
- if (Math.max(...visited) > 612) {
- score += 1;
- }
- let calc = Math.round((score / quadrantsAll) * 10000) / 100;
- setScore({ base: score, percentage: calc });
- };
- return (
- <SafeAreaView style={{ height: '100%' }}>
- <View style={styles.wrapper}>
- <Header label={'My Earth'} />
- {token && (
- <View style={styles.score}>
- <Text style={[styles.scoreText, { fontWeight: 'bold' }]}>Your score: {score.base}</Text>
- <Text style={[styles.scoreText, { fontSize: 14 }]}>{`(${score.percentage}%)`}</Text>
- </View>
- )}
- </View>
- <View style={styles.container}>
- <MapView
- style={styles.map}
- showsMyLocationButton={false}
- showsCompass={false}
- zoomControlEnabled={false}
- mapType={Platform.OS == 'android' ? 'none' : 'standard'}
- maxZoomLevel={15}
- minZoomLevel={0}
- initialRegion={{
- latitude: 0,
- longitude: 0,
- latitudeDelta: 180,
- longitudeDelta: 180
- }}
- >
- <UrlTile
- urlTemplate={`${MAP_HOST}/tiles_osm/{z}/{x}/{y}`}
- maximumZ={15}
- maximumNativeZ={13}
- shouldReplaceMapContent
- minimumZ={0}
- />
- <Geojson
- geojson={geojson as any}
- zIndex={1}
- tappable={true}
- onPress={(event) => {
- markQuadrant(event.feature.properties?.id);
- }}
- tracksViewChanges={false}
- />
- </MapView>
- </View>
- </SafeAreaView>
- );
- };
- export default EarthScreen;
|