Browse Source

Supported sticker suggestions by emoji

Also fixed blinking suggestions list
Closes #1409
Closes #1332
Closes #814
master
Igor Zhukov 8 years ago
parent
commit
092685db5a
  1. 57
      app/js/controllers.js
  2. 11
      app/js/lib/ng_utils.js
  3. 37
      app/js/message_composer.js
  4. 76
      app/js/services.js

57
app/js/controllers.js

@ -2288,7 +2288,7 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -2288,7 +2288,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.$on('user_update', angular.noop)
})
.controller('AppImSendController', function ($rootScope, $q, $scope, $timeout, MtpApiManager, Storage, AppProfileManager, AppChatsManager, AppUsersManager, AppPeersManager, AppDocsManager, AppMessagesManager, AppInlineBotsManager, MtpApiFileManager, DraftsManager, RichTextProcessor) {
.controller('AppImSendController', function ($rootScope, $q, $scope, $timeout, MtpApiManager, Storage, AppProfileManager, AppChatsManager, AppUsersManager, AppPeersManager, AppDocsManager, AppStickersManager, AppMessagesManager, AppInlineBotsManager, MtpApiFileManager, DraftsManager, RichTextProcessor) {
$scope.$watch('curDialog.peer', resetDraft)
$scope.$on('user_update', angular.noop)
$scope.$on('peer_draft_attachment', applyDraftAttachment)
@ -2793,6 +2793,7 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -2793,6 +2793,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
}
var inlineUsernameRegex = /^@([a-zA-Z\d_]{1,32})( | )([\s\S]*)$/
var inlineStickersEmojiRegex = /^\s*:(\S+):\s*$/
var getInlineResultsTO = false
var lastInlineBot = false
var jump = 0
@ -2809,6 +2810,39 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -2809,6 +2810,39 @@ angular.module('myApp.controllers', ['myApp.i18n'])
}
var matches = message.match(inlineUsernameRegex)
if (!matches) {
matches = message.match(inlineStickersEmojiRegex)
if (matches) {
var emojiCode = EmojiHelper.shortcuts[matches[1]]
if (emojiCode) {
$scope.draftMessage.inlineProgress = true
AppStickersManager.searchStickers(emojiCode).then(function (docs) {
var inlineResults = []
angular.forEach(docs, function (doc) {
inlineResults.push({
_: 'botInlineMediaResult',
qID: '_sticker_' + doc.id,
pFlags: {sticker: true},
id: doc.id,
type: 'sticker',
document: doc,
send_message: {_: 'botInlineMessageMediaAuto'}
})
})
var botResults = {
pFlags: {gallery: true},
query_id: 0,
results: inlineResults
}
botResults.text = message
$scope.$broadcast('inline_results', botResults)
delete $scope.draftMessage.inlineProgress
})
} else {
delete $scope.draftMessage.inlineProgress
$scope.$broadcast('inline_results', false)
return
}
}
delete $scope.draftMessage.inlineProgress
$scope.$broadcast('inline_results', false)
return
@ -2954,7 +2988,26 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -2954,7 +2988,26 @@ angular.module('myApp.controllers', ['myApp.i18n'])
replyToMsgID: $scope.draftMessage.replyToMsgID,
clearDraft: true
}
AppInlineBotsManager.sendInlineResult($scope.curDialog.peerID, qID, options)
if (qID.substr(0, 9) == '_sticker_') {
var docID = qID.substr(9)
var doc = AppDocsManager.getDoc(docID)
if (doc.id && doc.access_hash) {
var inputMedia = {
_: 'inputMediaDocument',
id: {
_: 'inputDocument',
id: doc.id,
access_hash: doc.access_hash
}
}
AppMessagesManager.sendOther($scope.curDialog.peerID, inputMedia, options)
}
}
else {
AppInlineBotsManager.sendInlineResult($scope.curDialog.peerID, qID, options)
}
if (forceDraft == $scope.curDialog.peer) {
forceDraft = false

11
app/js/lib/ng_utils.js

@ -1160,7 +1160,6 @@ angular.module('izhukov.utils', []) @@ -1160,7 +1160,6 @@ angular.module('izhukov.utils', [])
})
.service('RichTextProcessor', function ($sce, $sanitize) {
var emojiMap = {}
var emojiData = Config.Emoji
var emojiIconSize = 18
var emojiSupported = navigator.userAgent.search(/OS X|iPhone|iPad|iOS|Android/i) != -1,
@ -1168,10 +1167,6 @@ angular.module('izhukov.utils', []) @@ -1168,10 +1167,6 @@ angular.module('izhukov.utils', [])
var emojiRegExp = '\\u0023\\u20E3|\\u00a9|\\u00ae|\\u203c|\\u2049|\\u2139|[\\u2194-\\u2199]|\\u21a9|\\u21aa|\\u231a|\\u231b|\\u23e9|[\\u23ea-\\u23ec]|\\u23f0|\\u24c2|\\u25aa|\\u25ab|\\u25b6|\\u2611|\\u2614|\\u26fd|\\u2705|\\u2709|[\\u2795-\\u2797]|\\u27a1|\\u27b0|\\u27bf|\\u2934|\\u2935|[\\u2b05-\\u2b07]|\\u2b1b|\\u2b1c|\\u2b50|\\u2b55|\\u3030|\\u303d|\\u3297|\\u3299|[\\uE000-\\uF8FF\\u270A-\\u2764\\u2122\\u25C0\\u25FB-\\u25FE\\u2615\\u263a\\u2648-\\u2653\\u2660-\\u2668\\u267B\\u267F\\u2693\\u261d\\u26A0-\\u26FA\\u2708\\u2702\\u2601\\u260E]|[\\u2600\\u26C4\\u26BE\\u23F3\\u2764]|\\uD83D[\\uDC00-\\uDFFF]|\\uD83C[\\uDDE8-\\uDDFA\uDDEC]\\uD83C[\\uDDEA-\\uDDFA\uDDE7]|[0-9]\\u20e3|\\uD83C[\\uDC00-\\uDFFF]'
for (emojiCode in emojiData) {
emojiMap[emojiData[emojiCode][0]] = emojiCode
}
var alphaCharsRegExp = 'a-z' +
'\\u00c0-\\u00d6\\u00d8-\\u00f6\\u00f8-\\u00ff' + // Latin-1
'\\u0100-\\u024f' + // Latin Extended A and B
@ -1363,8 +1358,8 @@ angular.module('izhukov.utils', []) @@ -1363,8 +1358,8 @@ angular.module('izhukov.utils', [])
})
}
else if (match[8]) { // Emoji
if ((emojiCode = emojiMap[match[8]]) &&
(emojiCoords = getEmojiSpritesheetCoords(emojiCode))) {
if ((emojiCode = EmojiHelper.emojiMap[match[8]]) &&
(emojiCoords = getEmojiSpritesheetCoords(emojiCode))) {
entities.push({
_: 'messageEntityEmoji',
offset: matchIndex,
@ -1906,7 +1901,7 @@ angular.module('izhukov.utils', []) @@ -1906,7 +1901,7 @@ angular.module('izhukov.utils', [])
text.push(raw.substr(0, match.index))
if (match[8]) {
if ((emojiCode = emojiMap[match[8]]) &&
if ((emojiCode = EmojiHelper.emojiMap[match[8]]) &&
(emojiTitle = emojiData[emojiCode][1][0])) {
text.push(':' + emojiTitle + ':')
} else {

37
app/js/message_composer.js

@ -9,9 +9,10 @@ @@ -9,9 +9,10 @@
/* EmojiHelper */
;(function (global, emojis, categories, spritesheets) {
;(function (global, emojiData, categories, spritesheets) {
var emojis = {}
var shortcuts = {}
var emojiMap = {}
var spritesheetPositions = {}
var index = false
@ -32,7 +33,7 @@ @@ -32,7 +33,7 @@
totalColumns = spritesheets[i][1]
for (j = 0, len2 = categories[i].length; j < len2; j++) {
code = categories[i][j]
emoji = Config.Emoji[code]
emoji = emojiData[code]
shortcut = emoji[1][0]
emojis[code] = [emoji[0], shortcut]
shortcuts[shortcut] = code
@ -40,6 +41,10 @@ @@ -40,6 +41,10 @@
}
}
angular.forEach(emojiData, function (emoji, emojiCode) {
emojiMap[emoji[0]] = emojiCode
})
function getPopularEmoji (callback) {
ConfigStorage.get('emojis_popular', function (popEmojis) {
var result = []
@ -126,6 +131,7 @@ @@ -126,6 +131,7 @@
global.EmojiHelper = {
emojis: emojis,
emojiMap: emojiMap,
shortcuts: shortcuts,
spritesheetPositions: spritesheetPositions,
getPopularEmoji: getPopularEmoji,
@ -715,6 +721,7 @@ function MessageComposer (textarea, options) { @@ -715,6 +721,7 @@ function MessageComposer (textarea, options) {
this.onInlineResultSend = options.onInlineResultSend
this.mentions = options.mentions
this.commands = options.commands
this.renderToggleCnt = 0
}
MessageComposer.autoCompleteRegEx = /(\s|^)(:|@|\/)([\S]*)$/
@ -1096,6 +1103,9 @@ MessageComposer.prototype.checkAutocomplete = function (forceFull) { @@ -1096,6 +1103,9 @@ MessageComposer.prototype.checkAutocomplete = function (forceFull) {
}
}
else if (matches[2] == ':') { // emoji
if (value.match(/^\s*:(.+):\s*$/)) {
return
}
EmojiHelper.getPopularEmoji((function (popular) {
if (query.length) {
var found = EmojiHelper.searchEmojis(query)
@ -1497,6 +1507,7 @@ MessageComposer.prototype.renderSuggestions = function () { @@ -1497,6 +1507,7 @@ MessageComposer.prototype.renderSuggestions = function () {
}
MessageComposer.prototype.showEmojiSuggestions = function (codes) {
var renderCnt = ++this.renderToggleCnt
var self = this
setZeroTimeout(function () {
self.autoCompleteScope.$apply(function () {
@ -1504,12 +1515,15 @@ MessageComposer.prototype.showEmojiSuggestions = function (codes) { @@ -1504,12 +1515,15 @@ MessageComposer.prototype.showEmojiSuggestions = function (codes) {
self.autoCompleteScope.emojiCodes = codes
})
onContentLoaded(function () {
self.renderSuggestions()
if (renderCnt == self.renderToggleCnt) {
self.renderSuggestions()
}
})
})
}
MessageComposer.prototype.showMentionSuggestions = function (users) {
var renderCnt = ++this.renderToggleCnt
var self = this
setZeroTimeout(function () {
self.autoCompleteScope.$apply(function () {
@ -1517,12 +1531,15 @@ MessageComposer.prototype.showMentionSuggestions = function (users) { @@ -1517,12 +1531,15 @@ MessageComposer.prototype.showMentionSuggestions = function (users) {
self.autoCompleteScope.mentionUsers = users
})
onContentLoaded(function () {
self.renderSuggestions()
if (renderCnt == self.renderToggleCnt) {
self.renderSuggestions()
}
})
})
}
MessageComposer.prototype.showCommandsSuggestions = function (commands) {
var renderCnt = ++this.renderToggleCnt
var self = this
setZeroTimeout(function () {
self.autoCompleteScope.$apply(function () {
@ -1530,7 +1547,9 @@ MessageComposer.prototype.showCommandsSuggestions = function (commands) { @@ -1530,7 +1547,9 @@ MessageComposer.prototype.showCommandsSuggestions = function (commands) {
self.autoCompleteScope.commands = commands
})
onContentLoaded(function () {
self.renderSuggestions()
if (renderCnt == self.renderToggleCnt) {
self.renderSuggestions()
}
})
})
}
@ -1540,6 +1559,7 @@ MessageComposer.prototype.showInlineSuggestions = function (botResults) { @@ -1540,6 +1559,7 @@ MessageComposer.prototype.showInlineSuggestions = function (botResults) {
this.hideSuggestions()
return
}
var renderCnt = ++this.renderToggleCnt
var self = this
if (self.autoCompleteScope.type == 'inline' &&
self.autoCompleteScope.botResults == botResults &&
@ -1552,7 +1572,9 @@ MessageComposer.prototype.showInlineSuggestions = function (botResults) { @@ -1552,7 +1572,9 @@ MessageComposer.prototype.showInlineSuggestions = function (botResults) {
self.autoCompleteScope.botResults = botResults
})
onContentLoaded(function () {
self.renderSuggestions()
if (renderCnt == self.renderToggleCnt) {
self.renderSuggestions()
}
})
})
}
@ -1575,7 +1597,8 @@ MessageComposer.prototype.updatePosition = function () { @@ -1575,7 +1597,8 @@ MessageComposer.prototype.updatePosition = function () {
}
MessageComposer.prototype.hideSuggestions = function () {
// console.trace()
var renderCnt = ++this.renderToggleCnt
// console.trace(dT())
// return
this.autoCompleteWrapEl.hide()
delete this.autocompleteShown

76
app/js/services.js

@ -2209,6 +2209,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2209,6 +2209,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
var started = false
var applied = false
var currentStickerSets = []
var emojiIndex = {}
$rootScope.$on('apiUpdate', function (e, update) {
if (update._ != 'updateStickerSets' &&
@ -2220,7 +2221,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2220,7 +2221,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
return Storage.get('all_stickers').then(function (stickers) {
if (!stickers ||
stickers.layer != Config.Schema.API.layer) {
stickers.layer != Config.Schema.API.layer) {
$rootScope.$broadcast('stickers_changed')
}
switch (update._) {
@ -2243,6 +2244,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2243,6 +2244,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
set.pFlags.installed = true
stickers.sets.unshift(set)
stickers.fullSets[set.id] = fullSet
indexStickerSetEmoticons(fullSet)
break
case 'updateDelStickerSet':
@ -2283,6 +2285,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2283,6 +2285,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
openStickerset: openStickerset,
installStickerset: installStickerset,
pushPopularSticker: pushPopularSticker,
searchStickers: searchStickers,
getStickerset: getStickerset
}
@ -2296,10 +2299,12 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2296,10 +2299,12 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
function getStickers (force) {
return Storage.get('all_stickers').then(function (stickers) {
var layer = Config.Schema.API.layer
if (stickers.layer != layer) {
if (stickers.layer != layer ||
stickers.emojiIndex === undefined) {
stickers = false
}
if (stickers && stickers.date > tsNow(true) && !force) {
emojiIndex = stickers.emojiIndex
return processRawStickers(stickers)
}
return MtpApiManager.invokeApi('messages.getAllStickers', {
@ -2315,6 +2320,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2315,6 +2320,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
if (notModified) {
Storage.set({all_stickers: newStickers})
emojiIndex = newStickers.emojiIndex
return processRawStickers(newStickers)
}
@ -2376,14 +2382,74 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2376,14 +2382,74 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
})
}
function indexStickerSetEmoticons(fullSet) {
angular.forEach(fullSet.packs, function (pack) {
var emoji = pack.emoticon
var emojiCode = false
while (emoji.length) {
emojiCode = EmojiHelper.emojiMap[emoji]
if (emojiCode !== undefined) {
break
}
emoji = emoji.substr(0, -1)
}
// console.warn('index', fullSet, pack, emojiCode)
if (emojiCode === undefined) {
return
}
var stickersList = emojiIndex[emojiCode]
if (stickersList === undefined) {
emojiIndex[emojiCode] = stickersList = []
}
angular.forEach(pack.documents, function (docID) {
if (stickersList.indexOf(docID) === -1) {
stickersList.push(docID)
}
})
})
}
function searchStickers(emojiCode) {
return getPopularStickers().then(function () {
// console.warn('search', emojiCode, emojiIndex, emojiIndex[emojiCode])
var stickersList = emojiIndex[emojiCode]
var result = []
if (stickersList === undefined) {
return result
}
var setIDs = []
angular.forEach(currentStickerSets, function (set) {
setIDs.push(set.id)
})
angular.forEach(stickersList, function (docID) {
var doc = AppDocsManager.getDoc(docID)
if (!doc || !doc.stickerSetInput) {
return
}
var setID = doc.stickerSetInput.id
if (setIDs.indexOf(setID) == -1) {
return
}
result.push(doc)
})
result.sort(function (doc1, doc2) {
return setIDs.indexOf(doc1.stickerSetInput.id) - setIDs.indexOf(doc2.stickerSetInput.id)
})
return result
})
}
function getStickerSets (allStickers, prevCachedSets) {
var promises = []
var cachedSets = prevCachedSets || allStickers.fullSets || {}
allStickers.fullSets = {}
emojiIndex = allStickers.emojiIndex = {}
angular.forEach(allStickers.sets, function (shortSet) {
var fullSet = cachedSets[shortSet.id]
if (fullSet && fullSet.set.hash == shortSet.hash) {
allStickers.fullSets[shortSet.id] = fullSet
indexStickerSetEmoticons(fullSet)
} else {
var promise = MtpApiManager.invokeApi('messages.getStickerSet', {
stickerset: {
@ -2393,6 +2459,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2393,6 +2459,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
}
}).then(function (fullSet) {
allStickers.fullSets[shortSet.id] = fullSet
indexStickerSetEmoticons(fullSet)
})
promises.push(promise)
}
@ -2653,8 +2720,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2653,8 +2720,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
function regroupWrappedResults (results, rowW, rowH) {
if (!results ||
!results[0] ||
results[0].type != 'photo' && results[0].type != 'gif' && results[0].type != 'sticker') {
!results[0] ||
['photo', 'gif', 'sticker'].indexOf(results[0].type) == -1) {
return
}
var ratios = []
@ -4768,6 +4835,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -4768,6 +4835,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
// console.warn(dT(), 'server', draft)
} else {
// console.warn(dT(), 'local', draft)
console.warn(dT(), 'local', draft)
}
var replyToMsgID = draft && draft.replyToMsgID
if (replyToMsgID) {

Loading…
Cancel
Save