save to local even if ongoing sync, alert user if sync is taking too long

This commit is contained in:
Mo Bitar
2017-04-25 09:51:46 -05:00
parent 0dc90551a3
commit f982f0b00a
4 changed files with 47 additions and 3 deletions

View File

@@ -29,6 +29,10 @@ angular.module('app.frontend')
this.postThemeToExternalEditor();
}.bind(this))
$rootScope.$on("sync:taking-too-long", function(){
this.syncTakingTooLong = true;
}.bind(this));
window.addEventListener("message", function(event){
if(event.data.status) {
this.postNoteToExternalEditor();
@@ -178,6 +182,7 @@ angular.module('app.frontend')
var note = this.note;
note.dummy = false;
this.save()(note, function(success){
this.syncTakingTooLong = false;
if(success) {
if(statusTimeout) $timeout.cancel(statusTimeout);
statusTimeout = $timeout(function(){

View File

@@ -1,11 +1,12 @@
class SyncManager {
constructor($rootScope, modelManager, authManager, dbManager, httpManager) {
constructor($rootScope, modelManager, authManager, dbManager, httpManager, $interval) {
this.$rootScope = $rootScope;
this.httpManager = httpManager;
this.modelManager = modelManager;
this.authManager = authManager;
this.dbManager = dbManager;
this.$interval = $interval;
this.syncStatus = {};
}
@@ -122,18 +123,40 @@ class SyncManager {
}
}
beginCheckingIfSyncIsTakingTooLong() {
this.syncStatus.checker = this.$interval(function(){
// check to see if the ongoing sync is taking too long, alert the user
var secondsPassed = (new Date() - this.syncStatus.syncStart) / 1000;
var warningThreshold = 5; // seconds
if(secondsPassed > warningThreshold) {
this.$rootScope.$broadcast("sync:taking-too-long");
this.stopCheckingIfSyncIsTakingTooLong();
}
}.bind(this), 500)
}
stopCheckingIfSyncIsTakingTooLong() {
this.$interval.cancel(this.syncStatus.checker);
}
sync(callback, options = {}) {
var allDirtyItems = this.modelManager.getDirtyItems();
if(this.syncStatus.syncOpInProgress) {
this.repeatOnCompletion = true;
if(callback) {
this.queuedCallbacks.push(callback);
}
// write to local storage nonetheless, since some users may see several second delay in server response.
// if they close the browser before the ongoing sync request completes, local changes will be lost if we dont save here
this.writeItemsToLocalStorage(allDirtyItems, false, null);
console.log("Sync op in progress; returning.");
return;
}
var allDirtyItems = this.modelManager.getDirtyItems();
// we want to write all dirty items to disk only if the user is offline, or if the sync op fails
// if the sync op succeeds, these items will be written to disk by handling the "saved_items" response from the server
@@ -146,6 +169,8 @@ class SyncManager {
var isContinuationSync = this.syncStatus.needsMoreSync;
this.syncStatus.syncOpInProgress = true;
this.syncStatus.syncStart = new Date();
this.beginCheckingIfSyncIsTakingTooLong();
let submitLimit = 100;
var subItems = allDirtyItems.slice(0, submitLimit);
@@ -172,6 +197,10 @@ class SyncManager {
params.sync_token = this.syncToken;
params.cursor_token = this.cursorToken;
var onSyncCompletion = function(response) {
this.stopCheckingIfSyncIsTakingTooLong();
}.bind(this);
var onSyncSuccess = function(response) {
this.modelManager.clearDirtyItems(subItems);
this.syncStatus.error = null;
@@ -197,6 +226,8 @@ class SyncManager {
this.syncToken = response.sync_token;
this.cursorToken = response.cursor_token;
onSyncCompletion(response);
if(this.cursorToken || this.syncStatus.needsMoreSync) {
setTimeout(function () {
this.sync(callback, options);
@@ -229,6 +260,8 @@ class SyncManager {
this.syncStatus.error = error;
this.writeItemsToLocalStorage(allDirtyItems, false, null);
onSyncCompletion(response);
this.$rootScope.$broadcast("sync:error", error);
this.callQueuedCallbacksAndCurrent(callback, {error: "Sync error"});

View File

@@ -145,6 +145,10 @@
color: red !important;
}
.orange {
color: orange !important;
}
.bold {
font-weight: bold !important;
}

View File

@@ -4,7 +4,9 @@
%input.input#note-title-editor{"ng-model" => "ctrl.note.title", "ng-keyup" => "$event.keyCode == 13 && ctrl.saveTitle($event)",
"ng-change" => "ctrl.nameChanged()", "ng-focus" => "ctrl.onNameFocus()",
"select-on-click" => "true"}
#save-status{"ng-class" => "{'red bold': ctrl.saveError}", "ng-bind-html" => "ctrl.noteStatus"}
#save-status{"ng-class" => "{'red bold': ctrl.saveError, 'orange bold': ctrl.syncTakingTooLong}", "ng-bind-html" => "ctrl.noteStatus"}
.editor-tags
%input.tags-input{"type" => "text", "ng-keyup" => "$event.keyCode == 13 && $event.target.blur();",
"ng-model" => "ctrl.tagsString", "placeholder" => "#tags", "ng-blur" => "ctrl.updateTagsFromTagsString($event, ctrl.tagsString)"}