Files
cruiseLovers/assets/components/ContactMapPreview.tsx

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} />;
}