diff --git a/.idea/scopes/Original.xml b/.idea/scopes/Original.xml index 2af377e..1eab363 100644 --- a/.idea/scopes/Original.xml +++ b/.idea/scopes/Original.xml @@ -1,3 +1,3 @@ - - \ No newline at end of file + + diff --git a/src/components/MapUI.vue b/src/components/MapUI.vue index 2bae816..b8ce75e 100644 --- a/src/components/MapUI.vue +++ b/src/components/MapUI.vue @@ -21,7 +21,9 @@
-
+
+ +
@@ -52,11 +54,10 @@ import ClockControl from "@/components/map/control/ClockControl.vue"; import LinkControl from "@/components/map/control/LinkControl.vue"; import ChatControl from "@/components/map/control/ChatControl.vue"; import LogoControl from "@/components/map/control/LogoControl.vue"; -import {LoadingControl} from "@/leaflet/control/LoadingControl"; import MapContextMenu from "@/components/map/MapContextMenu.vue"; import LoginControl from "@/components/map/control/LoginControl.vue"; -import {onMounted} from "vue"; import LiveAtlasLeafletMap from "@/leaflet/LiveAtlasLeafletMap"; +import LoadingControl from "@/components/map/control/LoadingControl.vue"; export default defineComponent({ props: { @@ -67,6 +68,7 @@ export default defineComponent({ }, components: { + LoadingControl, LogoControl, CoordinatesControl, LinkControl, @@ -87,13 +89,6 @@ export default defineComponent({ logoControls = computed(() => store.state.components.logoControls); - onMounted(() => { - props.leaflet.addControl(new LoadingControl({ - position: 'topleft', - delayIndicator: 500, - })) - }); - return { contextMenuEnabled, coordinatesControlEnabled, diff --git a/src/components/map/control/LoadingControl.vue b/src/components/map/control/LoadingControl.vue new file mode 100644 index 0000000..922442e --- /dev/null +++ b/src/components/map/control/LoadingControl.vue @@ -0,0 +1,226 @@ + + + + + + + diff --git a/src/leaflet/control/LoadingControl.ts b/src/leaflet/control/LoadingControl.ts deleted file mode 100644 index f91e81f..0000000 --- a/src/leaflet/control/LoadingControl.ts +++ /dev/null @@ -1,248 +0,0 @@ -/* -Portions of this file are taken from Leaflet.loading: - -Copyright (c) 2013 Eric Brelsford - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -import { - Control, - ControlOptions, - DomUtil, - Layer, - LeafletEvent, - Map, TileLayer, -} from 'leaflet'; -import '@/assets/icons/loading.svg'; -import {useStore} from "@/store"; - -export interface LoadingControlOptions extends ControlOptions { - delayIndicator?: number; -} - -/** - * Leaflet map control which displays a loading spinner when any tiles are loading - */ -export class LoadingControl extends Control { - declare options: LoadingControlOptions; - - private _dataLoaders: Set = new Set(); - private readonly _loadingIndicator: HTMLDivElement; - private _delayIndicatorTimeout: null | ReturnType = null; - - constructor(options: LoadingControlOptions) { - super(options); - - this._loadingIndicator = DomUtil.create('div', - 'leaflet-control-button leaflet-control-loading') as HTMLDivElement; - } - - onAdd(map: Map) { - this._loadingIndicator.title = useStore().state.messages.loadingTitle; - this._loadingIndicator.hidden = true; - this._loadingIndicator.innerHTML = ` - - - `; - - this._addLayerListeners(map); - this._addMapListeners(map); - - return this._loadingIndicator; - } - - onRemove(map: Map) { - this._removeLayerListeners(map); - this._removeMapListeners(map); - } - - addLoader(id: number) { - this._dataLoaders.add(id); - - if (this.options.delayIndicator && !this._delayIndicatorTimeout) { - // If we are delaying showing the indicator and we're not - // already waiting for that delay, set up a timeout. - this._delayIndicatorTimeout = setTimeout(() => { - this.updateIndicator(); - this._delayIndicatorTimeout = null; - }, this.options.delayIndicator); - } else { - // Otherwise show the indicator immediately - this.updateIndicator(); - } - } - - removeLoader(id: number) { - this._dataLoaders.delete(id); - this.updateIndicator(); - - // If removing this loader means we're in no danger of loading, - // clear the timeout. This prevents old delays from instantly - // triggering the indicator. - if (this.options.delayIndicator && this._delayIndicatorTimeout && !this.isLoading()) { - clearTimeout(this._delayIndicatorTimeout); - this._delayIndicatorTimeout = null; - } - } - - updateIndicator() { - if (this.isLoading()) { - this._showIndicator(); - } - else { - this._hideIndicator(); - } - } - - isLoading() { - return this._countLoaders() > 0; - } - - _countLoaders() { - return this._dataLoaders.size; - } - - _showIndicator() { - this._loadingIndicator.hidden = false; - } - - _hideIndicator() { - this._loadingIndicator.hidden = true; - } - - _handleLoading(e: LeafletEvent) { - this.addLoader(this.getEventId(e)); - } - - _handleBaseLayerChange (e: LeafletEvent) { - // Check for a target 'layer' that contains multiple layers, such as - // L.LayerGroup. This will happen if you have an L.LayerGroup in an - // L.Control.Layers. - if (e.layer && e.layer.eachLayer && typeof e.layer.eachLayer === 'function') { - e.layer.eachLayer((layer: Layer) => { - this._handleBaseLayerChange({ layer: layer } as LeafletEvent); - }); - } - } - - _handleLoad(e: LeafletEvent) { - this.removeLoader(this.getEventId(e)); - } - - getEventId(e: any) { - if (e.id) { - return e.id; - } else if (e.layer) { - return e.layer._leaflet_id; - } - return e.target._leaflet_id; - } - - _layerAdd(e: LeafletEvent) { - if(!(e.layer instanceof TileLayer)) { - return; - } - - try { - if(e.layer.isLoading()) { - this.addLoader((e.layer as any)._leaflet_id); - } - - e.layer.on('loading', this._handleLoading, this); - e.layer.on('load', this._handleLoad, this); - } catch (exception) { - console.warn('L.Control.Loading: Tried and failed to add ' + - ' event handlers to layer', e.layer); - console.warn('L.Control.Loading: Full details', exception); - } - } - - _layerRemove(e: LeafletEvent) { - if(!(e.layer instanceof TileLayer)) { - return; - } - - try { - e.layer.off('loading', this._handleLoading, this); - e.layer.off('load', this._handleLoad, this); - } catch (exception) { - console.warn('L.Control.Loading: Tried and failed to remove ' + - 'event handlers from layer', e.layer); - console.warn('L.Control.Loading: Full details', exception); - } - } - - _addLayerListeners(map: Map) { - // Add listeners for begin and end of load to any layers already - // on the map - map.eachLayer((layer: Layer) => { - if(!(layer instanceof TileLayer)) { - return; - } - - if(layer.isLoading()) { - this.addLoader((layer as any)._leaflet_id); - } - - layer.on('loading', this._handleLoading, this); - layer.on('load', this._handleLoad, this); - }); - - // When a layer is added to the map, add listeners for begin and - // end of load - map.on('layeradd', this._layerAdd, this); - map.on('layerremove', this._layerRemove, this); - } - - _removeLayerListeners(map: Map) { - // Remove listeners for begin and end of load from all layers - map.eachLayer((layer: Layer) => { - if(!(layer instanceof TileLayer)) { - return; - } - - this.removeLoader((layer as any)._leaflet_id); - - layer.off('loading', this._handleLoading, this); - layer.off('load', this._handleLoad, this); - }); - - // Remove layeradd/layerremove listener from map - map.off('layeradd', this._layerAdd, this); - map.off('layerremove', this._layerRemove, this); - } - - _addMapListeners(map: Map) { - // Add listeners to the map for (custom) dataloading and dataload - // events, eg, for AJAX calls that affect the map but will not be - // reflected in the above layer events. - map.on('baselayerchange', this._handleBaseLayerChange, this); - map.on('dataloading', this._handleLoading, this); - map.on('dataload', this._handleLoad, this); - map.on('layerremove', this._handleLoad, this); - } - - _removeMapListeners(map: Map) { - map.off('baselayerchange', this._handleBaseLayerChange, this); - map.off('dataloading', this._handleLoading, this); - map.off('dataload', this._handleLoad, this); - map.off('layerremove', this._handleLoad, this); - } -} diff --git a/src/scss/leaflet/_controls.scss b/src/scss/leaflet/_controls.scss index 9245331..1e9e22d 100644 --- a/src/scss/leaflet/_controls.scss +++ b/src/scss/leaflet/_controls.scss @@ -261,17 +261,3 @@ margin: 0; } } - -.leaflet-control-loading { - cursor: wait; - animation: fade 0.3s linear; - animation-fill-mode: forwards; - - &:hover, &:active, &:focus { - background-color: var(--background-base); - } - - &[hidden] { - display: none; - } -}