onyx/src/40-handlers.ts

488 lines
No EOL
14 KiB
TypeScript

class MapHandler {
map: L.Map;
overlays: OverlayState;
layers: TileLayerWrapper[];
modals: ModalCollection;
static instance: MapHandler | null = null;
private constructor(map: L.Map, overlays: OverlayState, layers: TileLayerWrapper[], modals: ModalCollection) {
this.map = map;
this.overlays = overlays;
this.layers = layers;
this.modals = modals;
}
static init(map: L.Map, overlays: OverlayState, layers: TileLayerWrapper[], modals: ModalCollection): void {
if (!MapHandler.instance) {
MapHandler.instance = new MapHandler(map, overlays, layers, modals);
}
}
static setButtonClick(btnId: string, handler: any): void {
const button = document.getElementById(btnId);
if (button) {
button.onclick = handler;
}
}
static resetMapClick(): void {
const self = MapHandler.instance;
if (self) {
try {
const addPointBtn = document.getElementById("addPoint-btn");
if (addPointBtn) {
addPointBtn.classList.remove("activeBtn");
}
self.map.off("click", MapHandler.addMarker);
} catch {}
try {
const addCircleBtn = document.getElementById("addCircle-btn");
if (addCircleBtn) {
addCircleBtn.classList.remove("activeBtn");
}
self.map.off("click", MapHandler.addCircle);
} catch {}
try {
const addPolygonBtn = document.getElementById("addPolygon-btn");
if (addPolygonBtn) {
addPolygonBtn.classList.remove("activeBtn");
}
self.map.off("click", MapHandler.polygonAddPoint);
} catch {}
try {
const saveBtn = document.getElementById("save-btn");
if (saveBtn) {
saveBtn.classList.remove("activeBtn");
}
} catch {}
try {
const clearBtn = document.getElementById("clear-btn");
if (clearBtn) {
clearBtn.classList.remove("activeBtn");
}
} catch {}
try {
const resetBtn = document.getElementById("restore-btn");
if (resetBtn) {
resetBtn.classList.remove("activeBtn");
}
} catch {}
try {
const menuBtn = document.getElementById("menu-btn");
if (menuBtn) {
menuBtn.classList.remove("activeBtn");
}
} catch {}
self.overlays.polyline.clearPoints();
}
}
static addMarker(e: any): void {
const self = MapHandler.instance;
if (self) {
self.modals.cancel.setVisible(false);
self.modals.createOverlay.setState(OverlayType.POINT, {
latlng: e.latlng,
map: self.map,
overlays: self.overlays,
});
MapHandler.resetMapClick();
self.modals.createOverlay.setVisible(true);
}
}
static editOverlay(overlay: OverlayBase, type: OverlayType): void {
const self = MapHandler.instance;
if (self) {
self.modals.closeAll();
self.modals.createOverlay.setState(type, {
self: overlay,
map: self.map,
overlays: self.overlays,
});
MapHandler.resetMapClick();
self.modals.createOverlay.setVisible(true);
}
}
static addCircle(e: any): void {
const self = MapHandler.instance;
if (self) {
self.modals.cancel.setVisible(false);
self.modals.createOverlay.setState(OverlayType.CIRCLE, {
latlng: e.latlng,
map: self.map,
overlays: self.overlays,
});
MapHandler.resetMapClick();
self.modals.createOverlay.setVisible(true);
}
}
static addPolygon(e: any): void {
const self = MapHandler.instance;
if (self) {
self.modals.okCancel.setVisible(false);
self.modals.createOverlay.setState(OverlayType.POLYGON, {
points: self.overlays.polyline.points,
map: self.map,
overlays: self.overlays,
});
MapHandler.resetMapClick();
self.overlays.polyline.clearPoints();
self.modals.createOverlay.setVisible(true);
}
}
static circleCollect(e: any): void {
const self = MapHandler.instance;
if (self) {
self.modals.closeAll();
MapHandler.resetMapClick();
(e.target as HTMLElement).classList.add("activeBtn");
self.map.on("click", MapHandler.addCircle);
const cancelBtn = self.modals.cancel.cancelBtn();
if (cancelBtn) {
cancelBtn.onclick = ()=> {
self.modals.closeAll();
MapHandler.resetMapClick();
};
}
self.modals.cancel.setMsg("Placing circle");
self.modals.cancel.setVisible(true);
}
}
static markerCollect(e: any): void {
const self = MapHandler.instance;
if (self) {
self.modals.closeAll();
MapHandler.resetMapClick();
(e.target as HTMLElement).classList.add("activeBtn");
self.map.on("click", MapHandler.addMarker);
const cancelBtn = self.modals.cancel.cancelBtn();
if (cancelBtn) {
cancelBtn.onclick = ()=> {
self.modals.closeAll();
MapHandler.resetMapClick();
};
}
self.modals.cancel.setMsg("Placing marker");
self.modals.cancel.setVisible(true);
}
}
static polygonCollect(e: any): void {
const self = MapHandler.instance;
if (self) {
self.modals.closeAll();
MapHandler.resetMapClick();
(e.target as HTMLElement).classList.add("activeBtn");
// show cancel -- on cancel, clear polyline and reset map handling
const cancelBtn = self.modals.cancel.cancelBtn();
if (cancelBtn) {
cancelBtn.onclick = MapHandler.polygonClearPoints;
}
self.modals.cancel.setMsg("Creating path");
self.modals.cancel.setVisible(true);
self.map.on("click", MapHandler.polygonAddPoint);
}
}
static polygonClearPoints(e: any): void {
const self = MapHandler.instance;
if (self) {
self.modals.closeAll();
self.overlays.polyline.clearPoints();
MapHandler.resetMapClick();
}
}
static polygonAddPoint(e: any): void {
const self = MapHandler.instance;
if (self) {
self.overlays.polyline.insertPoint(e.latlng);
if (self.overlays.polyline.numPoints() >= 3) {
self.modals.cancel.setVisible(false);
const okBtn = self.modals.okCancel.okBtn();
if (okBtn) {
okBtn.onclick = MapHandler.addPolygon;
}
const cancelBtn = self.modals.okCancel.cancelBtn();
if (cancelBtn) {
cancelBtn.onclick = MapHandler.polygonClearPoints;
}
self.modals.okCancel.setMsg("Creating path");
self.modals.okCancel.setVisible(true);
}
}
}
static overlaySave(e: any): void {
const self = MapHandler.instance;
if (self) {
self.modals.closeAll();
MapHandler.resetMapClick();
(e.target as HTMLElement).classList.add("activeBtn");
self.modals.okCancel.setMsg("Save current map overlays?");
const okBtn = self.modals.okCancel.okBtn();
if (okBtn) {
okBtn.onclick = ()=> {
OverlayState.save(self.overlays);
self.modals.okCancel.setVisible(false);
MapHandler.resetMapClick();
self.modals.info.setMsg("Save complete");
self.modals.info.setVisible(true);
}
}
const cancelBtn = self.modals.okCancel.cancelBtn();
if (cancelBtn) {
cancelBtn.onclick = () => {
self.modals.okCancel.setVisible(false);
MapHandler.resetMapClick();
}
}
self.modals.okCancel.setVisible(true);
}
}
static overlayReset(e: any): void {
const self = MapHandler.instance;
if (self) {
self.modals.closeAll();
MapHandler.resetMapClick();
(e.target as HTMLElement).classList.add("activeBtn");
self.modals.okCancel.setMsg("Restore overlays from saved data?");
const okBtn = self.modals.okCancel.okBtn();
if (okBtn) {
okBtn.onclick = ()=> {
self.overlays = OverlayState.clear(self.overlays, self.map);
self.overlays = OverlayState.load();
self.overlays.markers.forEach(m=>m.add(self.map));
self.overlays.circles.forEach(m=>m.add(self.map));
self.overlays.paths.forEach(m=>m.add(self.map));
self.overlays.polyline.add(self.map);
self.modals.okCancel.setVisible(false);
MapHandler.resetMapClick();
self.modals.info.setMsg("Restored");
self.modals.info.setVisible(true);
}
}
const cancelBtn = self.modals.okCancel.cancelBtn();
if (cancelBtn) {
cancelBtn.onclick = () => {
self.modals.okCancel.setVisible(false);
MapHandler.resetMapClick();
}
}
self.modals.okCancel.setVisible(true);
}
}
static overlayClear(e: any): void {
const self = MapHandler.instance;
if (self) {
self.modals.closeAll();
MapHandler.resetMapClick();
(e.target as HTMLElement).classList.add("activeBtn");
self.modals.okCancel.setMsg("Clear all map overlays (will not affect saved data)?");
const okBtn = self.modals.okCancel.okBtn();
if (okBtn) {
okBtn.onclick = ()=> {
self.overlays = OverlayState.clear(self.overlays, self.map);
MapHandler.resetMapClick();
self.modals.okCancel.setVisible(false);
}
}
const cancelBtn = self.modals.okCancel.cancelBtn();
if (cancelBtn) {
cancelBtn.onclick = () => {
MapHandler.resetMapClick();
self.modals.okCancel.setVisible(false);
}
}
self.modals.okCancel.setVisible(true);
}
}
static swapTiles(e: any): void {
const self = MapHandler.instance;
if (self) {
if (TileLayerWrapper.getActiveLayer() == "satelliteLayer") {
TileLayerWrapper.enableOnly("streetLayer", self.map);
} else {
TileLayerWrapper.enableOnly("satelliteLayer", self.map);
}
}
}
static setHome(e: any): void {
const self = MapHandler.instance;
if (self) {
self.modals.closeAll();
const okCancel = self.modals.okCancel;
okCancel.setMsg("Set Home to current coordinates?");
const okBtn = okCancel.okBtn();
if (okBtn) {
okBtn.onclick = (e: any) => {
okCancel.setVisible(false);
localStorage.setItem("home", JSON.stringify(self.map.getCenter() as Point));
const info = self.modals.info;
info.setMsg("Home coordinates set");
info.setVisible(true);
}
}
const cancelBtn = okCancel.cancelBtn();
if (cancelBtn) {
cancelBtn.onclick = () => {
okCancel.setVisible(false);
}
}
okCancel.setVisible(true);
}
}
static goHome(e: any): void {
const self = MapHandler.instance;
if (self) {
const homeData = localStorage.getItem("home");
if (homeData) {
const home = <Point>JSON.parse(homeData);
if (home) {
self.map.setView(home, 13);
}
}
}
}
static toggleMenu(e: any): void {
const self = MapHandler.instance;
if (self) {
const visible = self.modals.overlayMgr.visible();
self.modals.closeAll();
MapHandler.resetMapClick();
self.modals.overlayMgr.setVisible(!visible);
if (!visible) {
(e.target as HTMLElement).classList.add("activeBtn");
}
}
}
static confirmDelete(overlay: OverlayBase): void {
const self = MapHandler.instance;
if (self) {
self.modals.closeAll();
self.modals.okCancel.setMsg(`Delete "${overlay.name}"?`);
const okBtn = self.modals.okCancel.okBtn();
if (okBtn) {
okBtn.onclick = () => {
self.modals.closeAll();
overlay.remove(self.map);
self.modals.info.setMsg(`"${overlay.name}" deleted`);
self.modals.info.setVisible(true);
}
}
const cancelBtn = self.modals.okCancel.cancelBtn();
if (cancelBtn) {
cancelBtn.onclick = () => {
self.modals.closeAll();
}
}
self.modals.okCancel.setVisible(true);
}
}
static exportSingle(overlay: OverlayBase): void {
const self = MapHandler.instance;
if (self) {
self.modals.closeAll();
self.modals.importExport.setTitle("Export Overlay");
self.modals.importExport.setErrMsg("", false);
const okBtn = self.modals.importExport.okBtn();
if (okBtn) {
okBtn.innerText = "Copy to clipboard";
okBtn.onclick = () => {
self.modals.importExport.copyTextArea();
self.modals.closeAll();
self.modals.info.setMsg("Copied the data to the clipboard");
self.modals.info.setVisible(true);
}
}
self.modals.importExport.setTextArea(OverlayState.exportSingle(overlay), true);
self.modals.importExport.setVisible(true);
}
}
static exportAll(): void {
const self = MapHandler.instance;
if (self) {
self.modals.closeAll();
self.modals.importExport.setTitle("Export All Overlays");
self.modals.importExport.setErrMsg("", false);
const okBtn = self.modals.importExport.okBtn();
if (okBtn) {
okBtn.innerText = "Copy to clipboard";
okBtn.onclick = () => {
self.modals.importExport.copyTextArea();
self.modals.closeAll();
self.modals.info.setMsg("Copied the data to the clipboard");
self.modals.info.setVisible(true);
}
}
self.modals.importExport.setTextArea(OverlayState.export(self.overlays), true);
self.modals.importExport.setVisible(true);
}
}
static import(): void {
const self = MapHandler.instance;
if (self) {
self.modals.closeAll();
self.modals.importExport.setTitle("Import Overlay Data");
self.modals.importExport.setErrMsg("", false);
self.modals.importExport.setTextArea("", false);
const okBtn = self.modals.importExport.okBtn();
if (okBtn) {
okBtn.innerText = "Import";
okBtn.onclick = () => {
MapHandler.doImport(self.modals.importExport.getText());
}
}
self.modals.importExport.setVisible(true);
}
}
static doImport(data: string): void {
const self = MapHandler.instance;
if (self) {
if (OverlayState.importWrapper(data, self.overlays, self.map)) {
self.modals.closeAll();
self.modals.info.setMsg("Import successful");
self.modals.info.setVisible(true);
} else {
self.modals.importExport.setErrMsg("The data was malformed &mdash; please check that it is valid JSON exported from ONYX/scry", true);
}
}
}
static closeImportExport(): void {
const self = MapHandler.instance;
if (self) {
self.modals.closeAll();
}
}
}