From 89bfa0c5360424bd327107c9c6a550f0a2a7c4cb Mon Sep 17 00:00:00 2001 From: Francis Lachapelle Date: Thu, 1 Jun 2017 13:46:57 -0400 Subject: [PATCH] Expose user's settings and defaults inline This improves performance by removing two AJAX calls and a lot of JavaScript promises. --- NEWS | 1 + UI/PreferencesUI/product.plist | 4 +- .../PreferencesUI/UIxJSONPreferences.wox | 12 + UI/Templates/UIxPageFrame.wox | 15 +- .../js/Common/sgAvatarImage.directive.js | 21 +- .../js/Contacts/AddressBook.service.js | 175 +++++++------- .../js/Contacts/Card.service.js | 24 +- .../js/Mailer/Account.service.js | 46 ++-- .../js/Mailer/Mailbox.service.js | 79 +++---- .../js/Mailer/MailboxesController.js | 14 +- .../js/Mailer/Message.service.js | 17 +- .../js/Mailer/MessageEditorController.js | 15 +- .../js/Preferences/Preferences.app.js | 10 - .../js/Preferences/Preferences.service.js | 72 +++--- .../js/Preferences/PreferencesController.js | 14 +- .../js/Scheduler/Calendar.service.js | 8 +- .../js/Scheduler/CalendarController.js | 24 +- .../js/Scheduler/CalendarListController.js | 38 +-- .../js/Scheduler/CalendarsController.js | 64 +++--- .../js/Scheduler/Component.service.js | 217 ++++++++---------- .../js/Scheduler/Scheduler.app.js | 36 ++- .../sgCalendarScrollView.directive.js | 19 +- 22 files changed, 441 insertions(+), 484 deletions(-) create mode 100644 UI/Templates/PreferencesUI/UIxJSONPreferences.wox diff --git a/NEWS b/NEWS index afc97c661..a61128851 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,7 @@ Enhancements - [web] improve display of tasks status - [web] added custom fields support from Thunderbird's address book - [web] added Latvian (lv) translation - thanks to Juris Balandis + - [web] expose user's defaults and settings inline Bug fixes - [web] respect SOGoLanguage and SOGoSupportedLanguages (#4169) diff --git a/UI/PreferencesUI/product.plist b/UI/PreferencesUI/product.plist index ddb329aca..2299064e5 100644 --- a/UI/PreferencesUI/product.plist +++ b/UI/PreferencesUI/product.plist @@ -33,12 +33,12 @@ }; jsonDefaults = { protectedBy = "View"; - actionClass = "UIxJSONPreferences"; + pageName = "UIxJSONPreferences"; actionName = "jsonDefaults"; }; jsonSettings = { protectedBy = "View"; - actionClass = "UIxJSONPreferences"; + pageName = "UIxJSONPreferences"; actionName = "jsonSettings"; }; save = { diff --git a/UI/Templates/PreferencesUI/UIxJSONPreferences.wox b/UI/Templates/PreferencesUI/UIxJSONPreferences.wox new file mode 100644 index 000000000..594a1ab00 --- /dev/null +++ b/UI/Templates/PreferencesUI/UIxJSONPreferences.wox @@ -0,0 +1,12 @@ + + + + + diff --git a/UI/Templates/UIxPageFrame.wox b/UI/Templates/UIxPageFrame.wox index 3dc2ac165..dc4d9910c 100644 --- a/UI/Templates/UIxPageFrame.wox +++ b/UI/Templates/UIxPageFrame.wox @@ -58,16 +58,6 @@ - @@ -131,10 +121,15 @@ // This is the equivalent of an AJAX call to /SOGo/so/_UserLogin_/date var currentDay = ; + + + + + diff --git a/UI/WebServerResources/js/Common/sgAvatarImage.directive.js b/UI/WebServerResources/js/Common/sgAvatarImage.directive.js index d751ef302..01d3996ad 100644 --- a/UI/WebServerResources/js/Common/sgAvatarImage.directive.js +++ b/UI/WebServerResources/js/Common/sgAvatarImage.directive.js @@ -77,18 +77,15 @@ $element.off('click', toggleZoomFcn); }); - // Wait on user's defaults - Preferences.ready().then(function() { - $scope.$watch(function() { return vm.email; }, function(email, old) { - if (email && vm.urlEmail != email) { - // Email has changed or doesn't match the current URL (this happens when using md-virtual-repeat) - showGenericAvatar(); - if (Preferences.defaults.SOGoGravatarEnabled) - getGravatar(email); - } - else if (!email) - showGenericAvatar(); - }); + $scope.$watch(function() { return vm.email; }, function(email, old) { + if (email && vm.urlEmail != email) { + // Email has changed or doesn't match the current URL (this happens when using md-virtual-repeat) + showGenericAvatar(); + if (Preferences.defaults.SOGoGravatarEnabled) + getGravatar(email); + } + else if (!email) + showGenericAvatar(); }); // If sg-src is defined, watch the expression for the URL of a local image diff --git a/UI/WebServerResources/js/Contacts/AddressBook.service.js b/UI/WebServerResources/js/Contacts/AddressBook.service.js index ce6b0fd03..0697aa8e1 100644 --- a/UI/WebServerResources/js/Contacts/AddressBook.service.js +++ b/UI/WebServerResources/js/Contacts/AddressBook.service.js @@ -49,12 +49,11 @@ $refreshTimeout: null }); // Initialize sort parameters from user's settings - Preferences.ready().then(function() { - if (Preferences.settings.Contact.SortingState) { - AddressBook.$query.sort = Preferences.settings.Contact.SortingState[0]; - AddressBook.$query.asc = parseInt(Preferences.settings.Contact.SortingState[1]); - } - }); + if (Preferences.settings.Contact.SortingState) { + AddressBook.$query.sort = Preferences.settings.Contact.SortingState[0]; + AddressBook.$query.asc = parseInt(Preferences.settings.Contact.SortingState[1]); + } + return AddressBook; // return constructor }]; @@ -437,19 +436,15 @@ * @desc Starts the refresh timeout for the current selected address book */ AddressBook.prototype.$startRefreshTimeout = function() { - var _this = this; - if (AddressBook.$refreshTimeout) AddressBook.$timeout.cancel(AddressBook.$refreshTimeout); - AddressBook.$Preferences.ready().then(function() { - // Restart the refresh timer, if needed - var refreshViewCheck = AddressBook.$Preferences.defaults.SOGoRefreshViewCheck; - if (refreshViewCheck && refreshViewCheck != 'manually') { - var f = angular.bind(_this, AddressBook.prototype.$reload); - AddressBook.$refreshTimeout = AddressBook.$timeout(f, refreshViewCheck.timeInterval()*1000); - } - }); + // Restart the refresh timer, if needed + var refreshViewCheck = AddressBook.$Preferences.defaults.SOGoRefreshViewCheck; + if (refreshViewCheck && refreshViewCheck != 'manually') { + var f = angular.bind(this, AddressBook.prototype.$reload); + AddressBook.$refreshTimeout = AddressBook.$timeout(f, refreshViewCheck.timeInterval()*1000); + } }; /** @@ -487,91 +482,89 @@ if (!this.isRemote) query.partial = 1; } - return AddressBook.$Preferences.ready().then(function() { - if (options) { - angular.extend(query, options); - if (dry) { - if (!search) { - // No query specified - _this.$$cards = []; - return AddressBook.$q.when(_this.$$cards); - } + if (options) { + angular.extend(query, options); + if (dry) { + if (!search) { + // No query specified + _this.$$cards = []; + return AddressBook.$q.when(_this.$$cards); } } + } - if (angular.isDefined(search)) - query.value = search; + if (angular.isDefined(search)) + query.value = search; - return _this.$id().then(function(addressbookId) { - var futureData = AddressBook.$$resource.fetch(addressbookId, 'view', query); + return _this.$id().then(function(addressbookId) { + var futureData = AddressBook.$$resource.fetch(addressbookId, 'view', query); - if (dry) { - return futureData.then(function(response) { - var results, headers, card, index, fields, idFieldIndex, - cards = _this.$$cards, - compareIds = function(card) { - return this == card.id; - }; + if (dry) { + return futureData.then(function(response) { + var results, headers, card, index, fields, idFieldIndex, + cards = _this.$$cards, + compareIds = function(card) { + return this == card.id; + }; - if (response.headers) { - // First entry of 'headers' are keys - fields = _.invokeMap(response.headers[0], 'toLowerCase'); - idFieldIndex = fields.indexOf('id'); - response.headers.splice(0, 1); + if (response.headers) { + // First entry of 'headers' are keys + fields = _.invokeMap(response.headers[0], 'toLowerCase'); + idFieldIndex = fields.indexOf('id'); + response.headers.splice(0, 1); + } + + if (excludedCards) + // Remove excluded cards from results + results = _.filter(response.ids, function(id) { + return _.isUndefined(_.find(excludedCards, _.bind(compareIds, id))); + }); + else + results = response.ids; + + // Remove cards that no longer match the search query + for (index = cards.length - 1; index >= 0; index--) { + card = cards[index]; + if (_.isUndefined(_.find(results, _.bind(compareIds, card.id)))) { + cards.splice(index, 1); } + } - if (excludedCards) - // Remove excluded cards from results - results = _.filter(response.ids, function(id) { - return _.isUndefined(_.find(excludedCards, _.bind(compareIds, id))); - }); - else - results = response.ids; - - // Remove cards that no longer match the search query - for (index = cards.length - 1; index >= 0; index--) { - card = cards[index]; - if (_.isUndefined(_.find(results, _.bind(compareIds, card.id)))) { - cards.splice(index, 1); - } + // Add new cards matching the search query + _.forEach(results, function(cardId, index) { + if (_.isUndefined(_.find(cards, _.bind(compareIds, cardId)))) { + var data = { pid: addressbookId, id: cardId }; + var card = new AddressBook.$Card(data, search); + cards.splice(index, 0, card); } - - // Add new cards matching the search query - _.forEach(results, function(cardId, index) { - if (_.isUndefined(_.find(cards, _.bind(compareIds, cardId)))) { - var data = { pid: addressbookId, id: cardId }; - var card = new AddressBook.$Card(data, search); - cards.splice(index, 0, card); - } - }); - - // Respect the order of the results - _.forEach(results, function(cardId, index) { - var oldIndex, removedCards; - if (cards[index].id != cardId) { - oldIndex = _.findIndex(cards, _.bind(compareIds, cardId)); - removedCards = cards.splice(oldIndex, 1); - cards.splice(index, 0, removedCards[0]); - } - }); - - // Extend Card objects with received headers - _.forEach(response.headers, function(data) { - var card, index = _.findIndex(cards, _.bind(compareIds, data[idFieldIndex])); - if (index > -1) { - card = _.zipObject(fields, data); - cards[index].init(card, search); - } - }); - - return cards; }); - } - else { - // Unwrap promise and instantiate or extend Cards objets - return _this.$unwrap(futureData); - } - }); + + // Respect the order of the results + _.forEach(results, function(cardId, index) { + var oldIndex, removedCards; + if (cards[index].id != cardId) { + oldIndex = _.findIndex(cards, _.bind(compareIds, cardId)); + removedCards = cards.splice(oldIndex, 1); + cards.splice(index, 0, removedCards[0]); + } + }); + + // Extend Card objects with received headers + _.forEach(response.headers, function(data) { + var card, index = _.findIndex(cards, _.bind(compareIds, data[idFieldIndex])); + if (index > -1) { + card = _.zipObject(fields, data); + cards[index].init(card, search); + } + }); + + return cards; + }); + } + else { + // Unwrap promise and instantiate or extend Cards objets + return _this.$unwrap(futureData); + } }); }; diff --git a/UI/WebServerResources/js/Contacts/Card.service.js b/UI/WebServerResources/js/Contacts/Card.service.js index 8f8753164..2d6ac8b3a 100644 --- a/UI/WebServerResources/js/Contacts/Card.service.js +++ b/UI/WebServerResources/js/Contacts/Card.service.js @@ -46,13 +46,11 @@ $Preferences: Preferences }); // Initialize categories from user's defaults - Preferences.ready().then(function() { - if (Preferences.defaults.SOGoContactsCategories) { - Card.$categories = Preferences.defaults.SOGoContactsCategories; - } - if (Preferences.defaults.SOGoAlternateAvatar) - Card.$alternateAvatar = Preferences.defaults.SOGoAlternateAvatar; - }); + if (Preferences.defaults.SOGoContactsCategories) { + Card.$categories = Preferences.defaults.SOGoContactsCategories; + } + if (Preferences.defaults.SOGoAlternateAvatar) + Card.$alternateAvatar = Preferences.defaults.SOGoAlternateAvatar; return Card; // return constructor }]; @@ -149,9 +147,7 @@ if (!this.$$image) this.$$image = this.image; if (!this.$$image) - Card.$Preferences.avatar(this.$$email, 32, {no_404: true}).then(function(url) { - _this.$$image = url; - }); + this.$$image = Card.$Preferences.avatar(this.$$email, 32, {no_404: true}); if (this.hasphoto) this.photoURL = Card.$$resource.path(this.pid, this.id, 'photo'); if (this.isgroup) @@ -177,11 +173,9 @@ }); // Instanciate date object of birthday if (this.birthday) { - Card.$Preferences.ready().then(function() { - var dlp = Card.$Preferences.$mdDateLocaleProvider; - _this.birthday = _this.birthday.parseDate(dlp, '%Y-%m-%d'); - _this.$birthday = dlp.formatDate(_this.birthday); - }); + var dlp = Card.$Preferences.$mdDateLocaleProvider; + this.birthday = this.birthday.parseDate(dlp, '%Y-%m-%d'); + this.$birthday = dlp.formatDate(this.birthday); } this.$loaded = angular.isDefined(this.c_name)? Card.STATUS.LOADED : Card.STATUS.NOT_LOADED; diff --git a/UI/WebServerResources/js/Mailer/Account.service.js b/UI/WebServerResources/js/Mailer/Account.service.js index 38a8dd621..340c6fb0e 100644 --- a/UI/WebServerResources/js/Mailer/Account.service.js +++ b/UI/WebServerResources/js/Mailer/Account.service.js @@ -136,31 +136,29 @@ _this.$expanded = false; // Set expanded folders from user's settings - Account.$Preferences.ready().then(function() { - var expandedFolders, - _visit = function(mailboxes) { - _.forEach(mailboxes, function(o) { - o.$expanded = (expandedFolders.indexOf('/' + o.id) >= 0); - if (o.children && o.children.length > 0) { - _visit(o.children); - } - }); - }; - if (Account.$Preferences.settings.Mail.ExpandedFolders) { - if (angular.isString(Account.$Preferences.settings.Mail.ExpandedFolders)) - // Backward compatibility support - expandedFolders = angular.fromJson(Account.$Preferences.settings.Mail.ExpandedFolders); - else - expandedFolders = Account.$Preferences.settings.Mail.ExpandedFolders; - _this.$expanded = (expandedFolders.indexOf('/' + _this.id) >= 0); - if (expandedFolders.length > 0) { - _visit(_this.$mailboxes); - } + var expandedFolders, + _visit = function(mailboxes) { + _.forEach(mailboxes, function(o) { + o.$expanded = (expandedFolders.indexOf('/' + o.id) >= 0); + if (o.children && o.children.length > 0) { + _visit(o.children); + } + }); + }; + if (Account.$Preferences.settings.Mail.ExpandedFolders) { + if (angular.isString(Account.$Preferences.settings.Mail.ExpandedFolders)) + // Backward compatibility support + expandedFolders = angular.fromJson(Account.$Preferences.settings.Mail.ExpandedFolders); + else + expandedFolders = Account.$Preferences.settings.Mail.ExpandedFolders; + _this.$expanded = (expandedFolders.indexOf('/' + _this.id) >= 0); + if (expandedFolders.length > 0) { + _visit(_this.$mailboxes); } - if (Account.$accounts) - _this.$expanded |= (Account.$accounts.length == 1); // Always expand single account - _this.$flattenMailboxes({reload: true}); - }); + } + if (Account.$accounts) + _this.$expanded |= (Account.$accounts.length == 1); // Always expand single account + _this.$flattenMailboxes({reload: true}); return _this.$mailboxes; }); diff --git a/UI/WebServerResources/js/Mailer/Mailbox.service.js b/UI/WebServerResources/js/Mailer/Mailbox.service.js index ba3b7cc2b..5884e2fd3 100644 --- a/UI/WebServerResources/js/Mailer/Mailbox.service.js +++ b/UI/WebServerResources/js/Mailer/Mailbox.service.js @@ -48,12 +48,10 @@ PRELOAD: PRELOAD }); // Initialize sort parameters from user's settings - Preferences.ready().then(function() { - if (Preferences.settings.Mail.SortingState) { - Mailbox.$query.sort = Preferences.settings.Mail.SortingState[0]; - Mailbox.$query.asc = parseInt(Preferences.settings.Mail.SortingState[1]); - } - }); + if (Preferences.settings.Mail.SortingState) { + Mailbox.$query.sort = Preferences.settings.Mail.SortingState[0]; + Mailbox.$query.asc = parseInt(Preferences.settings.Mail.SortingState[1]); + } return Mailbox; // return constructor }]; @@ -343,46 +341,43 @@ _this.$isLoading = true; }); - return Mailbox.$Preferences.ready().then(function() { + if (Mailbox.$refreshTimeout) + Mailbox.$timeout.cancel(Mailbox.$refreshTimeout); - if (Mailbox.$refreshTimeout) - Mailbox.$timeout.cancel(Mailbox.$refreshTimeout); + if (sortingAttributes) + // Sorting preferences are common to all mailboxes + angular.extend(Mailbox.$query, sortingAttributes); - if (sortingAttributes) - // Sorting preferences are common to all mailboxes - angular.extend(Mailbox.$query, sortingAttributes); - - angular.extend(options, { sortingAttributes: Mailbox.$query }); - if (angular.isDefined(filters)) { - options.filters = _.reject(filters, function(filter) { - return !filter.searchInput || filter.searchInput.length === 0; - }); - // Decompose filters that match two fields - _.forEach(options.filters, function(filter) { - var secondFilter, - match = filter.searchBy.match(/(\w+)_or_(\w+)/); - if (match) { - options.sortingAttributes.match = 'OR'; - filter.searchBy = match[1]; - secondFilter = angular.copy(filter); - secondFilter.searchBy = match[2]; - options.filters.push(secondFilter); - } - }); - } - - // Restart the refresh timer, if needed - if (!Mailbox.$virtualMode) { - var refreshViewCheck = Mailbox.$Preferences.defaults.SOGoRefreshViewCheck; - if (refreshViewCheck && refreshViewCheck != 'manually') { - var f = angular.bind(_this, Mailbox.prototype.$filter, null, filters); - Mailbox.$refreshTimeout = Mailbox.$timeout(f, refreshViewCheck.timeInterval()*1000); + angular.extend(options, { sortingAttributes: Mailbox.$query }); + if (angular.isDefined(filters)) { + options.filters = _.reject(filters, function(filter) { + return !filter.searchInput || filter.searchInput.length === 0; + }); + // Decompose filters that match two fields + _.forEach(options.filters, function(filter) { + var secondFilter, + match = filter.searchBy.match(/(\w+)_or_(\w+)/); + if (match) { + options.sortingAttributes.match = 'OR'; + filter.searchBy = match[1]; + secondFilter = angular.copy(filter); + secondFilter.searchBy = match[2]; + options.filters.push(secondFilter); } - } + }); + } - var futureMailboxData = Mailbox.$$resource.post(_this.id, 'view', options); - return _this.$unwrap(futureMailboxData); - }); + // Restart the refresh timer, if needed + if (!Mailbox.$virtualMode) { + var refreshViewCheck = Mailbox.$Preferences.defaults.SOGoRefreshViewCheck; + if (refreshViewCheck && refreshViewCheck != 'manually') { + var f = angular.bind(this, Mailbox.prototype.$filter, null, filters); + Mailbox.$refreshTimeout = Mailbox.$timeout(f, refreshViewCheck.timeInterval()*1000); + } + } + + var futureMailboxData = Mailbox.$$resource.post(this.id, 'view', options); + return this.$unwrap(futureMailboxData); }; /** diff --git a/UI/WebServerResources/js/Mailer/MailboxesController.js b/UI/WebServerResources/js/Mailer/MailboxesController.js index 2e4121421..6bf15e79f 100644 --- a/UI/WebServerResources/js/Mailer/MailboxesController.js +++ b/UI/WebServerResources/js/Mailer/MailboxesController.js @@ -32,9 +32,7 @@ params: [] }; - Preferences.ready().then(function() { - vm.showSubscribedOnly = Preferences.defaults.SOGoMailShowSubscribedFoldersOnly; - }); + this.showSubscribedOnly = Preferences.defaults.SOGoMailShowSubscribedFoldersOnly; this.refreshUnseenCount(); @@ -258,7 +256,7 @@ }; // delegate this.refreshUnseenCount = function() { - var unseenCountFolders = $window.unseenCountFolders; + var unseenCountFolders = $window.unseenCountFolders, refreshViewCheck; _.forEach(vm.accounts, function(account) { @@ -282,11 +280,9 @@ }); }); - Preferences.ready().then(function() { - var refreshViewCheck = Preferences.defaults.SOGoRefreshViewCheck; - if (refreshViewCheck && refreshViewCheck != 'manually') - $timeout(vm.refreshUnseenCount, refreshViewCheck.timeInterval()*1000); - }); + refreshViewCheck = Preferences.defaults.SOGoRefreshViewCheck; + if (refreshViewCheck && refreshViewCheck != 'manually') + $timeout(vm.refreshUnseenCount, refreshViewCheck.timeInterval()*1000); }; this.isDroppableFolder = function(srcFolder, dstFolder) { diff --git a/UI/WebServerResources/js/Mailer/Message.service.js b/UI/WebServerResources/js/Mailer/Message.service.js index 99e7ce06c..0a412ffab 100644 --- a/UI/WebServerResources/js/Mailer/Message.service.js +++ b/UI/WebServerResources/js/Mailer/Message.service.js @@ -48,16 +48,15 @@ $$resource: new Resource(Settings.activeUser('folderURL') + 'Mail', Settings.activeUser()), $avatar: angular.bind(Preferences, Preferences.avatar) }); + // Initialize tags form user's defaults - Preferences.ready().then(function() { - if (Preferences.defaults.SOGoMailLabelsColors) { - Message.$tags = Preferences.defaults.SOGoMailLabelsColors; - } - if (Preferences.defaults.SOGoMailDisplayRemoteInlineImages && - Preferences.defaults.SOGoMailDisplayRemoteInlineImages == 'always') { - Message.$displayRemoteInlineImages = true; - } - }); + if (Preferences.defaults.SOGoMailLabelsColors) { + Message.$tags = Preferences.defaults.SOGoMailLabelsColors; + } + if (Preferences.defaults.SOGoMailDisplayRemoteInlineImages && + Preferences.defaults.SOGoMailDisplayRemoteInlineImages == 'always') { + Message.$displayRemoteInlineImages = true; + } return Message; // return constructor }]; diff --git a/UI/WebServerResources/js/Mailer/MessageEditorController.js b/UI/WebServerResources/js/Mailer/MessageEditorController.js index c3941a3f4..7c5524d12 100644 --- a/UI/WebServerResources/js/Mailer/MessageEditorController.js +++ b/UI/WebServerResources/js/Mailer/MessageEditorController.js @@ -65,6 +65,13 @@ } }); + // Read user's defaults + if (Preferences.defaults.SOGoMailAutoSave) + // Enable auto-save of draft + vm.autosave = $timeout(vm.autosaveDrafts, Preferences.defaults.SOGoMailAutoSave*1000*60); + // Set the locale of CKEditor + vm.localeCode = Preferences.defaults.LocaleCode; + // Destroy file uploader when the controller is being deactivated $scope.$on('$destroy', function() { vm.uploader.destroy(); }); @@ -297,14 +304,6 @@ vm.autosave = $timeout(vm.autosaveDrafts, Preferences.defaults.SOGoMailAutoSave*1000*60); } - // Read user's defaults - Preferences.ready().then(function() { - if (Preferences.defaults.SOGoMailAutoSave) - // Enable auto-save of draft - vm.autosave = $timeout(vm.autosaveDrafts, Preferences.defaults.SOGoMailAutoSave*1000*60); - // Set the locale of CKEditor - vm.localeCode = Preferences.defaults.LocaleCode; - }); } SendMessageToastController.$inject = ['$scope', '$mdToast']; diff --git a/UI/WebServerResources/js/Preferences/Preferences.app.js b/UI/WebServerResources/js/Preferences/Preferences.app.js index 538c6f25d..f38b224d9 100644 --- a/UI/WebServerResources/js/Preferences/Preferences.app.js +++ b/UI/WebServerResources/js/Preferences/Preferences.app.js @@ -22,9 +22,6 @@ controller: 'PreferencesController', controllerAs: 'app' } - }, - resolve: { - statePreferences: statePreferences } }) .state('preferences.general', { @@ -64,13 +61,6 @@ $urlRouterProvider.otherwise('/general'); } - /** - * @ngInject - */ - statePreferences.$inject = ['Preferences']; - function statePreferences(Preferences) { - return Preferences; - } /** * @ngInject diff --git a/UI/WebServerResources/js/Preferences/Preferences.service.js b/UI/WebServerResources/js/Preferences/Preferences.service.js index b0ae12eb2..83192eb7b 100644 --- a/UI/WebServerResources/js/Preferences/Preferences.service.js +++ b/UI/WebServerResources/js/Preferences/Preferences.service.js @@ -8,13 +8,19 @@ * @constructor */ function Preferences() { - var _this = this; + var _this = this, defaultsElement, settingsElement, data; this.defaults = {}; this.settings = {}; - this.defaultsPromise = Preferences.$$resource.fetch("jsonDefaults").then(function(response) { - var data = response || {}; + defaultsElement = Preferences.$document[0].getElementById('UserDefaults'); + if (defaultsElement) { + try { + data = angular.fromJson(defaultsElement.textContent || defaultsElement.innerHTML); + } catch (e) { + Preferences.$log.error("Can't parse user's defaults: " + e.message); + data = {}; + } // We swap $key -> _$key to avoid an Angular bug (https://github.com/angular/angular.js/issues/6266) var labels = _.fromPairs(_.map(data.SOGoMailLabelsColors, function(value, key) { @@ -117,22 +123,28 @@ _this.$mdDateLocaleProvider.msgCalendar = l('Calender'); _this.$mdDateLocaleProvider.msgOpenCalendar = l('Open Calendar'); _this.$mdDateLocaleProvider.parseDate = function(dateString) { - return dateString? dateString.parseDate(_this.$mdDateLocaleProvider, data.SOGoShortDateFormat) : new Date(NaN); + return dateString? dateString.parseDate(_this.$mdDateLocaleProvider, _this.defaults.SOGoShortDateFormat) : new Date(NaN); }; _this.$mdDateLocaleProvider.formatDate = function(date) { - return date? date.format(_this.$mdDateLocaleProvider, date.$dateFormat || data.SOGoShortDateFormat) : ''; + return date? date.format(_this.$mdDateLocaleProvider, date.$dateFormat || _this.defaults.SOGoShortDateFormat) : ''; }; _this.$mdDateLocaleProvider.parseTime = function(timeString) { - return timeString? timeString.parseDate(_this.$mdDateLocaleProvider, data.SOGoTimeFormat) : new Date(NaN); + return timeString? timeString.parseDate(_this.$mdDateLocaleProvider, _this.defaults.SOGoTimeFormat) : new Date(NaN); }; _this.$mdDateLocaleProvider.formatTime = function(date) { - return date? date.format(_this.$mdDateLocaleProvider, data.SOGoTimeFormat) : ''; + return date? date.format(_this.$mdDateLocaleProvider, _this.defaults.SOGoTimeFormat) : ''; }; + } - return _this.defaults; - }); + settingsElement = Preferences.$document[0].getElementById('UserSettings'); + if (settingsElement) { + try { + data = angular.fromJson(settingsElement.textContent || settingsElement.innerHTML); + } catch (e) { + Preferences.$log.error("Can't parse user's settings: " + e.message); + data = {}; + } - this.settingsPromise = Preferences.$$resource.fetch("jsonSettings").then(function(data) { // We convert our PreventInvitationsWhitelist hash into a array of user if (data.Calendar) { if (data.Calendar.PreventInvitationsWhitelist) { @@ -140,9 +152,7 @@ var match = /^(.+)\s<(\S+)>$/.exec(value), user = new Preferences.$User({uid: key, cn: match[1], c_email: match[2]}); if (!user.$$image) - _this.avatar(user.c_email, 32, {no_404: true}).then(function(url) { - user.$$image = url; - }); + user.$$image = _this.avatar(user.c_email, 32, {no_404: true}); return user; }); } @@ -151,9 +161,7 @@ } angular.extend(_this.settings, data); - - return _this.settings; - }); + } } /** @@ -161,8 +169,9 @@ * @desc The factory we'll use to register with Angular * @returns the Preferences constructor */ - Preferences.$factory = ['$q', '$timeout', '$log', '$mdDateLocale', 'sgSettings', 'Gravatar', 'Resource', 'User', function($q, $timeout, $log, $mdDateLocaleProvider, Settings, Gravatar, Resource, User) { + Preferences.$factory = ['$document', '$q', '$timeout', '$log', '$mdDateLocale', 'sgSettings', 'Gravatar', 'Resource', 'User', function($document, $q, $timeout, $log, $mdDateLocaleProvider, Settings, Gravatar, Resource, User) { angular.extend(Preferences, { + $document: $document, $q: $q, $timeout: $timeout, $log: $log, @@ -195,7 +204,8 @@ * @return a combined promise */ Preferences.prototype.ready = function() { - return Preferences.$q.all([this.defaultsPromise, this.settingsPromise]); + Preferences.$log.warn('Preferences.ready is deprecated -- access settings/defaults directly.'); + return Preferences.$q.when(true); }; /** @@ -206,16 +216,14 @@ */ Preferences.prototype.avatar = function(email, size, options) { var _this = this; - return this.ready().then(function() { - var alternate_avatar = _this.defaults.SOGoAlternateAvatar, url; - if (_this.defaults.SOGoGravatarEnabled) - url = Preferences.$gravatar(email, size, alternate_avatar, options); - else - url = [Preferences.$resourcesURL, 'img', 'ic_person_grey_24px.svg'].join('/'); - if (options && options.dstObject && options.dstAttr) - options.dstObject[options.dstAttr] = url; - return url; - }); + var alternate_avatar = _this.defaults.SOGoAlternateAvatar, url; + if (_this.defaults.SOGoGravatarEnabled) + url = Preferences.$gravatar(email, size, alternate_avatar, options); + else + url = [Preferences.$resourcesURL, 'img', 'ic_person_grey_24px.svg'].join('/'); + if (options && options.dstObject && options.dstAttr) + options.dstObject[options.dstAttr] = url; + return url; }; /** @@ -285,12 +293,16 @@ if (preferences.defaults.Vacation) { if (preferences.defaults.Vacation.startDateEnabled) preferences.defaults.Vacation.startDate = preferences.defaults.Vacation.startDate.getTime()/1000; - else + else { + delete preferences.defaults.Vacation.startDateEnabled; preferences.defaults.Vacation.startDate = 0; + } if (preferences.defaults.Vacation.endDateEnabled) preferences.defaults.Vacation.endDate = preferences.defaults.Vacation.endDate.getTime()/1000; - else + else { + delete preferences.defaults.Vacation.endDateEnabled; preferences.defaults.Vacation.endDate = 0; + } if (preferences.defaults.Vacation.autoReplyEmailAddresses) preferences.defaults.Vacation.autoReplyEmailAddresses = _.filter(preferences.defaults.Vacation.autoReplyEmailAddresses.split(","), function(v) { return v.length; }); diff --git a/UI/WebServerResources/js/Preferences/PreferencesController.js b/UI/WebServerResources/js/Preferences/PreferencesController.js index 3cc80c154..60bfb8519 100644 --- a/UI/WebServerResources/js/Preferences/PreferencesController.js +++ b/UI/WebServerResources/js/Preferences/PreferencesController.js @@ -7,11 +7,11 @@ /** * @ngInject */ - PreferencesController.$inject = ['$q', '$window', '$state', '$mdMedia', '$mdSidenav', '$mdDialog', '$mdToast', 'sgSettings', 'sgFocus', 'Dialog', 'User', 'Account', 'statePreferences', 'Authentication']; - function PreferencesController($q, $window, $state, $mdMedia, $mdSidenav, $mdDialog, $mdToast, sgSettings, focus, Dialog, User, Account, statePreferences, Authentication) { + PreferencesController.$inject = ['$q', '$window', '$state', '$mdMedia', '$mdSidenav', '$mdDialog', '$mdToast', 'sgSettings', 'sgFocus', 'Dialog', 'User', 'Account', 'Preferences', 'Authentication']; + function PreferencesController($q, $window, $state, $mdMedia, $mdSidenav, $mdDialog, $mdToast, sgSettings, focus, Dialog, User, Account, Preferences, Authentication) { var vm = this, account, mailboxes = [], today = new Date(), tomorrow = today.beginOfDay().addDays(1); - vm.preferences = statePreferences; + vm.preferences = Preferences; vm.passwords = { newPassword: null, newPasswordConfirmation: null }; vm.go = go; @@ -60,11 +60,9 @@ } // Set alternate avatar in User service - statePreferences.ready().then(function() { - if (statePreferences.defaults.SOGoAlternateAvatar) - User.$alternateAvatar = statePreferences.defaults.SOGoAlternateAvatar; - updateVacationDates(); - }); + if (Preferences.defaults.SOGoAlternateAvatar) + User.$alternateAvatar = Preferences.defaults.SOGoAlternateAvatar; + updateVacationDates(); function go(module, form) { if (form.$valid) { diff --git a/UI/WebServerResources/js/Scheduler/Calendar.service.js b/UI/WebServerResources/js/Scheduler/Calendar.service.js index 398f31f1d..d01311d83 100644 --- a/UI/WebServerResources/js/Scheduler/Calendar.service.js +++ b/UI/WebServerResources/js/Scheduler/Calendar.service.js @@ -102,11 +102,9 @@ else list.splice(sibling, 0, calendar); - this.$Preferences.ready().then(function() { - if (Calendar.$Preferences.settings.Calendar.FoldersOrder) - // Save list order - Calendar.saveFoldersOrder(_.flatMap(Calendar.$findAll(), 'id')); - }); + if (Calendar.$Preferences.settings.Calendar.FoldersOrder) + // Save list order + Calendar.saveFoldersOrder(_.flatMap(Calendar.$findAll(), 'id')); // Refresh list of calendars to fetch links associated to new calendar Calendar.$reloadAll(); }; diff --git a/UI/WebServerResources/js/Scheduler/CalendarController.js b/UI/WebServerResources/js/Scheduler/CalendarController.js index b0755ba6f..7fba6a0c0 100644 --- a/UI/WebServerResources/js/Scheduler/CalendarController.js +++ b/UI/WebServerResources/js/Scheduler/CalendarController.js @@ -23,23 +23,23 @@ vm.changeView = changeView; - _registerHotkeys(hotkeys); + this.$onInit = function() { + _registerHotkeys(hotkeys); - Preferences.ready().then(function() { _formatDate(vm.selectedDate); - }); - // Refresh current view when the list of calendars is modified - deregisterCalendarsList = $rootScope.$on('calendars:list', updateView); + // Refresh current view when the list of calendars is modified + deregisterCalendarsList = $rootScope.$on('calendars:list', updateView); - $scope.$on('$destroy', function() { - // Destroy event listener when the controller is being deactivated - deregisterCalendarsList(); - // Deregister hotkeys - _.forEach(hotkeys, function(key) { - sgHotkeys.deregisterHotkey(key); + $scope.$on('$destroy', function() { + // Destroy event listener when the controller is being deactivated + deregisterCalendarsList(); + // Deregister hotkeys + _.forEach(hotkeys, function(key) { + sgHotkeys.deregisterHotkey(key); + }); }); - }); + }; function _registerHotkeys(keys) { diff --git a/UI/WebServerResources/js/Scheduler/CalendarListController.js b/UI/WebServerResources/js/Scheduler/CalendarListController.js index 2e0e6bff0..e366a6a5f 100644 --- a/UI/WebServerResources/js/Scheduler/CalendarListController.js +++ b/UI/WebServerResources/js/Scheduler/CalendarListController.js @@ -8,7 +8,7 @@ */ CalendarListController.$inject = ['$rootScope', '$scope', '$timeout', '$state', '$mdDialog', 'sgHotkeys', 'sgFocus', 'Dialog', 'Preferences', 'CalendarSettings', 'Calendar', 'Component', 'Alarm']; function CalendarListController($rootScope, $scope, $timeout, $state, $mdDialog, sgHotkeys, focus, Dialog, Preferences, CalendarSettings, Calendar, Component, Alarm) { - var vm = this, hotkeys = []; + var vm = this, hotkeys = [], type; vm.component = Component; vm.componentType = 'events'; @@ -32,32 +32,32 @@ vm.mode = { search: false, multiple: 0 }; - _registerHotkeys(hotkeys); + this.$onInit = function() { + _registerHotkeys(hotkeys); - // Select list based on user's settings - Preferences.ready().then(function() { - var type = 'events'; + // Select list based on user's settings + type = 'events'; if (Preferences.settings.Calendar.SelectedList == 'tasksListView') { vm.selectedList = 1; type = 'tasks'; } selectComponentType(type, { reload: true }); // fetch events/tasks lists - }); - // Refresh current list when the list of calendars is modified - $rootScope.$on('calendars:list', function() { - Component.$filter(vm.componentType, { reload: true }); - }); - - // Update the component being dragged - $rootScope.$on('calendar:dragend', updateComponentFromGhost); - - $scope.$on('$destroy', function() { - // Deregister hotkeys - _.forEach(hotkeys, function(key) { - sgHotkeys.deregisterHotkey(key); + // Refresh current list when the list of calendars is modified + $rootScope.$on('calendars:list', function() { + Component.$filter(vm.componentType, { reload: true }); }); - }); + + // Update the component being dragged + $rootScope.$on('calendar:dragend', updateComponentFromGhost); + + $scope.$on('$destroy', function() { + // Deregister hotkeys + _.forEach(hotkeys, function(key) { + sgHotkeys.deregisterHotkey(key); + }); + }); + }; function _registerHotkeys(keys) { diff --git a/UI/WebServerResources/js/Scheduler/CalendarsController.js b/UI/WebServerResources/js/Scheduler/CalendarsController.js index fc588e695..ee134047c 100644 --- a/UI/WebServerResources/js/Scheduler/CalendarsController.js +++ b/UI/WebServerResources/js/Scheduler/CalendarsController.js @@ -38,47 +38,47 @@ accept: _sortableAccept }; - Preferences.ready().then(function() { + this.$onInit = function() { vm.categories = _.map(Preferences.defaults.SOGoCalendarCategories, function(name) { return { id: name.asCSSIdentifier(), name: name, color: Preferences.defaults.SOGoCalendarCategoriesColors[name] }; }); - }); - // Dispatch the event named 'calendars:list' when a calendar is activated or deactivated or - // when the color of a calendar is changed - $scope.$watch( - function() { - return _.union( - _.map(Calendar.$calendars, function(o) { return _.pick(o, ['id', 'active', 'color']); }), - _.map(Calendar.$subscriptions, function(o) { return _.pick(o, ['id', 'active', 'color']); }), - _.map(Calendar.$webcalendars, function(o) { return _.pick(o, ['id', 'active', 'color']); }) - ); - }, - function(newList, oldList) { - var commonList, ids, promise; + // Dispatch the event named 'calendars:list' when a calendar is activated or deactivated or + // when the color of a calendar is changed + $scope.$watch( + function() { + return _.union( + _.map(Calendar.$calendars, function(o) { return _.pick(o, ['id', 'active', 'color']); }), + _.map(Calendar.$subscriptions, function(o) { return _.pick(o, ['id', 'active', 'color']); }), + _.map(Calendar.$webcalendars, function(o) { return _.pick(o, ['id', 'active', 'color']); }) + ); + }, + function(newList, oldList) { + var commonList, ids, promise; - // Identify which calendar has changed - commonList = _.intersectionBy(newList, oldList, 'id'); - ids = _.map(_.filter(commonList, function(o) { - var oldObject = _.find(oldList, { id: o.id }); - return !_.isEqual(o, oldObject); - }), 'id'); - promise = Calendar.$q.when(); + // Identify which calendar has changed + commonList = _.intersectionBy(newList, oldList, 'id'); + ids = _.map(_.filter(commonList, function(o) { + var oldObject = _.find(oldList, { id: o.id }); + return !_.isEqual(o, oldObject); + }), 'id'); + promise = Calendar.$q.when(); - if (ids.length > 0) { - $log.debug(ids.join(', ') + ' changed'); - promise = Calendar.saveFoldersActivation(ids); - } - if (ids.length > 0 || commonList.length != newList.length || commonList.length != oldList.length) - promise.then(function() { - $rootScope.$emit('calendars:list'); - }); - }, - true // compare for object equality - ); + if (ids.length > 0) { + $log.debug(ids.join(', ') + ' changed'); + promise = Calendar.saveFoldersActivation(ids); + } + if (ids.length > 0 || commonList.length != newList.length || commonList.length != oldList.length) + promise.then(function() { + $rootScope.$emit('calendars:list'); + }); + }, + true // compare for object equality + ); + }; /** * Only allow to sort items within the same list. diff --git a/UI/WebServerResources/js/Scheduler/Component.service.js b/UI/WebServerResources/js/Scheduler/Component.service.js index 307b50dc3..e6321b55d 100644 --- a/UI/WebServerResources/js/Scheduler/Component.service.js +++ b/UI/WebServerResources/js/Scheduler/Component.service.js @@ -52,28 +52,26 @@ $refreshTimeout: null, $ghost: {} }); - Preferences.ready().then(function() { - // Initialize filter parameters from user's settings - if (Preferences.settings.Calendar.EventsFilterState) - Component.$queryEvents.filterpopup = Preferences.settings.Calendar.EventsFilterState; - if (Preferences.settings.Calendar.TasksFilterState) - Component.$queryTasks.filterpopup = Preferences.settings.Calendar.TasksFilterState; - if (Preferences.settings.Calendar.EventsSortingState) { - Component.$queryEvents.sort = Preferences.settings.Calendar.EventsSortingState[0]; - Component.$queryEvents.asc = parseInt(Preferences.settings.Calendar.EventsSortingState[1]); - } - if (Preferences.settings.Calendar.TasksSortingState) { - Component.$queryTasks.sort = Preferences.settings.Calendar.TasksSortingState[0]; - Component.$queryTasks.asc = parseInt(Preferences.settings.Calendar.TasksSortingState[1]); - } - Component.$queryTasks.show_completed = parseInt(Preferences.settings.ShowCompletedTasks); - // Initialize categories from user's defaults - Component.$categories = Preferences.defaults.SOGoCalendarCategoriesColors; - // Initialize time format from user's defaults - if (Preferences.defaults.SOGoTimeFormat) { - Component.timeFormat = Preferences.defaults.SOGoTimeFormat; - } - }); + // Initialize filter parameters from user's settings + if (Preferences.settings.Calendar.EventsFilterState) + Component.$queryEvents.filterpopup = Preferences.settings.Calendar.EventsFilterState; + if (Preferences.settings.Calendar.TasksFilterState) + Component.$queryTasks.filterpopup = Preferences.settings.Calendar.TasksFilterState; + if (Preferences.settings.Calendar.EventsSortingState) { + Component.$queryEvents.sort = Preferences.settings.Calendar.EventsSortingState[0]; + Component.$queryEvents.asc = parseInt(Preferences.settings.Calendar.EventsSortingState[1]); + } + if (Preferences.settings.Calendar.TasksSortingState) { + Component.$queryTasks.sort = Preferences.settings.Calendar.TasksSortingState[0]; + Component.$queryTasks.asc = parseInt(Preferences.settings.Calendar.TasksSortingState[1]); + } + Component.$queryTasks.show_completed = parseInt(Preferences.settings.ShowCompletedTasks); + // Initialize categories from user's defaults + Component.$categories = Preferences.defaults.SOGoCalendarCategoriesColors; + // Initialize time format from user's defaults + if (Preferences.defaults.SOGoTimeFormat) { + Component.timeFormat = Preferences.defaults.SOGoTimeFormat; + } return Component; // return constructor }]; @@ -124,19 +122,15 @@ * current view. */ Component.$startRefreshTimeout = function(type) { - var _this = this; - if (Component.$refreshTimeout) Component.$timeout.cancel(Component.$refreshTimeout); - Component.$Preferences.ready().then(function() { - // Restart the refresh timer, if needed - var refreshViewCheck = Component.$Preferences.defaults.SOGoRefreshViewCheck; - if (refreshViewCheck && refreshViewCheck != 'manually') { - var f = angular.bind(Component.$rootScope, Component.$rootScope.$emit, 'calendars:list'); - Component.$refreshTimeout = Component.$timeout(f, refreshViewCheck.timeInterval()*1000); - } - }); + // Restart the refresh timer, if needed + var refreshViewCheck = Component.$Preferences.defaults.SOGoRefreshViewCheck; + if (refreshViewCheck && refreshViewCheck != 'manually') { + var f = angular.bind(Component.$rootScope, Component.$rootScope.$emit, 'calendars:list'); + Component.$refreshTimeout = Component.$timeout(f, refreshViewCheck.timeInterval()*1000); + } }; /** @@ -166,44 +160,41 @@ queryKey = '$query' + type.capitalize(), params = { day: '' + year + (month < 10?'0':'') + month + (day < 10?'0':'') + day, - }; + }, + futureComponentData, + dirty = false, + otherType; Component.$startRefreshTimeout(type); - return this.$Preferences.ready().then(function() { - var futureComponentData, - dirty = false, - otherType; + angular.extend(this.$query, params); - angular.extend(_this.$query, params); + if (options) { + _.forEach(_.keys(options), function(key) { + // Query parameters common to events and tasks are compared + dirty |= (_this.$query[key] && options[key] != Component.$query[key]); + if (key == 'reload' && options[key]) + dirty = true; + // Update either the common parameters or the type-specific parameters + else if (angular.isDefined(_this.$query[key])) + _this.$query[key] = options[key]; + else + _this[queryKey][key] = options[key]; + }); + } - if (options) { - _.forEach(_.keys(options), function(key) { - // Query parameters common to events and tasks are compared - dirty |= (_this.$query[key] && options[key] != Component.$query[key]); - if (key == 'reload' && options[key]) - dirty = true; - // Update either the common parameters or the type-specific parameters - else if (angular.isDefined(_this.$query[key])) - _this.$query[key] = options[key]; - else - _this[queryKey][key] = options[key]; - }); - } + // Perform query with both common and type-specific parameters + futureComponentData = this.$$resource.fetch(null, type + 'list', + angular.extend(this[queryKey], this.$query)); - // Perform query with both common and type-specific parameters - futureComponentData = _this.$$resource.fetch(null, type + 'list', - angular.extend(_this[queryKey], _this.$query)); + // Invalidate cached results of other type if $query has changed + if (dirty) { + otherType = (type == 'tasks')? '$events' : '$tasks'; + delete Component[otherType]; + Component.$log.debug('force reload of ' + otherType); + } - // Invalidate cached results of other type if $query has changed - if (dirty) { - otherType = (type == 'tasks')? '$events' : '$tasks'; - delete Component[otherType]; - Component.$log.debug('force reload of ' + otherType); - } - - return _this.$unwrapCollection(type, futureComponentData); - }); + return this.$unwrapCollection(type, futureComponentData); }; /** @@ -256,40 +247,36 @@ * @returns a promise of a collection of objects describing the events blocks */ Component.$eventsBlocksForView = function(view, date) { - var _this = this; + var firstDayOfWeek, viewAction, startDate, endDate, params; - return Component.$Preferences.ready().then(function(data) { - var firstDayOfWeek, viewAction, startDate, endDate, params; - firstDayOfWeek = Component.$Preferences.defaults.SOGoFirstDayOfWeek; - - if (view == 'day') { - viewAction = 'dayView'; - startDate = endDate = date; - } - else if (view == 'multicolumnday') { - viewAction = 'multicolumndayView'; - startDate = endDate = date; - } - else if (view == 'week') { - viewAction = 'weekView'; - startDate = date.beginOfWeek(firstDayOfWeek); - endDate = new Date(); - endDate.setTime(startDate.getTime()); - endDate.addDays(6); - } - else if (view == 'month') { - viewAction = 'monthView'; - startDate = date; - startDate.setDate(1); - startDate = startDate.beginOfWeek(firstDayOfWeek); - endDate = new Date(); - endDate.setTime(date.getTime()); - endDate.setMonth(endDate.getMonth() + 1); - endDate.addDays(-1); - endDate = endDate.endOfWeek(firstDayOfWeek); - } - return _this.$eventsBlocks(viewAction, startDate, endDate); - }); + firstDayOfWeek = Component.$Preferences.defaults.SOGoFirstDayOfWeek; + if (view == 'day') { + viewAction = 'dayView'; + startDate = endDate = date; + } + else if (view == 'multicolumnday') { + viewAction = 'multicolumndayView'; + startDate = endDate = date; + } + else if (view == 'week') { + viewAction = 'weekView'; + startDate = date.beginOfWeek(firstDayOfWeek); + endDate = new Date(); + endDate.setTime(startDate.getTime()); + endDate.addDays(6); + } + else if (view == 'month') { + viewAction = 'monthView'; + startDate = date; + startDate.setDate(1); + startDate = startDate.beginOfWeek(firstDayOfWeek); + endDate = new Date(); + endDate.setTime(date.getTime()); + endDate.setMonth(endDate.getMonth() + 1); + endDate.addDays(-1); + endDate = endDate.endOfWeek(firstDayOfWeek); + } + return this.$eventsBlocks(viewAction, startDate, endDate); }; /** @@ -533,12 +520,10 @@ if (this.c_category) { // c_category is only defined in list mode (when calling $filter) - Component.$Preferences.ready().then(function() { - // Filter out categories for which there's no associated color - _this.categories = _.invokeMap(_.filter(_this.c_category, function(name) { - return Component.$Preferences.defaults.SOGoCalendarCategoriesColors[name]; - }), 'asCSSIdentifier'); - }); + // Filter out categories for which there's no associated color + this.categories = _.invokeMap(_.filter(this.c_category, function(name) { + return Component.$Preferences.defaults.SOGoCalendarCategoriesColors[name]; + }), 'asCSSIdentifier'); } // Parse recurrence rule definition and initialize default values @@ -591,24 +576,22 @@ if (this.isNew) { // Set default values - Component.$Preferences.ready().then(function() { - var type = (_this.type == 'appointment')? 'Events' : 'Tasks'; + var type = (this.type == 'appointment')? 'Events' : 'Tasks'; - // Set default classification - _this.classification = Component.$Preferences.defaults['SOGoCalendar' + type + 'DefaultClassification'].toLowerCase(); + // Set default classification + this.classification = Component.$Preferences.defaults['SOGoCalendar' + type + 'DefaultClassification'].toLowerCase(); - // Set default alarm - var units = { M: 'MINUTES', H: 'HOURS', D: 'DAYS', W: 'WEEKS' }; - var match = /-PT?([0-9]+)([MHDW])/.exec(Component.$Preferences.defaults.SOGoCalendarDefaultReminder); - if (match) { - _this.$hasAlarm = true; - _this.alarm.quantity = parseInt(match[1]); - _this.alarm.unit = units[match[2]]; - } + // Set default alarm + var units = { M: 'MINUTES', H: 'HOURS', D: 'DAYS', W: 'WEEKS' }; + var match = /-PT?([0-9]+)([MHDW])/.exec(Component.$Preferences.defaults.SOGoCalendarDefaultReminder); + if (match) { + this.$hasAlarm = true; + this.alarm.quantity = parseInt(match[1]); + this.alarm.unit = units[match[2]]; + } - // Set notitifications - _this.sendAppointmentNotifications = Component.$Preferences.defaults.SOGoAppointmentSendEMailNotifications; - }); + // Set notitifications + this.sendAppointmentNotifications = Component.$Preferences.defaults.SOGoAppointmentSendEMailNotifications; } else if (angular.isUndefined(data.$hasAlarm)) { this.$hasAlarm = angular.isDefined(data.alarm); diff --git a/UI/WebServerResources/js/Scheduler/Scheduler.app.js b/UI/WebServerResources/js/Scheduler/Scheduler.app.js index f6606bdbd..8b7015fca 100644 --- a/UI/WebServerResources/js/Scheduler/Scheduler.app.js +++ b/UI/WebServerResources/js/Scheduler/Scheduler.app.js @@ -116,26 +116,24 @@ }); if ($location.url().length === 0) { // Restore user's last view - Preferences.ready().then(function() { - var url = '/calendar/', - view = /(.+)view/.exec(Preferences.settings.Calendar.View); - if (view) - url += view[1]; - else - url += 'week'; - // Append today's date or next enabled weekday - var now = new Date(); - if (Preferences.defaults.SOGoCalendarWeekdays) { - var weekDays = ['SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA']; - var weekDay = weekDays[now.getDay()]; - while (Preferences.defaults.SOGoCalendarWeekdays.indexOf(weekDay) < 0) { - now.addDays(1); - weekDay = weekDays[now.getDay()]; - } + var url = '/calendar/', + view = /(.+)view/.exec(Preferences.settings.Calendar.View); + if (view) + url += view[1]; + else + url += 'week'; + // Append today's date or next enabled weekday + var now = new Date(); + if (Preferences.defaults.SOGoCalendarWeekdays) { + var weekDays = ['SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA']; + var weekDay = weekDays[now.getDay()]; + while (Preferences.defaults.SOGoCalendarWeekdays.indexOf(weekDay) < 0) { + now.addDays(1); + weekDay = weekDays[now.getDay()]; } - url += '/' + now.getDayString(); - $location.replace().url(url); - }); + } + url += '/' + now.getDayString(); + $location.replace().url(url); } } diff --git a/UI/WebServerResources/js/Scheduler/sgCalendarScrollView.directive.js b/UI/WebServerResources/js/Scheduler/sgCalendarScrollView.directive.js index 710086c00..3b74a9a40 100644 --- a/UI/WebServerResources/js/Scheduler/sgCalendarScrollView.directive.js +++ b/UI/WebServerResources/js/Scheduler/sgCalendarScrollView.directive.js @@ -48,17 +48,16 @@ function initView() { view = new sgScrollView(element, type); - if (type != 'monthly') + if (type != 'monthly') { // Scroll to the day start hour defined in the user's defaults - Preferences.ready().then(function() { - var time, hourCell, quartersOffset; - if (Preferences.defaults.SOGoDayStartTime) { - time = Preferences.defaults.SOGoDayStartTime.split(':'); - hourCell = document.getElementById('hour' + parseInt(time[0])); - quartersOffset = parseInt(time[1]) * view.quarterHeight; - view.element.scrollTop = hourCell.offsetTop + quartersOffset; - } - }); + var time, hourCell, quartersOffset; + if (Preferences.defaults.SOGoDayStartTime) { + time = Preferences.defaults.SOGoDayStartTime.split(':'); + hourCell = document.getElementById('hour' + parseInt(time[0])); + quartersOffset = parseInt(time[1]) * view.quarterHeight; + view.element.scrollTop = hourCell.offsetTop + quartersOffset; + } + } // Expose quarter height to the controller // See sgNowLine directive