Skip to content

Commit b8381b5

Browse files
committed
fix: share geolocation state across components
1 parent 026a48e commit b8381b5

File tree

1 file changed

+47
-42
lines changed

1 file changed

+47
-42
lines changed

app/composables/useUserLocation.ts

Lines changed: 47 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,59 +6,64 @@ interface NimiqGeoIpResponse {
66
city?: string
77
}
88

9-
export function useUserLocation() {
10-
const route = useRoute()
9+
// Module-level shared state (singleton across all components)
10+
const ipPoint = ref<Point | null>(null)
11+
const ipAccuracy = ref<number | null>(null)
12+
const ipCountry = ref<string | null>(null)
13+
const ipGeoStatus = ref<'idle' | 'pending' | 'success' | 'error'>('idle')
14+
15+
const gpsPoint = ref<Point | null>(null)
16+
const gpsAccuracy = ref<number | null>(null)
17+
const isLocating = ref(false)
18+
19+
// Shared useGeolocation instance (lazy initialized)
20+
let geoInstance: ReturnType<typeof useGeolocation> | null = null
21+
function getGeoInstance() {
22+
if (!geoInstance)
23+
geoInstance = useGeolocation({ immediate: false })
24+
return geoInstance
25+
}
1126

12-
const queryLat = route.query.lat ? Number(route.query.lat) : undefined
13-
const queryLng = route.query.lng ? Number(route.query.lng) : undefined
14-
const hasQueryParams = queryLat !== undefined && queryLng !== undefined
27+
async function fetchIpGeolocation() {
28+
if (ipGeoStatus.value !== 'idle')
29+
return
30+
ipGeoStatus.value = 'pending'
1531

16-
// Nimiq GeoIP (client-side fetch)
17-
const ipPoint = ref<Point | null>(null)
18-
const ipAccuracy = ref<number | null>(null) // in meters
19-
const ipCountry = ref<string | null>(null)
20-
const ipGeoStatus = ref<'idle' | 'pending' | 'success' | 'error'>('idle')
21-
22-
async function fetchIpGeolocation() {
23-
if (ipGeoStatus.value !== 'idle')
24-
return
25-
ipGeoStatus.value = 'pending'
26-
27-
try {
28-
const response = await fetch('https://geoip.nimiq-network.com:8443/v1/locate')
29-
const json: NimiqGeoIpResponse = await response.json()
30-
31-
if (json?.location?.latitude && json?.location?.longitude) {
32-
ipPoint.value = {
33-
lat: Number.parseFloat(json.location.latitude),
34-
lng: Number.parseFloat(json.location.longitude),
35-
}
36-
ipAccuracy.value = (json.location.accuracy_radius || 300) * 1000 // km -> meters
37-
ipCountry.value = json.country || null
38-
ipGeoStatus.value = 'success'
39-
}
40-
else {
41-
ipGeoStatus.value = 'error'
42-
}
32+
try {
33+
const response = await fetch('https://geoip.nimiq-network.com:8443/v1/locate')
34+
const json: NimiqGeoIpResponse = await response.json()
35+
36+
if (json?.location?.latitude && json?.location?.longitude) {
37+
ipPoint.value = { lat: Number.parseFloat(json.location.latitude), lng: Number.parseFloat(json.location.longitude) }
38+
ipAccuracy.value = (json.location.accuracy_radius || 300) * 1000 // km -> meters
39+
ipCountry.value = json.country || null
40+
ipGeoStatus.value = 'success'
4341
}
44-
catch {
42+
else {
4543
ipGeoStatus.value = 'error'
4644
}
4745
}
48-
49-
// Auto-fetch on client
50-
if (import.meta.client) {
51-
fetchIpGeolocation()
46+
catch {
47+
ipGeoStatus.value = 'error'
5248
}
49+
}
5350

54-
const isGeoReady = computed(() => ipGeoStatus.value === 'success' || ipGeoStatus.value === 'error')
51+
// Auto-fetch on client (only runs once due to ipGeoStatus check)
52+
if (import.meta.client) {
53+
fetchIpGeolocation()
54+
}
55+
56+
export function useUserLocation() {
57+
const route = useRoute()
5558

56-
const gpsPoint = ref<Point | null>(null)
57-
const gpsAccuracy = ref<number | null>(null)
58-
const isLocating = ref(false)
59-
const { coords, resume, pause } = useGeolocation({ immediate: false })
59+
const queryLat = route.query.lat ? Number(route.query.lat) : undefined
60+
const queryLng = route.query.lng ? Number(route.query.lng) : undefined
61+
const hasQueryParams = queryLat !== undefined && queryLng !== undefined
62+
63+
const isGeoReady = computed(() => ipGeoStatus.value === 'success' || ipGeoStatus.value === 'error')
6064

6165
function locateMe() {
66+
const { coords, resume, pause } = getGeoInstance()
6267
isLocating.value = true
6368
resume()
6469
watchOnce(coords, (newCoords) => {

0 commit comments

Comments
 (0)