Browse Source

Added keyboard shortcuts

Closes #81
master
Igor Zhukov 11 years ago
parent
commit
68496f8f62
  1. 2
      Makefile
  2. 18
      app/css/app.css
  3. 2
      app/js/controllers.js
  4. 140
      app/js/directives.js
  5. 2
      app/partials/im.html

2
Makefile

@ -7,4 +7,6 @@ publish:
./node_modules/gulp/bin/gulp.js clean ./node_modules/gulp/bin/gulp.js clean
cd dist && git pull origin gh-pages cd dist && git pull origin gh-pages
./node_modules/gulp/bin/gulp.js publish ./node_modules/gulp/bin/gulp.js publish
echo -n "Please open http://localhost:8000/dist/index.html and check if everything works fine."
read -e
cd dist && git add --all . && git commit -am "merged with master" && git push origin gh-pages cd dist && git add --all . && git commit -am "merged with master" && git push origin gh-pages

18
app/css/app.css

@ -949,7 +949,8 @@ a.tg_radio_on:hover i.icon-radio {
padding: 8px 9px; padding: 8px 9px;
border-radius: 0; border-radius: 0;
} }
.im_dialogs_scrollable_wrap a.im_dialog:hover { .im_dialogs_scrollable_wrap a.im_dialog:hover,
.im_dialogs_scrollable_wrap a.im_dialog_selected {
border-radius: 2px; border-radius: 2px;
background: #f2f6fa; background: #f2f6fa;
} }
@ -957,7 +958,8 @@ a.tg_radio_on:hover i.icon-radio {
border-radius: 2px; border-radius: 2px;
background-color: #6490b1; background-color: #6490b1;
} }
.im_dialogs_scrollable_wrap .active a.im_dialog:hover { .im_dialogs_scrollable_wrap .active a.im_dialog:hover,
.im_dialogs_scrollable_wrap .active a.im_dialog_selected {
background-color: #6490b1; background-color: #6490b1;
} }
@ -978,7 +980,8 @@ a.tg_radio_on:hover i.icon-radio {
.im_dialog_message_text { .im_dialog_message_text {
color: #808080; color: #808080;
} }
a.im_dialog:hover .im_dialog_message_text { a.im_dialog:hover .im_dialog_message_text,
a.im_dialog_selected .im_dialog_message_text {
color: #698192; color: #698192;
} }
.active a.im_dialog .im_dialog_chat_from_wrap, .active a.im_dialog .im_dialog_chat_from_wrap,
@ -1031,7 +1034,8 @@ a.im_dialog:hover .im_dialog_message_text {
margin: 10px 0 0; margin: 10px 0 0;
} }
a.im_dialog:hover .im_dialog_unread { a.im_dialog:hover .im_dialog_unread,
a.im_dialog_selected .im_dialog_unread {
background: #a3c0d4; background: #a3c0d4;
} }
.active .im_dialog_unread { .active .im_dialog_unread {
@ -1043,11 +1047,13 @@ a.im_dialog:hover .im_dialog_unread {
color: #b3b3b3; color: #b3b3b3;
font-size: 0.85em; font-size: 0.85em;
} }
a.im_dialog:hover .im_dialog_date { a.im_dialog:hover .im_dialog_date,
a.im_dialog_selected .im_dialog_date {
color: #91a6ba; color: #91a6ba;
} }
.active .im_dialog_date, .active .im_dialog_date,
.active a.im_dialog:hover .im_dialog_date { .active a.im_dialog:hover .im_dialog_date,
.active a.im_dialog_selected .im_dialog_date {
color: #b8d1e4; color: #b8d1e4;
} }

2
app/js/controllers.js

@ -565,7 +565,7 @@ angular.module('myApp.controllers', [])
} }
// console.trace('load history'); // console.trace('load history');
var curJump = jump, var curJump = ++jump,
inputMediaFilter = $scope.mediaType && {_: inputMediaFilters[$scope.mediaType]}, inputMediaFilter = $scope.mediaType && {_: inputMediaFilters[$scope.mediaType]},
getMessagesPromise = inputMediaFilter getMessagesPromise = inputMediaFilter
? AppMessagesManager.getSearch($scope.curDialog.inputPeer, '', inputMediaFilter, maxID) ? AppMessagesManager.getSearch($scope.curDialog.inputPeer, '', inputMediaFilter, maxID)

140
app/js/directives.js

@ -29,6 +29,135 @@ angular.module('myApp.directives', ['myApp.filters'])
}; };
}) })
.directive('myDialogs', function ($modalStack) {
return {
link: link
};
function link ($scope, element, attrs) {
var dialogsWrap = $('.im_dialogs_wrap', element)[0],
scrollableWrap = $('.im_dialogs_scrollable_wrap', element)[0],
searchField = $('.im_dialogs_search_field', element)[0],
searchFocused = false;
$(searchField).on('focus blur', function (e) {
searchFocused = e.type == 'focus';
if (!searchFocused) {
$(scrollableWrap).find('.im_dialog_selected').removeClass('.im_dialog_selected');
}
});
function onKeyDown(e) {
if (!searchFocused && $modalStack.getTop()) {
return true;
}
if (e.keyCode >= 48 && e.keyCode <= 57 && !e.shiftKey && e.altKey) { // Alt + [0-9 keys]
var currentSelected = $(scrollableWrap).find('.im_dialog_wrap a')[(e.keyCode - 48 || 10) - 1];
if (currentSelected) {
currentSelected.click();
}
return cancelEvent(e);
}
if (e.keyCode == 27 || e.keyCode == 9 && e.shiftKey) { // ESC or Shift + Tab
if (!searchFocused) {
searchField.focus();
if (searchField.value) {
searchField.select();
}
}
return cancelEvent(e);
}
if (searchFocused && e.keyCode == 13) { // Enter
var currentSelected = $(scrollableWrap).find('.im_dialog_selected')[0] || $(scrollableWrap).find('.im_dialog_wrap a')[0];
if (currentSelected) {
currentSelected.click();
}
return cancelEvent(e);
}
if (e.keyCode == 38 || e.keyCode == 40) { // UP, DOWN
var skip = !e.shiftKey && e.altKey;
if (!skip && (!searchFocused || e.metaKey)) {
return true;
}
var next = e.keyCode == 40,
currentSelected = !skip && $(scrollableWrap).find('.im_dialog_selected')[0] || $(scrollableWrap).find('.active a.im_dialog')[0],
currentSelectedWrap = currentSelected && currentSelected.parentNode,
nextDialogWrap;
if (currentSelectedWrap) {
var nextDialogWrap = currentSelected[next ? 'nextSibling' : 'previousSibling'];
if (!nextDialogWrap || !nextDialogWrap.className || nextDialogWrap.className.indexOf('im_dialog_wrap') == -1) {
var dialogWraps = $(scrollableWrap).find('.im_dialog_wrap'),
pos = dialogWraps.index(currentSelected.parentNode),
nextPos = pos + (next ? 1 : -1);
nextDialogWrap = dialogWraps[nextPos];
}
} else {
var dialogWraps = $(scrollableWrap).find('.im_dialog_wrap');
if (next) {
nextDialogWrap = dialogWraps[0];
} else {
nextDialogWrap = dialogWraps[dialogWraps.length - 1];
}
}
if (skip) {
if (nextDialogWrap) {
$(nextDialogWrap).find('a')[0].click();
}
} else {
if (currentSelectedWrap && nextDialogWrap) {
$(currentSelectedWrap).find('a').removeClass('im_dialog_selected');
}
if (nextDialogWrap) {
$(nextDialogWrap).find('a').addClass('im_dialog_selected');
}
}
if (nextDialogWrap) {
var elTop = nextDialogWrap.offsetTop,
elHeight = nextDialogWrap.offsetHeight,
scrollTop = scrollableWrap.scrollTop,
viewportHeight = scrollableWrap.clientHeight;
if (scrollTop > elTop) {
scrollableWrap.scrollTop = elTop;
$(dialogsWrap).nanoScroller({flash: true});
}
else if (scrollTop < elTop + elHeight - viewportHeight) {
scrollableWrap.scrollTop = elTop + elHeight - viewportHeight;
$(dialogsWrap).nanoScroller({flash: true});
}
}
return cancelEvent(e);
}
}
$(document).on('keydown', onKeyDown);
$scope.$on('$destroy', function () {
$(document).off('keydown', onKeyDown);
});
}
})
.directive('myDialogsList', function($window, $timeout) { .directive('myDialogsList', function($window, $timeout) {
return { return {
@ -417,7 +546,7 @@ angular.module('myApp.directives', ['myApp.filters'])
}) })
.directive('mySendForm', function ($timeout, AppConfigManager, ErrorService) { .directive('mySendForm', function ($timeout, $modalStack, AppConfigManager, ErrorService) {
return { return {
link: link, link: link,
@ -534,6 +663,14 @@ angular.module('myApp.directives', ['myApp.filters'])
} }
}; };
function onKeyDown(e) {
if (e.keyCode == 9 && !e.shiftKey && !$modalStack.getTop()) { // TAB
editorElement.focus();
return cancelEvent(e);
}
}
$(document).on('keydown', onKeyDown);
$('body').on('dragenter dragleave dragover drop', onDragDropEvent); $('body').on('dragenter dragleave dragover drop', onDragDropEvent);
$(document).on('paste', onPasteEvent); $(document).on('paste', onPasteEvent);
if (richTextarea) { if (richTextarea) {
@ -555,6 +692,7 @@ angular.module('myApp.directives', ['myApp.filters'])
$scope.$on('$destroy', function cleanup() { $scope.$on('$destroy', function cleanup() {
$('body').off('dragenter dragleave dragover drop', onDragDropEvent); $('body').off('dragenter dragleave dragover drop', onDragDropEvent);
$(document).off('paste', onPasteEvent); $(document).off('paste', onPasteEvent);
$(document).off('keydown', onKeyDown);
if (richTextarea) { if (richTextarea) {
$(richTextarea).off('DOMNodeInserted', onPastedImageEvent); $(richTextarea).off('DOMNodeInserted', onPastedImageEvent);
} }

2
app/partials/im.html

@ -4,7 +4,7 @@
<div class="im_page_split clearfix"> <div class="im_page_split clearfix">
<div class="im_dialogs_col_wrap" ng-controller="AppImDialogsController"> <div class="im_dialogs_col_wrap" ng-controller="AppImDialogsController" my-dialogs>
<div class="im_dialogs_panel"> <div class="im_dialogs_panel">
<div class="dropdown im_dialogs_panel_dropdown pull-right"> <div class="dropdown im_dialogs_panel_dropdown pull-right">
<a class="dropdown-toggle"> <a class="dropdown-toggle">

Loading…
Cancel
Save