diff --git a/css/app.css b/css/app.css index 6b1bb5a36..3399fe70b 100644 --- a/css/app.css +++ b/css/app.css @@ -2287,6 +2287,11 @@ img.wiki-image { /* Commit Modal ------------------------------------------------------- */ +.commit-modal { + width: 100%; + height: 100%; +} + .commit-modal a.user-info { display: inline-block; } diff --git a/index.html b/index.html index cd1177efb..348e9a2c1 100644 --- a/index.html +++ b/index.html @@ -167,6 +167,7 @@ + diff --git a/js/id/id.js b/js/id/id.js index 909ead40b..eb85ed275 100644 --- a/js/id/id.js +++ b/js/id/id.js @@ -45,26 +45,21 @@ window.iD = function () { return context; }; - context.ui = function() { - return function(container) { - context.container(container); - - if (locale && locale !== 'en' && iD.data.locales.indexOf(locale) !== -1) { - localePath = localePath || context.assetPath() + 'locales/' + locale + '.json'; - d3.json(localePath, function(err, result) { - window.locale[locale] = result; - window.locale.current(locale); - container.call(ui); - }); - } else { - container.call(ui); - } - - return ui; + context.loadLocale = function(cb) { + if (locale && locale !== 'en' && iD.data.locales.indexOf(locale) !== -1) { + localePath = localePath || context.assetPath() + 'locales/' + locale + '.json'; + d3.json(localePath, function(err, result) { + window.locale[locale] = result; + window.locale.current(locale); + cb(); + }); + } else { + cb(); } }; /* Straight accessors. Avoid using these if you can. */ + context.ui = function() { return ui; }; context.connection = function() { return connection; }; context.history = function() { return history; }; context.map = function() { return map; }; diff --git a/js/id/modes/add_point.js b/js/id/modes/add_point.js index 12eadef37..1973f542d 100644 --- a/js/id/modes/add_point.js +++ b/js/id/modes/add_point.js @@ -1,6 +1,7 @@ iD.modes.AddPoint = function(context) { var mode = { id: 'add-point', + button: 'point', title: t('modes.add_point.title'), description: t('modes.add_point.description'), key: '1' diff --git a/js/id/modes/save.js b/js/id/modes/save.js new file mode 100644 index 000000000..f46c00bec --- /dev/null +++ b/js/id/modes/save.js @@ -0,0 +1,95 @@ +iD.modes.Save = function(context) { + var ui = iD.ui.Commit(context) + .on('cancel', cancel) + .on('fix', fix) + .on('save', save); + + function cancel() { + context.enter(iD.modes.Browse(context)); + } + + function fix(d) { + context.map().zoomTo(d.entity); + context.enter(iD.modes.Select(context, [d.entity.id])); + } + + function save(e) { + var loading = iD.ui.Loading(context) + .message(t('save.uploading')) + .blocking(true); + + context.container() + .call(loading); + + context.connection().putChangeset( + context.history().changes(iD.actions.DiscardTags(context.history().difference())), + e.comment, + context.history().imagery_used(), + function(err, changeset_id) { + loading.close(); + if (err) { + var confirm = iD.ui.confirm(context.container()); + confirm + .select('.modal-section.header') + .append('h3') + .text(t('save.error')); + confirm + .select('.modal-section.message-text') + .append('p') + .text(err.responseText); + } else { + context.flush(); + success(e, changeset_id); + } + }); + } + + function success(e, changeset_id) { + context.ui().sidebar.hide(ui); + + ui = iD.ui.Success(context) + .changeset({ + id: changeset_id, + comment: e.comment + }) + .on('cancel', cancel); + + context.ui().sidebar.show(ui); + } + + var mode = { + id: 'save' + }; + + var behaviors = [ + iD.behavior.Hover(context), + iD.behavior.Select(context), + iD.behavior.Lasso(context), + iD.modes.DragNode(context).behavior]; + + mode.enter = function() { + context.container().selectAll('#bar button.save') + .classed('active', true); + + behaviors.forEach(function(behavior) { + context.install(behavior); + }); + + context.connection().authenticate(function(err) { + context.ui().sidebar.show(ui); + }); + }; + + mode.exit = function() { + context.container().selectAll('#bar button.save') + .classed('active', false); + + behaviors.forEach(function(behavior) { + context.uninstall(behavior); + }); + + context.ui().sidebar.hide(ui); + }; + + return mode; +}; diff --git a/js/id/ui.js b/js/id/ui.js index 6d78251a2..acb64c830 100644 --- a/js/id/ui.js +++ b/js/id/ui.js @@ -1,5 +1,5 @@ iD.ui = function(context) { - return function(container) { + function render(container) { var history = context.history(), map = context.map(); @@ -16,7 +16,7 @@ iD.ui = function(context) { container.append('div') .attr('id', 'sidebar') .attr('class', 'col4') - .call(iD.ui.Sidebar(context)); + .call(ui.sidebar); var content = container.append('div') .attr('id', 'content'); @@ -171,7 +171,18 @@ iD.ui = function(context) { .on('authenticated.ui', function() { authenticating.close(); }); - }; + } + + function ui(container) { + context.container(container); + context.loadLocale(function() { + render(container); + }); + } + + ui.sidebar = iD.ui.Sidebar(context); + + return ui; }; iD.ui.tooltipHtml = function(text, key) { diff --git a/js/id/ui/commit.js b/js/id/ui/commit.js index 8d4f9e7bb..7da066b03 100644 --- a/js/id/ui/commit.js +++ b/js/id/ui/commit.js @@ -23,35 +23,39 @@ iD.ui.Commit = function(context) { } function commit(selection) { + var changes = context.history().changes(), + user = context.connection().user(); + + selection.classed('commit-modal', true); function changesLength(d) { return changes[d].length; } - var changes = selection.datum(), - connection = changes.connection, - user = connection.user(), - header = selection.append('div').attr('class', 'header modal-section'), - body = selection.append('div').attr('class', 'body'); + var header = selection.append('div') + .attr('class', 'header'); header.append('h3') .text(t('commit.title')); + var body = selection.append('div') + .attr('class', 'body'); + // Comment Section var commentSection = body.append('div') .attr('class', 'modal-section form-field'); - commentSection.append('label') - .attr('class','form-label') - .text(t('commit.message_label')); + commentSection.append('label') + .attr('class', 'form-label') + .text(t('commit.message_label')); - var commentField = commentSection - .append('textarea') - .attr('placeholder', t('commit.description_placeholder')) - .property('value', context.storage('comment') || ''); + var commentField = commentSection.append('textarea') + .attr('placeholder', t('commit.description_placeholder')) + .property('value', context.storage('comment') || ''); commentField.node().select(); // Save Section - var saveSection = body.append('div').attr('class','modal-section cf'); + var saveSection = body.append('div') + .attr('class','modal-section cf'); var userLink = d3.select(document.createElement('div')); @@ -64,7 +68,7 @@ iD.ui.Commit = function(context) { userLink.append('a') .attr('class','user-info') .text(user.display_name) - .attr('href', connection.userURL(user.display_name)) + .attr('href', context.connection().userURL(user.display_name)) .attr('tabindex', -1) .attr('target', '_blank'); diff --git a/js/id/ui/save.js b/js/id/ui/save.js index bb22685f8..48328802a 100644 --- a/js/id/ui/save.js +++ b/js/id/ui/save.js @@ -1,84 +1,11 @@ iD.ui.Save = function(context) { - var map = context.map(), - history = context.history(), - connection = context.connection(), - key = iD.ui.cmd('⌘S'), - modal; + var history = context.history(), + key = iD.ui.cmd('⌘S'); function save() { d3.event.preventDefault(); - if (!history.hasChanges()) return; - - connection.authenticate(function(err) { - modal = iD.ui.modal(context.container()); - var changes = history.changes(); - changes.connection = connection; - modal.select('.content') - .classed('commit-modal', true) - .datum(changes) - .call(iD.ui.Commit(context) - .on('cancel', function() { - modal.remove(); - }) - .on('fix', clickFix) - .on('save', commit)); - }); - } - - function commit(e) { - context.container().select('.shaded') - .remove(); - - var loading = iD.ui.Loading(context) - .message(t('save.uploading')) - .blocking(true); - - context.container() - .call(loading); - - connection.putChangeset( - history.changes(iD.actions.DiscardTags(history.difference())), - e.comment, - history.imagery_used(), - function(err, changeset_id) { - loading.close(); - if (err) { - var confirm = iD.ui.confirm(context.container()); - confirm - .select('.modal-section.header') - .append('h3') - .text(t('save.error')); - confirm - .select('.modal-section.message-text') - .append('p') - .text(err.responseText); - } else { - context.flush(); - success(e, changeset_id); - } - }); - } - - function success(e, changeset_id) { - modal = iD.ui.modal(context.container()); - modal.select('.content') - .classed('success-modal', true) - .datum({ - id: changeset_id, - comment: e.comment - }) - .call(iD.ui.Success(context) - .on('cancel', function() { - modal.remove(); - })); - } - - function clickFix(d) { - var extent = d.entity.extent(context.graph()); - map.centerZoom(extent.center(), Math.min(19, map.extentZoom(extent))); - context.enter(iD.modes.Select(context, [d.entity.id])); - modal.remove(); + context.enter(iD.modes.Save(context)); } return function(selection) { diff --git a/js/id/ui/sidebar.js b/js/id/ui/sidebar.js index da5adebb8..dac928cee 100644 --- a/js/id/ui/sidebar.js +++ b/js/id/ui/sidebar.js @@ -1,12 +1,14 @@ iD.ui.Sidebar = function(context) { - return function(selection) { + var current; + + function sidebar(selection) { var wrap = selection.append('div') .attr('class', 'inspector-hidden inspector-wrap fr'); context.on('hover.sidebar', function(entity) { if (context.selection().length === 1) return; - if (entity) { + if (!current && entity) { wrap.classed('inspector-hidden', false) .classed('inspector-hover', true) .call(iD.ui.Inspector(context) @@ -18,7 +20,7 @@ iD.ui.Sidebar = function(context) { }); context.on('select.sidebar', function(selection) { - if (selection.length === 1) { + if (!current && selection.length === 1) { wrap.classed('inspector-hidden', false) .classed('inspector-hover', false) .call(iD.ui.Inspector(context) @@ -27,6 +29,20 @@ iD.ui.Sidebar = function(context) { } else { wrap.classed('inspector-hidden', true); } - }) + }); + + sidebar.show = function(component) { + wrap.classed('inspector-hidden', true); + current = selection.append('div') + .attr('class', 'sidebar-component') + .call(component); + }; + + sidebar.hide = function() { + current.remove(); + current = null; + }; } + + return sidebar; }; diff --git a/js/id/ui/success.js b/js/id/ui/success.js index 4d5cd721b..5e5c02e4e 100644 --- a/js/id/ui/success.js +++ b/js/id/ui/success.js @@ -1,23 +1,25 @@ iD.ui.Success = function(context) { - var event = d3.dispatch('cancel', 'save'); + var event = d3.dispatch('cancel'), + changeset; function success(selection) { - var changeset = selection.datum(), - header = selection.append('div').attr('class', 'header modal-section'), - body = selection.append('div').attr('class', 'body'); + var message = (changeset.comment || t('success.edited_osm')).substring(0, 130) + + ' ' + context.connection().changesetURL(changeset.id); - header.append('h3').text(t('just_edited')); + var header = selection.append('div') + .attr('class', 'header'); - var m = changeset.comment ? - changeset.comment.substring(0, 130) : ''; + header.append('h3') + .text(t('just_edited')); - var message = (m || t('success.edited_osm')) + ' ' + - context.connection().changesetURL(changeset.id); + var body = selection.append('div') + .attr('class', 'body'); - var links = body.append('div').attr('class','modal-actions cf'); + var links = body.append('div') + .attr('class', 'modal-actions cf'); links.append('a') - .attr('class','col4 osm') + .attr('class', 'col4 osm') .attr('target', '_blank') .attr('href', function() { return context.connection().changesetURL(changeset.id); @@ -25,7 +27,7 @@ iD.ui.Success = function(context) { .text(t('view_on_osm')); links.append('a') - .attr('class','col4 twitter') + .attr('class', 'col4 twitter') .attr('target', '_blank') .attr('href', function() { return 'https://twitter.com/intent/tweet?source=webclient&text=' + @@ -34,23 +36,29 @@ iD.ui.Success = function(context) { .text(t('success.tweet')); links.append('a') - .attr('class','col4 facebook') + .attr('class', 'col4 facebook') .attr('target', '_blank') .attr('href', function() { - return 'https://facebook.com/sharer/sharer.php?u=' + encodeURIComponent(message); + return 'https://facebook.com/sharer/sharer.php?u=' + + encodeURIComponent(message); }) .text(t('success.facebook')); - var section = body.append('div').attr('class','modal-section cf'); + var section = body.append('div') + .attr('class', 'modal-section cf'); section.append('button') .attr('class', 'action col2') - .on('click.save', function() { - event.cancel(); - }) + .on('click', event.cancel) .text(t('success.okay')) .node().focus(); } + success.changeset = function(_) { + if (!arguments.length) return changeset; + changeset = _; + return success; + }; + return d3.rebind(success, event, 'on'); }; diff --git a/test/index.html b/test/index.html index ebca79ffd..15529d330 100644 --- a/test/index.html +++ b/test/index.html @@ -93,6 +93,7 @@ +