Browse Source

Implemented universal scroller

Added keyboard hide/show
Added enter slash button
Added scroll to keyboard
master
Igor Zhukov 10 years ago
parent
commit
ba25a32b14
  1. 26
      app/js/controllers.js
  2. 20
      app/js/directives.js
  3. 167
      app/js/message_composer.js
  4. 16
      app/js/services.js
  5. 73
      app/less/app.less
  6. 109
      app/less/desktop.less
  7. 44
      app/partials/desktop/im.html
  8. 8
      app/partials/desktop/reply_markup.html

26
app/js/controllers.js

@ -995,6 +995,8 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.selectedFlush = selectedFlush; $scope.selectedFlush = selectedFlush;
$scope.botStart = botStart; $scope.botStart = botStart;
$scope.replyKeyboardToggle = replyKeyboardToggle;
$scope.toggleEdit = toggleEdit; $scope.toggleEdit = toggleEdit;
$scope.toggleMedia = toggleMedia; $scope.toggleMedia = toggleMedia;
$scope.returnToRecent = returnToRecent; $scope.returnToRecent = returnToRecent;
@ -1393,7 +1395,17 @@ angular.module('myApp.controllers', ['myApp.i18n'])
} }
console.log('update reply markup', peerID, replyKeyboard); console.log('update reply markup', peerID, replyKeyboard);
$scope.historyState.replyKeyboard = replyKeyboard; $scope.historyState.replyKeyboard = replyKeyboard;
$scope.$broadcast('ui_panel_update'); $scope.$broadcast('ui_keyboard_update');
}
function replyKeyboardToggle () {
var replyKeyboard = $scope.historyState.replyKeyboard;
if (!replyKeyboard) {
return;
}
replyKeyboard.pFlags.hidden = !replyKeyboard.pFlags.hidden;
console.log('toggle reply markup', peerID, replyKeyboard);
$scope.$broadcast('ui_keyboard_update');
} }
function botStart () { function botStart () {
@ -1859,7 +1871,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.$on('user_update', angular.noop); $scope.$on('user_update', angular.noop);
}) })
.controller('AppImSendController', function ($scope, $timeout, MtpApiManager, Storage, AppProfileManager, AppChatsManager, AppUsersManager, AppPeersManager, AppDocsManager, AppMessagesManager, MtpApiFileManager) { .controller('AppImSendController', function ($scope, $timeout, MtpApiManager, Storage, AppProfileManager, AppChatsManager, AppUsersManager, AppPeersManager, AppDocsManager, AppMessagesManager, MtpApiFileManager, RichTextProcessor) {
$scope.$watch('curDialog.peer', resetDraft); $scope.$watch('curDialog.peer', resetDraft);
$scope.$on('user_update', angular.noop); $scope.$on('user_update', angular.noop);
@ -1876,6 +1888,8 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.$watch('draftMessage.sticker', onStickerSelected); $scope.$watch('draftMessage.sticker', onStickerSelected);
$scope.$watch('draftMessage.command', onCommandSelected); $scope.$watch('draftMessage.command', onCommandSelected);
$scope.enterSlash = enterSlash;
function sendMessage (e) { function sendMessage (e) {
$scope.$broadcast('ui_message_before_send'); $scope.$broadcast('ui_message_before_send');
@ -1974,7 +1988,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
commandsList.push({ commandsList.push({
botID: peerBot.id, botID: peerBot.id,
value: value, value: value,
description: description rDescription: RichTextProcessor.wrapRichText(description, {noLinks: true, noLineBreaks: true})
}); });
SearchIndexManager.indexObject(value, botSearchText + ' ' + command + ' ' + description, commandsIndex); SearchIndexManager.indexObject(value, botSearchText + ' ' + command + ' ' + description, commandsIndex);
}) })
@ -2017,6 +2031,12 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.$broadcast('ui_peer_reply'); $scope.$broadcast('ui_peer_reply');
} }
function enterSlash (event) {
$scope.draftMessage.text = '/';
$scope.$broadcast('ui_peer_draft');
return cancelEvent(event);
}
function onMessageChange(newVal) { function onMessageChange(newVal) {
// console.log('ctrl text changed', newVal); // console.log('ctrl text changed', newVal);
// console.trace('ctrl text changed', newVal); // console.trace('ctrl text changed', newVal);

20
app/js/directives.js

@ -414,9 +414,26 @@ angular.module('myApp.directives', ['myApp.filters'])
}; };
function link ($scope, element, attrs) { function link ($scope, element, attrs) {
var scrollable = $('.reply_markup', element);
var scroller = new Scroller(scrollable, {
classPrefix: 'reply_markup',
maxHeight: 170
});
$scope.buttonSend = function (button) { $scope.buttonSend = function (button) {
$scope.$emit('reply_button_press', button); $scope.$emit('reply_button_press', button);
} }
$scope.$on('ui_keyboard_update', function () {
onContentLoaded(function () {
scroller.updateHeight();
scroller.scrollTo(0);
$scope.$emit('ui_panel_update');
})
});
onContentLoaded(function () {
scroller.updateHeight();
$scope.$emit('ui_panel_update');
});
} }
}) })
@ -1474,6 +1491,9 @@ angular.module('myApp.directives', ['myApp.filters'])
if (!Config.Navigator.touch) { if (!Config.Navigator.touch) {
composer.focus(); composer.focus();
} }
onContentLoaded(function () {
composer.checkAutocomplete(true);
});
if (emojiTooltip) { if (emojiTooltip) {
emojiTooltip.hide(); emojiTooltip.hide();
} }

167
app/js/message_composer.js

@ -196,21 +196,6 @@ EmojiTooltip.prototype.onMouseLeave = function (triggerUnshow) {
} }
}; };
EmojiTooltip.prototype.getScrollWidth = function() {
var outer = $('<div>').css({
position: 'absolute',
width: 100,
height: 100,
overflow: 'scroll',
top: -9999
}).appendTo($(document.body));
var scrollbarWidth = outer[0].offsetWidth - outer[0].clientWidth;
outer.remove();
return scrollbarWidth;
};
EmojiTooltip.prototype.createTooltip = function () { EmojiTooltip.prototype.createTooltip = function () {
@ -219,20 +204,12 @@ EmojiTooltip.prototype.createTooltip = function () {
} }
var self = this; var self = this;
this.tooltipEl = $('<div class="composer_emoji_tooltip noselect"><div class="composer_emoji_tooltip_tabs"></div><div class="composer_emoji_tooltip_content_wrap nano mobile_scrollable_wrap"><div class="composer_emoji_tooltip_content nano-content clearfix"></div></div><div class="composer_emoji_tooltip_footer"><a class="composer_emoji_tooltip_settings"></a></div><div class="composer_emoji_tooltip_tail"><i class="icon icon-tooltip-tail"></i></div></div>').appendTo(document.body); this.tooltipEl = $('<div class="composer_emoji_tooltip noselect"><div class="composer_emoji_tooltip_tabs"></div><div class="composer_emoji_tooltip_content clearfix"></div><div class="composer_emoji_tooltip_footer"><a class="composer_emoji_tooltip_settings"></a></div><div class="composer_emoji_tooltip_tail"><i class="icon icon-tooltip-tail"></i></div></div>').appendTo(document.body);
this.tabsEl = $('.composer_emoji_tooltip_tabs', this.tooltip); this.tabsEl = $('.composer_emoji_tooltip_tabs', this.tooltipEl);
this.contentWrapEl = $('.composer_emoji_tooltip_content_wrap', this.tooltip); this.contentEl = $('.composer_emoji_tooltip_content', this.tooltipEl);
this.contentEl = $('.composer_emoji_tooltip_content', this.tooltip); this.footerEl = $('.composer_emoji_tooltip_footer', this.tooltipEl);
this.footerEl = $('.composer_emoji_tooltip_footer', this.tooltip); this.settingsEl = $('.composer_emoji_tooltip_settings', this.tooltipEl);
this.settingsEl = $('.composer_emoji_tooltip_settings', this.tooltip);
var scrollWidth = this.getScrollWidth();
if (scrollWidth > 0) {
this.tooltipEl.css({
width: parseInt(this.tooltipEl.css('width')) + scrollWidth
});
}
angular.forEach(['recent', 'smile', 'flower', 'bell', 'car', 'grid', 'stickers'], function (tabName, tabIndex) { angular.forEach(['recent', 'smile', 'flower', 'bell', 'car', 'grid', 'stickers'], function (tabName, tabIndex) {
var tab = $('<a class="composer_emoji_tooltip_tab composer_emoji_tooltip_tab_' + tabName + '"></a>') var tab = $('<a class="composer_emoji_tooltip_tab composer_emoji_tooltip_tab_' + tabName + '"></a>')
@ -254,9 +231,7 @@ EmojiTooltip.prototype.createTooltip = function () {
} }
}); });
if (!Config.Mobile) { this.scroller = new Scroller(this.contentEl, {classPrefix: 'composer_emoji_tooltip'});
this.contentWrapEl.nanoScroller({preventPageScrolling: true, tabIndex: -1});
}
this.contentEl.on('mousedown', function (e) { this.contentEl.on('mousedown', function (e) {
e = e.originalEvent || e; e = e.originalEvent || e;
@ -323,13 +298,7 @@ EmojiTooltip.prototype.updateTabContents = function () {
var renderContent = function () { var renderContent = function () {
self.contentEl.html(html.join('')); self.contentEl.html(html.join(''));
self.scroller.reinit();
if (!Config.Mobile) {
self.contentWrapEl.nanoScroller({scroll: 'top'});
setTimeout(function () {
self.contentWrapEl.nanoScroller();
}, 100);
}
} }
if (this.tab == 6) { // Stickers if (this.tab == 6) { // Stickers
@ -488,12 +457,9 @@ function MessageComposer (textarea, options) {
this.setUpInput(); this.setUpInput();
this.autoCompleteWrapEl = $('<div class="composer_dropdown_wrap"></div>').appendTo(document.body); this.autoCompleteWrapEl = $('<div class="composer_dropdown_wrap"></div>').appendTo(document.body);
this.autoCompleteScrollerEl = $('<div class="composer_dropdown_scroller nano"></div>').appendTo(this.autoCompleteWrapEl); this.autoCompleteEl = $('<ul class="composer_dropdown dropdown-menu"></ul>').appendTo(this.autoCompleteWrapEl);
this.autoCompleteEl = $('<ul class="composer_dropdown dropdown-menu nano-content"></ul>').appendTo(this.autoCompleteScrollerEl);
if (!Config.Mobile) { this.scroller = new Scroller(this.autoCompleteEl, {maxHeight: 180});
this.autoCompleteScrollerEl.nanoScroller({preventPageScrolling: true, tabIndex: -1});
}
var self = this; var self = this;
this.autoCompleteEl.on('mousedown', function (e) { this.autoCompleteEl.on('mousedown', function (e) {
@ -614,18 +580,14 @@ MessageComposer.prototype.onKeyEvent = function (e) {
currentSelected.removeClass('composer_autocomplete_option_active'); currentSelected.removeClass('composer_autocomplete_option_active');
if (nextWrap) { if (nextWrap) {
$(nextWrap).find('a').addClass('composer_autocomplete_option_active'); $(nextWrap).find('a').addClass('composer_autocomplete_option_active');
if (!Config.Mobile) { this.scroller.scrollToNode(nextWrap);
scrollToNode(this.autoCompleteEl[0], nextWrap, this.autoCompleteScrollerEl);
}
return cancelEvent(e); return cancelEvent(e);
} }
} }
var childNodes = this.autoCompleteEl[0].childNodes; var childNodes = this.autoCompleteEl[0].childNodes;
var nextWrap = childNodes[next ? 0 : childNodes.length - 1]; var nextWrap = childNodes[next ? 0 : childNodes.length - 1];
if (!Config.Mobile) { this.scroller.scrollToNode(nextWrap);
scrollToNode(this.autoCompleteEl[0], nextWrap, this.autoCompleteScrollerEl);
}
$(nextWrap).find('a').addClass('composer_autocomplete_option_active'); $(nextWrap).find('a').addClass('composer_autocomplete_option_active');
return cancelEvent(e); return cancelEvent(e);
@ -714,7 +676,7 @@ MessageComposer.prototype.restoreSelection = function () {
MessageComposer.prototype.checkAutocomplete = function () { MessageComposer.prototype.checkAutocomplete = function (forceFull) {
if (Config.Mobile) { if (Config.Mobile) {
return false; return false;
} }
@ -730,7 +692,9 @@ MessageComposer.prototype.checkAutocomplete = function () {
var value = textarea.value; var value = textarea.value;
} }
value = value.substr(0, pos); if (!forceFull) {
value = value.substr(0, pos);
}
var matches = value.match(this.autoCompleteRegEx); var matches = value.match(this.autoCompleteRegEx);
if (matches) { if (matches) {
@ -1096,15 +1060,7 @@ MessageComposer.prototype.focus = function () {
MessageComposer.prototype.renderSuggestions = function (html) { MessageComposer.prototype.renderSuggestions = function (html) {
this.autoCompleteEl.html(html.join('')); this.autoCompleteEl.html(html.join(''));
this.autoCompleteWrapEl.show(); this.autoCompleteWrapEl.show();
this.scroller.reinit();
var self = this;
if (!Config.Mobile) {
self.autoCompleteScrollerEl.nanoScroller({scroll: 'top'});
setTimeout(function () {
self.autoCompleteScrollerEl.nanoScroller();
}, 100);
}
this.updatePosition(); this.updatePosition();
this.autocompleteShown = true; this.autocompleteShown = true;
} }
@ -1161,7 +1117,7 @@ MessageComposer.prototype.showCommandsSuggestions = function (commands) {
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
command = commands[i]; command = commands[i];
html.push('<li><a class="composer_command_option" data-command="' + encodeEntities(command.value) + '"><span class="composer_user_photo" data-user-id="' + command.botID + '"></span><span class="composer_command_value">' + encodeEntities(command.value) + '</span><span class="composer_command_desc">' + encodeEntities(command.description) + '</span></a></li>'); html.push('<li><a class="composer_command_option" data-command="' + encodeEntities(command.value) + '"><span class="composer_user_photo" data-user-id="' + command.botID + '"></span><span class="composer_command_value">' + encodeEntities(command.value) + '</span><span class="composer_command_desc">' + command.rDescription + '</span></a></li>');
} }
this.renderSuggestions(html); this.renderSuggestions(html);
@ -1182,14 +1138,13 @@ MessageComposer.prototype.showCommandsSuggestions = function (commands) {
MessageComposer.prototype.updatePosition = function () { MessageComposer.prototype.updatePosition = function () {
var offset = (this.richTextareaEl || this.textareaEl).offset(); var offset = (this.richTextareaEl || this.textareaEl).offset();
var width = (this.richTextareaEl || this.textareaEl).outerWidth(); var width = (this.richTextareaEl || this.textareaEl).outerWidth();
var contentHeight = this.autoCompleteEl[0].firstChild.clientHeight * this.autoCompleteEl[0].childNodes.length; var height = this.scroller.updateHeight();
var height = Math.min(180, contentHeight);
this.autoCompleteWrapEl.css({ this.autoCompleteWrapEl.css({
top: offset.top - height, top: offset.top - height,
left: offset.left, left: offset.left,
width: width - 2, width: width - 2
height: height
}); });
this.scroller.update();
} }
MessageComposer.prototype.hideSuggestions = function () { MessageComposer.prototype.hideSuggestions = function () {
@ -1202,3 +1157,83 @@ MessageComposer.prototype.resetTyping = function () {
this.lastLength = 0; this.lastLength = 0;
} }
function Scroller(content, options) {
options = options || {};
var classPrefix = options.classPrefix || 'scroller';
this.content = $(content);
this.content.wrap('<div class="' + classPrefix + '_scrollable_container"><div class="' + classPrefix + '_scrollable_wrap"><div class="' + classPrefix + '_scrollable"></div></div></div>');
this.scrollable = $(this.content[0].parentNode);
this.scroller = $(this.scrollable[0].parentNode);
this.wrap = $(this.scroller[0].parentNode);
this.useNano = options.nano !== undefined ? options.nano : !Config.Mobile;
this.maxHeight = options.maxHeight;
if (this.useNano) {
this.scrollable.addClass('nano-content');
this.scroller.addClass('nano');
this.scroller.nanoScroller({preventPageScrolling: true, tabIndex: -1});
} else {
if (this.maxHeight) {
this.wrap.css({maxHeight: this.maxHeight});
}
}
this.updateHeight();
}
Scroller.prototype.update = function () {
if (this.useNano) {
$(this.scroller).nanoScroller();
}
}
Scroller.prototype.reinit = function () {
this.scrollTo(0);
if (this.useNano) {
setTimeout((function () {
this.updateHeight();
}).bind(this), 100)
}
}
Scroller.prototype.updateHeight = function () {
var height;
if (this.maxHeight) {
var contentHeight = this.content[0].offsetHeight;
height = Math.min(this.maxHeight, contentHeight);
this.wrap.css({height: height});
} else {
height = this.scroller[0].offsetHeight;
}
$(this.scroller).nanoScroller();
return height;
}
Scroller.prototype.scrollTo = function (scrollTop) {
this.scrollable[0].scrollTop = scrollTop;
if (this.useNano) {
$(this.scroller).nanoScroller({flash: true});
}
}
Scroller.prototype.scrollToNode = function (node) {
node = node[0] || node;
var elTop = node.offsetTop - 15,
elHeight = node.offsetHeight + 30,
scrollTop = this.scrollable[0].scrollTop,
viewportHeight = this.scrollable[0].clientHeight;
if (scrollTop > elTop) { // we are below the node to scroll
this.scrollTo(elTop);
}
else if (scrollTop < elTop + elHeight - viewportHeight) { // we are over the node to scroll
this.scrollTo(elTop + elHeight - viewportHeight);
}
}

16
app/js/services.js

@ -1055,7 +1055,12 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
}); });
if (historiesStorage[peerID] === undefined) { if (historiesStorage[peerID] === undefined) {
historiesStorage[peerID] = {count: null, history: [dialog.top_message], pending: []} var historyStorage = {count: null, history: [dialog.top_message], pending: []};
historiesStorage[peerID] = historyStorage;
var message = getMessage(dialog.top_message);
if (mergeReplyKeyboard(historyStorage, message)) {
$rootScope.$broadcast('history_reply_markup', {peerID: peerID});
}
} }
NotificationsManager.savePeerSettings(peerID, dialog.notify_settings); NotificationsManager.savePeerSettings(peerID, dialog.notify_settings);
@ -1291,7 +1296,6 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
} }
function getReplyKeyboard (peerID) { function getReplyKeyboard (peerID) {
console.log('get', historiesStorage[peerID]);
return (historiesStorage[peerID] || {}).reply_markup || false; return (historiesStorage[peerID] || {}).reply_markup || false;
} }
@ -2413,6 +2417,10 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
} }
function wrapReplyMarkup (replyMarkup) { function wrapReplyMarkup (replyMarkup) {
if (!replyMarkup ||
replyMarkup._ == 'replyKeyboardHide') {
return false;
}
if (replyMarkup.wrapped) { if (replyMarkup.wrapped) {
return replyMarkup; return replyMarkup;
} }
@ -2422,6 +2430,10 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
markupButton.rText = RichTextProcessor.wrapRichText(markupButton.text, {noLinks: true, noLinebreaks: true}); markupButton.rText = RichTextProcessor.wrapRichText(markupButton.text, {noLinks: true, noLinebreaks: true});
}) })
}) })
if (nextRandomInt(1)) {
replyMarkup.rows = replyMarkup.rows.slice(0, 2);
}
return replyMarkup; return replyMarkup;
} }

73
app/less/app.less

@ -2062,11 +2062,14 @@ a.im_message_fwd_photo {
.im_send_field_wkeyboard { .im_send_field_wkeyboard {
.im_send_buttons_wrap { .im_send_buttons_wrap {
display: none; // display: none;
} }
} }
.reply_markup_wrap { .reply_markup_wrap {
margin: 5px -2px 0; margin: 7px -2px 0;
}
.reply_markup_scrollable_wrap.has-scrollbar .reply_markup_row {
margin-right: 6px;
} }
.reply_markup_button_wrap { .reply_markup_button_wrap {
display: inline-block; display: inline-block;
@ -2075,11 +2078,12 @@ a.im_message_fwd_photo {
.reply_markup_button { .reply_markup_button {
display: block; display: block;
width: 100%; width: 100%;
background: #EEE; background: #EFEFEF;
margin: 0; margin: 0;
} }
.reply_markup_button:hover { .reply_markup_button:hover {
background: #DDD; // background: #DDD;
background: #f2f6fa;
} }
.reply_markup_button_w1 {width: 100%;} .reply_markup_button_w1 {width: 100%;}
.reply_markup_button_w2 {width: 50%;} .reply_markup_button_w2 {width: 50%;}
@ -2094,6 +2098,8 @@ a.im_message_fwd_photo {
.reply_markup_button_w11 {width: 9.09090909%;} .reply_markup_button_w11 {width: 9.09090909%;}
.reply_markup_button_w12 {width: 8.33333333%;} .reply_markup_button_w12 {width: 8.33333333%;}
.im_history_not_selected, .im_history_not_selected,
.im_history_empty { .im_history_empty {
visibility: hidden; visibility: hidden;
@ -2360,14 +2366,11 @@ img.img_fullsize {
.composer_emoji_tooltip_tab_stickers {background-position: -9px -361px; } .composer_emoji_tooltip_tab_stickers {background-position: -9px -361px; }
.composer_emoji_tooltip_tab_stickers.active {background-position: -9px -333px; } .composer_emoji_tooltip_tab_stickers.active {background-position: -9px -333px; }
.nano.composer_emoji_tooltip_content_wrap { .composer_emoji_tooltip_scrollable_container {
height: 174px; height: 174px;
position: relative; position: relative;
} }
.composer_emoji_tooltip_content { .composer_emoji_tooltip_content {
/*position: relative;*/
/*overflow: hidden;
overflow-y: auto;*/
padding-right: 8px; padding-right: 8px;
outline: 0!important; outline: 0!important;
} }
@ -2568,6 +2571,9 @@ a.composer_command_option:hover .composer_command_desc,
a.composer_command_option.composer_autocomplete_option_active .composer_command_desc { a.composer_command_option.composer_autocomplete_option_active .composer_command_desc {
color: #698192; color: #698192;
} }
.composer_command_desc .emoji {
vertical-align: text-bottom;
}
.composer_stickerset_title { .composer_stickerset_title {
@ -2654,6 +2660,57 @@ a.composer_command_option.composer_autocomplete_option_active .composer_command_
} }
} }
.composer_command_btn {
display: block;
position: absolute;
right: 23px;
top: 2px;
cursor: pointer;
padding: 0;
width: 22px;
height: 22px;
margin-top: 1px;
}
.icon-slash {
display: inline-block;
width: 22px;
height: 22px;
vertical-align: top;
opacity: 0.8;
.image-2x('../img/icons/General.png', 40px, 778px);
background-position: -9px -335px;
}
.composer_keyboard_btn {
display: block;
position: absolute;
right: 28px;
top: -2px;
cursor: pointer;
padding: 0;
width: 22px;
height: 22px;
margin-top: 1px;
}
.icon-hide-keyboard {
display: inline-block;
width: 16px;
height: 16px;
border: 2px solid #BBB;
border-top: 0;
border-left: 0;
.transform(rotate(45deg));
vertical-align: top;
opacity: 0.8;
}
.composer_keyboard_btn:hover .icon-hide-keyboard {
opacity: 1.0;
}
.error_modal_window { .error_modal_window {
.modal-dialog { .modal-dialog {
max-width: 350px; max-width: 350px;

109
app/less/desktop.less

@ -702,6 +702,24 @@ a.footer_link.active:active {
} }
} }
.reply_markup_scrollable_container {
.nano > .nano-pane {
background: rgba(137, 160, 179, 0.1);
right: 2px;
width: 3px;
top: 2px;
bottom: 2px;
.rounded(1px);
& > .nano-slider {
.rounded(1px);
background: #d1d1d1;
background: rgba(137, 160, 179, 0.5);
margin: 0;
}
}
}
.im_history { .im_history {
&_no_dialogs_wrap { &_no_dialogs_wrap {
margin: 122px 170px 60px; margin: 122px 170px 60px;
@ -1396,13 +1414,104 @@ a.im_panel_peer_photo .peer_initials {
} }
.im_send_field_wkeyboard { .im_send_field_wkeyboard {
a {
&.im_panel_peer_photo,
&.im_panel_own_photo {
display: none;
}
}
.im_send_field_wrap {
margin-bottom: 0;
}
.composer { .composer {
&_rich_textarea, &_rich_textarea,
&_textarea { &_textarea {
min-height: 25px; min-height: 25px;
padding-right: 25px; padding-right: 25px;
} }
&_emoji_insert_btn {
top: 0;
right: 0px;
margin-top: -3px;
}
&_emoji_panel {
display: none;
}
}
.im_submit {
position: absolute;
top: 0;
left: 100%;
margin: 0 0 0 15px;
} }
.im_media_attach {
position: absolute;
top: -6px;
left: -43px;
width: 19px;
height: 24px;
}
.icon-camera {
display: inline-block;
width: 19px;
height: 23px;
vertical-align: text-top;
opacity: 0.8;
margin-top: -1px;
.image-2x('../img/icons/IconsetW.png', 42px, 1171px);
background-position: -12px -68px;
}
.im_media_attach {
&:hover .icon-camera,
&:active .icon-camera {
background-position: -12px -100px;
opacity: 1;
}
}
.im_attach {
display: none;
position: absolute;
top: 0;
right: 100%;
margin: 0;
margin-right: 45px;
margin-top: 1px;
}
.icon-emoji {
display: inline-block;
width: 22px;
height: 22px;
vertical-align: text-top;
opacity: 1;
margin: 0;
.image-2x('../img/icons/IconsetW.png', 42px, 1171px);
background-position: -10px -771px;
}
.composer_emoji_insert_btn:active .icon-emoji,
.is_1x .composer_emoji_insert_btn:active .icon-emoji,
.composer_emoji_insert_btn.composer_emoji_insert_btn_on .icon-emoji,
.is_1x .composer_emoji_insert_btn.composer_emoji_insert_btn_on .icon-emoji {
background-position: -10px -803px;
}
.im_send_dropbox_wrap {
display: none;
}
} }
/* Peer modals */ /* Peer modals */

44
app/partials/desktop/im.html

@ -158,7 +158,7 @@
<div class="im_send_form_wrap1"> <div class="im_send_form_wrap1">
<div class="im_send_form_wrap clearfix" ng-controller="AppImSendController" ng-class="{im_send_reply_form_wrap: draftMessage.replyToMessage != null}"> <div class="im_send_form_wrap clearfix" ng-controller="AppImSendController" ng-class="{im_send_reply_form_wrap: draftMessage.replyToMessage != null, im_send_field_wkeyboard: false && historyState.replyKeyboard._ == 'replyKeyboardMarkup' && !historyState.replyKeyboard.pFlags.hidden}">
<a class="pull-right im_panel_peer_photo" my-peer-photolink="historyPeer.id" img-class="im_panel_peer_photo" watch="true"> <a class="pull-right im_panel_peer_photo" my-peer-photolink="historyPeer.id" img-class="im_panel_peer_photo" watch="true">
<i class="icon im_panel_peer_online" ng-show="historyPeer.id > 0 &amp;&amp; historyPeer.data.status._ == 'userStatusOnline'"></i> <i class="icon im_panel_peer_online" ng-show="historyPeer.id > 0 &amp;&amp; historyPeer.data.status._ == 'userStatusOnline'"></i>
@ -172,37 +172,35 @@
<div my-reply-message="draftMessage.replyToMessage"></div> <div my-reply-message="draftMessage.replyToMessage"></div>
</div> </div>
<div class="im_send_field_wrap">
<a class="composer_emoji_insert_btn"><i class="icon icon-emoji"></i></a>
<a class="composer_command_btn" ng-show="!historyState.replyKeyboard && commands.list.length > 0 && !draftMessage.text.length" ng-mousedown="enterSlash($event)"><i class="icon icon-slash"></i></a>
<a class="composer_keyboard_btn" ng-show="historyState.replyKeyboard._ == 'replyKeyboardMarkup'" ng-click="replyKeyboardToggle()"><i class="icon" ng-class="historyState.replyKeyboard.pFlags.hidden ? 'icon-keyboard' : 'icon-hide-keyboard'"></i></a>
<div ng-class="historyState.replyKeyboard._ == 'replyKeyboardMarkup' && !historyState.replyKeyboard.pFlags.hidden ? 'im_send_field_wkeyboard' : ''"> <div class="im_send_dropbox_wrap" my-i18n="im_photos_drop_text"></div>
<textarea ng-model="draftMessage.text" placeholder="{{'im_message_field_placeholder' | i18n}}" class="form-control im_message_field no_outline" dir="auto"></textarea>
</div>
<div class="im_send_field_wrap"> <div class="im_send_buttons_wrap clearfix">
<a class="composer_emoji_insert_btn"><i class="icon icon-emoji"></i></a> <button type="submit" class="btn btn-md im_submit" my-i18n="im_submit_message"></button>
<div class="im_send_dropbox_wrap" my-i18n="im_photos_drop_text"></div> <div class="im_attach pull-left">
<textarea ng-model="draftMessage.text" placeholder="{{'im_message_field_placeholder' | i18n}}" class="form-control im_message_field no_outline" dir="auto"></textarea> <input type="file" class="im_attach_input" size="28" multiple="true" title="{{'im_attach_file_title' | i18n}}" />
<i class="icon icon-paperclip"></i>
</div> </div>
<div class="im_send_keyboard_wrap" ng-if="historyState.replyKeyboard._ == 'replyKeyboardMarkup'"> <div class="im_media_attach pull-left">
<div my-reply-markup="historyState.replyKeyboard"></div> <input type="file" class="im_media_attach_input" size="28" multiple="true" accept="image/*, video/*, audio/*" title="{{'im_media_attach_title' | i18n}}"/>
<i class="icon icon-camera"></i>
</div> </div>
<div class="im_send_buttons_wrap clearfix"> <div class="composer_emoji_panel"></div>
<button type="submit" class="btn btn-md im_submit" my-i18n="im_submit_message"></button> </div>
<div class="im_attach pull-left">
<input type="file" class="im_attach_input" size="28" multiple="true" title="{{'im_attach_file_title' | i18n}}" />
<i class="icon icon-paperclip"></i>
</div>
<div class="im_media_attach pull-left">
<input type="file" class="im_media_attach_input" size="28" multiple="true" accept="image/*, video/*, audio/*" title="{{'im_media_attach_title' | i18n}}"/>
<i class="icon icon-camera"></i>
</div>
<div class="composer_emoji_panel"></div>
</div>
<div class="im_send_keyboard_wrap" ng-if="historyState.replyKeyboard._ == 'replyKeyboardMarkup'" ng-show="!historyState.replyKeyboard.pFlags.hidden">
<div my-reply-markup="historyState.replyKeyboard"></div>
</div> </div>
</form> </form>
</div> </div>

8
app/partials/desktop/reply_markup.html

@ -1,7 +1,9 @@
<div class="reply_markup_wrap"> <div class="reply_markup_wrap">
<div class="reply_markup_row" ng-repeat="row in replyMarkup.rows"> <div class="reply_markup">
<div class="reply_markup_button_wrap" ng-class="'reply_markup_button_w' + row.buttons.length" ng-repeat="button in row.buttons"> <div class="reply_markup_row" ng-repeat="row in replyMarkup.rows">
<button class="btn reply_markup_button" ng-bind-html="::button.rText" ng-click="buttonSend(button)"></button> <div class="reply_markup_button_wrap" ng-class="'reply_markup_button_w' + row.buttons.length" ng-repeat="button in row.buttons">
<button class="btn reply_markup_button" ng-bind-html="::button.rText" ng-click="buttonSend(button)"></button>
</div>
</div> </div>
</div> </div>
</div> </div>
Loading…
Cancel
Save