Expose user's settings and defaults inline

This improves performance by removing two AJAX calls and a lot of
JavaScript promises.
pull/228/merge
Francis Lachapelle 2017-06-01 13:46:57 -04:00
parent 1fa056bb25
commit 89bfa0c536
22 changed files with 441 additions and 484 deletions

1
NEWS
View File

@ -11,6 +11,7 @@ Enhancements
- [web] improve display of tasks status - [web] improve display of tasks status
- [web] added custom fields support from Thunderbird's address book - [web] added custom fields support from Thunderbird's address book
- [web] added Latvian (lv) translation - thanks to Juris Balandis - [web] added Latvian (lv) translation - thanks to Juris Balandis
- [web] expose user's defaults and settings inline
Bug fixes Bug fixes
- [web] respect SOGoLanguage and SOGoSupportedLanguages (#4169) - [web] respect SOGoLanguage and SOGoSupportedLanguages (#4169)

View File

@ -33,12 +33,12 @@
}; };
jsonDefaults = { jsonDefaults = {
protectedBy = "View"; protectedBy = "View";
actionClass = "UIxJSONPreferences"; pageName = "UIxJSONPreferences";
actionName = "jsonDefaults"; actionName = "jsonDefaults";
}; };
jsonSettings = { jsonSettings = {
protectedBy = "View"; protectedBy = "View";
actionClass = "UIxJSONPreferences"; pageName = "UIxJSONPreferences";
actionName = "jsonSettings"; actionName = "jsonSettings";
}; };
save = { save = {

View File

@ -0,0 +1,12 @@
<?xml version='1.0' standalone='yes'?>
<container
xmlns="http://www.w3.org/1999/xhtml"
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:const="http://www.skyrix.com/od/constant">
<script id="UserDefaults" type="text/json">
<var:string value="jsonDefaults" const:escapeHTML="NO"/>
</script>
<script id="UserSettings" type="text/json">
<var:string value="jsonSettings" const:escapeHTML="NO"/>
</script>
</container>

View File

@ -58,16 +58,6 @@
<iframe width="100%" height="100%" src="/SOGo/loading"><!-- space --></iframe> <iframe width="100%" height="100%" src="/SOGo/loading"><!-- space --></iframe>
</div> </div>
</var:if> </var:if>
<script type="text/javascript">
<var:if condition="shortUserNameForDisplay" const:value="anonymous" const:negate="YES">
<var:if condition="hasUserSettingsKeys">
var UserSettings =<var:string value="userSettings" const:escapeHTML="NO" />;
</var:if>
<var:if condition="hasUserDefaultsKeys">
var UserDefaults = <var:string value="userDefaults" const:escapeHTML="NO" />;
</var:if>
</var:if>
</script>
<!-- MAIN CONTENT ROW --> <!-- MAIN CONTENT ROW -->
<var:component-content /> <var:component-content />
@ -131,10 +121,15 @@
// This is the equivalent of an AJAX call to /SOGo/so/_UserLogin_/date // This is the equivalent of an AJAX call to /SOGo/so/_UserLogin_/date
var currentDay = <var:string value="currentDayDescription" const:escapeHTML="NO"/>; var currentDay = <var:string value="currentDayDescription" const:escapeHTML="NO"/>;
<var:string value="commonLocalizableStrings" const:escapeHTML="NO" /> <var:string value="commonLocalizableStrings" const:escapeHTML="NO" />
<var:string value="productLocalizableStrings" const:escapeHTML="NO" /> <var:string value="productLocalizableStrings" const:escapeHTML="NO" />
</script> </script>
<var:if condition="shortUserNameForDisplay" const:value="anonymous" const:negate="YES">
<var:component className="UIxJSONPreferences"/>
</var:if>
<!-- JAVASCRIPT IMPORTS --> <!-- JAVASCRIPT IMPORTS -->
<script type="text/javascript" rsrc:src="js/vendor/lodash.min.js"><!-- space --></script> <script type="text/javascript" rsrc:src="js/vendor/lodash.min.js"><!-- space --></script>
<script type="text/javascript" rsrc:src="js/vendor/angular.min.js"><!-- space --></script> <script type="text/javascript" rsrc:src="js/vendor/angular.min.js"><!-- space --></script>

View File

@ -77,18 +77,15 @@
$element.off('click', toggleZoomFcn); $element.off('click', toggleZoomFcn);
}); });
// Wait on user's defaults $scope.$watch(function() { return vm.email; }, function(email, old) {
Preferences.ready().then(function() { if (email && vm.urlEmail != email) {
$scope.$watch(function() { return vm.email; }, function(email, old) { // Email has changed or doesn't match the current URL (this happens when using md-virtual-repeat)
if (email && vm.urlEmail != email) { showGenericAvatar();
// Email has changed or doesn't match the current URL (this happens when using md-virtual-repeat) if (Preferences.defaults.SOGoGravatarEnabled)
showGenericAvatar(); getGravatar(email);
if (Preferences.defaults.SOGoGravatarEnabled) }
getGravatar(email); else if (!email)
} showGenericAvatar();
else if (!email)
showGenericAvatar();
});
}); });
// If sg-src is defined, watch the expression for the URL of a local image // If sg-src is defined, watch the expression for the URL of a local image

View File

@ -49,12 +49,11 @@
$refreshTimeout: null $refreshTimeout: null
}); });
// Initialize sort parameters from user's settings // Initialize sort parameters from user's settings
Preferences.ready().then(function() { if (Preferences.settings.Contact.SortingState) {
if (Preferences.settings.Contact.SortingState) { AddressBook.$query.sort = Preferences.settings.Contact.SortingState[0];
AddressBook.$query.sort = Preferences.settings.Contact.SortingState[0]; AddressBook.$query.asc = parseInt(Preferences.settings.Contact.SortingState[1]);
AddressBook.$query.asc = parseInt(Preferences.settings.Contact.SortingState[1]); }
}
});
return AddressBook; // return constructor return AddressBook; // return constructor
}]; }];
@ -437,19 +436,15 @@
* @desc Starts the refresh timeout for the current selected address book * @desc Starts the refresh timeout for the current selected address book
*/ */
AddressBook.prototype.$startRefreshTimeout = function() { AddressBook.prototype.$startRefreshTimeout = function() {
var _this = this;
if (AddressBook.$refreshTimeout) if (AddressBook.$refreshTimeout)
AddressBook.$timeout.cancel(AddressBook.$refreshTimeout); AddressBook.$timeout.cancel(AddressBook.$refreshTimeout);
AddressBook.$Preferences.ready().then(function() { // Restart the refresh timer, if needed
// Restart the refresh timer, if needed var refreshViewCheck = AddressBook.$Preferences.defaults.SOGoRefreshViewCheck;
var refreshViewCheck = AddressBook.$Preferences.defaults.SOGoRefreshViewCheck; if (refreshViewCheck && refreshViewCheck != 'manually') {
if (refreshViewCheck && refreshViewCheck != 'manually') { var f = angular.bind(this, AddressBook.prototype.$reload);
var f = angular.bind(_this, AddressBook.prototype.$reload); AddressBook.$refreshTimeout = AddressBook.$timeout(f, refreshViewCheck.timeInterval()*1000);
AddressBook.$refreshTimeout = AddressBook.$timeout(f, refreshViewCheck.timeInterval()*1000); }
}
});
}; };
/** /**
@ -487,91 +482,89 @@
if (!this.isRemote) query.partial = 1; if (!this.isRemote) query.partial = 1;
} }
return AddressBook.$Preferences.ready().then(function() { if (options) {
if (options) { angular.extend(query, options);
angular.extend(query, options); if (dry) {
if (dry) { if (!search) {
if (!search) { // No query specified
// No query specified _this.$$cards = [];
_this.$$cards = []; return AddressBook.$q.when(_this.$$cards);
return AddressBook.$q.when(_this.$$cards);
}
} }
} }
}
if (angular.isDefined(search)) if (angular.isDefined(search))
query.value = search; query.value = search;
return _this.$id().then(function(addressbookId) { return _this.$id().then(function(addressbookId) {
var futureData = AddressBook.$$resource.fetch(addressbookId, 'view', query); var futureData = AddressBook.$$resource.fetch(addressbookId, 'view', query);
if (dry) { if (dry) {
return futureData.then(function(response) { return futureData.then(function(response) {
var results, headers, card, index, fields, idFieldIndex, var results, headers, card, index, fields, idFieldIndex,
cards = _this.$$cards, cards = _this.$$cards,
compareIds = function(card) { compareIds = function(card) {
return this == card.id; return this == card.id;
}; };
if (response.headers) { if (response.headers) {
// First entry of 'headers' are keys // First entry of 'headers' are keys
fields = _.invokeMap(response.headers[0], 'toLowerCase'); fields = _.invokeMap(response.headers[0], 'toLowerCase');
idFieldIndex = fields.indexOf('id'); idFieldIndex = fields.indexOf('id');
response.headers.splice(0, 1); 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) // Add new cards matching the search query
// Remove excluded cards from results _.forEach(results, function(cardId, index) {
results = _.filter(response.ids, function(id) { if (_.isUndefined(_.find(cards, _.bind(compareIds, cardId)))) {
return _.isUndefined(_.find(excludedCards, _.bind(compareIds, id))); var data = { pid: addressbookId, id: cardId };
}); var card = new AddressBook.$Card(data, search);
else cards.splice(index, 0, card);
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);
}
});
// 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 { // Respect the order of the results
// Unwrap promise and instantiate or extend Cards objets _.forEach(results, function(cardId, index) {
return _this.$unwrap(futureData); 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);
}
}); });
}; };

View File

@ -46,13 +46,11 @@
$Preferences: Preferences $Preferences: Preferences
}); });
// Initialize categories from user's defaults // Initialize categories from user's defaults
Preferences.ready().then(function() { if (Preferences.defaults.SOGoContactsCategories) {
if (Preferences.defaults.SOGoContactsCategories) { Card.$categories = Preferences.defaults.SOGoContactsCategories;
Card.$categories = Preferences.defaults.SOGoContactsCategories; }
} if (Preferences.defaults.SOGoAlternateAvatar)
if (Preferences.defaults.SOGoAlternateAvatar) Card.$alternateAvatar = Preferences.defaults.SOGoAlternateAvatar;
Card.$alternateAvatar = Preferences.defaults.SOGoAlternateAvatar;
});
return Card; // return constructor return Card; // return constructor
}]; }];
@ -149,9 +147,7 @@
if (!this.$$image) if (!this.$$image)
this.$$image = this.image; this.$$image = this.image;
if (!this.$$image) if (!this.$$image)
Card.$Preferences.avatar(this.$$email, 32, {no_404: true}).then(function(url) { this.$$image = Card.$Preferences.avatar(this.$$email, 32, {no_404: true});
_this.$$image = url;
});
if (this.hasphoto) if (this.hasphoto)
this.photoURL = Card.$$resource.path(this.pid, this.id, 'photo'); this.photoURL = Card.$$resource.path(this.pid, this.id, 'photo');
if (this.isgroup) if (this.isgroup)
@ -177,11 +173,9 @@
}); });
// Instanciate date object of birthday // Instanciate date object of birthday
if (this.birthday) { if (this.birthday) {
Card.$Preferences.ready().then(function() { var dlp = Card.$Preferences.$mdDateLocaleProvider;
var dlp = Card.$Preferences.$mdDateLocaleProvider; this.birthday = this.birthday.parseDate(dlp, '%Y-%m-%d');
_this.birthday = _this.birthday.parseDate(dlp, '%Y-%m-%d'); this.$birthday = dlp.formatDate(this.birthday);
_this.$birthday = dlp.formatDate(_this.birthday);
});
} }
this.$loaded = angular.isDefined(this.c_name)? Card.STATUS.LOADED : Card.STATUS.NOT_LOADED; this.$loaded = angular.isDefined(this.c_name)? Card.STATUS.LOADED : Card.STATUS.NOT_LOADED;

View File

@ -136,31 +136,29 @@
_this.$expanded = false; _this.$expanded = false;
// Set expanded folders from user's settings // Set expanded folders from user's settings
Account.$Preferences.ready().then(function() { var expandedFolders,
var expandedFolders, _visit = function(mailboxes) {
_visit = function(mailboxes) { _.forEach(mailboxes, function(o) {
_.forEach(mailboxes, function(o) { o.$expanded = (expandedFolders.indexOf('/' + o.id) >= 0);
o.$expanded = (expandedFolders.indexOf('/' + o.id) >= 0); if (o.children && o.children.length > 0) {
if (o.children && o.children.length > 0) { _visit(o.children);
_visit(o.children); }
} });
}); };
}; if (Account.$Preferences.settings.Mail.ExpandedFolders) {
if (Account.$Preferences.settings.Mail.ExpandedFolders) { if (angular.isString(Account.$Preferences.settings.Mail.ExpandedFolders))
if (angular.isString(Account.$Preferences.settings.Mail.ExpandedFolders)) // Backward compatibility support
// Backward compatibility support expandedFolders = angular.fromJson(Account.$Preferences.settings.Mail.ExpandedFolders);
expandedFolders = angular.fromJson(Account.$Preferences.settings.Mail.ExpandedFolders); else
else expandedFolders = Account.$Preferences.settings.Mail.ExpandedFolders;
expandedFolders = Account.$Preferences.settings.Mail.ExpandedFolders; _this.$expanded = (expandedFolders.indexOf('/' + _this.id) >= 0);
_this.$expanded = (expandedFolders.indexOf('/' + _this.id) >= 0); if (expandedFolders.length > 0) {
if (expandedFolders.length > 0) { _visit(_this.$mailboxes);
_visit(_this.$mailboxes);
}
} }
if (Account.$accounts) }
_this.$expanded |= (Account.$accounts.length == 1); // Always expand single account if (Account.$accounts)
_this.$flattenMailboxes({reload: true}); _this.$expanded |= (Account.$accounts.length == 1); // Always expand single account
}); _this.$flattenMailboxes({reload: true});
return _this.$mailboxes; return _this.$mailboxes;
}); });

View File

@ -48,12 +48,10 @@
PRELOAD: PRELOAD PRELOAD: PRELOAD
}); });
// Initialize sort parameters from user's settings // Initialize sort parameters from user's settings
Preferences.ready().then(function() { if (Preferences.settings.Mail.SortingState) {
if (Preferences.settings.Mail.SortingState) { Mailbox.$query.sort = Preferences.settings.Mail.SortingState[0];
Mailbox.$query.sort = Preferences.settings.Mail.SortingState[0]; Mailbox.$query.asc = parseInt(Preferences.settings.Mail.SortingState[1]);
Mailbox.$query.asc = parseInt(Preferences.settings.Mail.SortingState[1]); }
}
});
return Mailbox; // return constructor return Mailbox; // return constructor
}]; }];
@ -343,46 +341,43 @@
_this.$isLoading = true; _this.$isLoading = true;
}); });
return Mailbox.$Preferences.ready().then(function() { if (Mailbox.$refreshTimeout)
Mailbox.$timeout.cancel(Mailbox.$refreshTimeout);
if (Mailbox.$refreshTimeout) if (sortingAttributes)
Mailbox.$timeout.cancel(Mailbox.$refreshTimeout); // Sorting preferences are common to all mailboxes
angular.extend(Mailbox.$query, sortingAttributes);
if (sortingAttributes) angular.extend(options, { sortingAttributes: Mailbox.$query });
// Sorting preferences are common to all mailboxes if (angular.isDefined(filters)) {
angular.extend(Mailbox.$query, sortingAttributes); options.filters = _.reject(filters, function(filter) {
return !filter.searchInput || filter.searchInput.length === 0;
angular.extend(options, { sortingAttributes: Mailbox.$query }); });
if (angular.isDefined(filters)) { // Decompose filters that match two fields
options.filters = _.reject(filters, function(filter) { _.forEach(options.filters, function(filter) {
return !filter.searchInput || filter.searchInput.length === 0; var secondFilter,
}); match = filter.searchBy.match(/(\w+)_or_(\w+)/);
// Decompose filters that match two fields if (match) {
_.forEach(options.filters, function(filter) { options.sortingAttributes.match = 'OR';
var secondFilter, filter.searchBy = match[1];
match = filter.searchBy.match(/(\w+)_or_(\w+)/); secondFilter = angular.copy(filter);
if (match) { secondFilter.searchBy = match[2];
options.sortingAttributes.match = 'OR'; options.filters.push(secondFilter);
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);
} }
} });
}
var futureMailboxData = Mailbox.$$resource.post(_this.id, 'view', options); // Restart the refresh timer, if needed
return _this.$unwrap(futureMailboxData); 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);
}; };
/** /**

View File

@ -32,9 +32,7 @@
params: [] params: []
}; };
Preferences.ready().then(function() { this.showSubscribedOnly = Preferences.defaults.SOGoMailShowSubscribedFoldersOnly;
vm.showSubscribedOnly = Preferences.defaults.SOGoMailShowSubscribedFoldersOnly;
});
this.refreshUnseenCount(); this.refreshUnseenCount();
@ -258,7 +256,7 @@
}; // delegate }; // delegate
this.refreshUnseenCount = function() { this.refreshUnseenCount = function() {
var unseenCountFolders = $window.unseenCountFolders; var unseenCountFolders = $window.unseenCountFolders, refreshViewCheck;
_.forEach(vm.accounts, function(account) { _.forEach(vm.accounts, function(account) {
@ -282,11 +280,9 @@
}); });
}); });
Preferences.ready().then(function() { refreshViewCheck = Preferences.defaults.SOGoRefreshViewCheck;
var refreshViewCheck = Preferences.defaults.SOGoRefreshViewCheck; if (refreshViewCheck && refreshViewCheck != 'manually')
if (refreshViewCheck && refreshViewCheck != 'manually') $timeout(vm.refreshUnseenCount, refreshViewCheck.timeInterval()*1000);
$timeout(vm.refreshUnseenCount, refreshViewCheck.timeInterval()*1000);
});
}; };
this.isDroppableFolder = function(srcFolder, dstFolder) { this.isDroppableFolder = function(srcFolder, dstFolder) {

View File

@ -48,16 +48,15 @@
$$resource: new Resource(Settings.activeUser('folderURL') + 'Mail', Settings.activeUser()), $$resource: new Resource(Settings.activeUser('folderURL') + 'Mail', Settings.activeUser()),
$avatar: angular.bind(Preferences, Preferences.avatar) $avatar: angular.bind(Preferences, Preferences.avatar)
}); });
// Initialize tags form user's defaults // Initialize tags form user's defaults
Preferences.ready().then(function() { if (Preferences.defaults.SOGoMailLabelsColors) {
if (Preferences.defaults.SOGoMailLabelsColors) { Message.$tags = Preferences.defaults.SOGoMailLabelsColors;
Message.$tags = Preferences.defaults.SOGoMailLabelsColors; }
} if (Preferences.defaults.SOGoMailDisplayRemoteInlineImages &&
if (Preferences.defaults.SOGoMailDisplayRemoteInlineImages && Preferences.defaults.SOGoMailDisplayRemoteInlineImages == 'always') {
Preferences.defaults.SOGoMailDisplayRemoteInlineImages == 'always') { Message.$displayRemoteInlineImages = true;
Message.$displayRemoteInlineImages = true; }
}
});
return Message; // return constructor return Message; // return constructor
}]; }];

View File

@ -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 // Destroy file uploader when the controller is being deactivated
$scope.$on('$destroy', function() { vm.uploader.destroy(); }); $scope.$on('$destroy', function() { vm.uploader.destroy(); });
@ -297,14 +304,6 @@
vm.autosave = $timeout(vm.autosaveDrafts, Preferences.defaults.SOGoMailAutoSave*1000*60); 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']; SendMessageToastController.$inject = ['$scope', '$mdToast'];

View File

@ -22,9 +22,6 @@
controller: 'PreferencesController', controller: 'PreferencesController',
controllerAs: 'app' controllerAs: 'app'
} }
},
resolve: {
statePreferences: statePreferences
} }
}) })
.state('preferences.general', { .state('preferences.general', {
@ -64,13 +61,6 @@
$urlRouterProvider.otherwise('/general'); $urlRouterProvider.otherwise('/general');
} }
/**
* @ngInject
*/
statePreferences.$inject = ['Preferences'];
function statePreferences(Preferences) {
return Preferences;
}
/** /**
* @ngInject * @ngInject

View File

@ -8,13 +8,19 @@
* @constructor * @constructor
*/ */
function Preferences() { function Preferences() {
var _this = this; var _this = this, defaultsElement, settingsElement, data;
this.defaults = {}; this.defaults = {};
this.settings = {}; this.settings = {};
this.defaultsPromise = Preferences.$$resource.fetch("jsonDefaults").then(function(response) { defaultsElement = Preferences.$document[0].getElementById('UserDefaults');
var data = response || {}; 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) // 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) { var labels = _.fromPairs(_.map(data.SOGoMailLabelsColors, function(value, key) {
@ -117,22 +123,28 @@
_this.$mdDateLocaleProvider.msgCalendar = l('Calender'); _this.$mdDateLocaleProvider.msgCalendar = l('Calender');
_this.$mdDateLocaleProvider.msgOpenCalendar = l('Open Calendar'); _this.$mdDateLocaleProvider.msgOpenCalendar = l('Open Calendar');
_this.$mdDateLocaleProvider.parseDate = function(dateString) { _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) { _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) { _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) { _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 // We convert our PreventInvitationsWhitelist hash into a array of user
if (data.Calendar) { if (data.Calendar) {
if (data.Calendar.PreventInvitationsWhitelist) { if (data.Calendar.PreventInvitationsWhitelist) {
@ -140,9 +152,7 @@
var match = /^(.+)\s<(\S+)>$/.exec(value), var match = /^(.+)\s<(\S+)>$/.exec(value),
user = new Preferences.$User({uid: key, cn: match[1], c_email: match[2]}); user = new Preferences.$User({uid: key, cn: match[1], c_email: match[2]});
if (!user.$$image) if (!user.$$image)
_this.avatar(user.c_email, 32, {no_404: true}).then(function(url) { user.$$image = _this.avatar(user.c_email, 32, {no_404: true});
user.$$image = url;
});
return user; return user;
}); });
} }
@ -151,9 +161,7 @@
} }
angular.extend(_this.settings, data); angular.extend(_this.settings, data);
}
return _this.settings;
});
} }
/** /**
@ -161,8 +169,9 @@
* @desc The factory we'll use to register with Angular * @desc The factory we'll use to register with Angular
* @returns the Preferences constructor * @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, { angular.extend(Preferences, {
$document: $document,
$q: $q, $q: $q,
$timeout: $timeout, $timeout: $timeout,
$log: $log, $log: $log,
@ -195,7 +204,8 @@
* @return a combined promise * @return a combined promise
*/ */
Preferences.prototype.ready = function() { 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) { Preferences.prototype.avatar = function(email, size, options) {
var _this = this; var _this = this;
return this.ready().then(function() { var alternate_avatar = _this.defaults.SOGoAlternateAvatar, url;
var alternate_avatar = _this.defaults.SOGoAlternateAvatar, url; if (_this.defaults.SOGoGravatarEnabled)
if (_this.defaults.SOGoGravatarEnabled) url = Preferences.$gravatar(email, size, alternate_avatar, options);
url = Preferences.$gravatar(email, size, alternate_avatar, options); else
else url = [Preferences.$resourcesURL, 'img', 'ic_person_grey_24px.svg'].join('/');
url = [Preferences.$resourcesURL, 'img', 'ic_person_grey_24px.svg'].join('/'); if (options && options.dstObject && options.dstAttr)
if (options && options.dstObject && options.dstAttr) options.dstObject[options.dstAttr] = url;
options.dstObject[options.dstAttr] = url; return url;
return url;
});
}; };
/** /**
@ -285,12 +293,16 @@
if (preferences.defaults.Vacation) { if (preferences.defaults.Vacation) {
if (preferences.defaults.Vacation.startDateEnabled) if (preferences.defaults.Vacation.startDateEnabled)
preferences.defaults.Vacation.startDate = preferences.defaults.Vacation.startDate.getTime()/1000; preferences.defaults.Vacation.startDate = preferences.defaults.Vacation.startDate.getTime()/1000;
else else {
delete preferences.defaults.Vacation.startDateEnabled;
preferences.defaults.Vacation.startDate = 0; preferences.defaults.Vacation.startDate = 0;
}
if (preferences.defaults.Vacation.endDateEnabled) if (preferences.defaults.Vacation.endDateEnabled)
preferences.defaults.Vacation.endDate = preferences.defaults.Vacation.endDate.getTime()/1000; preferences.defaults.Vacation.endDate = preferences.defaults.Vacation.endDate.getTime()/1000;
else else {
delete preferences.defaults.Vacation.endDateEnabled;
preferences.defaults.Vacation.endDate = 0; preferences.defaults.Vacation.endDate = 0;
}
if (preferences.defaults.Vacation.autoReplyEmailAddresses) if (preferences.defaults.Vacation.autoReplyEmailAddresses)
preferences.defaults.Vacation.autoReplyEmailAddresses = _.filter(preferences.defaults.Vacation.autoReplyEmailAddresses.split(","), function(v) { return v.length; }); preferences.defaults.Vacation.autoReplyEmailAddresses = _.filter(preferences.defaults.Vacation.autoReplyEmailAddresses.split(","), function(v) { return v.length; });

View File

@ -7,11 +7,11 @@
/** /**
* @ngInject * @ngInject
*/ */
PreferencesController.$inject = ['$q', '$window', '$state', '$mdMedia', '$mdSidenav', '$mdDialog', '$mdToast', 'sgSettings', 'sgFocus', '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, statePreferences, 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); 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.passwords = { newPassword: null, newPasswordConfirmation: null };
vm.go = go; vm.go = go;
@ -60,11 +60,9 @@
} }
// Set alternate avatar in User service // Set alternate avatar in User service
statePreferences.ready().then(function() { if (Preferences.defaults.SOGoAlternateAvatar)
if (statePreferences.defaults.SOGoAlternateAvatar) User.$alternateAvatar = Preferences.defaults.SOGoAlternateAvatar;
User.$alternateAvatar = statePreferences.defaults.SOGoAlternateAvatar; updateVacationDates();
updateVacationDates();
});
function go(module, form) { function go(module, form) {
if (form.$valid) { if (form.$valid) {

View File

@ -102,11 +102,9 @@
else else
list.splice(sibling, 0, calendar); list.splice(sibling, 0, calendar);
this.$Preferences.ready().then(function() { if (Calendar.$Preferences.settings.Calendar.FoldersOrder)
if (Calendar.$Preferences.settings.Calendar.FoldersOrder) // Save list order
// Save list order Calendar.saveFoldersOrder(_.flatMap(Calendar.$findAll(), 'id'));
Calendar.saveFoldersOrder(_.flatMap(Calendar.$findAll(), 'id'));
});
// Refresh list of calendars to fetch links associated to new calendar // Refresh list of calendars to fetch links associated to new calendar
Calendar.$reloadAll(); Calendar.$reloadAll();
}; };

View File

@ -23,23 +23,23 @@
vm.changeView = changeView; vm.changeView = changeView;
_registerHotkeys(hotkeys); this.$onInit = function() {
_registerHotkeys(hotkeys);
Preferences.ready().then(function() {
_formatDate(vm.selectedDate); _formatDate(vm.selectedDate);
});
// Refresh current view when the list of calendars is modified // Refresh current view when the list of calendars is modified
deregisterCalendarsList = $rootScope.$on('calendars:list', updateView); deregisterCalendarsList = $rootScope.$on('calendars:list', updateView);
$scope.$on('$destroy', function() { $scope.$on('$destroy', function() {
// Destroy event listener when the controller is being deactivated // Destroy event listener when the controller is being deactivated
deregisterCalendarsList(); deregisterCalendarsList();
// Deregister hotkeys // Deregister hotkeys
_.forEach(hotkeys, function(key) { _.forEach(hotkeys, function(key) {
sgHotkeys.deregisterHotkey(key); sgHotkeys.deregisterHotkey(key);
});
}); });
}); };
function _registerHotkeys(keys) { function _registerHotkeys(keys) {

View File

@ -8,7 +8,7 @@
*/ */
CalendarListController.$inject = ['$rootScope', '$scope', '$timeout', '$state', '$mdDialog', 'sgHotkeys', 'sgFocus', 'Dialog', 'Preferences', 'CalendarSettings', 'Calendar', 'Component', 'Alarm']; 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) { 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.component = Component;
vm.componentType = 'events'; vm.componentType = 'events';
@ -32,32 +32,32 @@
vm.mode = { search: false, multiple: 0 }; vm.mode = { search: false, multiple: 0 };
_registerHotkeys(hotkeys); this.$onInit = function() {
_registerHotkeys(hotkeys);
// Select list based on user's settings // Select list based on user's settings
Preferences.ready().then(function() { type = 'events';
var type = 'events';
if (Preferences.settings.Calendar.SelectedList == 'tasksListView') { if (Preferences.settings.Calendar.SelectedList == 'tasksListView') {
vm.selectedList = 1; vm.selectedList = 1;
type = 'tasks'; type = 'tasks';
} }
selectComponentType(type, { reload: true }); // fetch events/tasks lists selectComponentType(type, { reload: true }); // fetch events/tasks lists
});
// Refresh current list when the list of calendars is modified // Refresh current list when the list of calendars is modified
$rootScope.$on('calendars:list', function() { $rootScope.$on('calendars:list', function() {
Component.$filter(vm.componentType, { reload: true }); 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);
}); });
});
// 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) { function _registerHotkeys(keys) {

View File

@ -38,47 +38,47 @@
accept: _sortableAccept accept: _sortableAccept
}; };
Preferences.ready().then(function() { this.$onInit = function() {
vm.categories = _.map(Preferences.defaults.SOGoCalendarCategories, function(name) { vm.categories = _.map(Preferences.defaults.SOGoCalendarCategories, function(name) {
return { id: name.asCSSIdentifier(), return { id: name.asCSSIdentifier(),
name: name, name: name,
color: Preferences.defaults.SOGoCalendarCategoriesColors[name] color: Preferences.defaults.SOGoCalendarCategoriesColors[name]
}; };
}); });
});
// Dispatch the event named 'calendars:list' when a calendar is activated or deactivated or // Dispatch the event named 'calendars:list' when a calendar is activated or deactivated or
// when the color of a calendar is changed // when the color of a calendar is changed
$scope.$watch( $scope.$watch(
function() { function() {
return _.union( return _.union(
_.map(Calendar.$calendars, function(o) { return _.pick(o, ['id', 'active', 'color']); }), _.map(Calendar.$calendars, function(o) { return _.pick(o, ['id', 'active', 'color']); }),
_.map(Calendar.$subscriptions, 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']); }) _.map(Calendar.$webcalendars, function(o) { return _.pick(o, ['id', 'active', 'color']); })
); );
}, },
function(newList, oldList) { function(newList, oldList) {
var commonList, ids, promise; var commonList, ids, promise;
// Identify which calendar has changed // Identify which calendar has changed
commonList = _.intersectionBy(newList, oldList, 'id'); commonList = _.intersectionBy(newList, oldList, 'id');
ids = _.map(_.filter(commonList, function(o) { ids = _.map(_.filter(commonList, function(o) {
var oldObject = _.find(oldList, { id: o.id }); var oldObject = _.find(oldList, { id: o.id });
return !_.isEqual(o, oldObject); return !_.isEqual(o, oldObject);
}), 'id'); }), 'id');
promise = Calendar.$q.when(); promise = Calendar.$q.when();
if (ids.length > 0) { if (ids.length > 0) {
$log.debug(ids.join(', ') + ' changed'); $log.debug(ids.join(', ') + ' changed');
promise = Calendar.saveFoldersActivation(ids); promise = Calendar.saveFoldersActivation(ids);
} }
if (ids.length > 0 || commonList.length != newList.length || commonList.length != oldList.length) if (ids.length > 0 || commonList.length != newList.length || commonList.length != oldList.length)
promise.then(function() { promise.then(function() {
$rootScope.$emit('calendars:list'); $rootScope.$emit('calendars:list');
}); });
}, },
true // compare for object equality true // compare for object equality
); );
};
/** /**
* Only allow to sort items within the same list. * Only allow to sort items within the same list.

View File

@ -52,28 +52,26 @@
$refreshTimeout: null, $refreshTimeout: null,
$ghost: {} $ghost: {}
}); });
Preferences.ready().then(function() { // Initialize filter parameters from user's settings
// Initialize filter parameters from user's settings if (Preferences.settings.Calendar.EventsFilterState)
if (Preferences.settings.Calendar.EventsFilterState) Component.$queryEvents.filterpopup = Preferences.settings.Calendar.EventsFilterState;
Component.$queryEvents.filterpopup = Preferences.settings.Calendar.EventsFilterState; if (Preferences.settings.Calendar.TasksFilterState)
if (Preferences.settings.Calendar.TasksFilterState) Component.$queryTasks.filterpopup = Preferences.settings.Calendar.TasksFilterState;
Component.$queryTasks.filterpopup = Preferences.settings.Calendar.TasksFilterState; if (Preferences.settings.Calendar.EventsSortingState) {
if (Preferences.settings.Calendar.EventsSortingState) { Component.$queryEvents.sort = Preferences.settings.Calendar.EventsSortingState[0];
Component.$queryEvents.sort = Preferences.settings.Calendar.EventsSortingState[0]; Component.$queryEvents.asc = parseInt(Preferences.settings.Calendar.EventsSortingState[1]);
Component.$queryEvents.asc = parseInt(Preferences.settings.Calendar.EventsSortingState[1]); }
} if (Preferences.settings.Calendar.TasksSortingState) {
if (Preferences.settings.Calendar.TasksSortingState) { Component.$queryTasks.sort = Preferences.settings.Calendar.TasksSortingState[0];
Component.$queryTasks.sort = Preferences.settings.Calendar.TasksSortingState[0]; Component.$queryTasks.asc = parseInt(Preferences.settings.Calendar.TasksSortingState[1]);
Component.$queryTasks.asc = parseInt(Preferences.settings.Calendar.TasksSortingState[1]); }
} Component.$queryTasks.show_completed = parseInt(Preferences.settings.ShowCompletedTasks);
Component.$queryTasks.show_completed = parseInt(Preferences.settings.ShowCompletedTasks); // Initialize categories from user's defaults
// Initialize categories from user's defaults Component.$categories = Preferences.defaults.SOGoCalendarCategoriesColors;
Component.$categories = Preferences.defaults.SOGoCalendarCategoriesColors; // Initialize time format from user's defaults
// Initialize time format from user's defaults if (Preferences.defaults.SOGoTimeFormat) {
if (Preferences.defaults.SOGoTimeFormat) { Component.timeFormat = Preferences.defaults.SOGoTimeFormat;
Component.timeFormat = Preferences.defaults.SOGoTimeFormat; }
}
});
return Component; // return constructor return Component; // return constructor
}]; }];
@ -124,19 +122,15 @@
* current view. * current view.
*/ */
Component.$startRefreshTimeout = function(type) { Component.$startRefreshTimeout = function(type) {
var _this = this;
if (Component.$refreshTimeout) if (Component.$refreshTimeout)
Component.$timeout.cancel(Component.$refreshTimeout); Component.$timeout.cancel(Component.$refreshTimeout);
Component.$Preferences.ready().then(function() { // Restart the refresh timer, if needed
// Restart the refresh timer, if needed var refreshViewCheck = Component.$Preferences.defaults.SOGoRefreshViewCheck;
var refreshViewCheck = Component.$Preferences.defaults.SOGoRefreshViewCheck; if (refreshViewCheck && refreshViewCheck != 'manually') {
if (refreshViewCheck && refreshViewCheck != 'manually') { var f = angular.bind(Component.$rootScope, Component.$rootScope.$emit, 'calendars:list');
var f = angular.bind(Component.$rootScope, Component.$rootScope.$emit, 'calendars:list'); Component.$refreshTimeout = Component.$timeout(f, refreshViewCheck.timeInterval()*1000);
Component.$refreshTimeout = Component.$timeout(f, refreshViewCheck.timeInterval()*1000); }
}
});
}; };
/** /**
@ -166,44 +160,41 @@
queryKey = '$query' + type.capitalize(), queryKey = '$query' + type.capitalize(),
params = { params = {
day: '' + year + (month < 10?'0':'') + month + (day < 10?'0':'') + day, day: '' + year + (month < 10?'0':'') + month + (day < 10?'0':'') + day,
}; },
futureComponentData,
dirty = false,
otherType;
Component.$startRefreshTimeout(type); Component.$startRefreshTimeout(type);
return this.$Preferences.ready().then(function() { angular.extend(this.$query, params);
var futureComponentData,
dirty = false,
otherType;
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) { // Perform query with both common and type-specific parameters
_.forEach(_.keys(options), function(key) { futureComponentData = this.$$resource.fetch(null, type + 'list',
// Query parameters common to events and tasks are compared angular.extend(this[queryKey], this.$query));
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 // Invalidate cached results of other type if $query has changed
futureComponentData = _this.$$resource.fetch(null, type + 'list', if (dirty) {
angular.extend(_this[queryKey], _this.$query)); 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 return this.$unwrapCollection(type, futureComponentData);
if (dirty) {
otherType = (type == 'tasks')? '$events' : '$tasks';
delete Component[otherType];
Component.$log.debug('force reload of ' + otherType);
}
return _this.$unwrapCollection(type, futureComponentData);
});
}; };
/** /**
@ -256,40 +247,36 @@
* @returns a promise of a collection of objects describing the events blocks * @returns a promise of a collection of objects describing the events blocks
*/ */
Component.$eventsBlocksForView = function(view, date) { Component.$eventsBlocksForView = function(view, date) {
var _this = this; var firstDayOfWeek, viewAction, startDate, endDate, params;
return Component.$Preferences.ready().then(function(data) { firstDayOfWeek = Component.$Preferences.defaults.SOGoFirstDayOfWeek;
var firstDayOfWeek, viewAction, startDate, endDate, params; if (view == 'day') {
firstDayOfWeek = Component.$Preferences.defaults.SOGoFirstDayOfWeek; viewAction = 'dayView';
startDate = endDate = date;
if (view == 'day') { }
viewAction = 'dayView'; else if (view == 'multicolumnday') {
startDate = endDate = date; viewAction = 'multicolumndayView';
} startDate = endDate = date;
else if (view == 'multicolumnday') { }
viewAction = 'multicolumndayView'; else if (view == 'week') {
startDate = endDate = date; viewAction = 'weekView';
} startDate = date.beginOfWeek(firstDayOfWeek);
else if (view == 'week') { endDate = new Date();
viewAction = 'weekView'; endDate.setTime(startDate.getTime());
startDate = date.beginOfWeek(firstDayOfWeek); endDate.addDays(6);
endDate = new Date(); }
endDate.setTime(startDate.getTime()); else if (view == 'month') {
endDate.addDays(6); viewAction = 'monthView';
} startDate = date;
else if (view == 'month') { startDate.setDate(1);
viewAction = 'monthView'; startDate = startDate.beginOfWeek(firstDayOfWeek);
startDate = date; endDate = new Date();
startDate.setDate(1); endDate.setTime(date.getTime());
startDate = startDate.beginOfWeek(firstDayOfWeek); endDate.setMonth(endDate.getMonth() + 1);
endDate = new Date(); endDate.addDays(-1);
endDate.setTime(date.getTime()); endDate = endDate.endOfWeek(firstDayOfWeek);
endDate.setMonth(endDate.getMonth() + 1); }
endDate.addDays(-1); return this.$eventsBlocks(viewAction, startDate, endDate);
endDate = endDate.endOfWeek(firstDayOfWeek);
}
return _this.$eventsBlocks(viewAction, startDate, endDate);
});
}; };
/** /**
@ -533,12 +520,10 @@
if (this.c_category) { if (this.c_category) {
// c_category is only defined in list mode (when calling $filter) // 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
// Filter out categories for which there's no associated color this.categories = _.invokeMap(_.filter(this.c_category, function(name) {
_this.categories = _.invokeMap(_.filter(_this.c_category, function(name) { return Component.$Preferences.defaults.SOGoCalendarCategoriesColors[name];
return Component.$Preferences.defaults.SOGoCalendarCategoriesColors[name]; }), 'asCSSIdentifier');
}), 'asCSSIdentifier');
});
} }
// Parse recurrence rule definition and initialize default values // Parse recurrence rule definition and initialize default values
@ -591,24 +576,22 @@
if (this.isNew) { if (this.isNew) {
// Set default values // 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 // Set default classification
_this.classification = Component.$Preferences.defaults['SOGoCalendar' + type + 'DefaultClassification'].toLowerCase(); this.classification = Component.$Preferences.defaults['SOGoCalendar' + type + 'DefaultClassification'].toLowerCase();
// Set default alarm // Set default alarm
var units = { M: 'MINUTES', H: 'HOURS', D: 'DAYS', W: 'WEEKS' }; var units = { M: 'MINUTES', H: 'HOURS', D: 'DAYS', W: 'WEEKS' };
var match = /-PT?([0-9]+)([MHDW])/.exec(Component.$Preferences.defaults.SOGoCalendarDefaultReminder); var match = /-PT?([0-9]+)([MHDW])/.exec(Component.$Preferences.defaults.SOGoCalendarDefaultReminder);
if (match) { if (match) {
_this.$hasAlarm = true; this.$hasAlarm = true;
_this.alarm.quantity = parseInt(match[1]); this.alarm.quantity = parseInt(match[1]);
_this.alarm.unit = units[match[2]]; this.alarm.unit = units[match[2]];
} }
// Set notitifications // Set notitifications
_this.sendAppointmentNotifications = Component.$Preferences.defaults.SOGoAppointmentSendEMailNotifications; this.sendAppointmentNotifications = Component.$Preferences.defaults.SOGoAppointmentSendEMailNotifications;
});
} }
else if (angular.isUndefined(data.$hasAlarm)) { else if (angular.isUndefined(data.$hasAlarm)) {
this.$hasAlarm = angular.isDefined(data.alarm); this.$hasAlarm = angular.isDefined(data.alarm);

View File

@ -116,26 +116,24 @@
}); });
if ($location.url().length === 0) { if ($location.url().length === 0) {
// Restore user's last view // Restore user's last view
Preferences.ready().then(function() { var url = '/calendar/',
var url = '/calendar/', view = /(.+)view/.exec(Preferences.settings.Calendar.View);
view = /(.+)view/.exec(Preferences.settings.Calendar.View); if (view)
if (view) url += view[1];
url += view[1]; else
else url += 'week';
url += 'week'; // Append today's date or next enabled weekday
// Append today's date or next enabled weekday var now = new Date();
var now = new Date(); if (Preferences.defaults.SOGoCalendarWeekdays) {
if (Preferences.defaults.SOGoCalendarWeekdays) { var weekDays = ['SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA'];
var weekDays = ['SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA']; var weekDay = weekDays[now.getDay()];
var weekDay = weekDays[now.getDay()]; while (Preferences.defaults.SOGoCalendarWeekdays.indexOf(weekDay) < 0) {
while (Preferences.defaults.SOGoCalendarWeekdays.indexOf(weekDay) < 0) { now.addDays(1);
now.addDays(1); weekDay = weekDays[now.getDay()];
weekDay = weekDays[now.getDay()];
}
} }
url += '/' + now.getDayString(); }
$location.replace().url(url); url += '/' + now.getDayString();
}); $location.replace().url(url);
} }
} }

View File

@ -48,17 +48,16 @@
function initView() { function initView() {
view = new sgScrollView(element, type); view = new sgScrollView(element, type);
if (type != 'monthly') if (type != 'monthly') {
// Scroll to the day start hour defined in the user's defaults // Scroll to the day start hour defined in the user's defaults
Preferences.ready().then(function() { var time, hourCell, quartersOffset;
var time, hourCell, quartersOffset; if (Preferences.defaults.SOGoDayStartTime) {
if (Preferences.defaults.SOGoDayStartTime) { time = Preferences.defaults.SOGoDayStartTime.split(':');
time = Preferences.defaults.SOGoDayStartTime.split(':'); hourCell = document.getElementById('hour' + parseInt(time[0]));
hourCell = document.getElementById('hour' + parseInt(time[0])); quartersOffset = parseInt(time[1]) * view.quarterHeight;
quartersOffset = parseInt(time[1]) * view.quarterHeight; view.element.scrollTop = hourCell.offsetTop + quartersOffset;
view.element.scrollTop = hourCell.offsetTop + quartersOffset; }
} }
});
// Expose quarter height to the controller // Expose quarter height to the controller
// See sgNowLine directive // See sgNowLine directive