diff --git a/css/60_photos.css b/css/60_photos.css index 7213ee728..63173726d 100644 --- a/css/60_photos.css +++ b/css/60_photos.css @@ -113,46 +113,6 @@ stroke-opacity: 1; } -/* Notes Layer */ -.layer-notes { - pointer-events: none; -} -.layer-notes * { - pointer-events: visible; - cursor: pointer; -} -.layer-notes .note-shadow { - color: #000; -} -.layer-notes .note-fill { - color: #ee3; -} - - -/* TODO: possibly move this note detail .css to another file */ - -.comment-first { - background-color:#ddd; - border-radius: 5px; - padding: 5px; - margin: 5px auto; -} - -.comment { - background-color:#fff; - border-radius: 5px; - padding: 5px; - margin: 5px auto; -} - -.commentCreator { - color: #666; -} - -.commentText { - margin: 20px auto; -} - /* Streetside Image Layer */ .layer-streetside-images { diff --git a/css/65_data.css b/css/65_data.css new file mode 100644 index 000000000..b66b48c11 --- /dev/null +++ b/css/65_data.css @@ -0,0 +1,45 @@ + +/* OSM Notes Layer */ +.layer-notes { + pointer-events: none; +} +.layer-notes * { + pointer-events: visible; + cursor: pointer; +} + +.layer-notes .note .note-shadow { + color: #000; +} +.layer-notes .note .note-fill { + color: #ff3300; +} +.layer-notes .note.closed .note-fill { + color: #00bb33; +} +.layer-notes .note.hovered .note-fill { + color: #eebb00; +} +.layer-notes .note.selected .note-fill { + color: #ffee00; +} + +/* OSM Note UI */ +.comment-first { + background-color: #ddd; + border-radius: 5px; + padding: 5px; + margin: 5px auto; +} +.comment { + background-color: #fff; + border-radius: 5px; + padding: 5px; + margin: 5px auto; +} +.commentCreator { + color: #666; +} +.commentText { + margin: 20px auto; +} diff --git a/modules/services/osm.js b/modules/services/osm.js index 87af1beb5..037d23003 100644 --- a/modules/services/osm.js +++ b/modules/services/osm.js @@ -665,7 +665,7 @@ export default { s / 2 - projection.translate()[1] ]; - // what tiles cover the view + // what tiles cover the view? var tiler = d3_geoTile() .scaleExtent([tilezoom, tilezoom]) .scale(s) @@ -685,6 +685,8 @@ export default { }; }); + // remove inflight requests that no longer cover the view.. + var hadRequests = !_isEmpty(cache.inflight); _filter(cache.inflight, function(v, i) { var wanted = _find(tiles, function(tile) { return i === tile.id; }); if (!wanted) { @@ -693,12 +695,16 @@ export default { return !wanted; }).map(abortRequest); + if (hadRequests && !loadingNotes && _isEmpty(cache.inflight)) { + dispatch.call('loaded'); // stop the spinner + } + // issue new requests.. tiles.forEach(function(tile) { var id = tile.id; if (cache.loaded[id] || cache.inflight[id]) return; if (!loadingNotes && _isEmpty(cache.inflight)) { - dispatch.call('loading'); // start the spinner + dispatch.call('loading'); // start the spinner } cache.inflight[id] = that.loadFromAPI( @@ -717,7 +723,7 @@ export default { callback(err, _extend({ data: parsed }, tile)); } if (_isEmpty(cache.inflight)) { - dispatch.call('loaded'); // stop the spinner + dispatch.call('loaded'); // stop the spinner } } diff --git a/modules/svg/notes.js b/modules/svg/notes.js index ce869ddab..f0f77dcee 100644 --- a/modules/svg/notes.js +++ b/modules/svg/notes.js @@ -62,21 +62,36 @@ export function svgNotes(projection, context, dispatch) { .on('end', editOff); } - function click(d) { - _selected = d; - context.ui().sidebar.show(noteEditor, d); + + function click(which) { + _selected = which; + context.map().centerEase(which.loc); + + layer.selectAll('.note') + .classed('selected', function(d) { return d === _selected; }); + + context.ui().sidebar.show(noteEditor, which); } - function mouseover(d) { - context.ui().sidebar.show(noteEditor, d); + + function mouseover(which) { + layer.selectAll('.note') + .classed('hovered', function(d) { return d === which; }); + + context.ui().sidebar.show(noteEditor, which); } - function mouseout(d) { + + function mouseout() { + layer.selectAll('.note') + .classed('hovered', false); + // TODO: check if the item was clicked. If so, it should remain on the sidebar. // TODO: handle multi-clicks. Otherwise, utilize behavior/select.js context.ui().sidebar.hide(); } + function update() { var service = getService(); var data = (service ? service.notes(projection) : []); @@ -88,9 +103,10 @@ export function svgNotes(projection, context, dispatch) { notes.exit() .remove(); + // enter var notesEnter = notes.enter() .append('g') - .attr('class', function(d) { return 'note note-' + d.id; }) + .attr('class', function(d) { return 'note note-' + d.id + ' ' + d.status; }) .on('click', click) .on('mouseover', mouseover) .on('mouseout', mouseout); @@ -102,7 +118,7 @@ export function svgNotes(projection, context, dispatch) { .attr('height', '24px') .attr('x', '-12px') .attr('y', '-24px') - .attr('xlink:href', '#fas-comment-alt') + .attr('xlink:href', '#fas-comment-alt'); notesEnter .append('use') @@ -111,8 +127,9 @@ export function svgNotes(projection, context, dispatch) { .attr('height', '20px') .attr('x', '-10px') .attr('y', '-22px') - .attr('xlink:href', '#fas-comment-alt') + .attr('xlink:href', '#fas-comment-alt'); + // update notes .merge(notesEnter) .sort(function(a, b) { @@ -120,9 +137,11 @@ export function svgNotes(projection, context, dispatch) { : (b === _selected) ? -1 : b.loc[1] - a.loc[1]; // sort Y }) + .classed('selected', function(d) { return d === _selected; }) .attr('transform', transform); } + function drawNotes(selection) { var enabled = svgNotes.enabled; var service = getService();