From 3fc99e1df5223d7555fea77441212956d969e851 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Tue, 13 Jan 2015 16:28:06 -0500 Subject: [PATCH] Allow undeletions --- data/core.yaml | 12 ++++----- dist/locales/en.json | 12 ++++----- js/id/modes/save.js | 63 ++++++++++++++++++++++++++++++++------------ 3 files changed, 58 insertions(+), 29 deletions(-) diff --git a/data/core.yaml b/data/core.yaml index 181bccdae..63662c451 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -314,23 +314,23 @@ en: no_changes: No changes to save. error: Errors occurred while trying to save status_code: "Server returned status code {code}" - status_gone: '{type} "{id}" {name} has already been deleted.' + status_gone: '{name} has already been deleted.' unknown_error_details: "Please ensure you are connected to the internet." uploading: Uploading changes to OpenStreetMap. unsaved_changes: You have unsaved changes conflict: header: Conflicting edits detected - message: 'Conflicting edits were made to {type} "{id}" {name}' + message: 'Conflicting edits were made to {name}' keep_local: Keep Mine keep_remote: Keep Theirs restore: Restore delete: Leave Deleted annotation: safe: Merged remote changes from server. - keep_local: 'Kept local version of "{id}".' - keep_remote: 'Kept remote version of "{id}".' - restore: 'Restored local version of "{id}".' - delete: 'Deleted local version of "{id}".' + keep_local: 'Kept local version of {id}.' + keep_remote: 'Kept remote version of {id}.' + restore: 'Restored local version of {id}.' + delete: 'Deleted local version of {id}.' try_again: Try Again download_changes: Download Changes help: | diff --git a/dist/locales/en.json b/dist/locales/en.json index 350f8e016..fb86fcbea 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -388,23 +388,23 @@ "no_changes": "No changes to save.", "error": "Errors occurred while trying to save", "status_code": "Server returned status code {code}", - "status_gone": "{type} \"{id}\" {name} has already been deleted.", + "status_gone": "{name} has already been deleted.", "unknown_error_details": "Please ensure you are connected to the internet.", "uploading": "Uploading changes to OpenStreetMap.", "unsaved_changes": "You have unsaved changes", "conflict": { "header": "Conflicting edits detected", - "message": "Conflicting edits were made to {type} \"{id}\" {name}", + "message": "Conflicting edits were made to {name}", "keep_local": "Keep Mine", "keep_remote": "Keep Theirs", "restore": "Restore", "delete": "Leave Deleted", "annotation": { "safe": "Merged remote changes from server.", - "keep_local": "Kept local version of \"{id}\".", - "keep_remote": "Kept remote version of \"{id}\".", - "restore": "Restored local version of \"{id}\".", - "delete": "Deleted local version of \"{id}\"." + "keep_local": "Kept local version of {id}.", + "keep_remote": "Kept remote version of {id}.", + "restore": "Restored local version of {id}.", + "delete": "Deleted local version of {id}." }, "try_again": "Try Again", "download_changes": "Download Changes", diff --git a/js/id/modes/save.js b/js/id/modes/save.js index a82fbf138..1e6e6281d 100644 --- a/js/id/modes/save.js +++ b/js/id/modes/save.js @@ -1,7 +1,17 @@ iD.modes.Save = function(context) { - var ui = iD.ui.Commit(context) - .on('cancel', cancel) - .on('save', save); + var undeletions = [], + ui = iD.ui.Commit(context) + .on('cancel', cancel) + .on('save', save); + + function undelete(id) { + return function(graph) { + var entity = context.entity(id), + target = iD.Entity(entity, { version: +entity.version + 1 }); + undeletions.push(id); + return graph.replace(target); + }; + } function choice(text, actions) { return { @@ -18,7 +28,8 @@ iD.modes.Save = function(context) { var loading = iD.ui.Loading(context).message(t('save.uploading')).blocking(true), history = context.history(), altGraph = iD.Graph(history.base(), true), - toCheck = _.pluck(history.changes().modified, 'id'), + modified = _.pluck(history.changes().modified, 'id'), + toCheck = _.clone(modified), didMerge = false, conflicts = [], errors = [], @@ -39,23 +50,29 @@ iD.modes.Save = function(context) { var graph = context.graph(), local = graph.entity(id), type = iD.util.displayType(id), - name = iD.util.displayName(local) || ''; + name = iD.util.displayName(local) || (type + ' ' + id); toCheck = _.without(toCheck, id); if (err) { if (err.status === 410) { // Status: Gone (contains no responseText) - conflicts.push({ - id: id, - msg: t('save.status_gone', { id: id, type: type, name: name }), - details: [ t('save.status_code', { code: err.status }) ], - choices: [ - choice(t('save.conflict.restore'), - [ iD.actions.Noop() /*FIXME*/, t('save.conflict.annotation.restore', {id: id}) ]), - choice(t('save.conflict.delete'), - [ iD.actions.DeleteMultiple([id]), t('save.conflict.annotation.delete', {id: id}) ]) - ] - }); + if (undeletions.indexOf(id) === -1) { // skip if we have already undeleted it.. + if (local.type === 'node') { + checkParents(local); + } + + conflicts.push({ + id: id, + msg: t('save.status_gone', { name: name }), + details: [ t('save.status_code', { code: err.status }) ], + choices: [ + choice(t('save.conflict.restore'), + [ undelete(id), t('save.conflict.annotation.restore', {id: id}) ]), + choice(t('save.conflict.delete'), + [ iD.actions.DeleteMultiple([id]), t('save.conflict.annotation.delete', {id: id}) ]) + ] + }); + } } else { errors.push({ id: id, @@ -82,7 +99,7 @@ iD.modes.Save = function(context) { conflicts.push({ id: id, - msg: t('save.conflict.message', { id: id, type: type, name: name }), + msg: t('save.conflict.message', { name: name }), details: details, choices: [ choice(t('save.conflict.keep_local'), @@ -101,6 +118,18 @@ iD.modes.Save = function(context) { }); } + function checkParents(entity) { + var ids = _.pluck(context.graph().parentWays(entity), 'id'); + + for (var i = 0; i < ids.length; i++) { + if (modified.indexOf(ids[i]) === -1) { + modified.push(ids[i]); + toCheck.push(ids[i]); + check(ids[i]); + } + } + } + function finalize() { if (didMerge) { // set undo checkpoint.. context.perform(iD.actions.Noop(), t('save.conflict.annotation.safe'));