diff --git a/app/assets/javascripts/app/services/directives/accountDataMenu.js b/app/assets/javascripts/app/services/directives/accountDataMenu.js index a1c4a9d11..2d5c5fedf 100644 --- a/app/assets/javascripts/app/services/directives/accountDataMenu.js +++ b/app/assets/javascripts/app/services/directives/accountDataMenu.js @@ -7,14 +7,16 @@ class AccountDataMenu { }; } - controller($scope, apiController, modelManager) { + controller($scope, apiController, modelManager, keyManager) { 'ngInject'; + $scope.keys = keyManager.keys; + $scope.destroyLocalData = function() { if(!confirm("Are you sure you want to end your session? This will delete all local items, sync providers, keys, and extensions.")) { return; } - + apiController.destroyLocalData(function(){ window.location.reload(); }) diff --git a/app/assets/javascripts/app/services/directives/accountSyncSection.js b/app/assets/javascripts/app/services/directives/accountSyncSection.js index ea839c34a..bccec8351 100644 --- a/app/assets/javascripts/app/services/directives/accountSyncSection.js +++ b/app/assets/javascripts/app/services/directives/accountSyncSection.js @@ -26,8 +26,6 @@ class AccountSyncSection { } syncManager.enableSyncProvider(provider, primary); - syncManager.addAllDataAsNeedingSyncForProvider(provider); - syncManager.sync(); } $scope.removeSyncProvider = function(provider) { diff --git a/app/assets/javascripts/app/services/directives/delay-hide.js b/app/assets/javascripts/app/services/directives/delay-hide.js new file mode 100644 index 000000000..6bd3b6c0b --- /dev/null +++ b/app/assets/javascripts/app/services/directives/delay-hide.js @@ -0,0 +1,42 @@ +angular + .module('app.frontend') + .directive('delayHide', function($timeout) { + return { + restrict: 'A', + scope: { + show: '=', + delay: '@' + }, + link: function(scope, elem, attrs) { + var showTimer; + + //This is where all the magic happens! + // Whenever the scope variable updates we simply + // show if it evaluates to 'true' and hide if 'false' + scope.$watch('show', function(newVal){ + console.log("show value changed", newVal); + newVal ? showSpinner() : hideSpinner(); + }); + + function showSpinner() { + showElement(true); + } + + function hideSpinner() { + $timeout(showElement.bind(this, false), getDelay()); + } + + function showElement(show) { + console.log("show:", show); + show ? elem.css({display:''}) : elem.css({display:'none'}); + } + + function getDelay() { + var delay = parseInt(scope.delay); + + return angular.isNumber(delay) ? delay : 200; + } + } + + }; +}); diff --git a/app/assets/javascripts/app/services/sync/syncManager.js b/app/assets/javascripts/app/services/sync/syncManager.js index d9603fedf..c0d32ab6c 100644 --- a/app/assets/javascripts/app/services/sync/syncManager.js +++ b/app/assets/javascripts/app/services/sync/syncManager.js @@ -123,6 +123,8 @@ class SyncManager { this.addAllDataAsNeedingSyncForProvider(syncProvider); this.didMakeChangesToSyncProviders(); this.syncWithProvider(syncProvider); + this.syncWithProvider(syncProvider); + this.syncWithProvider(syncProvider); } addAllDataAsNeedingSyncForProvider(syncProvider) { diff --git a/app/assets/javascripts/app/services/sync/syncProvider.js b/app/assets/javascripts/app/services/sync/syncProvider.js index 79055803c..0e197e8d9 100644 --- a/app/assets/javascripts/app/services/sync/syncProvider.js +++ b/app/assets/javascripts/app/services/sync/syncProvider.js @@ -2,6 +2,7 @@ class SyncProvider { constructor(obj) { this.encrypted = true; + this.syncStatus = new SyncStatus(); _.merge(this, obj); } @@ -39,5 +40,14 @@ class SyncProvider { syncToken: this.syncToken } } - +} + +class SyncStatus { + constructor() { + + } + + get statusString() { + return `${this.current}/${this.total}` + } } diff --git a/app/assets/javascripts/app/services/sync/syncRunner.js b/app/assets/javascripts/app/services/sync/syncRunner.js index 0d1b809e9..4172e3a8e 100644 --- a/app/assets/javascripts/app/services/sync/syncRunner.js +++ b/app/assets/javascripts/app/services/sync/syncRunner.js @@ -91,6 +91,8 @@ class SyncRunner { return; } + // whether this is a repeat sync (a continuation from another sync; we use this to update status accurately) + var isRepeatRun = provider.repeatOnCompletion; provider.syncOpInProgress = true; @@ -104,6 +106,11 @@ class SyncRunner { provider.repeatOnCompletion = false; } + if(!isRepeatRun) { + provider.syncStatus.total = allItems.length; + provider.syncStatus.current = 0; + } + console.log("Syncing with provider:", provider.url, "items:", subItems.length); // Remove dirty items now. If this operation fails, we'll re-add them. @@ -123,7 +130,9 @@ class SyncRunner { request.post().then(function(response) { - console.log("Completed sync for provider:", provider.url, "Response:", response); + if(!provider.primary) { + console.log("Completed sync for provider:", provider.url, "Response:", response); + } provider.syncToken = response.sync_token; @@ -145,6 +154,10 @@ class SyncRunner { } provider.syncOpInProgress = false; + if(!provider.primary) { + console.log("Adding", subItems.length, "to", provider.syncStatus.current); + } + provider.syncStatus.current += subItems.length; if(provider.cursorToken || provider.repeatOnCompletion == true) { this.__performSyncWithProvider(provider, options, callback); diff --git a/app/assets/stylesheets/app/_directives.scss b/app/assets/stylesheets/app/_directives.scss index 6037d8051..1f06542c4 100644 --- a/app/assets/stylesheets/app/_directives.scss +++ b/app/assets/stylesheets/app/_directives.scss @@ -242,6 +242,11 @@ Extensions margin-top: 4px; } + .sync-status { + font-weight: bold; + height: 30px; + } + > .options { margin-top: 10px; } diff --git a/app/assets/templates/frontend/directives/account-data-menu.html.haml b/app/assets/templates/frontend/directives/account-data-menu.html.haml index 123ba1c9c..195d82343 100644 --- a/app/assets/templates/frontend/directives/account-data-menu.html.haml +++ b/app/assets/templates/frontend/directives/account-data-menu.html.haml @@ -10,7 +10,7 @@ %account-sync-section{"ng-if" => "showSync"} %section.account-item - %h3{"ng-click" => "showKeys = !showKeys"} Encryption Keys + %h3{"ng-click" => "showKeys = !showKeys"} Encryption Keys ({{keys.length}}) %account-keys-section{"ng-if" => "showKeys"} %section.account-item diff --git a/app/assets/templates/frontend/directives/account-sync-section.html.haml b/app/assets/templates/frontend/directives/account-sync-section.html.haml index b16189b48..856fde971 100644 --- a/app/assets/templates/frontend/directives/account-sync-section.html.haml +++ b/app/assets/templates/frontend/directives/account-sync-section.html.haml @@ -17,6 +17,9 @@ %button.light{"ng-if" => "syncProviders.length > 1", "ng-click" => "enableSyncProvider(provider, false)"} Enable as Secondary sync provider %button.light{"ng-if" => "provider.keyName", "ng-click" => "changeEncryptionKey(provider)"} Change Encryption Key %button.light{"ng-click" => "removeSyncProvider(provider)"} Remove Provider + .sync-status{"delay-hide" => "true", "show" => "provider.syncOpInProgress", "delay" => "1000"} + .text{"style" => "float: left;"} Syncing: {{provider.syncStatus.statusString}} + .spinner{"style" => "float: right"} %a{"ng-click" => "newSyncData.showAddSyncForm = !newSyncData.showAddSyncForm"} Add external sync with Secret URL %form.sync-form{"ng-if" => "newSyncData.showAddSyncForm"}