Added keyboard shortcuts (part 1) (#70)

Scrolling in message view (#109)
This commit is contained in:
RainLoop Team 2014-04-08 01:03:58 +04:00
parent 3936a818b7
commit 8979687f88
37 changed files with 2095 additions and 333 deletions

View file

@ -27,6 +27,18 @@ Enums.StateType = {
'Admin': 1
};
/**
* @enum {string}
*/
Enums.KeyState = {
'None': 'none',
'ContactList': 'contact-list',
'MessageList': 'message-list',
'MessageView': 'message-view',
'Compose': 'compose',
'PopupAsk': 'popup-ask'
};
/**
* @enum {number}
*/

View file

@ -137,10 +137,12 @@ Selector.prototype.goUp = function ()
this.newSelectPosition(Enums.EventKeyCode.Up, false);
};
Selector.prototype.init = function (oContentVisible, oContentScrollable)
Selector.prototype.init = function (oContentVisible, oContentScrollable, sKeyScope)
{
this.oContentVisible = oContentVisible;
this.oContentScrollable = oContentScrollable;
sKeyScope = sKeyScope || 'all';
if (this.oContentVisible && this.oContentScrollable)
{
@ -183,27 +185,43 @@ Selector.prototype.init = function (oContentVisible, oContentScrollable)
})
;
$(window.document).on('keydown', function (oEvent) {
var bResult = true;
if (oEvent && self.bUseKeyboard && !Utils.inFocus())
key('space, enter', sKeyScope, function () {
return false;
});
key('up, shift+up, down, shift+down, insert, home, end, pageup, pagedown', sKeyScope, function (event, handler) {
if (event && handler && handler.shortcut)
{
if (-1 < Utils.inArray(oEvent.keyCode, [Enums.EventKeyCode.Up, Enums.EventKeyCode.Down, Enums.EventKeyCode.Insert,
Enums.EventKeyCode.Home, Enums.EventKeyCode.End, Enums.EventKeyCode.PageUp, Enums.EventKeyCode.PageDown]))
var iKey = 0, aCodes = null;
switch (handler.shortcut)
{
self.newSelectPosition(oEvent.keyCode, oEvent.shiftKey);
bResult = false;
case 'up':
case 'shift+up':
iKey = Enums.EventKeyCode.Up;
break;
case 'down':
case 'shift+down':
iKey = Enums.EventKeyCode.Down;
break;
case 'insert':
case 'home':
case 'end':
case 'pageup':
case 'pagedown':
aCodes = key.getPressedKeyCodes();
if (aCodes && aCodes[0])
{
iKey = aCodes[0];
}
break;
}
else if (Enums.EventKeyCode.Delete === oEvent.keyCode && !oEvent.ctrlKey && !oEvent.shiftKey)
if (0 < iKey)
{
if (self.oCallbacks['onDelete'])
{
self.oCallbacks['onDelete']();
}
bResult = false;
self.newSelectPosition(iKey, key.shift);
return false;
}
}
return bResult;
});
}
};

View file

@ -1719,3 +1719,31 @@ Utils.selectElement = function (element)
}
/* jshint onevar: true */
};
Utils.disableKeyFilter = function ()
{
if (window.key)
{
key.filter = function () {
return true;
};
}
};
Utils.restoreKeyFilter = function ()
{
if (window.key)
{
key.filter = function (event) {
var
element = event.target || event.srcElement,
tagName = element ? element.tagName : ''
;
tagName = tagName.toUpperCase();
return !(tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA' ||
(element && tagName === 'DIV' && 'editorHtmlArea' === element.className && element.contentEditable)
);
};
}
};

View file

@ -63,14 +63,11 @@ KnoinAbstractViewModel.prototype.cancelCommand = KnoinAbstractViewModel.prototyp
KnoinAbstractViewModel.prototype.registerPopupEscapeKey = function ()
{
var self = this;
$window.on('keydown', function (oEvent) {
if (oEvent && Enums.EventKeyCode.Esc === oEvent.keyCode && self.modalVisibility())
key('esc', _.bind(function () {
if (this.modalVisibility && this.modalVisibility())
{
Utils.delegateRun(self, 'cancelCommand');
Utils.delegateRun(this, 'cancelCommand');
return false;
}
return true;
});
}, this));
};

View file

@ -12,8 +12,9 @@ function ContactModel()
this.readOnly = false;
this.scopeType = Enums.ContactScopeType.Default;
this.checked = ko.observable(false);
this.focused = ko.observable(false);
this.selected = ko.observable(false);
this.checked = ko.observable(false);
this.deleted = ko.observable(false);
this.shared = ko.observable(false);
}
@ -118,6 +119,10 @@ ContactModel.prototype.lineAsCcc = function ()
{
aResult.push('shared');
}
if (this.focused())
{
aResult.push('focused');
}
return aResult.join(' ');
};

View file

@ -24,6 +24,7 @@ function FolderModel()
this.type = ko.observable(Enums.FolderType.User);
this.focused = ko.observable(false);
this.selected = ko.observable(false);
this.edited = ko.observable(false);
this.collapsed = ko.observable(true);

View file

@ -35,6 +35,7 @@ function MessageModel()
this.forwarded = ko.observable(false);
this.isReadReceipt = ko.observable(false);
this.focused = ko.observable(false);
this.selected = ko.observable(false);
this.checked = ko.observable(false);
this.hasAttachments = ko.observable(false);
@ -514,6 +515,10 @@ MessageModel.prototype.lineAsCcc = function ()
{
aResult.push('forwarded');
}
if (this.focused())
{
aResult.push('focused');
}
if (this.hasAttachments())
{
aResult.push('withAttachments');

View file

@ -37,6 +37,13 @@ MailBoxScreen.prototype.setNewTitle = function ()
MailBoxScreen.prototype.onShow = function ()
{
this.setNewTitle();
RL.data().keyScope(Enums.KeyState.MessageList);
};
MailBoxScreen.prototype.onHide = function ()
{
RL.data().keyScope(Enums.KeyState.None);
};
/**

View file

@ -37,12 +37,27 @@ function WebMailDataStorage()
this.accountIncLogin = ko.observable('');
this.accountOutLogin = ko.observable('');
this.projectHash = ko.observable('');
this.threading = ko.observable(false);
this.lastFoldersHash = '';
this.lastFoldersHash = '';
this.remoteSuggestions = false;
this.keyScope = ko.observable(Enums.KeyState.None);
this.keyScope.subscribe(function (sValue) {
if (Enums.KeyState.Compose === sValue)
{
Utils.disableKeyFilter();
}
else
{
Utils.restoreKeyFilter();
}
// window.console.log(sValue);
key.setScope(sValue);
});
// system folders
this.sentFolder = ko.observable('');
this.draftFolder = ko.observable('');
@ -257,6 +272,23 @@ function WebMailDataStorage()
this.messageLoading = ko.observable(false);
this.messageLoadingThrottle = ko.observable(false).extend({'throttle': 50});
this.message.focused = ko.observable(false);
this.message.subscribe(function (oMessage) {
if (!oMessage)
{
this.message.focused(false);
}
else if (Enums.Layout.NoPreview === this.layout())
{
this.message.focused(true);
}
}, this);
this.message.focused.subscribe(function (bValue) {
RL.data().keyScope(bValue ? Enums.KeyState.MessageView : Enums.KeyState.MessageList);
});
this.messageLoading.subscribe(function (bValue) {
this.messageLoadingThrottle(bValue);
}, this);

View file

@ -42,6 +42,7 @@
@import "SystemDropDown.less";
@import "Login.less";
@import "Ask.less";
@import "Shortcuts.less";
@import "FolderList.less";
@import "FolderClear.less";
@import "FolderCreate.less";

View file

@ -478,6 +478,10 @@ html.rl-no-preview-pane {
}
}
&.message-focused .b-content {
.opacity(97);
}
&.hideMessageListCheckbox {
.checkedParent, .checkboxCkeckAll {
display: none !important;

View file

@ -30,10 +30,9 @@ html.rl-no-preview-pane {
top: 50px + @rlLowMargin;
bottom: @rlLowMargin + @rlBottomMargin;
right: @rlLowMargin;
left: 0;
left: -1px;
overflow: hidden;
border: @rlLowBorderSize solid @rlMainDarkColor;
border-left: 0px;
.border-top-right-radius(@rlLowBorderRadius);
.border-bottom-right-radius(@rlLowBorderRadius);
@ -351,6 +350,17 @@ html.rl-no-preview-pane {
}
}
}
&.message-focused .messageItemHeader {
background-color: #fafafa !important;
}
&.message-focused .b-content {
z-index: 102;
.box-shadow(0px 2px 8px rgba(0, 0, 0, 0.3));
border-color: darken(@rlMainDarkColor, 5%);
.border-radius(@rlLowBorderRadius);
}
}
html.rl-no-preview-pane .messageView {

View file

@ -0,0 +1,7 @@
.popups {
.b-shortcuts-content {
.modal-header {
background-color: #fff;
}
}
}

View file

@ -24,11 +24,19 @@ Utils.extendAsViewModel('MailBoxFolderListViewModel', MailBoxFolderListViewModel
MailBoxFolderListViewModel.prototype.onBuild = function (oDom)
{
oDom
.on('click', '.b-folders .b-content', function () {
if (RL.data().useKeyboardShortcuts() && RL.data().message.focused())
{
RL.data().message.focused(false);
}
})
.on('click', '.b-folders .e-item .e-link .e-collapsed-sign', function (oEvent) {
var
var
oFolder = ko.dataFor(this),
bCollapsed = false
;
if (oFolder && oEvent)
{
bCollapsed = oFolder.collapsed();

View file

@ -16,6 +16,7 @@ function MailBoxMessageListViewModel()
this.popupVisibility = RL.popupVisibility;
this.message = oData.message;
this.messageList = oData.messageList;
this.currentMessage = oData.currentMessage;
this.isMessageSelected = oData.isMessageSelected;
@ -214,13 +215,6 @@ function MailBoxMessageListViewModel()
return oMessage ? oMessage.generateUid() : '';
});
this.selector.on('onDelete', _.bind(function () {
if (0 < RL.data().messageListCheckedOrSelected().length)
{
this.deleteCommand();
}
}, this));
RL
.sub('mailbox.message-list.selector.go-down', function () {
this.selector.goDown();
@ -540,31 +534,15 @@ MailBoxMessageListViewModel.prototype.onBuild = function (oDom)
return false;
});
this.selector.init(this.oContentVisible, this.oContentScrollable);
$document.on('keydown', function (oEvent) {
var
bResult = true,
iKeyCode = oEvent ? oEvent.keyCode : 0
;
if (oEvent && self.viewModelVisibility() && oData.useKeyboardShortcuts() && !RL.popupVisibility() && !oData.messageFullScreenMode() && !Utils.inFocus())
{
if (Enums.Layout.NoPreview !== oData.layout() || (!oData.message() && (Enums.EventKeyCode.Delete === iKeyCode || Enums.EventKeyCode.A === iKeyCode)))
{
if (oEvent.ctrlKey && Enums.EventKeyCode.A === iKeyCode)
{
self.checkAll(!(self.checkAll() && !self.isIncompleteChecked()));
bResult = false;
}
}
}
return bResult;
});
this.selector.init(this.oContentVisible, this.oContentScrollable, Enums.KeyState.MessageList);
oDom
.on('click', '.messageList .b-message-list-wrapper', function () {
if (oData.useKeyboardShortcuts() && self.message.focused())
{
self.message.focused(false);
}
})
.on('click', '.e-pagenator .e-page', function () {
var oPage = ko.dataFor(this);
if (oPage)
@ -625,6 +603,7 @@ MailBoxMessageListViewModel.prototype.onBuild = function (oDom)
}, this).extend({'notify': 'always'});
this.initUploaderForAppend();
this.initShortcuts();
if (!Globals.bMobileDevice && !!RL.settingsGet('AllowPrefetch') && ifvisible)
{
@ -636,6 +615,121 @@ MailBoxMessageListViewModel.prototype.onBuild = function (oDom)
}
};
MailBoxMessageListViewModel.prototype.initShortcuts = function ()
{
var
self = this,
oData = RL.data()
;
// disable print
key('ctrl+p, command+p', Enums.KeyState.MessageList, function () {
if (oData.useKeyboardShortcuts())
{
return false;
}
});
// delete
key('delete, shift+delete', Enums.KeyState.MessageList, function (event, handler) {
if (oData.useKeyboardShortcuts() && event)
{
if (0 < RL.data().messageListCheckedOrSelected().length)
{
if (handler && 'shift+delete' === handler.shortcut)
{
self.deleteWithoutMoveCommand();
}
else
{
self.deleteCommand();
}
}
return false;
}
});
// check all
key('ctrl+a, command+a', Enums.KeyState.MessageList, function () {
if (oData.useKeyboardShortcuts())
{
self.checkAll(!(self.checkAll() && !self.isIncompleteChecked()));
return false;
}
});
// new message (open compose popup)
key('c,n', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
if (oData.useKeyboardShortcuts())
{
kn.showScreenPopup(PopupsComposeViewModel);
return false;
}
});
// shortcuts help
key('shift+/', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
if (oData.useKeyboardShortcuts())
{
kn.showScreenPopup(PopupsKeyboardShortcutsHelpViewModel);
return false;
}
});
// search input focus
key('/', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
if (oData.useKeyboardShortcuts())
{
if (self.message())
{
self.message.focused(false);
}
self.inputMessageListSearchFocus(true);
return false;
}
});
// cancel search
key('esc', Enums.KeyState.MessageList, function () {
if (oData.useKeyboardShortcuts() && '' !== self.messageListSearchDesc())
{
self.cancelSearch();
return false;
}
});
// change focused state
key('tab, enter', Enums.KeyState.MessageList, function () {
if (oData.useKeyboardShortcuts())
{
if (self.message())
{
self.message.focused(true);
}
return false;
}
});
key('ctrl+left, command+left', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts())
{
// TODO
return false;
}
});
key('ctrl+right, command+right', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts())
{
// TODO
return false;
}
});
};
MailBoxMessageListViewModel.prototype.prefetchNextTick = function ()
{
if (!this.bPrefetch && !ifvisible.now() && this.viewModelVisibility())

View file

@ -21,6 +21,7 @@ function MailBoxMessageViewViewModel()
this.oMessageScrollerDom = null;
this.keyScope = oData.keyScope;
this.message = oData.message;
this.messageLoading = oData.messageLoading;
this.messageLoadingThrottle = oData.messageLoadingThrottle;
@ -36,6 +37,7 @@ function MailBoxMessageViewViewModel()
this.fullScreenMode = oData.messageFullScreenMode;
this.showFullInfo = ko.observable(false);
this.messageDomFocused = ko.observable(false);
this.messageVisibility = ko.computed(function () {
return !this.messageLoadingThrottle() && !!this.message();
@ -68,36 +70,39 @@ function MailBoxMessageViewViewModel()
}, this.messageVisibility);
this.deleteCommand = Utils.createCommand(this, function () {
if (this.message())
{
RL.deleteMessagesFromFolder(Enums.FolderType.Trash,
this.message().folderFullNameRaw,
[this.message().uid], true);
}
}, this.messageVisibility);
this.deleteWithoutMoveCommand = Utils.createCommand(this, function () {
if (this.message())
{
RL.deleteMessagesFromFolder(Enums.FolderType.Trash,
RL.data().currentFolderFullNameRaw(),
RL.data().messageListCheckedOrSelectedUidsWithSubMails(), false);
}
}, this.messageVisibility);
this.archiveCommand = Utils.createCommand(this, function () {
if (this.message())
{
RL.deleteMessagesFromFolder(Enums.FolderType.Archive,
this.message().folderFullNameRaw,
[this.message().uid], true);
}
}, this.messageVisibility);
this.spamCommand = Utils.createCommand(this, function () {
if (this.message())
{
RL.deleteMessagesFromFolder(Enums.FolderType.Spam,
this.message().folderFullNameRaw,
[this.message().uid], true);
}
}, this.messageVisibility);
// viewer
@ -291,29 +296,14 @@ MailBoxMessageViewViewModel.prototype.onBuild = function (oDom)
self = this,
oData = RL.data()
;
$document.on('keydown', function (oEvent) {
var
bResult = true,
iKeyCode = oEvent ? oEvent.keyCode : 0
;
if (0 < iKeyCode && (Enums.EventKeyCode.Esc === iKeyCode) &&
self.viewModelVisibility() && oData.useKeyboardShortcuts() && !Utils.inFocus() && oData.message())
this.fullScreenMode.subscribe(function (bValue) {
if (bValue)
{
self.fullScreenMode(false);
if (Enums.Layout.NoPreview === oData.layout())
{
RL.historyBack();
}
bResult = false;
self.message.focused(true);
}
return bResult;
});
}, this);
$('.attachmentsPlace', oDom).magnificPopup({
'delegate': '.magnificPopupImage:visible',
'type': 'image',
@ -335,6 +325,12 @@ MailBoxMessageViewViewModel.prototype.onBuild = function (oDom)
});
oDom
.on('click', '.messageView .messageItem', function () {
if (oData.useKeyboardShortcuts() && self.message())
{
self.message.focused(true);
}
})
.on('mousedown', 'a', function (oEvent) {
// setup maito protocol
return !(oEvent && 3 !== oEvent['which'] && RL.mailToHelper($(this).attr('href')));
@ -358,8 +354,171 @@ MailBoxMessageViewViewModel.prototype.onBuild = function (oDom)
})
;
this.message.focused.subscribe(function (bValue) {
this.messageDomFocused(!!bValue);
}, this);
this.keyScope.subscribe(function (sValue) {
if (Enums.KeyState.MessageView === sValue && this.message.focused())
{
this.messageDomFocused(true);
}
}, this);
this.oMessageScrollerDom = oDom.find('.messageItem .content');
this.oMessageScrollerDom = this.oMessageScrollerDom && this.oMessageScrollerDom[0] ? this.oMessageScrollerDom : null;
this.initShortcuts();
};
/**
* @return {boolean}
*/
MailBoxMessageViewViewModel.prototype.escShortcuts = function ()
{
if (this.viewModelVisibility() && RL.data().useKeyboardShortcuts() && this.message())
{
if (this.fullScreenMode())
{
this.fullScreenMode(false);
}
else
{
this.message.focused(false);
}
if (Enums.Layout.NoPreview === RL.data().layout())
{
RL.historyBack();
}
return false;
}
};
MailBoxMessageViewViewModel.prototype.initShortcuts = function ()
{
var
self = this,
oData = RL.data()
;
// exit fullscreen, back
key('esc', Enums.KeyState.MessageView, _.bind(this.escShortcuts, this));
// fullscreen
key('enter', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts())
{
self.toggleFullScreen();
return false;
}
});
// reply
key('r', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts())
{
self.replyCommand();
return false;
}
});
// replaAll
key('a', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts())
{
self.replyAllCommand();
return false;
}
});
// forward
key('f', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts())
{
self.forwardCommand();
return false;
}
});
// message information
key('i', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts())
{
self.showFullInfo(!self.showFullInfo());
return false;
}
});
key('ctrl+left, command+left', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts())
{
self.goDownCommand();
return false;
}
});
key('ctrl+right, command+right', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts())
{
self.goUpCommand();
return false;
}
});
// print
key('ctrl+p, command+p', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts())
{
if (self.message())
{
self.message().printMessage();
}
return false;
}
});
// archive
// key('delete', Enums.KeyState.MessageView, function () {
// if (oData.useKeyboardShortcuts())
// {
// self.archiveCommand();
// return false;
// }
// });
// delete
key('delete, shift+delete', Enums.KeyState.MessageView, function (event, handler) {
if (oData.useKeyboardShortcuts() && event)
{
self.deleteCommand();
if (handler && 'shift+delete' === handler.shortcut)
{
// self.deleteWithoutMoveCommand();
self.deleteCommand();
}
else
{
self.deleteCommand();
}
return false;
}
});
// change focused state
key('tab', Enums.KeyState.MessageView, function () {
if (oData.useKeyboardShortcuts())
{
if (self.message())
{
self.message.focused(false);
}
return false;
}
});
};
/**

View file

@ -19,6 +19,7 @@ function PopupsAskViewModel()
this.fNoAction = null;
this.bDisabeCloseOnEsc = true;
this.sKeyScope = Enums.KeyState.MessageList;
Knoin.constructorEnd(this);
}
@ -40,22 +41,22 @@ PopupsAskViewModel.prototype.clearPopup = function ()
PopupsAskViewModel.prototype.yesClick = function ()
{
this.cancelCommand();
if (Utils.isFunc(this.fYesAction))
{
this.fYesAction.call(null);
}
this.cancelCommand();
};
PopupsAskViewModel.prototype.noClick = function ()
{
this.cancelCommand();
if (Utils.isFunc(this.fNoAction))
{
this.fNoAction.call(null);
}
this.cancelCommand();
};
/**
@ -82,6 +83,9 @@ PopupsAskViewModel.prototype.onShow = function (sAskDesc, fYesFunc, fNoFunc, sYe
{
this.yesButton(sNoButton);
}
this.sKeyScope = RL.data().keyScope();
RL.data().keyScope(Enums.KeyState.PopupAsk);
};
PopupsAskViewModel.prototype.onFocus = function ()
@ -91,31 +95,25 @@ PopupsAskViewModel.prototype.onFocus = function ()
PopupsAskViewModel.prototype.onHide = function ()
{
RL.data().keyScope(this.sKeyScope);
};
PopupsAskViewModel.prototype.onBuild = function ()
{
var self = this;
$window.on('keydown', function (oEvent) {
var bResult = true;
if (oEvent && self.modalVisibility())
key('tab, right, left', Enums.KeyState.PopupAsk, _.bind(function () {
if (this.modalVisibility())
{
if (Enums.EventKeyCode.Tab === oEvent.keyCode || Enums.EventKeyCode.Right === oEvent.keyCode || Enums.EventKeyCode.Left === oEvent.keyCode)
if (this.yesFocus())
{
if (self.yesFocus())
{
self.noFocus(true);
}
else
{
self.yesFocus(true);
}
bResult = false;
this.noFocus(true);
}
else
{
this.yesFocus(true);
}
}
return bResult;
});
return false;
}
}, this));
};

View file

@ -351,7 +351,8 @@ function PopupsComposeViewModel()
// this.driveCallback = _.bind(this.driveCallback, this);
this.bDisabeCloseOnEsc = true;
this.sKeyScope = Enums.KeyState.MessageList;
Knoin.constructorEnd(this);
}
@ -568,6 +569,8 @@ PopupsComposeViewModel.prototype.onHide = function ()
{
this.reset();
kn.routeOn();
RL.data().keyScope(this.sKeyScope);
};
/**
@ -639,6 +642,9 @@ PopupsComposeViewModel.prototype.editor = function (fOnInit)
PopupsComposeViewModel.prototype.onShow = function (sType, oMessageOrArray, aToEmails)
{
kn.routeOff();
this.sKeyScope = RL.data().keyScope();
RL.data().keyScope(Enums.KeyState.Compose);
var
self = this,
@ -914,6 +920,11 @@ PopupsComposeViewModel.prototype.tryToClosePopup = function ()
}]);
};
PopupsComposeViewModel.prototype.useShortcuts = function ()
{
return this.modalVisibility() && RL.data().useKeyboardShortcuts();
};
PopupsComposeViewModel.prototype.onBuild = function ()
{
this.initUploader();
@ -923,29 +934,25 @@ PopupsComposeViewModel.prototype.onBuild = function ()
oScript = null
;
$window.on('keydown', function (oEvent) {
var bResult = true;
if (oEvent && self.modalVisibility() && RL.data().useKeyboardShortcuts())
key('ctrl+s, command+s', Enums.KeyState.Compose, function () {
if (self.useShortcuts())
{
if (oEvent.ctrlKey && !oEvent.shiftKey && !oEvent.altKey && Enums.EventKeyCode.S === oEvent.keyCode)
{
self.saveCommand();
bResult = false;
}
else if (oEvent.ctrlKey && !oEvent.shiftKey && !oEvent.altKey && Enums.EventKeyCode.Enter === oEvent.keyCode)
{
self.sendCommand();
bResult = false;
}
else if (Enums.EventKeyCode.Esc === oEvent.keyCode)
{
self.tryToClosePopup();
bResult = false;
}
self.saveCommand();
return false;
}
});
return bResult;
key('ctrl+enter, command+enter', Enums.KeyState.Compose, function () {
if (self.useShortcuts())
{
self.sendCommand();
return false;
}
});
key('esc', Enums.KeyState.Compose, function () {
self.tryToClosePopup();
return false;
});
$window.on('resize', function () {

View file

@ -171,10 +171,6 @@ function PopupsContactsViewModel()
return oContact ? oContact.generateUid() : '';
});
this.selector.on('onDelete', _.bind(function () {
this.deleteCommand();
}, this));
this.newCommand = Utils.createCommand(this, function () {
this.populateViewContact(null);
this.currentContact(null);
@ -307,6 +303,8 @@ function PopupsContactsViewModel()
}
}, this);
this.sKeyScope = Enums.KeyState.MessageList;
Knoin.constructorEnd(this);
}
@ -577,10 +575,18 @@ PopupsContactsViewModel.prototype.onBuild = function (oDom)
this.oContentVisible = $('.b-list-content', oDom);
this.oContentScrollable = $('.content', this.oContentVisible);
this.selector.init(this.oContentVisible, this.oContentScrollable);
this.selector.init(this.oContentVisible, this.oContentScrollable, Enums.KeyState.ContactList);
var self = this;
key('delete', Enums.KeyState.ContactList, function () {
if (RL.data().useKeyboardShortcuts())
{
self.deleteCommand();
return false;
}
});
ko.computed(function () {
var
bModalVisibility = this.modalVisibility(),
@ -607,6 +613,9 @@ PopupsContactsViewModel.prototype.onShow = function ()
{
kn.routeOff();
this.reloadContactList(true);
this.sKeyScope = RL.data().keyScope();
RL.data().keyScope(Enums.KeyState.ContactList);
};
PopupsContactsViewModel.prototype.onHide = function ()
@ -619,4 +628,6 @@ PopupsContactsViewModel.prototype.onHide = function ()
_.each(this.contacts(), function (oItem) {
oItem.checked(false);
});
RL.data().keyScope(this.sKeyScope);
};

View file

@ -0,0 +1,27 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
/**
* @constructor
* @extends KnoinAbstractViewModel
*/
function PopupsKeyboardShortcutsHelpViewModel()
{
KnoinAbstractViewModel.call(this, 'Popups', 'PopupsKeyboardShortcutsHelp');
this.sKeyScope = Enums.KeyState.None;
Knoin.constructorEnd(this);
}
Utils.extendAsViewModel('PopupsKeyboardShortcutsHelpViewModel', PopupsKeyboardShortcutsHelpViewModel);
PopupsKeyboardShortcutsHelpViewModel.prototype.onShow = function ()
{
this.sKeyScope = RL.data().keyScope();
RL.data().keyScope(Enums.KeyState.None);
};
PopupsKeyboardShortcutsHelpViewModel.prototype.onHide = function ()
{
RL.data().keyScope(this.sKeyScope);
};

View file

@ -127,14 +127,11 @@ PopupsPluginViewModel.prototype.tryToClosePopup = function ()
PopupsPluginViewModel.prototype.onBuild = function ()
{
var self = this;
$window.on('keydown', function (oEvent) {
var bResult = true;
if (oEvent && Enums.EventKeyCode.Esc === oEvent.keyCode && self.modalVisibility())
key('esc', _.bind(function () {
if (this.modalVisibility())
{
self.tryToClosePopup();
bResult = false;
this.tryToClosePopup();
return false;
}
return bResult;
});
}));
};