Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | 3x 3x 3x 3x 3x 3x 3x 3x 3x 1x 1x 1x | import { Inject, Injectable, InjectionToken } from '@angular/core';
import { Loader } from '@googlemaps/js-api-loader';
import { Store, select } from '@ngrx/store';
import { InjectSingle } from 'ish-core/utils/injection';
import { StoreLocationHelper } from '../../models/store-location/store-location.helper';
import { StoreLocation } from '../../models/store-location/store-location.model';
import { getGMAKey } from '../../store/store-locator-config';
import { getHighlightedStore, getStores, highlightStore } from '../../store/stores';
type IconConfiguration = { default: string; highlight: string };
export const STORE_MAP_ICON_CONFIGURATION = new InjectionToken<IconConfiguration>('Store Map Icon Configuration');
@Injectable({ providedIn: 'root' })
export class StoresMapService {
private map: google.maps.Map;
private infoWindow: google.maps.InfoWindow;
// eslint-disable-next-line etc/no-deprecated
private entries: { store: StoreLocation; marker: google.maps.Marker }[] = [];
constructor(
private store: Store,
@Inject(STORE_MAP_ICON_CONFIGURATION) private icons: InjectSingle<typeof STORE_MAP_ICON_CONFIGURATION>
) {}
initialize(container: HTMLElement) {
this.store.pipe(select(getGMAKey)).subscribe((gmaKey: string) => {
this.initializeMap(container, gmaKey);
});
}
private initializeMap(container: HTMLElement, gmaKey: string) {
const loader = new Loader({
apiKey: gmaKey,
version: 'weekly',
});
// eslint-disable-next-line @typescript-eslint/naming-convention
loader.importLibrary('maps').then(({ Map }) => {
this.map = new Map(container, {
center: { lat: 0, lng: 0 },
zoom: 2,
minZoom: 2,
mapTypeId: 'roadmap',
fullscreenControl: false,
streetViewControl: false,
});
this.infoWindow = new google.maps.InfoWindow();
this.store.pipe(select(getStores)).subscribe(stores => {
this.placeMarkers(stores.filter(store => store.longitude && store.latitude));
});
this.store.pipe(select(getHighlightedStore)).subscribe(data => {
this.highlightMarkers(data);
});
});
}
private placeMarkers(stores: StoreLocation[]) {
this.entries.forEach(entry => {
entry.marker.setMap(undefined);
});
this.entries = [];
const bounds = new google.maps.LatLngBounds();
stores.forEach(store => {
// eslint-disable-next-line etc/no-deprecated
const marker = new google.maps.Marker({
map: this.map,
position: { lat: store.latitude, lng: store.longitude },
icon: this.icons?.default,
});
bounds.extend(marker.getPosition());
marker.addListener('click', () => {
this.store.dispatch(highlightStore({ storeId: store.id }));
});
this.entries.push({ store, marker });
});
this.map.fitBounds(bounds);
}
private highlightMarkers(store: StoreLocation) {
this.entries.forEach(entry => {
if (StoreLocationHelper.equal(entry.store, store)) {
entry.marker.setIcon(this.icons?.highlight);
entry.marker.setZIndex(1);
this.map.panTo(entry.marker.getPosition());
this.infoWindow.close();
this.infoWindow.setContent(entry.store.name);
this.infoWindow.open({
map: this.map,
anchor: entry.marker,
});
} else {
entry.marker.setIcon(this.icons?.default);
entry.marker.setZIndex(0);
}
});
}
}
|