From ac86869b4a463a7a1d7a77a16f7a739148c92ae3 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Fri, 5 Jan 2018 18:11:49 -0500 Subject: [PATCH] Add conflict checking progress, guard code for user authentication --- data/core.yaml | 1 + dist/locales/en.json | 1 + modules/modes/save.js | 64 +++++++++++++++++++++++++++++++++++------ modules/services/osm.js | 16 +++++++++-- 4 files changed, 72 insertions(+), 10 deletions(-) diff --git a/data/core.yaml b/data/core.yaml index 9261276af..08021a33f 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -470,6 +470,7 @@ en: status_code: "Server returned status code {code}" unknown_error_details: "Please ensure you are connected to the internet." uploading: Uploading changes to OpenStreetMap... + conflict_progress: "Checking for conflicts: {num} of {total}" unsaved_changes: You have unsaved changes conflict: header: Resolve conflicting edits diff --git a/dist/locales/en.json b/dist/locales/en.json index 1e13481be..976862a90 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -582,6 +582,7 @@ "status_code": "Server returned status code {code}", "unknown_error_details": "Please ensure you are connected to the internet.", "uploading": "Uploading changes to OpenStreetMap...", + "conflict_progress": "Checking for conflicts: {num} of {total}", "unsaved_changes": "You have unsaved changes", "conflict": { "header": "Resolve conflicting edits", diff --git a/modules/modes/save.js b/modules/modes/save.js index 73479e72a..99d4641a0 100644 --- a/modules/modes/save.js +++ b/modules/modes/save.js @@ -60,6 +60,9 @@ export function modeSave(context) { var _toCheck = []; var _toLoad = []; + var _toLoadCount = 0; + var _toLoadTotal = 0; + var _conflicts = []; var _errors = []; var _origChanges; @@ -76,13 +79,33 @@ export function modeSave(context) { function save(changeset, tryAgain, checkConflicts) { // Guard against accidentally entering save code twice - #4641 - if (_isSaving && !tryAgain) return; + if (_isSaving && !tryAgain) { + return; + } var osm = context.connection(); - if (!osm) return; + if (!osm) { + cancel(); + return; + } - _isSaving = true; - context.container().call(loading); // block input + // If user somehow got logged out mid-save, try to reauthenticate.. + // This can happen if they were logged in from before, but the tokens are no longer valid. + if (!osm.authenticated()) { + osm.authenticate(function(err) { + if (err) { + cancel(); // quit save mode.. + } else { + save(changeset, tryAgain, checkConflicts); // continue where we left off.. + } + }); + return; + } + + if (!_isSaving) { + context.container().call(loading); // block input + _isSaving = true; + } var history = context.history(); var localGraph = context.graph(); @@ -109,7 +132,11 @@ export function modeSave(context) { var modified = _filter(history.difference().summary(), { changeType: 'modified' }); _toCheck = _map(_map(modified, 'entity'), 'id'); _toLoad = withChildNodes(_toCheck, localGraph); + _toLoadCount = 0; + _toLoadTotal = _toLoad.length; + if (_toCheck.length) { + showProgress(_toLoadCount, _toLoadTotal); osm.loadMultiple(_toLoad, loaded); } else { upload(changeset); @@ -142,12 +169,13 @@ export function modeSave(context) { if (err) { _errors.push({ - msg: err.responseText, + msg: err.message || err.responseText, details: [ t('save.status_code', { code: err.status }) ] }); showErrors(); } else { + var loadMore = []; result.data.forEach(function(entity) { remoteGraph.replace(entity); @@ -165,6 +193,10 @@ export function modeSave(context) { } }); + _toLoadCount += result.data.length; + _toLoadTotal += loadMore.length; + showProgress(_toLoadCount, _toLoadTotal); + if (loadMore.length) { _toLoad.push.apply(_toLoad, loadMore); osm.loadMultiple(loadMore, loaded); @@ -274,7 +306,7 @@ export function modeSave(context) { save(changeset, true, true); // tryAgain = true, checkConflicts = true } else { _errors.push({ - msg: err.responseText, + msg: err.message || err.responseText, details: [ t('save.status_code', { code: err.status }) ] }); showErrors(); @@ -294,6 +326,20 @@ export function modeSave(context) { } + function showProgress(num, total) { + var modal = context.container().select('.loading-modal .modal-section'); + var progress = modal.selectAll('.progress') + .data([0]); + + // enter/update + progress.enter() + .append('div') + .attr('class', 'progress') + .merge(progress) + .text(t('save.conflict_progress', { num: num, total: total })); + } + + function showConflicts(changeset) { var history = context.history(); var selection = context.container() @@ -425,7 +471,10 @@ export function modeSave(context) { .attr('class', 'inactive'); var osm = context.connection(); - if (!osm) return; + if (!osm) { + cancel(); + return; + } if (osm.authenticated()) { done(); @@ -442,7 +491,6 @@ export function modeSave(context) { mode.exit = function() { - loading.close(); _isSaving = false; keybinding.off(); diff --git a/modules/services/osm.js b/modules/services/osm.js index 89b45013d..9ead1f5b0 100644 --- a/modules/services/osm.js +++ b/modules/services/osm.js @@ -253,8 +253,7 @@ export default { // 400 Bad Request, 401 Unauthorized, 403 Forbidden // Logout and retry the request.. - if (isAuthenticated && err && - (err.status === 400 || err.status === 401 || err.status === 403)) { + if (isAuthenticated && err && (err.status === 400 || err.status === 401 || err.status === 403)) { that.logout(); that.loadFromAPI(path, callback); @@ -371,6 +370,10 @@ export default { _changeset.inflight = null; if (err) { + // 400 Bad Request, 401 Unauthorized, 403 Forbidden.. + if (err.status === 400 || err.status === 401 || err.status === 403) { + that.logout(); + } return callback(err, changeset); } if (that.getConnectionId() !== cid) { @@ -428,12 +431,17 @@ export default { function done(err, user_details) { if (err) { + // 400 Bad Request, 401 Unauthorized, 403 Forbidden.. + if (err.status === 400 || err.status === 401 || err.status === 403) { + that.logout(); + } return callback(err); } if (that.getConnectionId() !== cid) { return callback({ message: 'Connection Switched', status: -1 }); } + var u = user_details.getElementsByTagName('user')[0]; var img = u.getElementsByTagName('img'); var image_url = ''; @@ -482,6 +490,10 @@ export default { function done(err, changesets) { if (err) { + // 400 Bad Request, 401 Unauthorized, 403 Forbidden.. + if (err.status === 400 || err.status === 401 || err.status === 403) { + that.logout(); + } return callback(err); } if (that.getConnectionId() !== cid) {