universal navigation button

This commit is contained in:
Anton Tranelis 2025-09-13 11:29:15 +02:00
parent 5f5bdd6a45
commit e8c5f3682f

View File

@ -21,9 +21,6 @@ import { useNavigate } from 'react-router-dom'
import { toast } from 'react-toastify' import { toast } from 'react-toastify'
import ChevronSVG from '#assets/chevron.svg' import ChevronSVG from '#assets/chevron.svg'
import AppleMapsSVG from '#assets/navigation/apple-maps.svg'
import GoogleMapsSVG from '#assets/navigation/googlemaps.svg'
import OpenStreetMapSVG from '#assets/navigation/OSM.svg'
import ClipboardSVG from '#assets/share/clipboard.svg' import ClipboardSVG from '#assets/share/clipboard.svg'
import FacebookSVG from '#assets/share/facebook.svg' import FacebookSVG from '#assets/share/facebook.svg'
import LinkedinSVG from '#assets/share/linkedin.svg' import LinkedinSVG from '#assets/share/linkedin.svg'
@ -151,29 +148,30 @@ export function HeaderView({
.replace('{title}', encodeURIComponent(shareTitle)) .replace('{title}', encodeURIComponent(shareTitle))
} }
const routingServices = [ const coordinates = item?.position?.coordinates
{ const latitude = coordinates?.[1]
name: 'Google Maps', const longitude = coordinates?.[0]
url: item?.position?.coordinates
? `https://www.google.com/maps/dir/?api=1&destination=${item.position.coordinates[1]},${item.position.coordinates[0]}` const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent)
: '', const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
icon: <img src={GoogleMapsSVG} alt='Google Maps' className='tw:w-6 tw:h-6' />, navigator.userAgent,
}, )
{
name: 'Apple Maps', const getNavigationUrl = () => {
url: item?.position?.coordinates if (!coordinates || !latitude || !longitude) return ''
? `https://maps.apple.com/?daddr=${item.position.coordinates[1]},${item.position.coordinates[0]}`
: '', // Try geo: link first (works on most mobile devices)
icon: <img src={AppleMapsSVG} alt='Apple Maps' className='tw:w-6 tw:h-6' />, if (isMobile) {
}, return `geo:${latitude},${longitude}`
{ }
name: 'OpenStreetMap',
url: item?.position?.coordinates // Fallback to web-based maps
? `https://www.openstreetmap.org/directions?to=${item.position.coordinates[1]},${item.position.coordinates[0]}` if (isIOS) {
: '', return `https://maps.apple.com/?daddr=${latitude},${longitude}`
icon: <img src={OpenStreetMapSVG} alt='OpenStreetMap' className='tw:w-6 tw:h-6' />, } else {
}, return `https://www.google.com/maps/dir/?api=1&destination=${latitude},${longitude}`
] }
}
const openDeleteModal = async (event: React.MouseEvent<HTMLElement>) => { const openDeleteModal = async (event: React.MouseEvent<HTMLElement>) => {
setModalOpen(true) setModalOpen(true)
@ -323,31 +321,16 @@ export function HeaderView({
Follow Follow
</button> </button>
{item?.position?.coordinates ? ( {item?.position?.coordinates ? (
<div className='tw:dropdown tw:dropdown-end tw:mr-2'> <a
<div tabIndex={0} role='button' className='tw:btn tw:btn-sm tw:px-2'> href={getNavigationUrl()}
<LuNavigation className='tw:h-4 tw:w-4' /> target='_blank'
</div> rel='noopener noreferrer'
<ul className='tw:btn tw:btn-sm tw:mr-2 tw:px-2 tw:no-underline hover:tw:no-underline'
tabIndex={0} style={{ color: 'inherit' }}
className='tw:dropdown-content tw:menu tw:bg-base-100 tw:rounded-box tw:z-[1] tw:p-2 tw:shadow-sm' title={`Navigate with ${isMobile ? 'default navigation app' : isIOS ? 'Apple Maps' : 'Google Maps'}`}
> >
{routingServices.map((service) => ( <LuNavigation className='tw:h-4 tw:w-4' />
<li key={service.name}> </a>
<a
href={service.url}
target='_blank'
rel='noopener noreferrer'
className='tw:flex tw:items-center tw:gap-3'
>
<div className='tw:w-6 tw:h-6 tw:rounded-full tw:flex tw:items-center tw:justify-center tw:text-white'>
<span className='tw:text-xs'>{service.icon}</span>
</div>
{service.name}
</a>
</li>
))}
</ul>
</div>
) : ( ) : (
<div className='tw:btn tw:btn-sm tw:mr-2 tw:px-2 tw:btn-disabled'> <div className='tw:btn tw:btn-sm tw:mr-2 tw:px-2 tw:btn-disabled'>
<LuNavigation className='tw:h-4 tw:w-4' /> <LuNavigation className='tw:h-4 tw:w-4' />