diff --git a/css/60_photos.css b/css/60_photos.css index 1368ad40f..71d9efa3a 100644 --- a/css/60_photos.css +++ b/css/60_photos.css @@ -76,6 +76,18 @@ width: 100%; } +.photoviewer .error-handler { + border-radius: 0; + padding: 15px; + position: absolute; + left: 50%; + top: 75px; + transform: translate(-50%, -50%); + z-index: 50; + color: red; + font-size: 20px; +} + .photo-wrapper { width: 100%; diff --git a/data/core.yaml b/data/core.yaml index 9db7df56a..a751f855b 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -789,6 +789,7 @@ en: set_photo_from_viewer: "Store this photo on the currently selected map object" set_photo_from_field: "Use the currently displayed photo" show_photo_from_field: "Open image in viewer" + show_photo_from_field_error: "Invalid ID" background: title: Background description: Background Settings diff --git a/modules/services/mapillary.js b/modules/services/mapillary.js index fb64e1eab..b8e46004f 100644 --- a/modules/services/mapillary.js +++ b/modules/services/mapillary.js @@ -19,7 +19,7 @@ const trafficSignTileUrl = `${baseTileUrl}/mly_map_feature_traffic_sign/2/{z}/{x const viewercss = 'mapillary-js/mapillary.css'; const viewerjs = 'mapillary-js/mapillary.js'; const minZoom = 14; -const dispatch = d3_dispatch('change', 'loadedImages', 'loadedSigns', 'loadedMapFeatures', 'bearingChanged', 'imageChanged'); +const dispatch = d3_dispatch('change', 'loadedImages', 'loadedSigns', 'loadedMapFeatures', 'bearingChanged', 'imageChanged', 'error'); let _loadViewerPromise; let _mlyActiveImage; @@ -606,6 +606,7 @@ export default { _mlyViewer.moveTo(imageId) .catch(function(e) { console.error('mly3', e); // eslint-disable-line no-console + dispatch.call('error', undefined, e); }); } diff --git a/modules/ui/fields/input.js b/modules/ui/fields/input.js index cc09b8d80..d5157a7aa 100644 --- a/modules/ui/fields/input.js +++ b/modules/ui/fields/input.js @@ -384,7 +384,7 @@ export function uiFieldText(field, context) { utilGetSetValue(input, image.id); change()(); }); - mapillarySetButton.node().blur(); + mapillarySetButton.node()?.blur(); }) .merge(mapillarySetButton) .classed('disabled', _debounce(() => { @@ -412,13 +412,13 @@ export function uiFieldText(field, context) { if (isHidden) { if (!utilGetSetValue(input).trim()) return; + service .ensureViewerLoaded(context) .then(function() { service - .showViewer(context) .selectImage(context, utilGetSetValue(input).trim()) - .initViewer(context); + .showViewer(context); }); } else { if (!utilGetSetValue(input).trim()) return; @@ -430,11 +430,10 @@ export function uiFieldText(field, context) { .ensureViewerLoaded(context) .then(function() { service - .selectImage(context, utilGetSetValue(input).trim()) - .initViewer(context); + .selectImage(context, utilGetSetValue(input).trim()); }); } - mapillaryViewButton.node().blur(); + mapillaryViewButton.node()?.blur(); }) .merge(mapillaryViewButton) .classed('disabled', _debounce(() => { diff --git a/modules/ui/photoviewer.js b/modules/ui/photoviewer.js index d72baa4b6..1f523adc5 100644 --- a/modules/ui/photoviewer.js +++ b/modules/ui/photoviewer.js @@ -143,6 +143,24 @@ export function uiPhotoviewer(context) { } } + // error message handler + const errorHandler = selection + .append('div') + .attr('class', 'error-handler') + .append('div') + .style('opacity', '0'); + + + services.mapillary + .on('error', function(e) { + errorHandler + .text(t('inspector.show_photo_from_field_error')) + .style('opacity', '1') + .transition() + .duration(1000) + .style('opacity', '0'); + }); + function buildResizeListener(target, eventName, dispatch, options) { var resizeOnX = !!options.resizeOnX;