Browse Source

Improved emoji tooltip

master
Igor Zhukov 9 years ago
parent
commit
7acc4bfdab
  1. 12
      app/js/directives.js
  2. 11
      app/js/lib/utils.js
  3. 3
      app/js/locales/en-us.json
  4. 360
      app/js/message_composer.js
  5. 8
      app/js/messages_manager.js
  6. 62
      app/js/services.js
  7. 118
      app/less/app.less
  8. 2
      app/less/desktop.less

12
app/js/directives.js

@ -1426,14 +1426,18 @@ angular.module('myApp.directives', ['myApp.filters'])
AppStickersManager.getStickers().then(callback); AppStickersManager.getStickers().then(callback);
}, },
getStickerImage: function (element, docID) { getStickerImage: function (element, docID) {
if (cachedStickerImages[docID]) { var category = element.attr('data-category');
element.replaceWith(cachedStickerImages[docID]); var cached = cachedStickerImages[docID];
if (cached && !isInDOM(cached[0])) {
cached.attr('data-category', category);
element.replaceWith(cached);
return; return;
} }
var scope = $scope.$new(true); var scope = $scope.$new(true);
scope.document = AppDocsManager.getDoc(docID); scope.document = AppDocsManager.getDoc(docID);
stickerImageCompiled(scope, function (clonedElement) { stickerImageCompiled(scope, function (clonedElement) {
cachedStickerImages[docID] = clonedElement; cachedStickerImages[docID] = clonedElement;
clonedElement.attr('data-category', category);
element.replaceWith(clonedElement); element.replaceWith(clonedElement);
}); });
}, },
@ -1449,6 +1453,10 @@ angular.module('myApp.directives', ['myApp.filters'])
$scope.$apply(function () { $scope.$apply(function () {
$scope.draftMessage.sticker = docID; $scope.draftMessage.sticker = docID;
}); });
},
langpack: {
im_emoji_tab: _('im_emoji_tab'),
im_stickers_tab: _('im_stickers_tab')
} }
}); });

11
app/js/lib/utils.js

@ -22,6 +22,17 @@ function checkClick (e, noprevent) {
return false; return false;
} }
function isInDOM (element, parentNode) {
if (!element) {
return false;
}
parentNode = parentNode || document.body;
if (element == parentNode) {
return true;
}
return isInDOM(element.parentNode, parentNode)
}
function checkDragEvent(e) { function checkDragEvent(e) {
if (!e || e.target && (e.target.tagName == 'IMG' || e.target.tagName == 'A')) return false; if (!e || e.target && (e.target.tagName == 'IMG' || e.target.tagName == 'A')) return false;
if (e.dataTransfer && e.dataTransfer.types) { if (e.dataTransfer && e.dataTransfer.types) {

3
app/js/locales/en-us.json

@ -444,6 +444,9 @@
"im_photos_drop_text": "Drop photos here to send", "im_photos_drop_text": "Drop photos here to send",
"im_message_field_placeholder": "Write a message...", "im_message_field_placeholder": "Write a message...",
"im_broadcast_field_placeholder": "Broadcast a message...", "im_broadcast_field_placeholder": "Broadcast a message...",
"im_emoji_tab": "Emoji",
"im_stickers_tab": "Stickers",
"im_stickers_tab_recent": "Frequently used",
"im_media_attach_title": "Send media", "im_media_attach_title": "Send media",
"im_attach_file_title": "Send file", "im_attach_file_title": "Send file",
"im_emoji_btn_title": "Insert emoticon", "im_emoji_btn_title": "Insert emoticon",

360
app/js/message_composer.js

@ -140,6 +140,7 @@ function EmojiTooltip (btnEl, options) {
this.getStickers = options.getStickers; this.getStickers = options.getStickers;
this.getStickerImage = options.getStickerImage; this.getStickerImage = options.getStickerImage;
this.onStickersetSelected = options.onStickersetSelected; this.onStickersetSelected = options.onStickersetSelected;
this.langpack = options.langpack || {};
if (!Config.Navigator.touch) { if (!Config.Navigator.touch) {
$(this.btnEl).on('mouseenter mouseleave', function (e) { $(this.btnEl).on('mouseenter mouseleave', function (e) {
@ -203,34 +204,117 @@ EmojiTooltip.prototype.createTooltip = function () {
return false; return false;
} }
var html =
'<div class="composer_emoji_tooltip noselect">\
<div class="composer_emoji_tooltip_tabs">\
<div class="composer_emoji_tooltip_tab composer_emoji_tooltip_tab_emoji">' +this.langpack.im_emoji_tab + '</div>\
<div class="composer_emoji_tooltip_tab composer_emoji_tooltip_tab_stickers">' +this.langpack.im_stickers_tab + '</div>\
<div class="composer_emoji_tooltip_tab_shadow"></div>\
</div>\
<div class="composer_emoji_tooltip_tabs_wrap">\
<div class="composer_emoji_tooltip_tabs_contents clearfix">\
<div class="composer_emoji_tooltip_tab_emoji_content">\
<div class="composer_emoji_tooltip_content_wrap">\
<div class="composer_emoji_tooltip_content composer_emoji_tooltip_content_emoji clearfix"></div>\
</div>\
<div class="composer_emoji_tooltip_categories">\
<a class="composer_emoji_tooltip_category composer_emoji_tooltip_category_recent active" data-category="0"></a>\
<a class="composer_emoji_tooltip_category composer_emoji_tooltip_category_smile" data-category="1"></a>\
<a class="composer_emoji_tooltip_category composer_emoji_tooltip_category_flower" data-category="2"></a>\
<a class="composer_emoji_tooltip_category composer_emoji_tooltip_category_bell" data-category="3"></a>\
<a class="composer_emoji_tooltip_category composer_emoji_tooltip_category_car" data-category="4"></a>\
<a class="composer_emoji_tooltip_category composer_emoji_tooltip_category_grid" data-category="5"></a>\
</div>\
</div>\
<div class="composer_emoji_tooltip_tab_stickers_content">\
<div class="composer_emoji_tooltip_content_wrap">\
<div class="composer_emoji_tooltip_content composer_emoji_tooltip_content_stickers clearfix"></div>\
</div>\
<div class="composer_emoji_tooltip_categories"></div>\
</div>\
</div>\
</div>\
<div class="composer_emoji_tooltip_tail"><i class="icon icon-tooltip-tail"></i></div>\
</div>';
html = html.replace(/>\s+</g, '><');
var self = this; var self = this;
this.tooltipEl = $('<div class="composer_emoji_tooltip noselect"><div class="composer_emoji_tooltip_tabs"><a class="composer_emoji_tooltip_tab composer_emoji_tooltip_tab_emoji">Emoji</a><a class="composer_emoji_tooltip_tab composer_emoji_tooltip_tab_stickers">Stickers</a><div class="composer_emoji_tooltip_tab_shadow"></div></div><div class="composer_emoji_tooltip_content clearfix"></div><div class="composer_emoji_tooltip_categories"></div><div class="composer_emoji_tooltip_stickers_categories"></div><div class="composer_emoji_tooltip_tail"><i class="icon icon-tooltip-tail"></i></div></div>').appendTo(document.body); this.tooltipEl = $(html).appendTo(document.body);
this.tabsEl = $('.composer_emoji_tooltip_tabs', this.tooltipEl); this.tabsEl = $('.composer_emoji_tooltip_tabs', this.tooltipEl);
this.categoriesEl = $('.composer_emoji_tooltip_categories', this.tooltipEl); this.categoriesEl = $('.composer_emoji_tooltip_categories', this.tooltipEl);
this.stickersCategoriesEl = $('.composer_emoji_tooltip_tab_stickers_content .composer_emoji_tooltip_categories', this.tooltipEl);
this.contentEl = $('.composer_emoji_tooltip_content', this.tooltipEl); this.contentEl = $('.composer_emoji_tooltip_content', this.tooltipEl);
this.emojiContentEl = $('.composer_emoji_tooltip_content_emoji', this.tooltipEl);
this.stickersContentEl = $('.composer_emoji_tooltip_content_stickers', this.tooltipEl);
angular.forEach(['recent', 'smile', 'flower', 'bell', 'car', 'grid'], function (tabName, tabIndex) { // Tabs
var tab = $('<a class="composer_emoji_tooltip_category composer_emoji_tooltip_category_' + tabName + '"></a>') angular.forEach(['emoji', 'stickers'], function (tabName, tabIndex) {
var tab = $('.composer_emoji_tooltip_tab_' + tabName, self.tabsEl)
.on('mousedown', function (e) { .on('mousedown', function (e) {
self.selectCategory(tabIndex); self.selectTab(tabIndex);
return cancelEvent(e); return cancelEvent(e);
}) });
.appendTo(self.categoriesEl);
if (!Config.Navigator.touch) { if (!Config.Navigator.touch) {
tab.on('mouseenter mouseleave', function (e) { tab.on('mouseenter mouseleave', function (e) {
clearTimeout(self.selectCategoryTimeout); clearTimeout(self.selectTabTimeout);
if (e.type == 'mouseenter') { if (e.type == 'mouseenter') {
self.selectCategoryTimeout = setTimeout(function () { self.selectTabTimeout = setTimeout(function () {
self.selectCategory(tabIndex); self.selectTab(tabIndex);
}, 300); }, 300);
} }
}); });
} }
}); });
this.scroller = new Scroller(this.contentEl, {classPrefix: 'composer_emoji_tooltip'}); // Categories
var handleEvents = 'mousedown';
if (!Config.Navigator.touch) {
handleEvents += ' mouseover mouseout';
}
this.categoriesEl.on(handleEvents, function (e) {
e = e.originalEvent || e;
var target = e.target;
if (target.tagName != 'A') {
target = target.parentNode;
}
if (target.tagName != 'A') {
return;
}
var catIndex = parseInt(target.getAttribute('data-category'));
if (e.type == 'mousedown') {
self.selectCategory(catIndex);
return cancelEvent(e);
}
if (self.tab) {
return;
}
var isOver = e.type == 'mouseover';
if (isOver && self.selectCategoryIndex == catIndex) {
return;
}
clearTimeout(self.selectCategoryTimeout);
delete self.selectCategoryTimeout;
if (isOver) {
self.selectCategoryIndex = catIndex;
self.selectCategoryTimeout = setTimeout(function () {
delete self.selectCategoryIndex;
delete self.selectCategoryTimeout;
self.selectCategory(catIndex);
}, 300);
} else {
delete self.selectCategoryIndex;
}
});
this.emojiScroller = new Scroller(this.emojiContentEl, {classPrefix: 'composer_emoji_tooltip'});
this.stickersScroller = new Scroller(this.stickersContentEl, {classPrefix: 'composer_emoji_tooltip'});
this.stickersScroller.onScroll(function (el, st) {
self.onStickersScroll(el, st);
});
this.contentEl.on('mousedown', function (e) { this.contentEl.on('mousedown', function (e) {
e = e.originalEvent || e; e = e.originalEvent || e;
@ -271,7 +355,7 @@ EmojiTooltip.prototype.createTooltip = function () {
}); });
} }
this.selectCategory(0); this.selectTab(0);
$(window).on('resize', this.updatePosition.bind(this)); $(window).on('resize', this.updatePosition.bind(this));
@ -279,64 +363,48 @@ EmojiTooltip.prototype.createTooltip = function () {
} }
EmojiTooltip.prototype.selectCategory = function (tab) { EmojiTooltip.prototype.selectCategory = function (cat, force) {
if (this.tab === tab && tab != 6) { if (this.cat === cat && !force) {
return false; return false;
} }
$('.active', this.categoriesEl).removeClass('active'); $('.active', this.categoriesEl).removeClass('active');
this.cat = cat;
if (this.tab) {
this.activateStickerCategory();
this.updateStickersContents(force);
} else {
$(this.categoriesEl[this.tab].childNodes[cat]).addClass('active');
this.updateEmojiContents();
}
};
EmojiTooltip.prototype.selectTab = function (tab, force) {
if (this.tab === tab && !force) {
return false;
}
this.tab = tab; this.tab = tab;
$(this.categoriesEl[0].childNodes[tab]).addClass('active'); this.selectCategory(0, true);
this.updateTabContents(); var self = this;
setTimeout(function () {
$(self.tooltipEl).toggleClass('composer_emoji_tooltip_tabs_stickers_active', tab == 1);
}, 0);
}; };
EmojiTooltip.prototype.updateTabContents = function () { EmojiTooltip.prototype.updateEmojiContents = function () {
var html = []; var html = [];
var self = this; var self = this;
var iconSize = 26;//Config.Mobile ? 26 : 20; var iconSize = 26;
var renderContent = function () { var renderContent = function () {
self.contentEl.html(html.join('')); self.emojiContentEl.html(html.join(''));
self.scroller.reinit(); self.emojiScroller.reinit();
}
if (this.tab == 6) { // Stickers
var renderStickers = function (stickersets) {
if (self.tab != 6) {
return;
}
var set, docID, i, j, len1, len2;
for (i = 0, len1 = stickersets.length; i < len1; i++) {
set = stickersets[i];
if (!set.docIDs.length) {
continue;
}
html.push('<div class="composer_stickerset_wrap clearfix">');
if (set.id && set.title) {
html.push(
'<a class="composer_stickerset_title" data-stickerset="',
encodeEntities(set.short_name),
'">',
encodeEntities(set.title),
'</a>'
);
}
for (j = 0, len2 = set.docIDs.length; j < len2; j++) {
docID = set.docIDs[j];
html.push('<a class="composer_sticker_btn" data-sticker="' + docID + '"></a>');
} }
html.push('</div>');
}
renderContent();
self.contentEl.find('.composer_sticker_btn').each(function (k, element) { if (this.cat > 0) {
self.getStickerImage($(element), element.getAttribute('data-sticker')); var categoryIndex = this.cat - 1;
});
};
this.getStickers(renderStickers);
}
else if (this.tab > 0) {
var categoryIndex = this.tab - 1;
var emoticonCodes = Config.EmojiCategories[categoryIndex]; var emoticonCodes = Config.EmojiCategories[categoryIndex];
var totalColumns = Config.EmojiCategorySpritesheetDimens[categoryIndex][1]; var totalColumns = Config.EmojiCategorySpritesheetDimens[categoryIndex][1];
var count = emoticonCodes.length; var count = emoticonCodes.length;
@ -373,6 +441,148 @@ EmojiTooltip.prototype.updateTabContents = function () {
} }
}; };
EmojiTooltip.prototype.updateStickersContents = function (force) {
var html = [];
var categoriesHtml = [];
var self = this;
var iconSize = 26;
var scrollStickers = function () {
var scrollTop = self.cat ? self.stickersetPositions[self.cat][0] : 0;
self.stickersScroller.scrollTo(scrollTop, force ? 0 : 100);
}
if (!force && self.stickersetPositions.length) {
scrollStickers();
return;
}
var renderStickers = function (stickersets) {
var set, docID, i, j, len1, len2;
for (i = 0, len1 = stickersets.length; i < len1; i++) {
set = stickersets[i];
if (!set.docIDs.length) {
continue;
}
html.push('<div class="composer_stickerset_wrap clearfix">');
if (set.title) {
html.push(
'<a class="composer_stickerset_title',
set.id ? '' : ' disabled',
'" data-stickerset="',
encodeEntities(set.short_name),
'">',
encodeEntities(set.title),
'</a>'
);
}
if (!set.id) {
categoriesHtml.push('<a class="composer_emoji_tooltip_category composer_emoji_tooltip_category_recent" data-category="0"></a>');
} else {
categoriesHtml.push('<a class="composer_sticker_btn" data-sticker="' + set.docIDs[0] + '" data-category="' + i + '"></a>');
}
for (j = 0, len2 = set.docIDs.length; j < len2; j++) {
docID = set.docIDs[j];
html.push('<a class="composer_sticker_btn" data-sticker="' + docID + '"></a>');
}
html.push('</div>');
}
self.stickersContentEl.html(html.join(''));
self.stickersCategoriesEl.html(categoriesHtml.join(''));
self.stickersScroller.reinit();
var scrollPositions = [];
$('.composer_stickerset_wrap', self.stickersContentEl).each(function (k, stickerSetEl) {
var height = stickerSetEl.offsetHeight;
var top = stickerSetEl.offsetTop;
scrollPositions.push([top, height]);
});
self.stickersetPositions = scrollPositions;
scrollStickers();
var preload = [];
self.contentEl.find('.composer_sticker_btn').each(function (k, element) {
if (k < 12) {
self.replaceStickerImage(element);
} else {
preload.push([element.offsetTop, element]);
}
});
self.stickersPreload = preload;
self.stickersCategoriesEl.find('.composer_sticker_btn').each(function (k, element) {
self.replaceStickerImage(element);
});
};
this.getStickers(renderStickers);
};
EmojiTooltip.prototype.replaceStickerImage = function (element) {
element = $(element);
this.getStickerImage(element, element.attr('data-sticker'));
}
EmojiTooltip.prototype.onStickersScroll = function (scrollable, scrollTop) {
var ch = scrollable.clientHeight;
var sh = scrollable.scrollHeight;
var len = this.stickersetPositions.length;
var currentCat = false;
var currentPos, i;
if (scrollTop < 20) {
currentCat = 0;
} else if (scrollTop > sh - ch - 20) {
currentCat = len - 1;
} else {
for (i = 0; i < len; i++) {
currentPos = this.stickersetPositions[i];
if (scrollTop >= currentPos[0] &&
scrollTop < (currentPos[0] + currentPos[1])) {
currentCat = i;
break;
}
}
}
var len = this.stickersPreload.length;
if (len) {
for (i = 0; i < len; i++) {
currentPos = this.stickersPreload[i];
if (currentPos[0] >= scrollTop && currentPos[0] <= scrollTop + ch) {
// console.log('replace', currentPos[1], i);
this.replaceStickerImage(currentPos[1]);
this.stickersPreload.splice(i, 1);
i--;
len--;
}
}
}
// console.log('on sticker scroll', scrollTop, ch, sh, currentCat, this.stickersetPositions);
if (this.cat === currentCat || currentCat === false) {
return;
}
$('.active', this.categoriesEl).removeClass('active');
this.cat = currentCat;
this.activateStickerCategory();
};
EmojiTooltip.prototype.activateStickerCategory = function () {
var categoriesEl = this.categoriesEl[1];
var categoryEl = categoriesEl.childNodes[this.cat];
if (!categoryEl) {
return;
}
$(categoryEl).addClass('active');
var left = categoryEl.offsetLeft;
var width = categoryEl.offsetWidth;
var viewportWidth = categoriesEl.clientWidth;
// console.log('current cat el', categoryEl, left, width, viewportWidth);
$(categoriesEl).animate({scrollLeft: left - (viewportWidth - width) / 2}, 200);
}
EmojiTooltip.prototype.updatePosition = function () { EmojiTooltip.prototype.updatePosition = function () {
var offset = this.btnEl.offset(); var offset = this.btnEl.offset();
this.tooltipEl.css({top: offset.top, left: offset.left}); this.tooltipEl.css({top: offset.top, left: offset.left});
@ -380,7 +590,11 @@ EmojiTooltip.prototype.updatePosition = function () {
EmojiTooltip.prototype.show = function () { EmojiTooltip.prototype.show = function () {
this.updatePosition(); this.updatePosition();
this.updateTabContents(); if (this.tab) {
this.updateStickersContents(true);
} else {
this.updateEmojiContents();
}
this.tooltipEl.addClass('composer_emoji_tooltip_shown'); this.tooltipEl.addClass('composer_emoji_tooltip_shown');
this.btnEl.addClass('composer_emoji_insert_btn_on'); this.btnEl.addClass('composer_emoji_insert_btn_on');
delete this.showTimeout; delete this.showTimeout;
@ -1255,6 +1469,18 @@ Scroller.prototype.setUpNative = function () {
} }
} }
Scroller.prototype.onScroll = function (cb) {
var self = this;
var scrollable = this.scrollable[0];
this.scrollable.on('scroll', function (e) {
if (self.isAnimatedScroll) {
return;
}
cb(scrollable, scrollable.scrollTop);
})
}
Scroller.prototype.update = function () { Scroller.prototype.update = function () {
if (this.useNano) { if (this.useNano) {
$(this.scroller).nanoScroller(); $(this.scroller).nanoScroller();
@ -1293,11 +1519,29 @@ Scroller.prototype.updateHeight = function () {
} }
Scroller.prototype.scrollTo = function (scrollTop) { Scroller.prototype.scrollTo = function (scrollTop, animation, cb) {
if (animation > 0) {
var self = this;
this.isAnimatedScroll = true;
this.scrollable.animate({scrollTop: scrollTop}, function () {
delete self.isAnimatedScroll;
if (self.useNano) {
$(self.scroller).nanoScroller({flash: true});
}
self.scrollable.trigger('scroll');
if (cb) {
cb();
}
});
} else {
this.scrollable[0].scrollTop = scrollTop; this.scrollable[0].scrollTop = scrollTop;
if (this.useNano) { if (this.useNano) {
$(this.scroller).nanoScroller({flash: true}); $(this.scroller).nanoScroller({flash: true});
} }
if (cb) {
cb();
}
}
} }
Scroller.prototype.scrollToNode = function (node) { Scroller.prototype.scrollToNode = function (node) {

8
app/js/messages_manager.js

@ -9,7 +9,7 @@
angular.module('myApp.services') angular.module('myApp.services')
.service('AppMessagesManager', function ($q, $rootScope, $location, $filter, $timeout, $sce, ApiUpdatesManager, AppUsersManager, AppChatsManager, AppPeersManager, AppPhotosManager, AppVideoManager, AppDocsManager, AppAudioManager, AppWebPagesManager, MtpApiManager, MtpApiFileManager, RichTextProcessor, NotificationsManager, PeersSelectService, Storage, AppProfileManager, FileManager, TelegramMeWebService, ErrorService, StatusManager, _) { .service('AppMessagesManager', function ($q, $rootScope, $location, $filter, $timeout, $sce, ApiUpdatesManager, AppUsersManager, AppChatsManager, AppPeersManager, AppPhotosManager, AppVideoManager, AppDocsManager, AppStickersManager, AppAudioManager, AppWebPagesManager, MtpApiManager, MtpApiFileManager, RichTextProcessor, NotificationsManager, PeersSelectService, Storage, AppProfileManager, FileManager, TelegramMeWebService, ErrorService, StatusManager, _) {
var messagesStorage = {}; var messagesStorage = {};
var messagesForHistory = {}; var messagesForHistory = {};
@ -1397,9 +1397,13 @@ angular.module('myApp.services')
break; break;
case 'inputMediaDocument': case 'inputMediaDocument':
var doc = AppDocsManager.getDoc(inputMedia.id.id);
if (doc.sticker && doc.stickerSetInput) {
AppStickersManager.pushPopularSticker(doc.id);
};
media = { media = {
_: 'messageMediaDocument', _: 'messageMediaDocument',
'document': AppDocsManager.getDoc(inputMedia.id.id) 'document': doc
}; };
break; break;
} }

62
app/js/services.js

@ -2118,6 +2118,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
openStickersetLink: openStickersetLink, openStickersetLink: openStickersetLink,
openStickerset: openStickerset, openStickerset: openStickerset,
installStickerset: installStickerset, installStickerset: installStickerset,
pushPopularSticker: pushPopularSticker,
getStickers: getStickers, getStickers: getStickers,
getStickerset: getStickerset, getStickerset: getStickerset,
getStickersImages: getStickersImages getStickersImages: getStickersImages
@ -2130,6 +2131,44 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
} }
} }
function getPopularStickers () {
return Storage.get('stickers_popular').then(function (popStickers) {
var result = [];
if (popStickers && popStickers.length) {
for (var i = 0, len = popStickers.length; i < len; i++) {
result.push({id: popStickers[i][0], rate: popStickers[i][1]});
}
};
return result;
});
}
function pushPopularSticker (id) {
getPopularStickers().then(function (popularStickers) {
var exists = false;
var count = popularStickers.length;
var result = [];
for (var i = 0; i < count; i++) {
if (popularStickers[i].id == id) {
exists = true;
popularStickers[i].rate++;
}
result.push([popularStickers[i].id, popularStickers[i].rate]);
}
if (exists) {
result.sort(function (a, b) {
return b[1] - a[1];
});
} else {
if (result.length > 15) {
result = result.slice(0, 15);
}
result.push([id, 1]);
}
ConfigStorage.set({stickers_popular: result});
});
}
function processRawStickers(stickers) { function processRawStickers(stickers) {
if (applied !== stickers.hash) { if (applied !== stickers.hash) {
applied = stickers.hash; applied = stickers.hash;
@ -2162,7 +2201,28 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
} }
} }
return currentStickersets; return getPopularStickers().then(function (popularStickers) {
var resultStickersets = currentStickersets;
if (popularStickers.length) {
resultStickersets = currentStickersets.slice();
var setItems = [];
var i, len;
for (i = 0, len = popularStickers.length; i < len; i++) {
setItems.push(popularStickers[i].id);
}
resultStickersets.unshift({
id: 0,
title: _('im_stickers_tab_recent'),
short_name: '',
installed: true,
disabled: false,
official: false,
docIDs: setItems
})
}
return resultStickersets;
});
} }
function getStickers (force) { function getStickers (force) {

118
app/less/app.less

@ -2370,9 +2370,9 @@ img.img_fullsize {
display: none; display: none;
position: absolute; position: absolute;
z-index: 999; z-index: 999;
width: 284px; width: 286px;
margin-left: -116px; margin-left: -133px;
margin-top: -245px; margin-top: -330px;
border: 1px #dfdfdf solid; border: 1px #dfdfdf solid;
@ -2380,7 +2380,7 @@ img.img_fullsize {
.box-shadow(0px 1px 1px rgba(0, 0, 0, 0.1)); .box-shadow(0px 1px 1px rgba(0, 0, 0, 0.1));
background: #fff; background: #fff;
padding: 5px 2px 5px 8px; padding: 0;
&_shown { &_shown {
display: block; display: block;
@ -2416,20 +2416,26 @@ img.img_fullsize {
} }
.composer_emoji_tooltip_tabs { .composer_emoji_tooltip_tabs {
border-bottom: 1px solid #e5e5e5; -webkit-box-shadow: 0px 1px 0px 0px rgba(0,0,0,0.1);
-moz-box-shadow: 0px 1px 0px 0px rgba(0,0,0,0.1);
box-shadow: 0px 1px 0px 0px rgba(0,0,0,0.1);
// border-bottom: 1px solid #e5e5e5;
// border-color: rgba(0,0,0,0.1);
} }
.composer_emoji_tooltip_tab { .composer_emoji_tooltip_tab {
cursor: pointer;
display: inline-block; display: inline-block;
line-height: 36px; line-height: 35px;
text-align: center; text-align: center;
width: 50%; width: 50%;
text-transform: uppercase; text-transform: uppercase;
font-weight: bold; font-weight: bold;
transition: color ease-in-out 0.2s;
&:hover, &:hover,
&:active, &:active,
&:focus { &:focus {
color: inherit;
text-decoration: none; text-decoration: none;
} }
} }
@ -2443,17 +2449,60 @@ img.img_fullsize {
} }
.composer_emoji_tooltip_tab_shadow { .composer_emoji_tooltip_tab_shadow {
width: 50%; width: 50%;
height: 2px; height: 1px;
background: #53a9ea; background: #53a9ea;
-webkit-box-shadow: 0px 1px 0px 0px rgba(83,169,234,1);
-moz-box-shadow: 0px 1px 0px 0px rgba(83,169,234,1);
box-shadow: 0px 1px 0px 0px rgba(83,169,234,1);
transform: translateX(0);
transition: transform ease-in-out 0.2s;
.composer_emoji_tooltip_tabs_stickers_active & { .composer_emoji_tooltip_tabs_stickers_active & {
left: 50%; transform: translateX(100%);
} }
} }
.composer_emoji_tooltip_categories { .composer_emoji_tooltip_categories {
width: 100%; width: 100%;
margin: 9px 0 4px; line-height: 0;
.composer_emoji_tooltip_tab_emoji_content & {
width: 100%;
margin: 9px 0 12px;
padding: 0 5px;
line-height: 0;
}
.composer_emoji_tooltip_tab_stickers_content & {
vertical-align: top;
padding: 2px 10px 2px;
overflow-x: scroll;
white-space: nowrap;
position: relative;
&::-webkit-scrollbar {
display: none;
}
.composer_emoji_tooltip_category_recent {
margin: 7px 10px 7px 7px;
}
.composer_sticker_btn {
width: 42px;
height: 38px;
padding: 3px 5px;
vertical-align: top;
margin-right: 2px;
&.active {
background: #f2f6fa;
}
}
.composer_sticker_image {
max-width: 32px;
max-height: 32px;
}
}
} }
.composer_emoji_tooltip_category { .composer_emoji_tooltip_category {
@ -2490,8 +2539,8 @@ img.img_fullsize {
.composer_emoji_tooltip_category_flower.active {background-position: -3px -155px; } .composer_emoji_tooltip_category_flower.active {background-position: -3px -155px; }
/* Bell */ /* Bell */
.composer_emoji_tooltip_category_bell {background-position: -3px -186px; } .composer_emoji_tooltip_category_bell {background-position: -3px -184px; }
.composer_emoji_tooltip_category_bell.active {background-position: -3px -217px; } .composer_emoji_tooltip_category_bell.active {background-position: -3px -215px; }
/* Car */ /* Car */
.composer_emoji_tooltip_category_car {background-position: -3px -245px; } .composer_emoji_tooltip_category_car {background-position: -3px -245px; }
@ -2502,11 +2551,37 @@ img.img_fullsize {
.composer_emoji_tooltip_category_grid.active {background-position: -3px -335px; } .composer_emoji_tooltip_category_grid.active {background-position: -3px -335px; }
.composer_emoji_tooltip_tabs_wrap {
height: 275px;
position: relative;
overflow: hidden;
}
.composer_emoji_tooltip_tabs_contents {
position: absolute;
width: 200%;
transform: translateX(0);
transition: transform ease-in-out 0.2s;
.composer_emoji_tooltip_tabs_stickers_active & {
transform: translateX(-284px);
}
}
.composer_emoji_tooltip_tab_emoji_content,
.composer_emoji_tooltip_tab_stickers_content {
width: 284px;
height: 275px;
float: left;
}
.composer_emoji_tooltip_content_stickers {
position: relative;
}
.composer_emoji_tooltip_content_wrap {
padding: 0 2px 0 8px;
}
.composer_emoji_tooltip .scroller_scrollable_container { .composer_emoji_tooltip .scroller_scrollable_container {
height: 233px; height: 233px;
position: relative; position: relative;
} }
.composer_emoji_tooltip_content { .composer_emoji_tooltip_content {
padding-top: 10px; padding-top: 10px;
padding-right: 8px; padding-right: 8px;
@ -2514,7 +2589,7 @@ img.img_fullsize {
} }
a.composer_emoji_btn { a.composer_emoji_btn {
margin: 0 1px 0 0; margin: 0 2px 0 0;
padding: 5px; padding: 5px;
display: block; display: block;
float: left; float: left;
@ -2722,8 +2797,9 @@ a.composer_command_option.composer_autocomplete_option_active .composer_command_
font-size: 13px; font-size: 13px;
color: #444; color: #444;
margin: 10px 0 3px; margin: 10px 0 3px;
padding: 0 6px;
&:first-child { .composer_stickerset_wrap:first-child & {
margin-top: 0; margin-top: 0;
} }
&:hover { &:hover {
@ -2731,12 +2807,12 @@ a.composer_command_option.composer_autocomplete_option_active .composer_command_
} }
} }
.composer_sticker_btn { .composer_sticker_btn {
width: 78px; width: 66px;
height: 78px; height: 66px;
display: block;
display: inline-block; display: inline-block;
text-align: center; text-align: center;
padding: 3px; padding: 3px;
vertical-align: top;
&:hover { &:hover {
background: #f2f6fa; background: #f2f6fa;
@ -2744,9 +2820,9 @@ a.composer_command_option.composer_autocomplete_option_active .composer_command_
} }
.composer_sticker_image { .composer_sticker_image {
max-width: 72px; max-width: 60px;
max-height: 72px; max-height: 60px;
vertical-align: top; vertical-align: middle;
} }
.composer_rich_textarea { .composer_rich_textarea {

2
app/less/desktop.less

@ -489,6 +489,8 @@
.nano > .nano-pane { .nano > .nano-pane {
background : rgba(255,255,255,0.0); background : rgba(255,255,255,0.0);
right: -2px; right: -2px;
top: 5px;
bottom: 5px;
& > .nano-slider { & > .nano-slider {
background: #d1d1d1; background: #d1d1d1;

Loading…
Cancel
Save