Handle item sync success through sync observer, remove sync locking
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
angular.module('app')
|
angular.module('app')
|
||||||
|
|
||||||
.constant('appVersion', '3.0.9')
|
.constant('appVersion', '3.0.10')
|
||||||
|
|
||||||
;
|
;
|
||||||
@@ -39,6 +39,28 @@ angular.module('app')
|
|||||||
this.syncTakingTooLong = false;
|
this.syncTakingTooLong = false;
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|
||||||
|
const MinimumStatusDurationMs = 400;
|
||||||
|
|
||||||
|
syncManager.addEventHandler((eventName, data) => {
|
||||||
|
if(!this.note) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(eventName == "sync:completed") {
|
||||||
|
if(this.note.dirty) {
|
||||||
|
// if we're still dirty, don't change status, a sync is likely upcoming.
|
||||||
|
} else {
|
||||||
|
let savedItem = data.savedItems.find((item) => item.uuid == this.note.uuid);
|
||||||
|
let isInErrorState = this.saveError;
|
||||||
|
if(isInErrorState || savedItem) {
|
||||||
|
this.showAllChangesSavedStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(eventName == "sync:error") {
|
||||||
|
this.showErrorStatus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Right now this only handles offline saving status changes.
|
// Right now this only handles offline saving status changes.
|
||||||
this.syncStatusObserver = syncManager.registerSyncStatusObserver((status) => {
|
this.syncStatusObserver = syncManager.registerSyncStatusObserver((status) => {
|
||||||
if(status.localError) {
|
if(status.localError) {
|
||||||
@@ -245,7 +267,7 @@ angular.module('app')
|
|||||||
this.showMenu = false;
|
this.showMenu = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var statusTimeout;
|
// var statusTimeout;
|
||||||
|
|
||||||
this.saveNote = function(note, callback, updateClientModified, dontUpdatePreviews) {
|
this.saveNote = function(note, callback, updateClientModified, dontUpdatePreviews) {
|
||||||
// We don't want to update the client modified date if toggling lock for note.
|
// We don't want to update the client modified date if toggling lock for note.
|
||||||
@@ -261,6 +283,7 @@ angular.module('app')
|
|||||||
note.content.preview_html = null;
|
note.content.preview_html = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.showSavingStatus();
|
||||||
syncManager.sync().then((response) => {
|
syncManager.sync().then((response) => {
|
||||||
if(response && response.error) {
|
if(response && response.error) {
|
||||||
if(!this.didShowErrorAlert) {
|
if(!this.didShowErrorAlert) {
|
||||||
@@ -295,9 +318,8 @@ angular.module('app')
|
|||||||
note.hasChanges = bypassDebouncer ? false : true;
|
note.hasChanges = bypassDebouncer ? false : true;
|
||||||
|
|
||||||
if(saveTimeout) $timeout.cancel(saveTimeout);
|
if(saveTimeout) $timeout.cancel(saveTimeout);
|
||||||
if(statusTimeout) $timeout.cancel(statusTimeout);
|
// if(statusTimeout) $timeout.cancel(statusTimeout);
|
||||||
saveTimeout = $timeout(() => {
|
saveTimeout = $timeout(() => {
|
||||||
this.showSavingStatus();
|
|
||||||
note.dummy = false;
|
note.dummy = false;
|
||||||
// Make sure the note exists. A safety measure, as toggling between tags triggers deletes for dummy notes.
|
// Make sure the note exists. A safety measure, as toggling between tags triggers deletes for dummy notes.
|
||||||
// Race conditions have been fixed, but we'll keep this here just in case.
|
// Race conditions have been fixed, but we'll keep this here just in case.
|
||||||
@@ -306,24 +328,12 @@ angular.module('app')
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.saveNote(note, (success) => {
|
this.saveNote(note, null, updateClientModified, dontUpdatePreviews);
|
||||||
if(success) {
|
|
||||||
if(statusTimeout) $timeout.cancel(statusTimeout);
|
|
||||||
statusTimeout = $timeout(() => {
|
|
||||||
this.showAllChangesSavedStatus();
|
|
||||||
}, 200)
|
|
||||||
} else {
|
|
||||||
if(statusTimeout) $timeout.cancel(statusTimeout);
|
|
||||||
statusTimeout = $timeout(() => {
|
|
||||||
this.showErrorStatus();
|
|
||||||
}, 200)
|
|
||||||
}
|
|
||||||
}, updateClientModified, dontUpdatePreviews);
|
|
||||||
}, delay)
|
}, delay)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.showSavingStatus = function() {
|
this.showSavingStatus = function() {
|
||||||
this.noteStatus = {message: "Saving..."};
|
this.setStatus({message: "Saving..."}, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.showAllChangesSavedStatus = function() {
|
this.showAllChangesSavedStatus = function() {
|
||||||
@@ -334,7 +344,8 @@ angular.module('app')
|
|||||||
if(authManager.offline()) {
|
if(authManager.offline()) {
|
||||||
status += " (offline)";
|
status += " (offline)";
|
||||||
}
|
}
|
||||||
this.noteStatus = {message: status};
|
|
||||||
|
this.setStatus({message: status});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.showErrorStatus = function(error) {
|
this.showErrorStatus = function(error) {
|
||||||
@@ -346,7 +357,23 @@ angular.module('app')
|
|||||||
}
|
}
|
||||||
this.saveError = true;
|
this.saveError = true;
|
||||||
this.syncTakingTooLong = false;
|
this.syncTakingTooLong = false;
|
||||||
this.noteStatus = error;
|
this.setStatus(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setStatus = function(status, wait = true) {
|
||||||
|
// Keep every status up for a minimum duration so it doesnt flash crazily.
|
||||||
|
let waitForMs;
|
||||||
|
if(!this.noteStatus || !this.noteStatus.date) {
|
||||||
|
waitForMs = 0;
|
||||||
|
} else {
|
||||||
|
waitForMs = MinimumStatusDurationMs - (new Date() - this.noteStatus.date);
|
||||||
|
}
|
||||||
|
if(!wait || waitForMs < 0) {waitForMs = 0;}
|
||||||
|
if(this.statusTimeout) $timeout.cancel(this.statusTimeout);
|
||||||
|
this.statusTimeout = $timeout(() => {
|
||||||
|
status.date = new Date();
|
||||||
|
this.noteStatus = status;
|
||||||
|
}, waitForMs)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.contentChanged = function() {
|
this.contentChanged = function() {
|
||||||
@@ -698,19 +725,8 @@ angular.module('app')
|
|||||||
|
|
||||||
else if(action === "save-items" || action === "save-success" || action == "save-error") {
|
else if(action === "save-items" || action === "save-success" || action == "save-error") {
|
||||||
if(data.items.map((item) => {return item.uuid}).includes(this.note.uuid)) {
|
if(data.items.map((item) => {return item.uuid}).includes(this.note.uuid)) {
|
||||||
|
|
||||||
if(action == "save-items") {
|
if(action == "save-items") {
|
||||||
if(this.componentSaveTimeout) $timeout.cancel(this.componentSaveTimeout);
|
this.showSavingStatus();
|
||||||
this.componentSaveTimeout = $timeout(this.showSavingStatus.bind(this), 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
else {
|
|
||||||
if(this.componentStatusTimeout) $timeout.cancel(this.componentStatusTimeout);
|
|
||||||
if(action == "save-success") {
|
|
||||||
this.componentStatusTimeout = $timeout(this.showAllChangesSavedStatus.bind(this), 400);
|
|
||||||
} else {
|
|
||||||
this.componentStatusTimeout = $timeout(this.showErrorStatus.bind(this), 400);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,6 @@ angular.module('app')
|
|||||||
dbManager, syncManager, authManager, themeManager, passcodeManager, storageManager, migrationManager,
|
dbManager, syncManager, authManager, themeManager, passcodeManager, storageManager, migrationManager,
|
||||||
privilegesManager, statusManager) {
|
privilegesManager, statusManager) {
|
||||||
|
|
||||||
// Lock syncing until local data is loaded. Syncing may be called from a variety of places,
|
|
||||||
// such as when the window focuses, for example. We don't want sync to occur until all local items are loaded,
|
|
||||||
// otherwise, if sync happens first, then load, the load may override synced values.
|
|
||||||
syncManager.lockSyncing();
|
|
||||||
|
|
||||||
storageManager.initialize(passcodeManager.hasPasscode(), authManager.isEphemeralSession());
|
storageManager.initialize(passcodeManager.hasPasscode(), authManager.isEphemeralSession());
|
||||||
|
|
||||||
$scope.platform = getPlatformString();
|
$scope.platform = getPlatformString();
|
||||||
@@ -98,11 +93,7 @@ angular.module('app')
|
|||||||
this.syncStatus = statusManager.replaceStatusWithString(this.syncStatus, encryptionEnabled ? `Decrypting ${notesString}` : `Loading ${notesString}`);
|
this.syncStatus = statusManager.replaceStatusWithString(this.syncStatus, encryptionEnabled ? `Decrypting ${notesString}` : `Loading ${notesString}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
syncManager.loadLocalItems(incrementalCallback).then(() => {
|
syncManager.loadLocalItems({incrementalCallback}).then(() => {
|
||||||
|
|
||||||
// First unlock after initially locked to wait for local data loaded.
|
|
||||||
syncManager.unlockSyncing();
|
|
||||||
|
|
||||||
$timeout(() => {
|
$timeout(() => {
|
||||||
$rootScope.$broadcast("initial-data-loaded"); // This needs to be processed first before sync is called so that singletonManager observers function properly.
|
$rootScope.$broadcast("initial-data-loaded"); // This needs to be processed first before sync is called so that singletonManager observers function properly.
|
||||||
// Perform integrity check on first sync
|
// Perform integrity check on first sync
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "standard-notes-web",
|
"name": "standard-notes-web",
|
||||||
"version": "3.0.9",
|
"version": "3.0.10",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|||||||
Reference in New Issue
Block a user