(js) Initial support for keyboard shortcuts
This commit is contained in:
parent
93de7b9ab3
commit
a2e3807a3a
376
UI/WebServerResources/js/Common/sgHotkeys.service.js
Normal file
376
UI/WebServerResources/js/Common/sgHotkeys.service.js
Normal file
|
@ -0,0 +1,376 @@
|
|||
/* -*- Mode: js; indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
|
||||
(function() {
|
||||
/* jshint validthis: true */
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* $sgHotkeys - A service to associate keyboard shortcuts to actions.
|
||||
* @memberof SOGo.Common
|
||||
*
|
||||
* @description
|
||||
* This service is a modified version of angular-hotkeys-light by Eugene Brodsky:
|
||||
* https://github.com/fupslot/angular-hotkeys-light
|
||||
*/
|
||||
function $sgHotkeys() {
|
||||
|
||||
// Key-code values for various meta-keys.
|
||||
// Source : http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes
|
||||
// http://unixpapa.com/js/key.html
|
||||
// Date: Oct 02, 2015.
|
||||
//var KEY_CODES = this.KEY_CODES = {
|
||||
var KEY_CODES = {
|
||||
8: 'backspace',
|
||||
9: 'tab',
|
||||
13: 'enter',
|
||||
16: 'shift',
|
||||
17: 'ctrl',
|
||||
18: 'alt',
|
||||
19: 'pause',
|
||||
20: 'caps',
|
||||
27: 'escape',
|
||||
32: 'space',
|
||||
33: 'pageup',
|
||||
34: 'pagedown',
|
||||
35: 'end',
|
||||
36: 'home',
|
||||
37: 'left',
|
||||
38: 'up',
|
||||
39: 'right',
|
||||
40: 'down',
|
||||
45: 'insert',
|
||||
46: 'delete',
|
||||
// Numpad
|
||||
96: '0',
|
||||
97: '1',
|
||||
98: '2',
|
||||
99: '3',
|
||||
100: '4',
|
||||
101: '5',
|
||||
102: '6',
|
||||
103: '7',
|
||||
104: '8',
|
||||
105: '9',
|
||||
106: '*',
|
||||
107: '+',
|
||||
109: '-',
|
||||
110: '.',
|
||||
111: '/',
|
||||
// Function keys
|
||||
112: 'f1',
|
||||
113: 'f2',
|
||||
114: 'f3',
|
||||
115: 'f4',
|
||||
116: 'f5',
|
||||
117: 'f6',
|
||||
118: 'f7',
|
||||
119: 'f8',
|
||||
120: 'f9',
|
||||
121: 'f10',
|
||||
122: 'f11',
|
||||
123: 'f12'
|
||||
};
|
||||
|
||||
this.$get = getService;
|
||||
|
||||
getService.$inject = ['$rootScope', '$window'];
|
||||
function getService($rootScope, $window) {
|
||||
|
||||
var wrapWithApply = function (fn) {
|
||||
return function(event, args) {
|
||||
$rootScope.$apply(function() {
|
||||
fn.call(this, event, args);
|
||||
}.bind(this));
|
||||
};
|
||||
};
|
||||
|
||||
var HotKey = function(params) {
|
||||
this.id = params.id || guid();
|
||||
this.key = params.key;
|
||||
this.context = params.context || null;
|
||||
this.callback = params.callback;
|
||||
this.preventInClass = params.preventInClass;
|
||||
this.args = params.args;
|
||||
this.onKeyUp = false;
|
||||
};
|
||||
|
||||
HotKey.prototype.clone = function() {
|
||||
return new HotKey(this);
|
||||
};
|
||||
|
||||
var Hotkeys = function() {
|
||||
/**
|
||||
* Sometimes a UI wants keybindings which are global, so called hotkeys.
|
||||
* Keys are keystrings (identify key combinations) and values are objects
|
||||
* with keys callback, context.
|
||||
*/
|
||||
this._hotkeys = {};
|
||||
|
||||
/**
|
||||
* Sometimes a UI wants keybindings for keyup behaviour.
|
||||
*/
|
||||
this._hotkeysUp = {};
|
||||
|
||||
/**
|
||||
* Keybindings are ignored by default when coming from a form input field.
|
||||
*/
|
||||
this._preventIn = ['INPUT', 'SELECT', 'MD-SELECT', 'TEXTAREA'];
|
||||
|
||||
this._onKeydown = this._onKeydown.bind(this);
|
||||
this._onKeyup = this._onKeyup.bind(this);
|
||||
|
||||
this.initialize();
|
||||
};
|
||||
|
||||
/**
|
||||
* Binds Keydown, Keyup with the window object
|
||||
*/
|
||||
Hotkeys.prototype.initialize = function() {
|
||||
$window.addEventListener('keydown', this._onKeydown, true);
|
||||
$window.addEventListener('keyup', this._onKeyup, true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Invokes callback functions assosiated with the given hotkey
|
||||
* @param {Event} event
|
||||
* @param {String} keyString hotkey
|
||||
* @param {Array.<HotKey>} hotkeys List of registered callbacks for
|
||||
* the given hotkey
|
||||
* @private
|
||||
*/
|
||||
Hotkeys.prototype._invokeHotkeyHandlers = function(event, keyString, hotkeys) {
|
||||
for (var i = 0, l = hotkeys.length; i < l; i++) {
|
||||
var hotkey = hotkeys[i],
|
||||
target = event.target || event.srcElement,
|
||||
nodeName = target.nodeName.toUpperCase();
|
||||
if (!_.includes(this._preventIn, nodeName) &&
|
||||
_.intersection(target.classList, hotkey.preventInClass).length === 0) {
|
||||
try {
|
||||
hotkey.callback.call(hotkey.context, event, hotkey.args);
|
||||
} catch(e) {
|
||||
console.error('HotKeys: ', hotkey.key, e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Keydown Event Handler
|
||||
* @private
|
||||
*/
|
||||
Hotkeys.prototype._onKeydown = function(event) {
|
||||
var keyString = this.keyStringFromEvent(event);
|
||||
if (this._hotkeys[keyString]) {
|
||||
this._invokeHotkeyHandlers(event, keyString, this._hotkeys[keyString]);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Keyup Event Handler
|
||||
* @private
|
||||
*/
|
||||
Hotkeys.prototype._onKeyup = function(event) {
|
||||
var keyString = this.keyStringFromEvent(event);
|
||||
if (this._hotkeysUp[keyString]) {
|
||||
this._invokeHotkeyHandlers(this._hotkeysUp[keyString], keyString);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Cross-browser method which can extract a key string from an event.
|
||||
* Key strings are of the form
|
||||
*
|
||||
* ctrl+alt+shift+meta+character
|
||||
*
|
||||
* where each of the 4 modifiers may or may not appear, but always appear
|
||||
* in that order if they do appear.
|
||||
*
|
||||
* TODO : this is not yet implemented fully. The trouble is, the keyCode,
|
||||
* charCode, and which properties of the DOM standard KeyboardEvent are
|
||||
* discouraged in favour of the use of key and char, but key and char are
|
||||
* not yet implemented in Gecko nor in Blink/Webkit. We need to leverage
|
||||
* keyCode/charCode so that current browser versions are supported, but also
|
||||
* look to key and char because they're apparently more useful and are the
|
||||
* future.
|
||||
*/
|
||||
Hotkeys.prototype.keyStringFromEvent = function(event) {
|
||||
var result = [];
|
||||
var key = event.which;
|
||||
|
||||
if (KEY_CODES[key]) {
|
||||
key = KEY_CODES[key];
|
||||
} else {
|
||||
key = String.fromCharCode(key).toLowerCase();
|
||||
}
|
||||
|
||||
if (event.ctrlKey) { result.push('ctrl'); }
|
||||
if (event.altKey) { result.push('alt'); }
|
||||
if (event.shiftKey) { result.push('shift'); }
|
||||
if (event.metaKey) { result.push('meta'); }
|
||||
result.push(key);
|
||||
return _.uniq(result).join('+');
|
||||
};
|
||||
|
||||
/**
|
||||
* Unregister a hotkey (shortcut) helper for (keyUp/keyDown).
|
||||
*
|
||||
* @param {String} params.key - valid key string.
|
||||
*/
|
||||
Hotkeys.prototype._deregisterHotkey = function(hotkey) {
|
||||
var ret;
|
||||
var table = this._hotkeys;
|
||||
|
||||
if (hotkey.onKeyUp) {
|
||||
table = this._hotkeysUp;
|
||||
}
|
||||
|
||||
if (table[hotkey.key]) {
|
||||
var callbackArray = table[hotkey.key];
|
||||
for (var i = 0; i < callbackArray.length; ++i) {
|
||||
var callbackData = callbackArray[i];
|
||||
if ((hotkey.callback === callbackData.callback &&
|
||||
callbackData.context === hotkey.context) ||
|
||||
(hotkey.id === callbackData.id)) {
|
||||
ret = callbackArray.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
/**
|
||||
* Unregister hotkeys
|
||||
* @param {Hotkey} hotkey A hotkey object
|
||||
* @return {Array}
|
||||
*/
|
||||
Hotkeys.prototype.deregisterHotkey = function(hotkey) {
|
||||
var result = [];
|
||||
|
||||
this._validateHotkey(hotkey);
|
||||
|
||||
if (angular.isArray(hotkey.key)) {
|
||||
for (var i = hotkey.key.length - 1; i >= 0; i--) {
|
||||
var clone = hotkey.clone();
|
||||
clone.key = hotkey.key[i];
|
||||
var ret = this._deregisterHotkey(clone);
|
||||
if (ret !== void 0) {
|
||||
result.push(ret[0]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result.push(this._deregisterHotkey(hotkey));
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Validate HotKey type
|
||||
*/
|
||||
Hotkeys.prototype._validateHotkey = function(hotkey) {
|
||||
if (!(hotkey instanceof HotKey)) {
|
||||
throw new TypeError('Hotkeys: Expected a hotkey object be instance of HotKey');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Register a hotkey (shortcut) helper for (keyUp/keyDown).
|
||||
* @param {Object} params Parameters object
|
||||
* @param {String} params.key - valid key string.
|
||||
* @param {Function} params.callback - routine to run when key is pressed.
|
||||
* @param {Object} params.context - @this value in the callback.
|
||||
* @param [Boolean] params.onKeyUp - if this is intended for a keyup.
|
||||
* @param [String] params.id - the identifier for this registration.
|
||||
*/
|
||||
Hotkeys.prototype._registerKey = function(hotkey) {
|
||||
var table = this._hotkeys;
|
||||
|
||||
if (hotkey.onKeyUp) {
|
||||
table = this._hotkeysUp;
|
||||
}
|
||||
|
||||
table[hotkey.key] = table[hotkey.key] || [];
|
||||
table[hotkey.key].push(hotkey);
|
||||
return hotkey;
|
||||
};
|
||||
|
||||
Hotkeys.prototype._registerKeys = function(hotkey) {
|
||||
var result = [];
|
||||
|
||||
if (angular.isArray(hotkey.key)) {
|
||||
for (var i = hotkey.key.length - 1; i >= 0; i--) {
|
||||
var clone = hotkey.clone();
|
||||
clone.id = guid();
|
||||
clone.key = hotkey.key[i];
|
||||
result.push(this._registerKey(clone));
|
||||
}
|
||||
} else {
|
||||
result.push(this._registerKey(hotkey));
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Register a hotkey (shortcut). see _registerHotKey
|
||||
*/
|
||||
Hotkeys.prototype.registerHotkey = function(hotkey) {
|
||||
this._validateHotkey(hotkey);
|
||||
return this._registerKeys(hotkey);
|
||||
};
|
||||
|
||||
/**
|
||||
* Register a hotkey (shortcut) keyup behavior.
|
||||
* see _registerHotKey
|
||||
*/
|
||||
Hotkeys.prototype.registerHotkeyUp = function(hotkey) {
|
||||
this._validateHotkey(hotkey);
|
||||
hotkey.onKeyUp = true;
|
||||
this._registerKeys(hotkey);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates new hotkey object.
|
||||
* @param {Object} args
|
||||
* @return {HotKey}
|
||||
*/
|
||||
Hotkeys.prototype.createHotkey = function(args) {
|
||||
if (args.key === null || args.key === void 0) {
|
||||
throw new TypeError('HotKeys: Argument "key" is required');
|
||||
}
|
||||
|
||||
if (args.callback === null || args.callback === void 0) {
|
||||
throw new TypeError('HotKeys: Argument "callback" is required');
|
||||
}
|
||||
|
||||
args.callback = wrapWithApply(args.callback);
|
||||
return new HotKey(args);
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if given shortcut match the event
|
||||
* @param {Event} event An event
|
||||
* @param {String|Array} key A shortcut
|
||||
* @return {Boolean}
|
||||
*/
|
||||
Hotkeys.prototype.match = function(event, key) {
|
||||
if (!angular.isArray(key)) {
|
||||
key = [key];
|
||||
}
|
||||
|
||||
var eventHotkey = this.keyStringFromEvent(event);
|
||||
return Boolean(~key.indexOf(eventHotkey));
|
||||
};
|
||||
|
||||
return Hotkeys;
|
||||
}
|
||||
}
|
||||
|
||||
sgHotkeys.$inject = ['$sgHotkeys'];
|
||||
function sgHotkeys($sgHotkeys) {
|
||||
return new $sgHotkeys();
|
||||
}
|
||||
|
||||
angular
|
||||
.module('SOGo.Common')
|
||||
.service('sgHotkeys', sgHotkeys)
|
||||
.provider('$sgHotkeys', $sgHotkeys);
|
||||
})();
|
|
@ -6,10 +6,11 @@
|
|||
/**
|
||||
* @ngInject
|
||||
*/
|
||||
MailboxController.$inject = ['$window', '$scope', '$timeout', '$q', '$state', '$mdDialog', '$mdToast', 'stateAccounts', 'stateAccount', 'stateMailbox', 'encodeUriFilter', 'sgFocus', 'Dialog', 'Account', 'Mailbox'];
|
||||
function MailboxController($window, $scope, $timeout, $q, $state, $mdDialog, $mdToast, stateAccounts, stateAccount, stateMailbox, encodeUriFilter, focus, Dialog, Account, Mailbox) {
|
||||
MailboxController.$inject = ['$window', '$scope', '$timeout', '$q', '$state', '$mdDialog', '$mdToast', 'stateAccounts', 'stateAccount', 'stateMailbox', 'sgHotkeys', 'encodeUriFilter', 'sgFocus', 'Dialog', 'Account', 'Mailbox'];
|
||||
function MailboxController($window, $scope, $timeout, $q, $state, $mdDialog, $mdToast, stateAccounts, stateAccount, stateMailbox, sgHotkeys, encodeUriFilter, focus, Dialog, Account, Mailbox) {
|
||||
var vm = this, messageDialog = null,
|
||||
defaultWindowTitle = angular.element($window.document).find('title').attr('sg-default') || "SOGo";
|
||||
defaultWindowTitle = angular.element($window.document).find('title').attr('sg-default') || "SOGo",
|
||||
hotkeys = [];
|
||||
|
||||
// Expose controller for eventual popup windows
|
||||
$window.$mailboxController = vm;
|
||||
|
@ -41,6 +42,10 @@
|
|||
angular.element($window).on('beforeunload', _compactBeforeUnload);
|
||||
$scope.$on('$destroy', function() {
|
||||
angular.element($window).off('beforeunload', _compactBeforeUnload);
|
||||
// Deregister hotkeys
|
||||
_.forEach(hotkeys, function(key) {
|
||||
sgHotkeys.deregisterHotkey(key);
|
||||
});
|
||||
});
|
||||
|
||||
// Update window's title with unseen messages count of selected mailbox
|
||||
|
@ -52,6 +57,49 @@
|
|||
$window.document.title = title;
|
||||
});
|
||||
|
||||
_registerHotkeys(hotkeys);
|
||||
|
||||
|
||||
function _registerHotkeys(keys) {
|
||||
keys.push(sgHotkeys.createHotkey({
|
||||
key: 'c',
|
||||
callback: newMessage
|
||||
}));
|
||||
keys.push(sgHotkeys.createHotkey({
|
||||
key: 'space',
|
||||
callback: toggleMessageSelection
|
||||
}));
|
||||
keys.push(sgHotkeys.createHotkey({
|
||||
key: 'up',
|
||||
callback: _nextMessage,
|
||||
preventInClass: ['sg-mail-part']
|
||||
}));
|
||||
keys.push(sgHotkeys.createHotkey({
|
||||
key: 'down',
|
||||
callback: _previousMessage,
|
||||
preventInClass: ['sg-mail-part']
|
||||
}));
|
||||
keys.push(sgHotkeys.createHotkey({
|
||||
key: 'shift+up',
|
||||
callback: _addNextMessageToSelection,
|
||||
preventInClass: ['sg-mail-part']
|
||||
}));
|
||||
keys.push(sgHotkeys.createHotkey({
|
||||
key: 'shift+down',
|
||||
callback: _addPreviousMessageToSelection,
|
||||
preventInClass: ['sg-mail-part']
|
||||
}));
|
||||
keys.push(sgHotkeys.createHotkey({
|
||||
key: 'backspace',
|
||||
callback: confirmDeleteSelectedMessages
|
||||
}));
|
||||
|
||||
// Register the hotkeys
|
||||
_.forEach(hotkeys, function(key) {
|
||||
sgHotkeys.registerHotkey(key);
|
||||
});
|
||||
}
|
||||
|
||||
function _compactBeforeUnload(event) {
|
||||
return vm.selectedFolder.$compact();
|
||||
}
|
||||
|
@ -106,6 +154,68 @@
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* User has pressed up arrow key
|
||||
*/
|
||||
function _nextMessage($event) {
|
||||
var index = vm.selectedFolder.$selectedMessageIndex();
|
||||
|
||||
if (angular.isDefined(index))
|
||||
index--;
|
||||
else
|
||||
// No message is selected, show oldest message
|
||||
index = vm.selectedFolder.getLength() - 1;
|
||||
|
||||
if (index > -1)
|
||||
selectMessage(vm.selectedFolder.$messages[index]);
|
||||
|
||||
$event.preventDefault();
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* User has pressed the down arrow key
|
||||
*/
|
||||
function _previousMessage($event) {
|
||||
var index = vm.selectedFolder.$selectedMessageIndex();
|
||||
|
||||
if (angular.isDefined(index))
|
||||
index++;
|
||||
else
|
||||
// No message is selected, show newest
|
||||
index = 0;
|
||||
|
||||
if (index < vm.selectedFolder.getLength())
|
||||
selectMessage(vm.selectedFolder.$messages[index]);
|
||||
else
|
||||
index = -1;
|
||||
|
||||
$event.preventDefault();
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
function _addNextMessageToSelection($event) {
|
||||
var index;
|
||||
|
||||
if (vm.selectedFolder.hasSelectedMessage()) {
|
||||
index = _nextMessage($event);
|
||||
if (index >= 0)
|
||||
toggleMessageSelection($event, vm.selectedFolder.$messages[index]);
|
||||
}
|
||||
}
|
||||
|
||||
function _addPreviousMessageToSelection($event) {
|
||||
var index;
|
||||
|
||||
if (vm.selectedFolder.hasSelectedMessage()) {
|
||||
index = _previousMessage($event);
|
||||
if (index >= 0)
|
||||
toggleMessageSelection($event, vm.selectedFolder.$messages[index]);
|
||||
}
|
||||
}
|
||||
|
||||
function selectMessage(message) {
|
||||
if (Mailbox.$virtualMode)
|
||||
$state.go('mail.account.virtualMailbox.message', {mailboxId: encodeUriFilter(message.$mailbox.path), messageId: message.uid});
|
||||
|
@ -114,6 +224,7 @@
|
|||
}
|
||||
|
||||
function toggleMessageSelection($event, message) {
|
||||
if (!message) message = vm.selectedFolder.$selectedMessage();
|
||||
message.selected = !message.selected;
|
||||
vm.mode.multiple += message.selected? 1 : -1;
|
||||
$event.preventDefault();
|
||||
|
@ -170,27 +281,30 @@
|
|||
}
|
||||
}
|
||||
|
||||
function confirmDeleteSelectedMessages() {
|
||||
Dialog.confirm(l('Warning'),
|
||||
l('Are you sure you want to delete the selected messages?'),
|
||||
{ ok: l('Delete') })
|
||||
function confirmDeleteSelectedMessages($event) {
|
||||
var selectedMessages = vm.selectedFolder.$selectedMessages();
|
||||
|
||||
if (_.size(selectedMessages) > 0)
|
||||
Dialog.confirm(l('Warning'),
|
||||
l('Are you sure you want to delete the selected messages?'),
|
||||
{ ok: l('Delete') })
|
||||
.then(function() {
|
||||
var deleteSelectedMessage = vm.selectedFolder.hasSelectedMessage();
|
||||
var selectedMessages = vm.selectedFolder.$selectedMessages();
|
||||
if (_.size(selectedMessages) > 0)
|
||||
vm.selectedFolder.$deleteMessages(selectedMessages).then(function(index) {
|
||||
if (Mailbox.$virtualMode) {
|
||||
// When performing an advanced search, we refresh the view if the selected message
|
||||
// was deleted, but only once all promises have completed.
|
||||
if (deleteSelectedMessage)
|
||||
$state.go('mail.account.virtualMailbox');
|
||||
}
|
||||
else {
|
||||
// In normal mode, we immediately unselect the selected message.
|
||||
_unselectMessage(deleteSelectedMessage, index);
|
||||
}
|
||||
});
|
||||
vm.selectedFolder.$deleteMessages(selectedMessages).then(function(index) {
|
||||
if (Mailbox.$virtualMode) {
|
||||
// When performing an advanced search, we refresh the view if the selected message
|
||||
// was deleted, but only once all promises have completed.
|
||||
if (deleteSelectedMessage)
|
||||
$state.go('mail.account.virtualMailbox');
|
||||
}
|
||||
else {
|
||||
// In normal mode, we immediately unselect the selected message.
|
||||
_unselectMessage(deleteSelectedMessage, index);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$event.preventDefault();
|
||||
}
|
||||
|
||||
function markOrUnMarkMessagesAsJunk() {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* -*- Mode: js; indent-tabs-mode: nil; js-indent-level: 2; -*- */
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
@ -366,7 +366,7 @@
|
|||
}
|
||||
|
||||
function refreshUnseenCount() {
|
||||
var unseenCountFolders = window.unseenCountFolders;
|
||||
var unseenCountFolders = $window.unseenCountFolders;
|
||||
|
||||
_.forEach(vm.accounts, function(account) {
|
||||
|
||||
|
|
|
@ -357,7 +357,9 @@
|
|||
}
|
||||
}
|
||||
};
|
||||
_visit(this.parts);
|
||||
|
||||
if (this.parts)
|
||||
_visit(this.parts);
|
||||
|
||||
return parts;
|
||||
};
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
/**
|
||||
* @ngInject
|
||||
*/
|
||||
MessageController.$inject = ['$window', '$scope', '$state', '$mdMedia', '$mdDialog', 'sgConstant', 'stateAccounts', 'stateAccount', 'stateMailbox', 'stateMessage', 'encodeUriFilter', 'sgSettings', 'sgFocus', 'Dialog', 'Calendar', 'Component', 'Account', 'Mailbox', 'Message'];
|
||||
function MessageController($window, $scope, $state, $mdMedia, $mdDialog, sgConstant, stateAccounts, stateAccount, stateMailbox, stateMessage, encodeUriFilter, sgSettings, focus, Dialog, Calendar, Component, Account, Mailbox, Message) {
|
||||
var vm = this, messageDialog = null, popupWindow = null;
|
||||
MessageController.$inject = ['$window', '$scope', '$state', '$mdMedia', '$mdDialog', 'sgConstant', 'stateAccounts', 'stateAccount', 'stateMailbox', 'stateMessage', 'sgHotkeys', 'encodeUriFilter', 'sgSettings', 'sgFocus', 'Dialog', 'Calendar', 'Component', 'Account', 'Mailbox', 'Message'];
|
||||
function MessageController($window, $scope, $state, $mdMedia, $mdDialog, sgConstant, stateAccounts, stateAccount, stateMailbox, stateMessage, sgHotkeys, encodeUriFilter, sgSettings, focus, Dialog, Calendar, Component, Account, Mailbox, Message) {
|
||||
var vm = this, messageDialog = null, popupWindow = null, hotkeys = [];
|
||||
|
||||
// Expose controller
|
||||
$window.$messageController = vm;
|
||||
|
@ -93,6 +93,32 @@
|
|||
});
|
||||
}
|
||||
|
||||
$scope.$on('$destroy', function() {
|
||||
// Deregister hotkeys
|
||||
_.forEach(hotkeys, function(key) {
|
||||
sgHotkeys.deregisterHotkey(key);
|
||||
});
|
||||
});
|
||||
|
||||
_registerHotkeys(hotkeys);
|
||||
|
||||
|
||||
function _registerHotkeys(keys) {
|
||||
keys.push(sgHotkeys.createHotkey({
|
||||
key: 'backspace',
|
||||
callback: function($event) {
|
||||
if (vm.mailbox.$selectedCount() === 0)
|
||||
deleteMessage();
|
||||
$event.preventDefault();
|
||||
}
|
||||
}));
|
||||
|
||||
// Register the hotkeys
|
||||
_.forEach(hotkeys, function(key) {
|
||||
sgHotkeys.registerHotkey(key);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* If this is a popup window, retrieve the matching controllers (mailbox and message) of the parent window.
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue