mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-14 21:06:34 +00:00
Pause map autofit when user initiates pan/zoom (#26114)
* Pause map autofit when user initiates pan/zoom * not a state * a different approach
This commit is contained in:
parent
5233086efb
commit
e7e062a222
@ -36,6 +36,8 @@ declare global {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PROGRAMMITIC_FIT_DELAY = 250;
|
||||||
|
|
||||||
const getEntityId = (entity: string | HaMapEntity): string =>
|
const getEntityId = (entity: string | HaMapEntity): string =>
|
||||||
typeof entity === "string" ? entity : entity.entity_id;
|
typeof entity === "string" ? entity : entity.entity_id;
|
||||||
|
|
||||||
@ -113,14 +115,33 @@ export class HaMap extends ReactiveElement {
|
|||||||
|
|
||||||
private _clickCount = 0;
|
private _clickCount = 0;
|
||||||
|
|
||||||
|
private _isProgrammaticFit = false;
|
||||||
|
|
||||||
|
private _pauseAutoFit = false;
|
||||||
|
|
||||||
public connectedCallback(): void {
|
public connectedCallback(): void {
|
||||||
|
this._pauseAutoFit = false;
|
||||||
|
document.addEventListener("visibilitychange", this._handleVisibilityChange);
|
||||||
|
this._handleVisibilityChange();
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
this._loadMap();
|
this._loadMap();
|
||||||
this._attachObserver();
|
this._attachObserver();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleVisibilityChange = async () => {
|
||||||
|
if (!document.hidden) {
|
||||||
|
setTimeout(() => {
|
||||||
|
this._pauseAutoFit = false;
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public disconnectedCallback(): void {
|
public disconnectedCallback(): void {
|
||||||
super.disconnectedCallback();
|
super.disconnectedCallback();
|
||||||
|
document.removeEventListener(
|
||||||
|
"visibilitychange",
|
||||||
|
this._handleVisibilityChange
|
||||||
|
);
|
||||||
if (this.leafletMap) {
|
if (this.leafletMap) {
|
||||||
this.leafletMap.remove();
|
this.leafletMap.remove();
|
||||||
this.leafletMap = undefined;
|
this.leafletMap = undefined;
|
||||||
@ -145,7 +166,7 @@ export class HaMap extends ReactiveElement {
|
|||||||
|
|
||||||
if (changedProps.has("_loaded") || changedProps.has("entities")) {
|
if (changedProps.has("_loaded") || changedProps.has("entities")) {
|
||||||
this._drawEntities();
|
this._drawEntities();
|
||||||
autoFitRequired = true;
|
autoFitRequired = !this._pauseAutoFit;
|
||||||
} else if (this._loaded && oldHass && this.entities) {
|
} else if (this._loaded && oldHass && this.entities) {
|
||||||
// Check if any state has changed
|
// Check if any state has changed
|
||||||
for (const entity of this.entities) {
|
for (const entity of this.entities) {
|
||||||
@ -154,7 +175,7 @@ export class HaMap extends ReactiveElement {
|
|||||||
this.hass!.states[getEntityId(entity)]
|
this.hass!.states[getEntityId(entity)]
|
||||||
) {
|
) {
|
||||||
this._drawEntities();
|
this._drawEntities();
|
||||||
autoFitRequired = true;
|
autoFitRequired = !this._pauseAutoFit;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -178,7 +199,11 @@ export class HaMap extends ReactiveElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (changedProps.has("zoom")) {
|
if (changedProps.has("zoom")) {
|
||||||
|
this._isProgrammaticFit = true;
|
||||||
this.leafletMap!.setZoom(this.zoom);
|
this.leafletMap!.setZoom(this.zoom);
|
||||||
|
setTimeout(() => {
|
||||||
|
this._isProgrammaticFit = false;
|
||||||
|
}, PROGRAMMITIC_FIT_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -234,13 +259,30 @@ export class HaMap extends ReactiveElement {
|
|||||||
}
|
}
|
||||||
this._clickCount++;
|
this._clickCount++;
|
||||||
});
|
});
|
||||||
|
this.leafletMap.on("zoomstart", () => {
|
||||||
|
if (!this._isProgrammaticFit) {
|
||||||
|
this._pauseAutoFit = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.leafletMap.on("movestart", () => {
|
||||||
|
if (!this._isProgrammaticFit) {
|
||||||
|
this._pauseAutoFit = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
this._loaded = true;
|
this._loaded = true;
|
||||||
} finally {
|
} finally {
|
||||||
this._loading = false;
|
this._loading = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public fitMap(options?: { zoom?: number; pad?: number }): void {
|
public fitMap(options?: {
|
||||||
|
zoom?: number;
|
||||||
|
pad?: number;
|
||||||
|
unpause_autofit?: boolean;
|
||||||
|
}): void {
|
||||||
|
if (options?.unpause_autofit) {
|
||||||
|
this._pauseAutoFit = false;
|
||||||
|
}
|
||||||
if (!this.leafletMap || !this.Leaflet || !this.hass) {
|
if (!this.leafletMap || !this.Leaflet || !this.hass) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -250,6 +292,7 @@ export class HaMap extends ReactiveElement {
|
|||||||
!this._mapFocusZones.length &&
|
!this._mapFocusZones.length &&
|
||||||
!this.layers?.length
|
!this.layers?.length
|
||||||
) {
|
) {
|
||||||
|
this._isProgrammaticFit = true;
|
||||||
this.leafletMap.setView(
|
this.leafletMap.setView(
|
||||||
new this.Leaflet.LatLng(
|
new this.Leaflet.LatLng(
|
||||||
this.hass.config.latitude,
|
this.hass.config.latitude,
|
||||||
@ -257,6 +300,9 @@ export class HaMap extends ReactiveElement {
|
|||||||
),
|
),
|
||||||
options?.zoom || this.zoom
|
options?.zoom || this.zoom
|
||||||
);
|
);
|
||||||
|
setTimeout(() => {
|
||||||
|
this._isProgrammaticFit = false;
|
||||||
|
}, PROGRAMMITIC_FIT_DELAY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,8 +323,11 @@ export class HaMap extends ReactiveElement {
|
|||||||
});
|
});
|
||||||
|
|
||||||
bounds = bounds.pad(options?.pad ?? 0.5);
|
bounds = bounds.pad(options?.pad ?? 0.5);
|
||||||
|
this._isProgrammaticFit = true;
|
||||||
this.leafletMap.fitBounds(bounds, { maxZoom: options?.zoom || this.zoom });
|
this.leafletMap.fitBounds(bounds, { maxZoom: options?.zoom || this.zoom });
|
||||||
|
setTimeout(() => {
|
||||||
|
this._isProgrammaticFit = false;
|
||||||
|
}, PROGRAMMITIC_FIT_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public fitBounds(
|
public fitBounds(
|
||||||
@ -291,7 +340,11 @@ export class HaMap extends ReactiveElement {
|
|||||||
const bounds = this.Leaflet.latLngBounds(boundingbox).pad(
|
const bounds = this.Leaflet.latLngBounds(boundingbox).pad(
|
||||||
options?.pad ?? 0.5
|
options?.pad ?? 0.5
|
||||||
);
|
);
|
||||||
|
this._isProgrammaticFit = true;
|
||||||
this.leafletMap.fitBounds(bounds, { maxZoom: options?.zoom || this.zoom });
|
this.leafletMap.fitBounds(bounds, { maxZoom: options?.zoom || this.zoom });
|
||||||
|
setTimeout(() => {
|
||||||
|
this._isProgrammaticFit = false;
|
||||||
|
}, PROGRAMMITIC_FIT_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _drawLayers(prevLayers: Layer[] | undefined): void {
|
private _drawLayers(prevLayers: Layer[] | undefined): void {
|
||||||
|
@ -239,7 +239,7 @@ class HuiMapCard extends LitElement implements LovelaceCard {
|
|||||||
)}
|
)}
|
||||||
.path=${mdiImageFilterCenterFocus}
|
.path=${mdiImageFilterCenterFocus}
|
||||||
style=${isDarkMode ? "color:#ffffff" : "color:#000000"}
|
style=${isDarkMode ? "color:#ffffff" : "color:#000000"}
|
||||||
@click=${this._fitMap}
|
@click=${this._resetFocus}
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
></ha-icon-button>
|
></ha-icon-button>
|
||||||
</div>
|
</div>
|
||||||
@ -389,8 +389,8 @@ class HuiMapCard extends LitElement implements LovelaceCard {
|
|||||||
: (root.style.paddingBottom = "100%");
|
: (root.style.paddingBottom = "100%");
|
||||||
}
|
}
|
||||||
|
|
||||||
private _fitMap() {
|
private _resetFocus() {
|
||||||
this._map?.fitMap();
|
this._map?.fitMap({ unpause_autofit: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
private _toggleClusterMarkers() {
|
private _toggleClusterMarkers() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user