-
+
diff --git a/UI/WebServerResources/js/Contacts/AddressBook.service.js b/UI/WebServerResources/js/Contacts/AddressBook.service.js
index 0485ef20b..329393071 100644
--- a/UI/WebServerResources/js/Contacts/AddressBook.service.js
+++ b/UI/WebServerResources/js/Contacts/AddressBook.service.js
@@ -45,6 +45,9 @@
$Preferences: Preferences,
$query: {value: '', sort: 'c_cn', asc: 1},
activeUser: Settings.activeUser(),
+ $addressbooks: [],
+ $subscriptions: [],
+ $remotes: [],
selectedFolder: null,
$refreshTimeout: null
});
@@ -159,10 +162,10 @@
*/
AddressBook.$findAll = function(data) {
var _this = this;
- if (data) {
- this.$addressbooks = [];
- this.$subscriptions = [];
- this.$remotes = [];
+ if (data && data.length) {
+ this.$addressbooks.splice(0, this.$addressbooks.length);
+ this.$subscriptions.splice(0, this.$subscriptions.length);
+ this.$remotes.splice(0, this.$remotes.length);
// Instanciate AddressBook objects
angular.forEach(data, function(o, i) {
var addressbook = new AddressBook(o);
@@ -174,6 +177,12 @@
_this.$addressbooks.push(addressbook);
});
}
+ else if (angular.isArray(data)) { // empty array
+ return AddressBook.$$resource.fetch('addressbooksList').then(function(data) {
+ return AddressBook.$findAll(data.addressbooks);
+ });
+ }
+
return _.union(this.$addressbooks, this.$subscriptions, this.$remotes);
};
diff --git a/UI/WebServerResources/js/Mailer/MessageController.js b/UI/WebServerResources/js/Mailer/MessageController.js
index 7dc4b78ec..bfc6e6b0c 100644
--- a/UI/WebServerResources/js/Mailer/MessageController.js
+++ b/UI/WebServerResources/js/Mailer/MessageController.js
@@ -6,8 +6,8 @@
/**
* @ngInject
*/
- MessageController.$inject = ['$window', '$scope', '$q', '$state', '$mdMedia', '$mdDialog', 'sgConstant', 'stateAccounts', 'stateAccount', 'stateMailbox', 'stateMessage', 'sgHotkeys', 'encodeUriFilter', 'sgSettings', 'ImageGallery', 'sgFocus', 'Dialog', 'Preferences', 'Calendar', 'Component', 'Account', 'Mailbox', 'Message'];
- function MessageController($window, $scope, $q, $state, $mdMedia, $mdDialog, sgConstant, stateAccounts, stateAccount, stateMailbox, stateMessage, sgHotkeys, encodeUriFilter, sgSettings, ImageGallery, focus, Dialog, Preferences, Calendar, Component, Account, Mailbox, Message) {
+ MessageController.$inject = ['$window', '$scope', '$q', '$state', '$mdMedia', '$mdDialog', '$mdPanel', 'sgConstant', 'stateAccounts', 'stateAccount', 'stateMailbox', 'stateMessage', 'sgHotkeys', 'encodeUriFilter', 'sgSettings', 'ImageGallery', 'sgFocus', 'Dialog', 'Preferences', 'Calendar', 'Component', 'Account', 'Mailbox', 'Message', 'AddressBook', 'Card'];
+ function MessageController($window, $scope, $q, $state, $mdMedia, $mdDialog, $mdPanel, sgConstant, stateAccounts, stateAccount, stateMailbox, stateMessage, sgHotkeys, encodeUriFilter, sgSettings, ImageGallery, focus, Dialog, Preferences, Calendar, Component, Account, Mailbox, Message, AddressBook, Card) {
var vm = this, popupWindow = null, hotkeys = [];
this.$onInit = function() {
@@ -27,7 +27,8 @@
this.service = Message;
this.tags = { searchText: '', selected: '' };
this.showFlags = stateMessage.flags && stateMessage.flags.length > 0;
- this.$showDetailedRecipients = false;
+ this.$alwaysShowDetailedRecipients = (!stateMessage.to || stateMessage.to.length < 5) && (!stateMessage.cc || stateMessage.cc.length < 5);
+ this.$showDetailedRecipients = this.$alwaysShowDetailedRecipients;
this.showRawSource = false;
_registerHotkeys(hotkeys);
@@ -197,6 +198,108 @@
$event.preventDefault();
};
+ this.focusChip = function($event) {
+ var chipElement = $event.target;
+ while (chipElement.tagName !== 'MD-CHIP') {
+ chipElement = chipElement.parentNode;
+ }
+ chipElement.classList.add('md-focused');
+ };
+
+ this.blurChip = function($event) {
+ var chipElement = $event.target;
+ while (chipElement.tagName !== 'MD-CHIP') {
+ chipElement = chipElement.parentNode;
+ }
+ chipElement.classList.remove('md-focused');
+ if ($event.relatedTarget && $event.relatedTarget.tagName === 'MD-CHIP-TEMPLATE') {
+ // Moving to another chip; close menu
+ vm.panel.close();
+ }
+ };
+
+ this.selectRecipient = function(recipient, $event) {
+ // Fetch addressbooks list
+ AddressBook.$findAll([]);
+
+ var targetElement = $event.target;
+
+ var panelPosition = $mdPanel.newPanelPosition()
+ .relativeTo(targetElement)
+ .addPanelPosition(
+ $mdPanel.xPosition.ALIGN_START,
+ $mdPanel.yPosition.ALIGN_TOPS
+ );
+
+ var panelAnimation = $mdPanel.newPanelAnimation()
+ .openFrom(targetElement)
+ .duration(100)
+ .withAnimation($mdPanel.animation.FADE);
+
+ var config = {
+ attachTo: angular.element(document.body),
+ locals: {
+ recipient: recipient,
+ addressbooks: AddressBook.$addressbooks,
+ subscriptions: AddressBook.$subscriptions,
+ newMessage: angular.bind(this, this.newMessage)
+ },
+ bindToController: true,
+ controller: MenuController,
+ controllerAs: '$menuCtrl',
+ position: panelPosition,
+ animation: panelAnimation,
+ targetEvent: $event,
+ templateUrl: 'UIxMailViewRecipientMenu',
+ trapFocus: true,
+ clickOutsideToClose: true,
+ escapeToClose: true,
+ focusOnOpen: false
+ };
+
+ $mdPanel.open(config)
+ .then(function(panelRef) {
+ vm.panel = panelRef;
+ // Automatically close panel when clicking inside of it
+ panelRef.panelEl.one('click', function() {
+ panelRef.close();
+ });
+ });
+
+ MenuController.$inject = ['mdPanelRef', '$state', '$mdToast'];
+ function MenuController(mdPanelRef, $state, $mdToast) {
+ this.onKeyDown = function($event) {
+ if ($event.which === 9) { // Tab
+ mdPanelRef.close();
+ }
+ };
+
+ this.newCard = function(recipient, addressbookId) {
+ var card = new Card({
+ pid: addressbookId,
+ c_cn: recipient.name,
+ emails: [{ value: recipient.email }]
+ });
+ card.$id().then(function(id) {
+ card.$save().then(function() {
+ // Show success toast when action succeeds
+ $mdToast.show(
+ $mdToast.simple()
+ .content(l('Successfully created card'))
+ .position('top right')
+ .hideDelay(2000));
+ });
+ });
+ mdPanelRef.close();
+ };
+ }
+
+ if (targetElement.tagName === 'A') {
+ $event.stopPropagation();
+ $event.preventDefault();
+ }
+ };
+
this.filterMailtoLinks = function($event) {
var href, match, to, cc, bcc, subject, body, data;
if ($event.target.tagName == 'A' && 'href' in $event.target.attributes) {
@@ -382,8 +485,10 @@
};
this.newMessage = function($event, mailto) {
- $event.stopPropagation();
- $event.preventDefault();
+ if ($event.target.tagName === 'A') {
+ $event.stopPropagation();
+ $event.preventDefault();
+ }
this.account.$newMessage({ mailto: mailto }).then(function(message) {
_showMailEditor($event, message);
});
diff --git a/UI/WebServerResources/scss/components/chips/chips.scss b/UI/WebServerResources/scss/components/chips/chips.scss
index 3167b59d0..65effc644 100644
--- a/UI/WebServerResources/scss/components/chips/chips.scss
+++ b/UI/WebServerResources/scss/components/chips/chips.scss
@@ -1,6 +1,11 @@
/// chips.scss -*- Mode: scss; indent-tabs-mode: nil; basic-offset: 2 -*-
@import 'extends';
+$chip-dense-font-size: rem(1.2) !default;
+$chip-dense-height: rem(2.4) !default;
+$chip-dense-padding: 0 rem(0.8) 0 rem(0.8) !default;
+$chip-dense-margin: rem(0.6) rem(0.6) 0 0 !default;
+
md-chips {
// Remove the line under the tags of the message viewer
&.sg-readonly {
@@ -9,6 +14,9 @@ md-chips {
&.md-focused {
box-shadow: none;
}
+ md-chip-template:focus {
+ outline: 0;
+ }
.md-chip-content {
//max-width: initial; // fix bug in ng-material
}
@@ -25,6 +33,15 @@ md-chips {
}
}
}
+
+ // Small, compact chip
+ &.sg-dense md-chip {
+ height: $chip-dense-height;
+ padding: $chip-dense-padding;
+ @include rtl(margin, $chip-dense-margin, rtl-value($chip-dense-margin));
+ font-size: $chip-dense-font-size;
+ line-height: $chip-dense-height;
+ }
.sg-chip-progress {
border-radius: $chip-height / 2;
bottom: 0;
diff --git a/UI/WebServerResources/scss/views/MailerUI.scss b/UI/WebServerResources/scss/views/MailerUI.scss
index 6ec7d792b..2d5e5c8c6 100644
--- a/UI/WebServerResources/scss/views/MailerUI.scss
+++ b/UI/WebServerResources/scss/views/MailerUI.scss
@@ -61,6 +61,9 @@
padding-left: $mg;
padding-right: $mg;
}
+ md-chip {
+ cursor: pointer;
+ }
}
// Vertical buttons in header area of mail composer dialog