@panoramax/web-viewer
Version:
Panoramax web viewer for geolocated pictures
156 lines (141 loc) • 4.43 kB
JavaScript
import { LitElement, html, nothing, css } from "lit";
import { fa, onceParentAvailable } from "../../../utils/widgets";
import { josmBboxParameters } from "../../../utils/utils";
import { IdEditorURL } from "../../../utils/services";
import { faLocationDot } from "@fortawesome/free-solid-svg-icons/faLocationDot";
import { faSatelliteDish } from "@fortawesome/free-solid-svg-icons/faSatelliteDish";
import { faExternalLinkAlt } from "@fortawesome/free-solid-svg-icons/faExternalLinkAlt";
const JOSM_REMOTE_URL = "http://127.0.0.1:8111";
/**
* OSM Editors component offers direct links to OpenStreetMap's iD and JOSM editors.
* @class Panoramax.components.ui.widgets.OSMEditors
* @element pnx-widget-osmeditors
* @extends [lit.LitElement](https://lit.dev/docs/api/LitElement/)
* @example
* ```html
* <pnx-widget-osmeditors _parent=${viewer} />
* ```
*/
export default class OSMEditors extends LitElement {
/** @private */
static properties = {
_pic: {state: true},
_josm: {state: true},
};
/** @private */
static styles = css`
:host { display: inline-flex; gap: 5px; }
:host > * { flex: 1; }
pnx-link-button::part(btn) { height: auto; }
`;
constructor() {
super();
this._josm = false;
}
/** @private */
connectedCallback() {
super.connectedCallback();
onceParentAvailable(this).then(() => this._parent.onceReady()).then(() => {
this._parent.onceFirstPicLoaded().then(this._onPictureLoad.bind(this));
this._parent.psv.addEventListener("picture-loaded", this._onPictureLoad.bind(this));
});
}
/** @private */
_onPictureLoad() {
this._pic = this._parent?.psv?.getPictureMetadata();
}
/**
* Enable or disable JOSM live editing using [Remote](https://josm.openstreetmap.de/wiki/Help/RemoteControlCommands)
* @private
*/
_toggleJOSMLive() {
this._josm = !this._josm;
if(this._josm) {
// Check if JOSM remote is enabled
fetch(JOSM_REMOTE_URL+"/version")
.then(() => {
// First loading : download + zoom
const p1 = josmBboxParameters(this._parent?.psv?.getPictureMetadata?.());
if(p1) {
const url = `${JOSM_REMOTE_URL}/load_and_zoom?${p1}`;
fetch(url).catch(e => {
console.warn(e);
this._toggleJOSMLive();
});
}
// Enable event listening
this._josmListener = () => {
const p2 = josmBboxParameters(this._parent?.psv?.getPictureMetadata?.());
if(p2) {
// Next loadings : just zoom
// This avoids desktop focus to go on JOSM instead of
// staying on web browser
const url = `${JOSM_REMOTE_URL}/zoom?${p2}`;
fetch(url).catch(e => {
console.warn(e);
this._toggleJOSMLive();
});
}
};
this._parent?.psv?.addEventListener?.("picture-loaded", this._josmListener);
this._parent?.psv?.addEventListener?.("picture-loading", this._josmListener);
})
.catch(e => {
console.warn(e);
alert(this._parent?._t.pnx.error_josm);
this._toggleJOSMLive();
});
}
else {
if(this._josmListener) {
this._parent?.psv?.removeEventListener?.("picture-loading", this._josmListener);
this._parent?.psv?.removeEventListener?.("picture-loaded", this._josmListener);
delete this._josmListener;
}
}
}
/** @private */
render() {
if(!this._pic) { return nothing; }
// Mobile -> Geo URI
if(this._parent?.isWidthSmall()) {
return html`
<pnx-link-button
size="sm"
href="geo:${this._pic.gps[1]},${this._pic.gps[0]};u=3"
>
${fa(faExternalLinkAlt)} ${this._parent?._t.pnx.geo_uri}
</pnx-link-button>
`;
}
else {
const idOpts = {
"map": `19/${this._pic.gps[1]}/${this._pic.gps[0]}`,
"source": "Panoramax",
"photo_overlay": "panoramax",
"photo": `panoramax/${this._pic.id}`,
};
const idUrl = idOpts && `${IdEditorURL()}#${new URLSearchParams(idOpts).toString()}`;
return html`
<pnx-link-button
size="sm"
href=${idUrl}
target="_blank"
title="${this._parent?._t.pnx.contribute_id}"
>
${fa(faLocationDot)} ${this._parent?._t.pnx.id}
</pnx-link-button>
<pnx-button
id="pnx-edit-josm"
size="sm"
active=${this._josm ? "" : nothing}
=${this._toggleJOSMLive}
title="${this._parent?._t.pnx.josm_live}"
>
${fa(faSatelliteDish)} ${this._parent?._t.pnx.josm}
</pnx-button>
`;
}
}
}
customElements.define("pnx-widget-osmeditors", OSMEditors);