77 lines
2.4 KiB
TypeScript
77 lines
2.4 KiB
TypeScript
import { LoadingSpinner } from '@/assets/components/LoadingSpinner';
|
|
import { colors } from '@/assets/styles/colors';
|
|
import styles from '@/styles/screens/tabs/contactos.styles';
|
|
import { FontAwesome } from '@expo/vector-icons';
|
|
import Constants, { ExecutionEnvironment } from 'expo-constants';
|
|
import { lazy, Suspense, useMemo, useState } from 'react';
|
|
import { Image, Platform, Pressable, Text, View } from 'react-native';
|
|
|
|
const MAP_ZOOM = 15;
|
|
const isExpoGo = Constants.executionEnvironment === ExecutionEnvironment.StoreClient;
|
|
const useNativeMaps = !isExpoGo && (Platform.OS === 'ios' || Platform.OS === 'android');
|
|
|
|
const NativeMapPreview = useNativeMaps
|
|
? lazy(() => import('./ContactMapPreviewNative'))
|
|
: null;
|
|
|
|
const buildStaticMapUrl = (lat: number, lng: number): string => {
|
|
const delta = 0.012;
|
|
const bbox = [lng - delta, lat - delta, lng + delta, lat + delta].join(',');
|
|
return `https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/export?bbox=${bbox}&bboxSR=4326&size=600,300&format=png&f=image`;
|
|
};
|
|
|
|
type Props = {
|
|
lat: number;
|
|
lng: number;
|
|
title?: string;
|
|
onPress: () => void;
|
|
};
|
|
|
|
function StaticMapFallback({ lat, lng, onPress }: Props) {
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState(false);
|
|
const mapUrl = useMemo(() => buildStaticMapUrl(lat, lng), [lat, lng]);
|
|
|
|
return (
|
|
<Pressable onPress={onPress} style={styles.mapImageWrap}>
|
|
<Image
|
|
source={{ uri: mapUrl }}
|
|
style={styles.mapImage}
|
|
resizeMode="cover"
|
|
onLoadStart={() => {
|
|
setLoading(true);
|
|
setError(false);
|
|
}}
|
|
onLoad={() => setLoading(false)}
|
|
onError={() => {
|
|
setLoading(false);
|
|
setError(true);
|
|
}}
|
|
/>
|
|
{loading && !error && (
|
|
<View style={styles.mapOverlay}>
|
|
<LoadingSpinner size="small" />
|
|
</View>
|
|
)}
|
|
{error && (
|
|
<View style={styles.mapOverlay}>
|
|
<FontAwesome name="map-marker" size={28} color={colors.vermelho} />
|
|
<Text style={styles.mapErrorText}>Mapa indisponível</Text>
|
|
</View>
|
|
)}
|
|
</Pressable>
|
|
);
|
|
}
|
|
|
|
export function ContactMapPreview(props: Props) {
|
|
if (NativeMapPreview) {
|
|
return (
|
|
<Suspense fallback={<StaticMapFallback {...props} />}>
|
|
<NativeMapPreview {...props} />
|
|
</Suspense>
|
|
);
|
|
}
|
|
|
|
return <StaticMapFallback {...props} />;
|
|
}
|