From 1dd437a1f2da765f492efd2e54c0678cf23c68b2 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Tue, 14 Nov 2017 11:32:42 -0500 Subject: [PATCH] Hide mapillary-js attribution and just handle it in iD (closes #4526) What we were doing before was d3.selecting the attribution line and inserting the capture date into it. This was confusing the viewer (which updates asynchronously) so that the sitelink would never update. To make things easier, we'll just hide the viewer's built in attribution and construct the attribution line the way we want it. --- css/60_photos.css | 60 ++++++++++++++--------------- modules/services/mapillary.js | 64 ++++++++++++++++++++++--------- modules/services/openstreetcam.js | 8 ++-- test/spec/services/mapillary.js | 7 ++-- 4 files changed, 83 insertions(+), 56 deletions(-) diff --git a/css/60_photos.css b/css/60_photos.css index 8433eb60d..94f86793b 100644 --- a/css/60_photos.css +++ b/css/60_photos.css @@ -24,25 +24,35 @@ overflow: hidden; } +.photo-wrapper .photo-attribution { + width: 100%; + font-size: 10px; + text-align: right; + position: absolute; + bottom: 0; + right: 0; + padding: 4px 2px; + z-index: 10; +} + +.photo-attribution a, +.photo-attribution a:visited, +.photo-attribution span { + padding: 4px 2px; + color: #fff; +} + /* markers and sequences */ .viewfield-group { pointer-events: visible; cursor: pointer; } -.viewfield-group * { - z-index: 50; -} .viewfield-group.selected * { fill: #ffee00 !important; - z-index: 60; } .viewfield-group.hovered * { fill: #eebb00 !important; - z-index: 70; -} -.viewfield-group.highlighted * { - z-index: 60; } .viewfield-group circle { @@ -162,11 +172,18 @@ top: -25px; } #mly .domRenderer .Attribution { - width: 100%; - font-size: 10px; - text-align: right; + /* we will roll our own to avoid async update issues like #4526 */ + display: none; } +.mly-wrapper .photo-attribution a:active, +.mly-wrapper .photo-attribution a:hover { + color: #35af6d; +} + +.mly-wrapper .mapillary-js-dom { + z-index: 9; +} /* OpenStreetCam viewer */ .osc-wrapper { @@ -177,25 +194,8 @@ background-repeat: no-repeat; } -.osc-wrapper .osc-attribution { - width: 100%; - font-size: 10px; - text-align: right; - position: absolute; - bottom: 0; - right: 0; - padding: 4px 2px; - z-index: 10; -} - -.osc-attribution a, -.osc-attribution a:visited, -.osc-attribution span { - padding: 4px 2px; - color: #fff; -} -.osc-attribution a:active, -.osc-attribution a:hover { +.osc-wrapper .photo-attribution a:active, +.osc-wrapper .photo-attribution a:hover { color: #77ddff; } diff --git a/modules/services/mapillary.js b/modules/services/mapillary.js index b67d02365..cb06b4edd 100644 --- a/modules/services/mapillary.js +++ b/modules/services/mapillary.js @@ -172,6 +172,7 @@ function loadNextTilePage(which, currZoom, url, tile) { key: feature.properties.key, ca: feature.properties.ca, captured_at: feature.properties.captured_at, + captured_by: feature.properties.username, pano: feature.properties.pano }; cache.forImageKey[d.key] = d; // cache imageKey -> image @@ -424,15 +425,21 @@ export default { loadViewer: function(context) { - // add mly-wrapper for viewer-js - d3_select('#photoviewer').selectAll('.mly-wrapper') - .data([0]) - .enter() + // add mly-wrapper + var wrap = d3_select('#photoviewer').selectAll('.mly-wrapper') + .data([0]); + + var wrapEnter = wrap.enter() .append('div') .attr('id', 'mly') .attr('class', 'photo-wrapper mly-wrapper') .classed('hide', true); + wrapEnter + .append('div') + .attr('class', 'photo-attribution fillD'); + + // load mapillary-viewercss d3_select('head').selectAll('#mapillary-viewercss') .data([0]) @@ -586,25 +593,44 @@ export default { }); }); - if (!d) return this; + var wrap = d3_select('#photoviewer .mly-wrapper'); + var attribution = wrap.selectAll('.photo-attribution').html(''); - // if viewer is just starting up, attribution might not be available yet - var attribution = d3_select('.mapillary-js-dom .Attribution'); - var timestamp = localeTimestamp(d.captured_at); - var capturedAt = attribution.selectAll('.captured-at'); - if (capturedAt.empty()) { - capturedAt = attribution - .insert('span', ':last-child') - .attr('class', 'captured-at'); + if (d) { + if (d.captured_by) { + attribution + .append('a') + .attr('class', 'captured_by') + .attr('target', '_blank') + .attr('href', 'https://www.mapillary.com/app/user/' + encodeURIComponent(d.captured_by)) + .text('@' + d.captured_by); + + attribution + .append('span') + .text('|'); + } + + if (d.captured_at) { + attribution + .append('span') + .attr('class', 'captured_at') + .text(localeTimestamp(d.captured_at)); + + attribution + .append('span') + .text('|'); + } attribution - .insert('span', ':last-child') - .text('|'); - } - capturedAt - .text(timestamp); + .append('a') + .attr('class', 'image_link') + .attr('target', '_blank') + .attr('href', 'https://www.mapillary.com/app/?pKey=' + encodeURIComponent(d.key) + + '&focus=photo&lat=' + d.loc[1] + '&lng=' + d.loc[0] + '&z=17') + .text('mapillary.com'); - this.updateDetections(d); + this.updateDetections(d); + } return this; }, diff --git a/modules/services/openstreetcam.js b/modules/services/openstreetcam.js index d0f35a020..fd3f81e09 100644 --- a/modules/services/openstreetcam.js +++ b/modules/services/openstreetcam.js @@ -306,7 +306,7 @@ export default { wrapEnter .append('div') - .attr('class', 'osc-attribution fillD'); + .attr('class', 'photo-attribution fillD'); var controlsEnter = wrapEnter .append('div') @@ -427,14 +427,14 @@ export default { .style('transform', 'rotate(' + r + 'deg)') .attr('src', apibase + '/' + d.imagePath); - var attribution = wrap.selectAll('.osc-attribution').html(''); + var attribution = wrap.selectAll('.photo-attribution').html(''); if (d.captured_by) { attribution .append('a') .attr('class', 'captured_by') .attr('target', '_blank') - .attr('href', apibase + '/user/' + d.captured_by) + .attr('href', 'http://openstreetcam.org/user/' + encodeURIComponent(d.captured_by)) .text('@' + d.captured_by); attribution @@ -457,7 +457,7 @@ export default { .append('a') .attr('class', 'image_link') .attr('target', '_blank') - .attr('href', apibase + '/details/' + d.sequence_id + '/' + d.sequence_index) + .attr('href', 'http://openstreetcam.org/details/' + d.sequence_id + '/' + d.sequence_index) .text('openstreetcam.org'); } return this; diff --git a/test/spec/services/mapillary.js b/test/spec/services/mapillary.js index 8fb7aef15..26d674bc6 100644 --- a/test/spec/services/mapillary.js +++ b/test/spec/services/mapillary.js @@ -66,7 +66,7 @@ describe('iD.serviceMapillary', function() { describe('#reset', function() { it('resets cache and image', function() { mapillary.cache().foo = 'bar'; - mapillary.selectImage({key: 'baz'}); + mapillary.selectImage({ key: 'baz', loc: [10,0] }); mapillary.reset(); expect(mapillary.cache()).to.not.have.property('foo'); @@ -432,8 +432,9 @@ describe('iD.serviceMapillary', function() { describe('#selectImage', function() { it('gets and sets the selected image', function() { - mapillary.selectImage('foo'); - expect(mapillary.getSelectedImage()).to.eql('foo'); + var d = { key: 'baz', loc: [10,0] }; + mapillary.selectImage(d); + expect(mapillary.getSelectedImage()).to.eql(d); }); });