@@ -4,117 +4,31 @@ import { useTheme } from 'next-themes'
44import { useEffect , useRef } from 'react'
55import { useMap } from 'react-leaflet'
66
7- function getAttributions ( style : unknown ) {
8- if ( ! style || typeof style !== 'object' ) return [ ]
9-
10- const sources = ( style as { sources ?: Record < string , unknown > } ) . sources
11- if ( ! sources || typeof sources !== 'object' ) return [ ]
12-
13- const attributions = new Set < string > ( )
14- for ( const source of Object . values ( sources ) ) {
15- if ( ! source || typeof source !== 'object' ) continue
16- const attribution = ( source as { attribution ?: unknown } ) . attribution
17- if ( typeof attribution === 'string' && attribution . trim ( ) ) {
18- attributions . add ( attribution )
19- }
20- }
21-
22- return Array . from ( attributions )
23- }
24-
25- function getMapStyle ( style : unknown ) {
26- if ( process . env . NEXT_PUBLIC_STADIA_TILE_PROXY !== '1' ) return style
27- if ( ! style || typeof style !== 'object' ) return style
28-
29- const sources = ( style as { sources ?: Record < string , unknown > } ) . sources
30- if ( ! sources || typeof sources !== 'object' ) return style
31-
32- for ( const source of Object . values ( sources ) ) {
33- if ( ! source || typeof source !== 'object' ) continue
34-
35- const tiles = ( source as { tiles ?: unknown } ) . tiles
36- if ( ! Array . isArray ( tiles ) ) continue
37-
38- ; ( source as { tiles : string [ ] } ) . tiles = tiles . map ( ( tile ) =>
39- typeof tile === 'string' &&
40- tile . startsWith ( 'https://tiles.stadiamaps.com/tiles/' )
41- ? tile . replace (
42- 'https://tiles.stadiamaps.com/tiles/' ,
43- '/api/stadia-tiles/' ,
44- )
45- : ( tile as string ) ,
46- )
47- }
48-
49- return style
50- }
51-
52- async function waitForMaplibreMap ( layer : L . MaplibreGL , signal : AbortSignal ) {
53- for ( let attempt = 0 ; attempt < 20 ; attempt ++ ) {
54- if ( signal . aborted ) return null
55- const maplibreMap = layer . getMaplibreMap ( )
56- if ( maplibreMap ) return maplibreMap
57- await new Promise ( ( resolve ) => setTimeout ( resolve , 50 ) )
58- }
59- return null
60- }
61-
627export default function TileLayer ( ) {
638 const map = useMap ( )
649 const { resolvedTheme } = useTheme ( )
65- const glRef = useRef < L . MaplibreGL | null > ( null )
66- const attributionRef = useRef < string [ ] > ( [ ] )
10+ const glRef = useRef < L . MaplibreGL > (
11+ L . maplibreGL ( {
12+ style : `/map-styles/${ resolvedTheme } .json` ,
13+ } ) ,
14+ )
6715
6816 useEffect ( ( ) => {
69- map . attributionControl . setPrefix (
70- '<a href="https://leafletjs.com">Leaflet</a>' ,
71- )
72- } , [ map ] )
17+ const maplibreMap = glRef . current . getMaplibreMap ( )
7318
74- useEffect ( ( ) => {
75- if ( ! resolvedTheme ) return
19+ if ( ! maplibreMap ) {
20+ glRef . current . addTo ( map )
7621
77- const controller = new AbortController ( )
78- const styleUrl = `/map-styles/${ resolvedTheme } .json`
22+ map . attributionControl . setPrefix (
23+ '<a href="https://leafletjs.com">Leaflet</a>' ,
24+ )
7925
80- const applyStyle = async ( ) => {
81- try {
82- const response = await fetch ( styleUrl , { signal : controller . signal } )
83- if ( ! response . ok ) return
84-
85- const style = getMapStyle ( await response . json ( ) )
86- if ( controller . signal . aborted ) return
87-
88- if ( glRef . current ) {
89- glRef . current . removeFrom ( map )
90- glRef . current = null
91- }
92- if ( map . attributionControl ) {
93- for ( const attribution of attributionRef . current ) {
94- map . attributionControl . removeAttribution ( attribution )
95- }
96- }
97- attributionRef . current = getAttributions ( style )
98-
99- glRef . current = L . maplibreGL ( {
100- style : style as never ,
101- } )
102- glRef . current . addTo ( map )
103-
104- await waitForMaplibreMap (
105- glRef . current as L . MaplibreGL ,
106- controller . signal ,
107- )
108- } catch ( error ) {
109- if ( ( error as Error ) . name === 'AbortError' ) return
110- throw error
111- }
26+ return
11227 }
11328
114- applyStyle ( )
115-
116- return ( ) => controller . abort ( )
117- } , [ resolvedTheme , map ] )
29+ // Update the style when the theme changes
30+ maplibreMap . setStyle ( `/map-styles/${ resolvedTheme } .json` )
31+ } , [ map , resolvedTheme ] )
11832
11933 return null
12034}
0 commit comments