Browse Source

Added stickers send

master
Igor Zhukov 10 years ago
parent
commit
26557c1f35
  1. 15
      app/css/app.css
  2. 28
      app/js/controllers.js
  3. 12
      app/js/directives.js
  4. 2
      app/js/lib/config.js
  5. 16
      app/js/lib/schema.tl.txt
  6. 34
      app/js/message_composer.js
  7. 123
      app/js/services.js

15
app/css/app.css

@ -2170,6 +2170,21 @@ a.composer_emoji_btn:hover { @@ -2170,6 +2170,21 @@ a.composer_emoji_btn:hover {
margin-left: 15px;
line-height: 20px;
}
.composer_sticker_btn {
width: 70px;
height: 70px;
display: block;
display: inline-block;
text-align: center;
padding: 3px;
}
.composer_sticker_btn:hover {
background: #f2f6fa;
}
.composer_sticker_image {
max-width: 64px;
max-height: 64px;
}

28
app/js/controllers.js

@ -316,7 +316,7 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -316,7 +316,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
LayoutSwitchService.start();
})
.controller('AppIMController', function ($scope, $location, $routeParams, $modal, $rootScope, $modalStack, MtpApiManager, AppUsersManager, AppChatsManager, AppPeersManager, ContactsSelectService, ChangelogNotifyService, ErrorService, AppRuntimeManager, HttpsMigrateService, LayoutSwitchService, LocationParamsService) {
.controller('AppIMController', function ($scope, $location, $routeParams, $modal, $rootScope, $modalStack, MtpApiManager, AppUsersManager, AppChatsManager, AppPeersManager, ContactsSelectService, ChangelogNotifyService, ErrorService, AppRuntimeManager, HttpsMigrateService, LayoutSwitchService, LocationParamsService, AppStickersManager) {
$scope.$on('$routeUpdate', updateCurDialog);
@ -486,6 +486,7 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -486,6 +486,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
HttpsMigrateService.start();
LayoutSwitchService.start();
LocationParamsService.start();
AppStickersManager.start();
})
.controller('AppImDialogsController', function ($scope, $location, $q, $timeout, $routeParams, MtpApiManager, AppUsersManager, AppChatsManager, AppMessagesManager, AppPeersManager, PhonebookContactsService, ErrorService, AppRuntimeManager) {
@ -1429,7 +1430,7 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -1429,7 +1430,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.$on('user_update', angular.noop);
})
.controller('AppImSendController', function ($scope, $timeout, MtpApiManager, Storage, AppPeersManager, AppMessagesManager, ApiUpdatesManager, MtpApiFileManager) {
.controller('AppImSendController', function ($scope, $timeout, MtpApiManager, Storage, AppPeersManager, AppDocsManager, AppMessagesManager, ApiUpdatesManager, MtpApiFileManager) {
$scope.$watch('curDialog.peer', resetDraft);
$scope.$on('user_update', angular.noop);
@ -1438,6 +1439,7 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -1438,6 +1439,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.draftMessage = {text: '', send: sendMessage};
$scope.$watch('draftMessage.text', onMessageChange);
$scope.$watch('draftMessage.files', onFilesSelected);
$scope.$watch('draftMessage.sticker', onStickerSelected);
function sendMessage (e) {
$scope.$broadcast('ui_message_before_send');
@ -1530,6 +1532,28 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -1530,6 +1532,28 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.$broadcast('ui_message_send');
}
}
function onStickerSelected (newVal) {
if (!newVal) {
return;
}
var doc = AppDocsManager.getDoc(newVal);
if (doc.id && doc.access_hash) {
console.log('sticker', doc);
var inputMedia = {
_: 'inputMediaDocument',
id: {
_: 'inputDocument',
id: doc.id,
access_hash: doc.access_hash
}
}
AppMessagesManager.sendOther($scope.curDialog.peerID, inputMedia);
$scope.$broadcast('ui_message_send');
}
delete $scope.draftMessage.sticker;
}
})
.controller('AppLangSelectController', function ($scope, _, Storage, ErrorService, AppRuntimeManager) {

12
app/js/directives.js

@ -1061,7 +1061,7 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -1061,7 +1061,7 @@ angular.module('myApp.directives', ['myApp.filters'])
})
.directive('mySendForm', function ($timeout, $modalStack, $http, $interpolate, Storage, ErrorService) {
.directive('mySendForm', function ($timeout, $modalStack, $http, $interpolate, Storage, AppStickersManager, ErrorService) {
return {
link: link,
@ -1074,8 +1074,18 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -1074,8 +1074,18 @@ angular.module('myApp.directives', ['myApp.filters'])
var emojiButton = $('.composer_emoji_insert_btn', element)[0];
new EmojiTooltip(emojiButton, {
getStickers: function (callback) {
AppStickersManager.getStickers().then(function () {
AppStickersManager.getStickersImages().then(function (stickersData) {
callback(stickersData);
});
});
},
onEmojiSelected: function (code) {
composer.onEmojiSelected(code);
},
onStickerSelected: function (docID) {
$scope.draftMessage.sticker = docID;
}
});

2
app/js/lib/config.js

File diff suppressed because one or more lines are too long

16
app/js/lib/schema.tl.txt

@ -156,8 +156,6 @@ peerNotifyEventsAll#6d1ded88 = PeerNotifyEvents; @@ -156,8 +156,6 @@ peerNotifyEventsAll#6d1ded88 = PeerNotifyEvents;
peerNotifySettingsEmpty#70a68512 = PeerNotifySettings;
peerNotifySettings#8d5e11ee mute_until:int sound:string show_previews:Bool events_mask:int = PeerNotifySettings;
globalPrivacySettings#40f5c53a no_suggestions:Bool hide_contacts:Bool hide_located:Bool hide_last_visit:Bool = GlobalPrivacySettings;
wallPaper#ccb03657 id:int title:string sizes:Vector<PhotoSize> color:int = WallPaper;
userFull#771095da user:User link:contacts.Link profile_photo:Photo notify_settings:PeerNotifySettings blocked:Bool real_first_name:string real_last_name:string = UserFull;
@ -209,8 +207,6 @@ messages.statedMessage#d07ae726 message:Message chats:Vector<Chat> users:Vector< @@ -209,8 +207,6 @@ messages.statedMessage#d07ae726 message:Message chats:Vector<Chat> users:Vector<
messages.sentMessage#d1f4d35c id:int date:int pts:int seq:int = messages.SentMessage;
messages.chat#40e9002a chat:Chat users:Vector<User> = messages.Chat;
messages.chats#8150cbd8 chats:Vector<Chat> users:Vector<User> = messages.Chats;
messages.chatFull#e5d7d19c full_chat:ChatFull chats:Vector<Chat> users:Vector<User> = messages.ChatFull;
@ -221,6 +217,7 @@ inputMessagesFilterEmpty#57e2f66c = MessagesFilter; @@ -221,6 +217,7 @@ inputMessagesFilterEmpty#57e2f66c = MessagesFilter;
inputMessagesFilterPhotos#9609a51c = MessagesFilter;
inputMessagesFilterVideo#9fc00e65 = MessagesFilter;
inputMessagesFilterPhotoVideo#56e9f0e4 = MessagesFilter;
inputMessagesFilterPhotoVideoDocuments#d95e73bb = MessagesFilter;
inputMessagesFilterDocument#9eddf188 = MessagesFilter;
inputMessagesFilterAudio#cfc87522 = MessagesFilter;
@ -228,7 +225,6 @@ updateNewMessage#13abdb3 message:Message pts:int = Update; @@ -228,7 +225,6 @@ updateNewMessage#13abdb3 message:Message pts:int = Update;
updateMessageID#4e90bfd6 id:int random_id:long = Update;
updateReadMessages#c6649e31 messages:Vector<int> pts:int = Update;
updateDeleteMessages#a92bfe26 messages:Vector<int> pts:int = Update;
updateRestoreMessages#d15de04d messages:Vector<int> pts:int = Update;
updateUserTyping#5c486927 user_id:int action:SendMessageAction = Update;
updateChatUserTyping#9a65ea1f chat_id:int user_id:int action:SendMessageAction = Update;
updateChatParticipants#7761198 participants:ChatParticipants = Update;
@ -237,7 +233,6 @@ updateUserName#a7332b73 user_id:int first_name:string last_name:string username: @@ -237,7 +233,6 @@ updateUserName#a7332b73 user_id:int first_name:string last_name:string username:
updateUserPhoto#95313b0c user_id:int date:int photo:UserProfilePhoto previous:Bool = Update;
updateContactRegistered#2575bbb9 user_id:int date:int = Update;
updateContactLink#51a48a9a user_id:int my_link:contacts.MyLink foreign_link:contacts.ForeignLink = Update;
updateActivation#6f690963 user_id:int = Update;
updateNewAuthorization#8f06529a auth_key_id:long date:int device:string location:string = Update;
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
@ -438,6 +433,11 @@ documentAttributeFilename#15590068 file_name:string = DocumentAttribute; @@ -438,6 +433,11 @@ documentAttributeFilename#15590068 file_name:string = DocumentAttribute;
messages.stickersNotModified#f1749a22 = messages.Stickers;
messages.stickers#8a8ecd32 hash:string stickers:Vector<Document> = messages.Stickers;
stickerPack#12b299d4 emoticon:string documents:Vector<long> = StickerPack;
messages.allStickersNotModified#e86602c3 = messages.AllStickers;
messages.allStickers#dcef3102 hash:string packs:Vector<StickerPack> documents:Vector<Document> = messages.AllStickers;
---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
@ -487,7 +487,6 @@ messages.search#7e9f2ab peer:InputPeer q:string filter:MessagesFilter min_date:i @@ -487,7 +487,6 @@ messages.search#7e9f2ab peer:InputPeer q:string filter:MessagesFilter min_date:i
messages.readHistory#eed884c6 peer:InputPeer max_id:int offset:int read_contents:Bool = messages.AffectedHistory;
messages.deleteHistory#f4f8fb61 peer:InputPeer offset:int = messages.AffectedHistory;
messages.deleteMessages#14f2dd0a id:Vector<int> = Vector<int>;
messages.restoreMessages#395f9d7e id:Vector<int> = Vector<int>;
messages.receivedMessages#28abcb68 max_id:int = Vector<int>;
messages.setTyping#a3825e50 peer:InputPeer action:SendMessageAction = Bool;
messages.sendMessage#4cde0aab peer:InputPeer message:string random_id:long = messages.SentMessage;
@ -578,4 +577,5 @@ account.setPassword#dd2a4d8f current_password_hash:bytes new_salt:bytes new_pass @@ -578,4 +577,5 @@ account.setPassword#dd2a4d8f current_password_hash:bytes new_salt:bytes new_pass
auth.checkPassword#a63011e password_hash:bytes = auth.Authorization;
messages.getStickers#ae22e045 emoticon:string hash:string = messages.Stickers;
messages.getStickers#ae22e045 emoticon:string hash:string = messages.Stickers;
messages.getAllStickers#aa3bc868 hash:string = messages.AllStickers;

34
app/js/message_composer.js

@ -134,6 +134,8 @@ function EmojiTooltip (btnEl, options) { @@ -134,6 +134,8 @@ function EmojiTooltip (btnEl, options) {
this.btnEl = $(btnEl);
this.onEmojiSelected = options.onEmojiSelected;
this.onStickerSelected = options.onStickerSelected;
this.getStickers = options.getStickers;
$(this.btnEl).on('mouseenter mouseleave', function (e) {
self.isOverBtn = e.type == 'mouseenter';
@ -191,13 +193,21 @@ EmojiTooltip.prototype.createTooltip = function () { @@ -191,13 +193,21 @@ EmojiTooltip.prototype.createTooltip = function () {
self.selectTab(tabIndex);
return cancelEvent(e);
})
.on('mouseenter mouseleave', function (e) {
clearTimeout(self.selectTabTimeout);
if (e.type == 'mouseenter') {
self.selectTabTimeout = setTimeout(function () {
self.selectTab(tabIndex);
}, 300);
}
})
.appendTo(self.tabsEl);
});
this.contentEl.on('mousedown', function (e) {
e = e.originalEvent || e;
var target = $(e.target), code;
if (target.hasClass('emoji')) {
var target = $(e.target), code, sticker;
if (target.hasClass('emoji') || target.hasClass('composer_sticker_image')) {
target = $(target[0].parentNode);
}
if (code = target.attr('data-code')) {
@ -206,11 +216,15 @@ EmojiTooltip.prototype.createTooltip = function () { @@ -206,11 +216,15 @@ EmojiTooltip.prototype.createTooltip = function () {
}
EmojiHelper.pushPopularEmoji(code);
}
if (sticker = target.attr('data-sticker')) {
if (self.onStickerSelected) {
self.onStickerSelected(sticker);
}
}
return cancelEvent(e);
});
this.tooltipEl.on('mouseenter mouseleave', function (e) {
console.log(dT(), e.type);
if (e.type == 'mouseenter') {
self.onMouseEnter();
} else {
@ -240,7 +254,19 @@ EmojiTooltip.prototype.updateTabContents = function (tab) { @@ -240,7 +254,19 @@ EmojiTooltip.prototype.updateTabContents = function (tab) {
var self = this;
var iconSize = Config.Mobile ? 26 : 20;
if (this.tab > 0) {
if (this.tab == 6) { // Stickers
var renderStickers = function (stickers) {
var sticker, i;
var count = stickers.length;
for (i = 0; i < count; i++) {
sticker = stickers[i];
html.push('<a class="composer_sticker_btn" data-sticker="' + sticker.id + '"><img class="composer_sticker_image" src="' + encodeEntities(sticker.src) + '" /></a>');
}
self.contentEl.html(html.join(''));
};
this.getStickers(renderStickers);
}
else if (this.tab > 0) {
var categoryIndex = this.tab - 1;
var emoticonCodes = Config.EmojiCategories[categoryIndex];
var totalColumns = Config.EmojiCategorySpritesheetDimens[categoryIndex][1];

123
app/js/services.js

@ -509,6 +509,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -509,6 +509,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
.service('AppChatsManager', function ($rootScope, $modal, _, MtpApiFileManager, MtpApiManager, AppUsersManager, RichTextProcessor) {
var chats = {},
chatsFull = {},
cachedPhotoLocations = {};
function saveApiChats (apiChats) {
@ -1521,7 +1522,17 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1521,7 +1522,17 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
break;
case 'inputMediaPhoto':
media = {photo: AppPhotosManager.getPhoto(inputMedia.id.id)};
media = {
_: 'messageMediaPhoto',
photo: AppPhotosManager.getPhoto(inputMedia.id.id)
};
break;
case 'inputMediaDocument':
media = {
_: 'messageMediaDocument',
'document': AppDocsManager.getDoc(inputMedia.id.id)
};
break;
}
@ -2715,6 +2726,10 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2715,6 +2726,10 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
});
};
function getDoc (docID) {
return docs[docID] || {_: 'documentEmpty'};
}
function wrapForHistory (docID) {
if (docsForHistory[docID] !== undefined) {
return docsForHistory[docID];
@ -2872,6 +2887,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2872,6 +2887,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
return {
saveDoc: saveDoc,
getDoc: getDoc,
wrapForHistory: wrapForHistory,
updateDocDownloaded: updateDocDownloaded,
downloadDoc: downloadDoc,
@ -2985,6 +3001,111 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2985,6 +3001,111 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
}
})
.service('AppStickersManager', function ($q, FileManager, MtpApiManager, MtpApiFileManager, AppDocsManager, Storage) {
var stickersToEmoji = {};
var currentStickers = [];
var applied = false;
var started = false;
return {
start: start,
getStickerEmoji: getStickerEmoji,
getStickers: getStickers,
getStickersImages: getStickersImages
};
function start () {
if (!started) {
started = true;
setTimeout(getStickers, 1000);
setInterval(preloadStickers, 900000);
}
}
function preloadStickers() {
getStickers().then(getStickersImages);
}
function getStickerEmoji(docID) {
return stickersToEmoji[docID] || false;
}
function processRawStickers(stickers) {
if (applied !== stickers.hash) {
applied = stickers.hash;
var i, j, len1, len2;
len1 = stickers.documents.length;
for (i = 0; i < len1; i++) {
AppDocsManager.saveDoc(stickers.documents[i]);
}
var pack, emoticon, docID;
var doneDocIDs = {};
stickersToEmoji = {};
currentStickers = [];
len1 = stickers.packs.length;
for (i = 0; i < len1; i++) {
pack = stickers.packs[i];
emoticon = pack.emoticon;
len2 = pack.documents.length;
for (j = 0; j < len2; j++) {
docID = pack.documents[j];
if (stickersToEmoji[docID] === undefined) {
stickersToEmoji[docID] = emoticon;
}
if (doneDocIDs[docID] === undefined) {
doneDocIDs[docID] = true;
currentStickers.push(docID);
}
}
}
}
return currentStickers;
}
function getStickers () {
return Storage.get('all_stickers').then(function (stickers) {
var layer = Config.Schema.API.layer;
if (stickers.layer != layer) {
stickers = false;
}
if (stickers && stickers.date > tsNow(true)) {
return processRawStickers(stickers);
}
return MtpApiManager.invokeApi('messages.getAllStickers', {
hash: stickers && stickers.hash || ''
}).then(function (newStickers) {
if (newStickers._ == 'messages.allStickersNotModified') {
newStickers = stickers;
}
newStickers.date = tsNow(true) + 3600;
newStickers.layer = layer;
delete newStickers._;
Storage.set({all_stickers: newStickers});
return processRawStickers(newStickers);
});
})
}
function getStickersImages () {
var promises = [];
angular.forEach(currentStickers, function (docID) {
var doc = AppDocsManager.getDoc(docID);
var promise = MtpApiFileManager.downloadSmallFile(doc.thumb.location).then(function (blob) {
return {
id: docID,
src: FileManager.getUrl(blob, 'image/webp')
};
});
promises.push(promise);
});
return $q.all(promises);
}
})
.service('ApiUpdatesManager', function ($rootScope, MtpNetworkerFactory, AppUsersManager, AppChatsManager, AppPeersManager, MtpApiManager) {
var isSynchronizing = true,

Loading…
Cancel
Save