mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-13 01:02:58 +00:00
updated: siebar displays note details on hover (via svg)
This commit is contained in:
@@ -118,10 +118,37 @@
|
||||
pointer-events: none;
|
||||
}
|
||||
.layer-notes * {
|
||||
pointer-events: visible;
|
||||
cursor: pointer;
|
||||
color: #eebb00;
|
||||
}
|
||||
|
||||
|
||||
/* 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 {
|
||||
pointer-events: none;
|
||||
|
||||
@@ -609,6 +609,19 @@ en:
|
||||
title: "Photo Overlay (OpenStreetCam)"
|
||||
openstreetcam:
|
||||
view_on_openstreetcam: "View this image on OpenStreetCam"
|
||||
note:
|
||||
title: "Edit note"
|
||||
unresolved: "Unresolved note #"
|
||||
description: "Description"
|
||||
creator: "Comment from"
|
||||
anonymous: 'anonymous'
|
||||
creatorOn: 'on'
|
||||
commentTitle: 'Comments'
|
||||
resolve: "Resolve"
|
||||
comment: "Comment"
|
||||
commentResolve: "Comment & Resolve"
|
||||
save: "Save new note"
|
||||
cancel: "Cancel"
|
||||
help:
|
||||
title: Help
|
||||
key: H
|
||||
|
||||
14
dist/locales/en.json
vendored
14
dist/locales/en.json
vendored
@@ -742,6 +742,20 @@
|
||||
"openstreetcam": {
|
||||
"view_on_openstreetcam": "View this image on OpenStreetCam"
|
||||
},
|
||||
"note": {
|
||||
"title": "Edit note",
|
||||
"unresolved": "Unresolved note #",
|
||||
"description": "Description",
|
||||
"creator": "Comment from",
|
||||
"anonymous": "anonymous",
|
||||
"creatorOn": "on",
|
||||
"commentTitle": "Comments",
|
||||
"resolve": "Resolve",
|
||||
"comment": "Comment",
|
||||
"commentResolve": "Comment & Resolve",
|
||||
"save": "Save new note",
|
||||
"cancel": "Cancel"
|
||||
},
|
||||
"help": {
|
||||
"title": "Help",
|
||||
"key": "H",
|
||||
|
||||
225
modules/behavior/TAH_select.js
Normal file
225
modules/behavior/TAH_select.js
Normal file
@@ -0,0 +1,225 @@
|
||||
import _without from 'lodash-es/without';
|
||||
|
||||
import {
|
||||
event as d3_event,
|
||||
mouse as d3_mouse,
|
||||
select as d3_select
|
||||
} from 'd3-selection';
|
||||
|
||||
import { geoVecLength } from '../geo';
|
||||
|
||||
import {
|
||||
modeBrowse,
|
||||
modeSelect
|
||||
} from '../modes';
|
||||
|
||||
import {
|
||||
osmEntity,
|
||||
osmNote
|
||||
} from '../osm';
|
||||
|
||||
|
||||
export function behaviorSelect(context) {
|
||||
var lastMouse = null;
|
||||
var suppressMenu = true;
|
||||
var tolerance = 4;
|
||||
var p1 = null;
|
||||
|
||||
|
||||
function point() {
|
||||
return d3_mouse(context.container().node());
|
||||
}
|
||||
|
||||
|
||||
function keydown() {
|
||||
var e = d3_event;
|
||||
if (e && e.shiftKey) {
|
||||
context.surface()
|
||||
.classed('behavior-multiselect', true);
|
||||
}
|
||||
|
||||
if (e && e.keyCode === 93) { // context menu
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function keyup() {
|
||||
var e = d3_event;
|
||||
if (!e || !e.shiftKey) {
|
||||
context.surface()
|
||||
.classed('behavior-multiselect', false);
|
||||
}
|
||||
|
||||
|
||||
if (e && e.keyCode === 93) { // context menu
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
contextmenu();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function mousedown() {
|
||||
if (!p1) p1 = point();
|
||||
d3_select(window)
|
||||
.on('mouseup.select', mouseup, true);
|
||||
|
||||
var isShowAlways = +context.storage('edit-menu-show-always') === 1;
|
||||
suppressMenu = !isShowAlways;
|
||||
}
|
||||
|
||||
|
||||
function mousemove() {
|
||||
if (d3_event) lastMouse = d3_event;
|
||||
}
|
||||
|
||||
|
||||
function mouseup() {
|
||||
click();
|
||||
}
|
||||
|
||||
|
||||
function contextmenu() {
|
||||
var e = d3_event;
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
if (!+e.clientX && !+e.clientY) {
|
||||
if (lastMouse) {
|
||||
e.sourceEvent = lastMouse;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!p1) p1 = point();
|
||||
suppressMenu = false;
|
||||
click();
|
||||
}
|
||||
|
||||
|
||||
function click() {
|
||||
d3_select(window)
|
||||
.on('mouseup.select', null, true);
|
||||
|
||||
if (!p1) return;
|
||||
var p2 = point();
|
||||
var dist = geoVecLength(p1, p2);
|
||||
|
||||
p1 = null;
|
||||
if (dist > tolerance) {
|
||||
return;
|
||||
}
|
||||
|
||||
var isMultiselect = d3_event.shiftKey || d3_select('#surface .lasso').node();
|
||||
var isShowAlways = +context.storage('edit-menu-show-always') === 1;
|
||||
var datum = d3_event.target.__data__ || (lastMouse && lastMouse.target.__data__);
|
||||
var mode = context.mode();
|
||||
|
||||
var entity;
|
||||
if (datum instanceof osmNote) {
|
||||
entity = datum;
|
||||
} else {
|
||||
entity = datum && datum.properties && datum.properties.entity;
|
||||
}
|
||||
if (entity) datum = entity;
|
||||
|
||||
if (datum && datum.type === 'midpoint') {
|
||||
datum = datum.parents[0];
|
||||
}
|
||||
|
||||
if (!(datum instanceof osmEntity) && !(datum instanceof osmNote)) {
|
||||
// clicked nothing..
|
||||
if (!isMultiselect && mode.id !== 'browse') {
|
||||
context.enter(modeBrowse(context));
|
||||
}
|
||||
|
||||
} else {
|
||||
// clicked an entity.. (or a notes)
|
||||
var selectedIDs = context.selectedIDs();
|
||||
|
||||
if (!isMultiselect) {
|
||||
if (selectedIDs.length > 1 && (!suppressMenu && !isShowAlways)) {
|
||||
// multiple things already selected, just show the menu...
|
||||
mode.suppressMenu(false).reselect();
|
||||
} else {
|
||||
// select a single thing..
|
||||
context.enter(modeSelect(context, [datum.id]).suppressMenu(suppressMenu));
|
||||
}
|
||||
|
||||
} else {
|
||||
if (selectedIDs.indexOf(datum.id) !== -1) {
|
||||
// clicked entity is already in the selectedIDs list..
|
||||
if (!suppressMenu && !isShowAlways) {
|
||||
// don't deselect clicked entity, just show the menu.
|
||||
mode.suppressMenu(false).reselect();
|
||||
} else {
|
||||
// deselect clicked entity, then reenter select mode or return to browse mode..
|
||||
selectedIDs = _without(selectedIDs, datum.id);
|
||||
context.enter(selectedIDs.length ? modeSelect(context, selectedIDs) : modeBrowse(context));
|
||||
}
|
||||
} else {
|
||||
// clicked entity is not in the selected list, add it..
|
||||
selectedIDs = selectedIDs.concat([datum.id]);
|
||||
context.enter(modeSelect(context, selectedIDs).suppressMenu(suppressMenu));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// reset for next time..
|
||||
suppressMenu = true;
|
||||
}
|
||||
|
||||
|
||||
var behavior = function(selection) {
|
||||
lastMouse = null;
|
||||
suppressMenu = true;
|
||||
p1 = null;
|
||||
|
||||
d3_select(window)
|
||||
.on('keydown.select', keydown)
|
||||
.on('keyup.select', keyup)
|
||||
.on('contextmenu.select-window', function() {
|
||||
// Edge and IE really like to show the contextmenu on the
|
||||
// menubar when user presses a keyboard menu button
|
||||
// even after we've already preventdefaulted the key event.
|
||||
var e = d3_event;
|
||||
if (+e.clientX === 0 && +e.clientY === 0) {
|
||||
d3_event.preventDefault();
|
||||
d3_event.stopPropagation();
|
||||
}
|
||||
});
|
||||
|
||||
selection
|
||||
.on('mousedown.select', mousedown)
|
||||
.on('mousemove.select', mousemove)
|
||||
.on('contextmenu.select', contextmenu);
|
||||
|
||||
if (d3_event && d3_event.shiftKey) {
|
||||
context.surface()
|
||||
.classed('behavior-multiselect', true);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
behavior.off = function(selection) {
|
||||
d3_select(window)
|
||||
.on('keydown.select', null)
|
||||
.on('keyup.select', null)
|
||||
.on('contextmenu.select-window', null)
|
||||
.on('mouseup.select', null, true);
|
||||
|
||||
selection
|
||||
.on('mousedown.select', null)
|
||||
.on('mousemove.select', null)
|
||||
.on('contextmenu.select', null);
|
||||
|
||||
context.surface()
|
||||
.classed('behavior-multiselect', false);
|
||||
};
|
||||
|
||||
|
||||
return behavior;
|
||||
}
|
||||
@@ -6,7 +6,10 @@ import {
|
||||
} from 'd3-selection';
|
||||
|
||||
import { d3keybinding as d3_keybinding } from '../lib/d3.keybinding.js';
|
||||
import { osmEntity } from '../osm';
|
||||
import {
|
||||
osmEntity,
|
||||
osmNote
|
||||
} from '../osm';
|
||||
import { utilRebind } from '../util/rebind';
|
||||
|
||||
|
||||
@@ -110,7 +113,12 @@ export function behaviorHover(context) {
|
||||
var entity;
|
||||
if (datum instanceof osmEntity) {
|
||||
entity = datum;
|
||||
} else {
|
||||
}
|
||||
// TODO: TAH - reintroduce if we need a check for osmNote here
|
||||
// else if (datum instanceof osmNote) {
|
||||
// entity = datum;
|
||||
// }
|
||||
else {
|
||||
entity = datum && datum.properties && datum.properties.entity;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,32 +3,72 @@ import _extend from 'lodash-es/extend';
|
||||
import { osmEntity } from './entity';
|
||||
import { geoExtent } from '../geo';
|
||||
|
||||
import { debug } from '../index';
|
||||
|
||||
|
||||
export function osmNote() {
|
||||
if (!(this instanceof osmNote)) {
|
||||
return (new osmNote()).initialize(arguments);
|
||||
} else if (arguments.length) {
|
||||
this.initialize(arguments);
|
||||
}
|
||||
if (!(this instanceof osmNote)) return;
|
||||
|
||||
this.initialize(arguments);
|
||||
return this;
|
||||
}
|
||||
|
||||
osmEntity.note = osmNote;
|
||||
|
||||
osmNote.prototype = Object.create(osmEntity.prototype);
|
||||
|
||||
_extend(osmNote.prototype, {
|
||||
|
||||
type: 'note',
|
||||
|
||||
initialize: function(sources) {
|
||||
for (var i = 0; i < sources.length; ++i) {
|
||||
var source = sources[i];
|
||||
for (var prop in source) {
|
||||
if (Object.prototype.hasOwnProperty.call(source, prop)) {
|
||||
if (source[prop] === undefined) {
|
||||
delete this[prop];
|
||||
} else {
|
||||
this[prop] = source[prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.id && this.type) {
|
||||
this.id = osmEntity.id(this.type);
|
||||
}
|
||||
if (!this.hasOwnProperty('visible')) {
|
||||
this.visible = true;
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
Object.freeze(this);
|
||||
Object.freeze(this.tags);
|
||||
|
||||
if (this.loc) Object.freeze(this.loc);
|
||||
if (this.nodes) Object.freeze(this.nodes);
|
||||
if (this.members) Object.freeze(this.members);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
extent: function() {
|
||||
return new geoExtent(this.loc);
|
||||
},
|
||||
|
||||
|
||||
geometry: function(graph) {
|
||||
return graph.transient(this, 'geometry', function() {
|
||||
return graph.isPoi(this) ? 'point' : 'vertex';
|
||||
});
|
||||
},
|
||||
|
||||
getID: function() {
|
||||
return this.id;
|
||||
},
|
||||
|
||||
getType: function() {
|
||||
return this.type;
|
||||
},
|
||||
|
||||
getComments: function() {
|
||||
return this.comments;
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -16,15 +16,16 @@ import { xml as d3_xml } from 'd3-request';
|
||||
import { d3geoTile as d3_geoTile } from '../lib/d3.geo.tile';
|
||||
import { geoExtent } from '../geo';
|
||||
|
||||
import {
|
||||
osmNote,
|
||||
} from '../osm';
|
||||
|
||||
import {
|
||||
utilRebind,
|
||||
utilIdleWorker
|
||||
} from '../util';
|
||||
|
||||
import {
|
||||
osmNote
|
||||
} from '../osm';
|
||||
import { actionRestrictTurn } from '../actions';
|
||||
|
||||
var urlroot = 'https://api.openstreetmap.org',
|
||||
_notesCache,
|
||||
dispatch = d3_dispatch('loadedNotes', 'loading'),
|
||||
@@ -111,7 +112,7 @@ function parseComments(comments) {
|
||||
}
|
||||
|
||||
var parsers = {
|
||||
note: function parseNote(obj) {
|
||||
note: function parseNote(obj, uid) {
|
||||
var attrs = obj.attributes;
|
||||
var childNodes = obj.childNodes;
|
||||
var parsedNote = {};
|
||||
@@ -130,6 +131,9 @@ var parsers = {
|
||||
}
|
||||
});
|
||||
|
||||
parsedNote.id = uid;
|
||||
parsedNote.type = 'note';
|
||||
|
||||
return {
|
||||
minX: parsedNote.loc[0],
|
||||
minY: parsedNote.loc[1],
|
||||
@@ -151,17 +155,19 @@ function parse(xml, callback, options) {
|
||||
var parser = parsers[child.nodeName];
|
||||
if (parser) {
|
||||
|
||||
// TODO: change how a note uid is parsed. Nodes & notes share 'n' + id combination
|
||||
var childNodes = child.childNodes;
|
||||
var id;
|
||||
var i;
|
||||
for (i = 0; i < childNodes.length; i++) {
|
||||
if (childNodes[i].nodeName === 'id') { id = childNodes[i].nodeName; }
|
||||
}
|
||||
if (options.cache && _entityCache[id]) {
|
||||
|
||||
var uid;
|
||||
_forEach(childNodes, function(node) {
|
||||
if (node.nodeName === 'id') {
|
||||
uid = child.nodeName + node.innerHTML;
|
||||
}
|
||||
});
|
||||
|
||||
if (options.cache && _entityCache[uid]) {
|
||||
return null;
|
||||
}
|
||||
return parser(child);
|
||||
return parser(child, uid);
|
||||
}
|
||||
}
|
||||
utilIdleWorker(children, parseChild, callback);
|
||||
|
||||
@@ -3,12 +3,16 @@ import { select as d3_select } from 'd3-selection';
|
||||
import { svgPointTransform } from './index';
|
||||
import { services } from '../services';
|
||||
|
||||
import { uiNoteEditor } from '../ui';
|
||||
|
||||
export function svgNotes(projection, context, dispatch) {
|
||||
var throttledRedraw = _throttle(function () { dispatch.call('change'); }, 1000);
|
||||
var minZoom = 12;
|
||||
var layer = d3_select(null);
|
||||
var _notes;
|
||||
|
||||
var noteEditor = uiNoteEditor(context);
|
||||
|
||||
function init() {
|
||||
if (svgNotes.initialized) return; // run once
|
||||
svgNotes.enabled = false;
|
||||
@@ -57,6 +61,20 @@ export function svgNotes(projection, context, dispatch) {
|
||||
.on('end', editOff);
|
||||
}
|
||||
|
||||
function click(d) {
|
||||
context.ui().sidebar.show(noteEditor, d);
|
||||
}
|
||||
|
||||
function mouseover(d) {
|
||||
context.ui().sidebar.show(noteEditor, d);
|
||||
}
|
||||
|
||||
function mouseout(d) {
|
||||
// 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) : []);
|
||||
@@ -70,12 +88,15 @@ export function svgNotes(projection, context, dispatch) {
|
||||
|
||||
var notesEnter = notes.enter()
|
||||
.append('use')
|
||||
.attr('class', 'note')
|
||||
.attr('class', function(d) { return 'note ' + d.id; })
|
||||
.attr('width', '24px')
|
||||
.attr('height', '24px')
|
||||
.attr('x', '-12px')
|
||||
.attr('y', '-12px')
|
||||
.attr('xlink:href', '#fas-comment-alt');
|
||||
.attr('xlink:href', '#fas-comment-alt')
|
||||
.on('click', click)
|
||||
.on('mouseover', mouseover)
|
||||
.on('mouseout', mouseout);
|
||||
|
||||
notes
|
||||
.merge(notesEnter)
|
||||
|
||||
@@ -34,6 +34,7 @@ export { uiMapInMap } from './map_in_map';
|
||||
export { uiModal } from './modal';
|
||||
export { uiModes } from './modes';
|
||||
export { uiNotice } from './notice';
|
||||
export { uiNoteEditor } from './note_editor';
|
||||
export { uiPresetEditor } from './preset_editor';
|
||||
export { uiPresetIcon } from './preset_icon';
|
||||
export { uiPresetList } from './preset_list';
|
||||
|
||||
166
modules/ui/note_editor.js
Normal file
166
modules/ui/note_editor.js
Normal file
@@ -0,0 +1,166 @@
|
||||
import { dispatch as d3_dispatch } from 'd3-dispatch';
|
||||
import { uiFormFields } from './form_fields';
|
||||
|
||||
|
||||
import { uiField } from './field';
|
||||
import { utilRebind } from '../util';
|
||||
import { t } from '../util/locale';
|
||||
|
||||
|
||||
export function uiNoteEditor(context) {
|
||||
var dispatch = d3_dispatch('change');
|
||||
var formFields = uiFormFields(context);
|
||||
var _fieldsArr;
|
||||
var _noteID;
|
||||
|
||||
function noteEditor(selection, note) {
|
||||
render(selection, note);
|
||||
}
|
||||
|
||||
function parseNoteUnresolved(selection, note) {
|
||||
|
||||
var unresolved = selection.selectAll('.noteUnresolved')
|
||||
.data(note, function(d) { return d.id; })
|
||||
.enter()
|
||||
.append('h3')
|
||||
.attr('class', 'noteUnresolved')
|
||||
.text(function(d) { return String(t('note.unresolved') + ' ' + d.id); });
|
||||
|
||||
selection.merge(unresolved);
|
||||
return selection;
|
||||
}
|
||||
|
||||
function parseNoteComments(selection, note) {
|
||||
|
||||
function noteCreator(d) {
|
||||
var userName = d.user ? d.user : t('note.anonymous');
|
||||
return String(t('note.creator') + ' ' + userName + ' ' + t('note.creatorOn') + ' ' + d.date);
|
||||
}
|
||||
|
||||
var comments = selection
|
||||
.append('div')
|
||||
.attr('class', 'comments');
|
||||
|
||||
var comment = comments.selectAll('.comment')
|
||||
.data(note.comments, function(d) { return d.uid; })
|
||||
.enter()
|
||||
.append('div')
|
||||
.attr('class', 'comment');
|
||||
|
||||
// append the creator
|
||||
comment
|
||||
.append('p')
|
||||
.attr('class', 'commentCreator')
|
||||
.text(function(d) { return noteCreator(d); });
|
||||
|
||||
// append the comment
|
||||
comment
|
||||
.append('p')
|
||||
.attr('class', 'commentText')
|
||||
.text(function(d) { return d.text; });
|
||||
|
||||
comments.insert('h4', ':first-child')
|
||||
.text(t('note.description'));
|
||||
|
||||
// TODO: have a better check to highlight the first/author comment (e.g., check if `author: true`)
|
||||
comments.select('div')
|
||||
.attr('class', 'comment-first');
|
||||
|
||||
|
||||
selection.merge(comments);
|
||||
return selection;
|
||||
}
|
||||
|
||||
function render(selection, note) {
|
||||
|
||||
var exampleNote = {
|
||||
close_url: 'example_close_url',
|
||||
comment_url: 'example_comment_url',
|
||||
comments: [
|
||||
{
|
||||
action: 'opened',
|
||||
date: '2016-11-20 00:50:20 UTC',
|
||||
html: '<p>Test comment1.</p>',
|
||||
text: 'Test comment1',
|
||||
uid: '111111',
|
||||
user: 'User1',
|
||||
user_url: 'example_user_url1'
|
||||
},
|
||||
{
|
||||
action: 'opened',
|
||||
date: '2016-11-20 00:50:20 UTC',
|
||||
html: '<p>Test comment2.</p>',
|
||||
text: 'Test comment2',
|
||||
uid: '222222',
|
||||
user: 'User2',
|
||||
user_url: 'example_user_url2'
|
||||
},
|
||||
{
|
||||
action: 'opened',
|
||||
date: '2016-11-20 00:50:20 UTC',
|
||||
html: '<p>Test comment3.</p>',
|
||||
text: 'Test comment3',
|
||||
uid: '333333',
|
||||
user: 'User3',
|
||||
user_url: 'example_user_url3'
|
||||
}
|
||||
],
|
||||
date_created: '2016-11-20 00:50:20 UTC',
|
||||
id: 'note789148',
|
||||
loc: [
|
||||
-120.0219036,
|
||||
34.4611879
|
||||
],
|
||||
status: 'open',
|
||||
type: 'note',
|
||||
url: 'https://api.openstreetmap.org/api/0.6/notes/789148',
|
||||
visible: true
|
||||
};
|
||||
|
||||
var currentNote = note ? [note] : [exampleNote];
|
||||
|
||||
var author = currentNote[0].comments[0];
|
||||
author.author = true;
|
||||
|
||||
var header = selection.selectAll('.header')
|
||||
.data([0]);
|
||||
|
||||
header.enter()
|
||||
.append('div')
|
||||
.attr('class', 'header fillL')
|
||||
.append('h3')
|
||||
.text(t('note.title'));
|
||||
|
||||
var body = selection.selectAll('.body')
|
||||
.data([0]);
|
||||
|
||||
body = body.enter()
|
||||
.append('div')
|
||||
.attr('class', 'body')
|
||||
.merge(body);
|
||||
|
||||
// Note Section
|
||||
var noteSection = body.selectAll('.changeset-editor')
|
||||
.data([0]);
|
||||
|
||||
noteSection = noteSection.enter()
|
||||
.append('div')
|
||||
.attr('class', 'modal-section changeset-editor')
|
||||
.merge(noteSection);
|
||||
|
||||
noteSection = noteSection.call(parseNoteUnresolved, currentNote);
|
||||
|
||||
noteSection = noteSection.call(parseNoteComments, currentNote[0]);
|
||||
// TODO: revisit commit.js, changeset_editor.js to get warnings, fields array, button toggles, etc.
|
||||
}
|
||||
|
||||
noteEditor.noteID = function(_) {
|
||||
if (!arguments.length) return _noteID;
|
||||
if (_noteID === _) return noteEditor;
|
||||
_noteID = _;
|
||||
_fieldsArr = null;
|
||||
return noteEditor;
|
||||
};
|
||||
|
||||
return utilRebind(noteEditor, dispatch, 'on');
|
||||
}
|
||||
@@ -1,12 +1,26 @@
|
||||
import _throttle from 'lodash-es/throttle';
|
||||
import { uiFeatureList } from './feature_list';
|
||||
import { uiInspector } from './inspector';
|
||||
|
||||
import { uiNoteEditor } from './note_editor';
|
||||
|
||||
export function uiSidebar(context) {
|
||||
var inspector = uiInspector(context),
|
||||
current;
|
||||
|
||||
var inspector = uiInspector(context),
|
||||
noteEditor = uiNoteEditor(context),
|
||||
current,
|
||||
wasNote;
|
||||
|
||||
function isNote(id) {
|
||||
var isNote = (id && id.slice(0,4) === 'note') ? id.slice(0,4) : null;
|
||||
// TODO: have a better check, perhaps see if the hover class is activated on a note
|
||||
if (!isNote && wasNote) {
|
||||
wasNote = false;
|
||||
sidebar.hide();
|
||||
} else if (isNote) {
|
||||
wasNote = true;
|
||||
sidebar.show(noteEditor);
|
||||
}
|
||||
}
|
||||
|
||||
function sidebar(selection) {
|
||||
var featureListWrap = selection
|
||||
@@ -21,6 +35,8 @@ export function uiSidebar(context) {
|
||||
|
||||
|
||||
function hover(id) {
|
||||
// isNote(id); TODO: instantiate check if needed
|
||||
|
||||
if (!current && context.hasEntity(id)) {
|
||||
featureListWrap
|
||||
.classed('inspector-hidden', true);
|
||||
@@ -46,6 +62,7 @@ export function uiSidebar(context) {
|
||||
inspector
|
||||
.state('hide');
|
||||
}
|
||||
// } // TODO: - remove if note check logic is moved
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +99,7 @@ export function uiSidebar(context) {
|
||||
};
|
||||
|
||||
|
||||
sidebar.show = function(component) {
|
||||
sidebar.show = function(component, element) {
|
||||
featureListWrap
|
||||
.classed('inspector-hidden', true);
|
||||
inspectorWrap
|
||||
@@ -92,7 +109,7 @@ export function uiSidebar(context) {
|
||||
current = selection
|
||||
.append('div')
|
||||
.attr('class', 'sidebar-component')
|
||||
.call(component);
|
||||
.call(component, element);
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user