Browse Source

Layer 25 basic support

master
Igor Zhukov 10 years ago
parent
commit
46b2e72daf
  1. 15
      app/js/controllers.js
  2. 4
      app/js/lib/config.js
  3. 80
      app/js/lib/schema.tl.txt
  4. 13
      app/js/lib/tl_utils.js
  5. 395
      app/js/services.js
  6. 4
      app/partials/desktop/message.html
  7. 2
      app/partials/mobile/message.html
  8. 2
      webogram.sublime-project

15
app/js/controllers.js

@ -2360,13 +2360,14 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -2360,13 +2360,14 @@ angular.module('myApp.controllers', ['myApp.i18n'])
}).then(function (addResult) {
ApiUpdatesManager.processUpdateMessage({
_: 'updates',
seq: addResult.seq,
users: addResult.users,
chats: addResult.chats,
seq: 0,
updates: [{
_: 'updateNewMessage',
message: addResult.message,
pts: addResult.pts
pts: addResult.pts,
pts_count: addResult.pts_count
}]
});
});
@ -2997,13 +2998,14 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -2997,13 +2998,14 @@ angular.module('myApp.controllers', ['myApp.i18n'])
}).then(function (createdResult) {
ApiUpdatesManager.processUpdateMessage({
_: 'updates',
seq: createdResult.seq,
users: createdResult.users,
chats: createdResult.chats,
seq: 0,
updates: [{
_: 'updateNewMessage',
message: createdResult.message,
pts: createdResult.pts
pts: createdResult.pts,
pts_count: createdResult.pts_count
}]
});
@ -3037,13 +3039,14 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -3037,13 +3039,14 @@ angular.module('myApp.controllers', ['myApp.i18n'])
}).then(function (editResult) {
ApiUpdatesManager.processUpdateMessage({
_: 'updates',
seq: editResult.seq,
users: editResult.users,
chats: editResult.chats,
seq: 0,
updates: [{
_: 'updateNewMessage',
message: editResult.message,
pts: editResult.pts
pts: editResult.pts,
pts_count: editResult.pts_count
}]
});

4
app/js/lib/config.js

File diff suppressed because one or more lines are too long

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

@ -70,7 +70,7 @@ fileLocationUnavailable#7c596b46 volume_id:long local_id:int secret:long = FileL @@ -70,7 +70,7 @@ fileLocationUnavailable#7c596b46 volume_id:long local_id:int secret:long = FileL
fileLocation#53d69076 dc_id:int volume_id:long local_id:int secret:long = FileLocation;
userEmpty#200250ba id:int = User;
userSelf#7007b451 id:int first_name:string last_name:string username:string phone:string photo:UserProfilePhoto status:UserStatus inactive:Bool = User;
userSelf#1c60e608 id:int first_name:string last_name:string username:string phone:string photo:UserProfilePhoto status:UserStatus = User;
userContact#cab35e18 id:int first_name:string last_name:string username:string access_hash:long phone:string photo:UserProfilePhoto status:UserStatus = User;
userRequest#d9ccc4ef id:int first_name:string last_name:string username:string access_hash:long phone:string photo:UserProfilePhoto status:UserStatus = User;
userForeign#75cf7a8 id:int first_name:string last_name:string username:string access_hash:long photo:UserProfilePhoto status:UserStatus = User;
@ -98,8 +98,7 @@ chatPhotoEmpty#37c1011c = ChatPhoto; @@ -98,8 +98,7 @@ chatPhotoEmpty#37c1011c = ChatPhoto;
chatPhoto#6153276a photo_small:FileLocation photo_big:FileLocation = ChatPhoto;
messageEmpty#83e5de54 id:int = Message;
message#567699b3 flags:int id:int from_id:int to_id:Peer date:int message:string media:MessageMedia = Message;
messageForwarded#a367e716 flags:int id:int fwd_from_id:int fwd_date:int from_id:int to_id:Peer date:int message:string media:MessageMedia = Message;
message#a7ab1991 flags:# id:int from_id:int to_id:Peer fwd_from_id:flags.2?int fwd_date:flags.2?int reply_to_msg_id:flags.3?int date:int message:string media:MessageMedia = Message;
messageService#1d86f70e flags:int id:int from_id:int to_id:Peer date:int action:MessageAction = Message;
messageMediaEmpty#3ded6320 = MessageMedia;
@ -107,7 +106,7 @@ messageMediaPhoto#c8c45a2a photo:Photo = MessageMedia; @@ -107,7 +106,7 @@ messageMediaPhoto#c8c45a2a photo:Photo = MessageMedia;
messageMediaVideo#a2d24290 video:Video = MessageMedia;
messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia;
messageMediaContact#5e7d2f39 phone_number:string first_name:string last_name:string user_id:int = MessageMedia;
messageMediaUnsupported#29632a36 bytes:bytes = MessageMedia;
messageMediaUnsupported#9f84f49e = MessageMedia;
messageActionEmpty#b6aef7b0 = MessageAction;
messageActionChatCreate#a6638b9a title:string users:Vector<int> = MessageAction;
@ -117,7 +116,7 @@ messageActionChatDeletePhoto#95e3fbef = MessageAction; @@ -117,7 +116,7 @@ messageActionChatDeletePhoto#95e3fbef = MessageAction;
messageActionChatAddUser#5e3cfc4b user_id:int = MessageAction;
messageActionChatDeleteUser#b2ae9b0c user_id:int = MessageAction;
dialog#ab3a99ac peer:Peer top_message:int unread_count:int notify_settings:PeerNotifySettings = Dialog;
dialog#c1dd804a peer:Peer top_message:int read_inbox_max_id:int unread_count:int notify_settings:PeerNotifySettings = Dialog;
photoEmpty#2331b22d id:long = Photo;
photo#22b56751 id:long access_hash:long user_id:int date:int caption:string geo:GeoPoint sizes:Vector<PhotoSize> = Photo;
@ -132,7 +131,7 @@ video#388fa391 id:long access_hash:long user_id:int date:int caption:string dura @@ -132,7 +131,7 @@ video#388fa391 id:long access_hash:long user_id:int date:int caption:string dura
geoPointEmpty#1117dd5f = GeoPoint;
geoPoint#2049d70c long:double lat:double = GeoPoint;
auth.checkedPhone#e300cc3b phone_registered:Bool phone_invited:Bool = auth.CheckedPhone;
auth.checkedPhone#811ea28e phone_registered:Bool = auth.CheckedPhone;
auth.sentCode#efed51d9 phone_registered:Bool phone_code_hash:string send_call_timeout:int is_password:Bool = auth.SentCode;
@ -172,15 +171,7 @@ contactStatus#d3680c61 user_id:int status:UserStatus = ContactStatus; @@ -172,15 +171,7 @@ contactStatus#d3680c61 user_id:int status:UserStatus = ContactStatus;
chatLocated#3631cf4c chat_id:int distance:int = ChatLocated;
contacts.foreignLinkUnknown#133421f8 = contacts.ForeignLink;
contacts.foreignLinkRequested#a7801f47 has_phone:Bool = contacts.ForeignLink;
contacts.foreignLinkMutual#1bea8ce1 = contacts.ForeignLink;
contacts.myLinkEmpty#d22a1c60 = contacts.MyLink;
contacts.myLinkRequested#6c69efee contact:Bool = contacts.MyLink;
contacts.myLinkContact#c240ebd9 = contacts.MyLink;
contacts.link#eccea3f5 my_link:contacts.MyLink foreign_link:contacts.ForeignLink user:User = contacts.Link;
contacts.link#3ace484c my_link:ContactLink foreign_link:ContactLink user:User = contacts.Link;
contacts.contactsNotModified#b74ba9d2 = contacts.Contacts;
contacts.contacts#6f8b8cb2 contacts:Vector<Contact> users:Vector<User> = contacts.Contacts;
@ -199,19 +190,18 @@ messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vec @@ -199,19 +190,18 @@ messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vec
messages.messagesSlice#b446ae3 count:int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
messages.messageEmpty#3f4e0648 = messages.Message;
messages.message#ff90c417 message:Message chats:Vector<Chat> users:Vector<User> = messages.Message;
messages.statedMessages#969478bb messages:Vector<Message> chats:Vector<Chat> users:Vector<User> pts:int seq:int = messages.StatedMessages;
messages.statedMessages#7d84b48 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> pts:int pts_count:int = messages.StatedMessages;
messages.statedMessage#d07ae726 message:Message chats:Vector<Chat> users:Vector<User> pts:int seq:int = messages.StatedMessage;
messages.statedMessage#96240c6a message:Message chats:Vector<Chat> users:Vector<User> pts:int pts_count:int = messages.StatedMessage;
messages.sentMessage#d1f4d35c id:int date:int pts:int seq:int = messages.SentMessage;
messages.sentMessage#900eac40 id:int date:int pts:int pts_count:int = messages.SentMessage;
messages.chats#8150cbd8 chats:Vector<Chat> users:Vector<User> = messages.Chats;
messages.chats#64ff9fd5 chats:Vector<Chat> = messages.Chats;
messages.chatFull#e5d7d19c full_chat:ChatFull chats:Vector<Chat> users:Vector<User> = messages.ChatFull;
messages.affectedHistory#b7de36f2 pts:int seq:int offset:int = messages.AffectedHistory;
messages.affectedHistory#b45c69d1 pts:int pts_count:int offset:int = messages.AffectedHistory;
inputMessagesFilterEmpty#57e2f66c = MessagesFilter;
inputMessagesFilterPhotos#9609a51c = MessagesFilter;
@ -221,10 +211,10 @@ inputMessagesFilterPhotoVideoDocuments#d95e73bb = MessagesFilter; @@ -221,10 +211,10 @@ inputMessagesFilterPhotoVideoDocuments#d95e73bb = MessagesFilter;
inputMessagesFilterDocument#9eddf188 = MessagesFilter;
inputMessagesFilterAudio#cfc87522 = MessagesFilter;
updateNewMessage#13abdb3 message:Message pts:int = Update;
updateNewMessage#1f2b0afd message:Message pts:int pts_count: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;
updateReadMessages#2e5ab668 messages:Vector<int> pts:int pts_count:int = Update;
updateDeleteMessages#a20db0e5 messages:Vector<int> pts:int pts_count: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;
@ -232,7 +222,7 @@ updateUserStatus#1bfbd823 user_id:int status:UserStatus = Update; @@ -232,7 +222,7 @@ updateUserStatus#1bfbd823 user_id:int status:UserStatus = Update;
updateUserName#a7332b73 user_id:int first_name:string last_name:string username:string = Update;
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;
updateContactLink#9d2e67c5 user_id:int my_link:ContactLink foreign_link:ContactLink = 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;
@ -242,8 +232,8 @@ updates.difference#f49ca0 new_messages:Vector<Message> new_encrypted_messages:Ve @@ -242,8 +232,8 @@ updates.difference#f49ca0 new_messages:Vector<Message> new_encrypted_messages:Ve
updates.differenceSlice#a8fb1981 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> intermediate_state:updates.State = updates.Difference;
updatesTooLong#e317af7e = Updates;
updateShortMessage#d3f45784 id:int from_id:int message:string pts:int date:int seq:int = Updates;
updateShortChatMessage#2b2fbd4e id:int from_id:int chat_id:int message:string pts:int date:int seq:int = Updates;
updateShortMessage#ed5c2127 flags:# id:int user_id:int message:string pts:int pts_count:int date:int fwd_from_id:flags.2?int fwd_date:flags.2?int reply_to_msg_id:flags.3?int = Updates;
updateShortChatMessage#52238b3c flags:# id:int from_id:int chat_id:int message:string pts:int pts_count:int date:int fwd_from_id:flags.2?int fwd_date:flags.2?int reply_to_msg_id:flags.3?int = Updates;
updateShort#78d4dec1 update:Update date:int = Updates;
updatesCombined#725b04c3 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq_start:int seq:int = Updates;
updates#74ae4240 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq:int = Updates;
@ -257,7 +247,7 @@ upload.file#96a18d5 type:storage.FileType mtime:int bytes:bytes = upload.File; @@ -257,7 +247,7 @@ upload.file#96a18d5 type:storage.FileType mtime:int bytes:bytes = upload.File;
dcOption#2ec2a43c id:int hostname:string ip_address:string port:int = DcOption;
config#2e54dd74 date:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> chat_size_max:int broadcast_size_max:int = Config;
config#3e6f732a date:int expires:int test_mode:Bool this_dc:int dc_options:Vector<DcOption> chat_size_max:int broadcast_size_max:int online_update_period_ms:int offline_blur_timeout_ms:int offline_idle_timeout_ms:int online_cloud_timeout_ms:int notify_cloud_delay_ms:int notify_default_delay_ms:int chat_big_size:int disabled_features:Vector<DisabledFeature> = Config;
nearestDc#8e1a1775 country:string this_dc:int nearest_dc:int = NearestDc;
@ -266,11 +256,11 @@ help.noAppUpdate#c45a6536 = help.AppUpdate; @@ -266,11 +256,11 @@ help.noAppUpdate#c45a6536 = help.AppUpdate;
help.inviteText#18cb9f78 message:string = help.InviteText;
messages.statedMessagesLinks#3e74f5c6 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> links:Vector<contacts.Link> pts:int seq:int = messages.StatedMessages;
messages.statedMessagesLinks#51be5d19 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> pts:int pts_count:int links:Vector<contacts.Link> seq:int = messages.StatedMessages;
messages.statedMessageLink#a9af2881 message:Message chats:Vector<Chat> users:Vector<User> links:Vector<contacts.Link> pts:int seq:int = messages.StatedMessage;
messages.statedMessageLink#948a288 message:Message chats:Vector<Chat> users:Vector<User> pts:int pts_count:int links:Vector<contacts.Link> seq:int = messages.StatedMessage;
messages.sentMessageLink#e9db4a3f id:int date:int pts:int seq:int links:Vector<contacts.Link> = messages.SentMessage;
messages.sentMessageLink#e923400d id:int date:int pts:int pts_count:int links:Vector<contacts.Link> seq:int = messages.SentMessage;
inputGeoChat#74d456fa chat_id:int access_hash:long = InputGeoChat;
@ -425,7 +415,7 @@ account.password#739e5f72 current_salt:bytes new_salt:bytes hint:string = accoun @@ -425,7 +415,7 @@ account.password#739e5f72 current_salt:bytes new_salt:bytes hint:string = accoun
documentAttributeImageSize#6c37c15c w:int h:int = DocumentAttribute;
documentAttributeAnimated#11b58939 = DocumentAttribute;
documentAttributeSticker#fb0a5727 = DocumentAttribute;
documentAttributeSticker#994c9882 alt:string = DocumentAttribute;
documentAttributeVideo#5910cccb duration:int w:int h:int = DocumentAttribute;
documentAttributeAudio#51448e5 duration:int = DocumentAttribute;
documentAttributeFilename#15590068 file_name:string = DocumentAttribute;
@ -438,6 +428,18 @@ stickerPack#12b299d4 emoticon:string documents:Vector<long> = StickerPack; @@ -438,6 +428,18 @@ 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;
disabledFeature#ae636f24 feature:string description:string = DisabledFeature;
updateReadHistoryInbox#9961fd5c peer:Peer max_id:int pts:int pts_count:int = Update;
updateReadHistoryOutbox#2f2f21bf peer:Peer max_id:int pts:int pts_count:int = Update;
messages.affectedMessages#84d19185 pts:int pts_count:int = messages.AffectedMessages;
contactLinkUnknown#5f4f9247 = ContactLink;
contactLinkNone#feedd3ad = ContactLink;
contactLinkHasPhone#268f3f59 = ContactLink;
contactLinkContact#d502c2d0 = ContactLink;
---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
@ -484,14 +486,14 @@ messages.getMessages#4222fa74 id:Vector<int> = messages.Messages; @@ -484,14 +486,14 @@ messages.getMessages#4222fa74 id:Vector<int> = messages.Messages;
messages.getDialogs#eccf1df6 offset:int max_id:int limit:int = messages.Dialogs;
messages.getHistory#92a1df2f peer:InputPeer offset:int max_id:int limit:int = messages.Messages;
messages.search#7e9f2ab peer:InputPeer q:string filter:MessagesFilter min_date:int max_date:int offset:int max_id:int limit:int = messages.Messages;
messages.readHistory#eed884c6 peer:InputPeer max_id:int offset:int read_contents:Bool = messages.AffectedHistory;
messages.readHistory#b04f2510 peer:InputPeer max_id:int offset:int = messages.AffectedHistory;
messages.deleteHistory#f4f8fb61 peer:InputPeer offset:int = messages.AffectedHistory;
messages.deleteMessages#14f2dd0a id:Vector<int> = Vector<int>;
messages.deleteMessages#a5f18925 id:Vector<int> = messages.AffectedMessages;
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;
messages.sendMedia#a3c85d76 peer:InputPeer media:InputMedia random_id:long = messages.StatedMessage;
messages.forwardMessages#514cd10f peer:InputPeer id:Vector<int> = messages.StatedMessages;
messages.sendMessage#1ca852a1 peer:InputPeer reply_to_msg_id:int message:string random_id:long = messages.SentMessage;
messages.sendMedia#fcee7fc0 peer:InputPeer reply_to_msg_id:int media:InputMedia random_id:long = messages.StatedMessage;
messages.forwardMessages#ded42045 peer:InputPeer id:Vector<int> random_id:Vector<long> = messages.StatedMessages;
messages.getChats#3c6aa187 id:Vector<int> = messages.Chats;
messages.getFullChat#3b831c66 chat_id:int = messages.ChatFull;
messages.editChatTitle#b4bc68b5 chat_id:int title:string = messages.StatedMessage;
@ -553,7 +555,7 @@ help.getSupport#9cdf08cd = help.Support; @@ -553,7 +555,7 @@ help.getSupport#9cdf08cd = help.Support;
auth.sendSms#da9f3e8 phone_number:string phone_code_hash:string = Bool;
messages.readMessageContents#354b5bc2 id:Vector<int> = Vector<int>;
messages.readMessageContents#36a73f77 id:Vector<int> = messages.AffectedMessages;
account.checkUsername#2714d86c username:string = Bool;
account.updateUsername#3e0bdd7c username:string = User;
@ -579,3 +581,5 @@ auth.checkPassword#a63011e password_hash:bytes = auth.Authorization; @@ -579,3 +581,5 @@ auth.checkPassword#a63011e password_hash:bytes = auth.Authorization;
messages.getStickers#ae22e045 emoticon:string hash:string = messages.Stickers;
messages.getAllStickers#aa3bc868 hash:string = messages.AllStickers;
account.updateDeviceLocked#38df3532 period:int = Bool;

13
app/js/lib/tl_utils.js

@ -466,6 +466,7 @@ TLDeserialization.prototype.fetchRawBytes = function (len, typed, field) { @@ -466,6 +466,7 @@ TLDeserialization.prototype.fetchRawBytes = function (len, typed, field) {
TLDeserialization.prototype.fetchObject = function (type, field) {
switch (type) {
case '#':
case 'int': return this.fetchInt(field);
case 'long': return this.fetchLong(field);
case 'int128': return this.fetchIntBytes(128, false, field);
@ -574,7 +575,17 @@ TLDeserialization.prototype.fetchObject = function (type, field) { @@ -574,7 +575,17 @@ TLDeserialization.prototype.fetchObject = function (type, field) {
this.override[overrideKey].apply(this, [result, field + '[' + predicate + ']']);
} else {
angular.forEach(constructorData.params, function (param) {
result[param.name] = self.fetchObject(param.type, field + '[' + predicate + '][' + param.name + ']');
var type = param.type;
if (type.indexOf('?') !== -1) {
var condType = type.split('?');
var fieldBit = condType[0].split('.');
if (!(result[fieldBit[0]] & (1 << fieldBit[1]))) {
return;
}
type = condType[1];
}
result[param.name] = self.fetchObject(type, field + '[' + predicate + '][' + param.name + ']');
});
}

395
app/js/services.js

@ -411,7 +411,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -411,7 +411,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
break;
case 'updateContactLink':
onContactUpdated(update.user_id, update.my_link._ == 'contacts.myLinkContact');
onContactUpdated(update.user_id, update.my_link._ == 'contactLinkContact');
break;
}
});
@ -1183,12 +1183,14 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1183,12 +1183,14 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
function deleteMessages (messageIDs) {
return MtpApiManager.invokeApi('messages.deleteMessages', {
id: messageIDs
}).then(function (deletedMessageIDs) {
}).then(function (affectedMessages) {
ApiUpdatesManager.processUpdateMessage({
_: 'updateShort',
update: {
_: 'updateDeleteMessages',
messages: deletedMessageIDs
messages: messageIDs,
pts: affectedMessages.pts,
pts_count: affectedMessages.pts_count
}
});
return deletedMessageIDs;
@ -1197,9 +1199,12 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1197,9 +1199,12 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
function processAffectedHistory (inputPeer, affectedHistory, method) {
if (!ApiUpdatesManager.processUpdateMessage({
_: 'updates',
seq: affectedHistory.seq,
updates: []
_: 'updateShort',
update: {
_: 'updatePts',
pts: affectedHistory.pts,
pts_count: affectedHistory.pts_count
}
})) {
return false;
}
@ -1210,8 +1215,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1210,8 +1215,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
return MtpApiManager.invokeApi(method, {
peer: inputPeer,
offset: affectedHistory.offset,
max_id: 0,
read_contents: true
max_id: 0
}).then(function (affectedHistory) {
return processAffectedHistory(inputPeer, affectedHistory, method);
});
@ -1253,8 +1257,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1253,8 +1257,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
historyStorage.readPromise = MtpApiManager.invokeApi('messages.readHistory', {
peer: inputPeer,
offset: 0,
max_id: 0,
read_contents: true
max_id: 0
}).then(function (affectedHistory) {
return processAffectedHistory(inputPeer, affectedHistory, 'messages.readHistory');
}).then(function () {
@ -1334,9 +1337,6 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1334,9 +1337,6 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
case 'messageMediaAudio':
AppAudioManager.saveAudio(apiMessage.media.audio);
break;
case 'messageMediaUnsupported':
delete apiMessage.media.bytes;
break;
}
}
if (apiMessage.action && apiMessage.action._ == 'messageActionChatEditPhoto') {
@ -1398,7 +1398,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1398,7 +1398,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
MtpApiManager.invokeApi('messages.sendMessage', {
peer: inputPeer,
message: text,
random_id: randomID
random_id: randomID,
reply_to_msg_id: 0
}, sentRequestOptions).then(function (sentMessage) {
message.date = sentMessage.date;
message.id = sentMessage.id;
@ -1407,7 +1408,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1407,7 +1408,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
_: 'updates',
users: [],
chats: [],
seq: sentMessage.seq,
seq: 0,
updates: [{
_: 'updateMessageID',
random_id: randomIDS,
@ -1415,7 +1416,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1415,7 +1416,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
}, {
_: 'updateNewMessage',
message: message,
pts: sentMessage.pts
pts: sentMessage.pts,
pts_count: sentMessage.pts_count
}]
});
}, function (error) {
@ -1542,7 +1544,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1542,7 +1544,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
MtpApiManager.invokeApi('messages.sendMedia', {
peer: inputPeer,
media: inputMedia,
random_id: randomID
random_id: randomID,
reply_to_msg_id: 0
}).then(function (statedMessage) {
message.date = statedMessage.message.date;
message.id = statedMessage.message.id;
@ -1552,7 +1555,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1552,7 +1555,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
_: 'updates',
users: statedMessage.users,
chats: statedMessage.chats,
seq: statedMessage.seq,
seq: 0,
updates: [{
_: 'updateMessageID',
random_id: randomIDS,
@ -1560,7 +1563,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1560,7 +1563,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
}, {
_: 'updateNewMessage',
message: message,
pts: statedMessage.pts
pts: statedMessage.pts,
pts_count: statedMessage.pts_count
}]
});
}, function (error) {
@ -1667,7 +1671,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1667,7 +1671,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
MtpApiManager.invokeApi('messages.sendMedia', {
peer: inputPeer,
media: inputMedia,
random_id: randomID
random_id: randomID,
reply_to_msg_id: 0
}).then(function (statedMessage) {
message.date = statedMessage.message.date;
message.id = statedMessage.message.id;
@ -1677,7 +1682,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1677,7 +1682,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
_: 'updates',
users: statedMessage.users,
chats: statedMessage.chats,
seq: statedMessage.seq,
seq: 0,
updates: [{
_: 'updateMessageID',
random_id: randomIDS,
@ -1685,7 +1690,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1685,7 +1690,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
}, {
_: 'updateNewMessage',
message: message,
pts: statedMessage.pts
pts: statedMessage.pts,
pts_count: statedMessage.pts_count
}]
});
}, function (error) {
@ -1706,16 +1712,25 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1706,16 +1712,25 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
function forwardMessages (peerID, msgIDs) {
msgIDs = msgIDs.sort();
var randomIDs = [];
var i;
var len = msgIDs.length;
for (var i = 0; i < msgIDs.length; i++) {
randomIDs.push([nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)]);
}
return MtpApiManager.invokeApi('messages.forwardMessages', {
peer: AppPeersManager.getInputPeerByID(peerID),
id: msgIDs
id: msgIDs,
random_id: randomIDs
}).then(function (statedMessages) {
var updates = [];
angular.forEach(statedMessages.messages, function(apiMessage) {
updates.push({
_: 'updateNewMessage',
message: apiMessage,
pts: statedMessages.pts
pts: statedMessages.pts,
pts_count: statedMessages.pts_count
});
});
@ -1723,7 +1738,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1723,7 +1738,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
_: 'updates',
users: statedMessages.users,
chats: statedMessages.chats,
seq: statedMessages.seq,
seq: 0,
updates: updates
});
});
@ -1817,11 +1832,12 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1817,11 +1832,12 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
_: 'updates',
users: statedMessage.users,
chats: statedMessage.chats,
seq: statedMessage.seq,
seq: 0,
updates: [{
_: 'updateNewMessage',
message: statedMessage.message,
pts: statedMessage.pts
pts: statedMessage.pts,
pts_count: statedMessage.pts_count
}]
});
}
@ -2298,6 +2314,9 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2298,6 +2314,9 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
}
break;
// case 'updateReadHistoryInbox':
// case 'updateReadHistoryOutbox':
case 'updateDeleteMessages':
var dialogsUpdated = {},
historiesUpdated = {},
@ -2858,7 +2877,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -2858,7 +2877,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
break;
case 'documentAttributeSticker':
apiDoc.sticker = 1;
var stickerEmoji = EmojiHelper.stickers[apiDoc.id];
var stickerEmoji = attribute.alt || EmojiHelper.stickers[apiDoc.id];
if (stickerEmoji !== undefined) {
apiDoc.sticker = 2;
apiDoc.stickerEmoji = RichTextProcessor.wrapRichText(stickerEmoji, {noLinks: true, noLinebreaks: true});
@ -3270,39 +3289,106 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -3270,39 +3289,106 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
.service('ApiUpdatesManager', function ($rootScope, MtpNetworkerFactory, AppUsersManager, AppChatsManager, AppPeersManager, MtpApiManager) {
var isSynchronizing = true,
getDifferencePending = false,
curState = {},
pendingUpdates = {};
var curState = {};
function popPendingUpdate () {
var myID = 0;
MtpApiManager.getUserID().then(function (id) {
myID = id;
});
var syncPending = false;
var syncLoading = true;
var pendingSeqUpdates = {};
var pendingPtsUpdates = [];
function popPendingSeqUpdate () {
var nextSeq = curState.seq + 1,
updateMessage = pendingUpdates[nextSeq];
if (updateMessage) {
console.log(dT(), 'pop pending update', nextSeq, updateMessage);
if (processUpdateMessage(updateMessage)) {
delete pendingUpdates[nextSeq];
pendingUpdatesData = pendingSeqUpdates[nextSeq];
if (!pendingUpdatesData) {
return false;
}
var updates = pendingUpdatesData.updates;
var i, length;
for (var i = 0, length = updates.length; i < length; i++) {
saveUpdate(updates[i]);
}
curState.seq = pendingUpdatesData.seq;
if (pendingUpdatesData.date && curState.date < pendingUpdatesData.date) {
curState.date = pendingUpdatesData.date;
}
delete pendingSeqUpdates[nextSeq];
if (!popPendingSeqUpdate() &&
syncPending &&
syncPending.seqAwaiting &&
curState.seq >= syncPending.seqAwaiting) {
if (!syncPending.ptsAwaiting) {
clearTimeout(syncPending.timeout);
syncPending = false;
} else {
delete syncPending.seqAwaiting;
}
}
return true;
}
function forceGetDifference () {
if (!isSynchronizing) {
getDifference();
function popPendingPtsUpdate () {
if (!pendingPtsUpdates.length) {
return false;
}
}
pendingPtsUpdates.sort(function (a, b) {
return a.pts - b.pts;
});
function processUpdateMessage (updateMessage) {
if (updateMessage.seq) {
if (!saveSeq(updateMessage.seq, updateMessage.seq_start)) {
pendingUpdates[updateMessage.seq_start || updateMessage.seq] = updateMessage;
return false;
var curPts = curState.pts;
var goodPts = false;
var goodIndex = false;
var update;
for (var i = 0, length = pendingPtsUpdates.length; i < length; i++) {
update = pendingPtsUpdates[i];
curPts += update.pts_count;
if (curPts >= update.pts) {
goodPts = update.pts;
goodIndex = i;
}
if (updateMessage.date) {
curState.date = updateMessage.date;
}
if (!goodPts) {
return false;
}
curState.pts = goodPts;
for (i = 0; i <= goodIndex; i++) {
update = pendingPtsUpdates[i];
saveUpdate(update);
}
pendingPtsUpdates.splice(goodIndex, length - goodIndex);
if (!pendingPtsUpdates.length && syncPending) {
if (!syncPending.seqAwaiting) {
clearTimeout(syncPending.timeout);
syncPending = false;
} else {
delete syncPending.ptsAwaiting;
}
}
return true;
}
function forceGetDifference () {
if (!syncLoading) {
getDifference();
}
}
function processUpdateMessage (updateMessage) {
var processOpts = {
date: updateMessage.date,
seq: updateMessage.seq,
seqStart: updateMessage.seq_start
};
switch (updateMessage._) {
case 'updatesTooLong':
@ -3311,51 +3397,35 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -3311,51 +3397,35 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
break;
case 'updateShort':
saveUpdate(updateMessage.update);
processUpdate(updateMessage.update, processOpts);
break;
case 'updateShortMessage':
if (!AppUsersManager.hasUser(updateMessage.from_id)) {
console.log('User not found', updateMessage.from_id, 'getDiff');
forceGetDifference();
break;
}
saveUpdate({
_: 'updateNewMessage',
message: {
_: 'message',
id: updateMessage.id,
from_id: updateMessage.from_id,
to_id: AppPeersManager.getOutputPeer(MtpApiManager.getUserID()),
flags: 1,
date: updateMessage.date,
message: updateMessage.message
},
pts: updateMessage.pts
});
break;
case 'updateShortChatMessage':
if (!AppUsersManager.hasUser(updateMessage.from_id) ||
!AppChatsManager.hasChat(updateMessage.chat_id)) {
console.log('User or chat not found', updateMessage.from_id, updateMessage.chat_id, 'getDiff');
forceGetDifference();
break;
}
saveUpdate({
var isOut = updateMessage.flags & 2;
var fromID = updateMessage.from_id || (isOut ? myID : updateMessage.user_id);
var toID = updateMessage.chat_id
? -updateMessage.chat_id
: (isOut ? updateMessage.user_id : myID);
processUpdate({
_: 'updateNewMessage',
message: {
_: 'message',
flags: updateMessage.flags,
id: updateMessage.id,
from_id: updateMessage.from_id,
to_id: AppPeersManager.getOutputPeer(-updateMessage.chat_id),
flags: 1,
from_id: fromID,
to_id: AppPeersManager.getOutputPeer(toID),
date: updateMessage.date,
message: updateMessage.message
message: updateMessage.message,
fwd_from_id: updateMessage.fwd_from_id,
fwd_date: updateMessage.fwd_date,
reply_to_msg_id: updateMessage.reply_to_msg_id,
},
pts: updateMessage.pts
});
pts: updateMessage.pts,
pts_count: updateMessage.pts_count
}, processOpts);
break;
case 'updatesCombined':
@ -3363,52 +3433,26 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -3363,52 +3433,26 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
AppUsersManager.saveApiUsers(updateMessage.users);
AppChatsManager.saveApiChats(updateMessage.chats);
var i, update, message;
for (var i = 0; i < updateMessage.updates.length; i++) {
update = updateMessage.updates[i];
switch (update._) {
case 'updateNewMessage':
message = update.message;
if (message.from_id && !AppUsersManager.hasUser(message.from_id)) {
console.log('User not found', message.from_id, 'getDiff');
forceGetDifference();
return false;
}
if (message.to_id.chat_id && !AppChatsManager.hasChat(message.to_id.chat_id)) {
console.log('Chat not found', message.to_id.chat_id, 'getDiff');
forceGetDifference();
return false;
}
break;
}
}
angular.forEach(updateMessage.updates, function (update) {
saveUpdate(update);
processUpdate(update, processOpts);
});
break;
default:
console.warn(dT(), 'Unknown update message', updateMessage);
}
popPendingUpdate();
if (getDifferencePending && curState.seq >= getDifferencePending.seqAwaiting) {
console.log(dT(), 'cancel pending getDiff', getDifferencePending.seqAwaiting);
clearTimeout(getDifferencePending.timeout);
getDifferencePending = false;
}
return true;
}
function getDifference () {
isSynchronizing = true;
if (!syncLoading) {
syncLoading = true;
pendingSeqUpdates = {};
pendingPtsUpdates = [];
}
if (getDifferencePending) {
clearTimeout(getDifferencePending.timeout);
getDifferencePending = false;
if (syncPending) {
clearTimeout(syncPending.timeout);
syncPending = false;
}
MtpApiManager.invokeApi('updates.getDifference', {pts: curState.pts, date: curState.date, qts: 0}).then(function (differenceResult) {
@ -3416,8 +3460,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -3416,8 +3460,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
console.log(dT(), 'apply empty diff', differenceResult.seq);
curState.date = differenceResult.date;
curState.seq = differenceResult.seq;
isSynchronizing = false;
popPendingUpdate();
syncLoading = false;
return false;
}
@ -3433,7 +3476,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -3433,7 +3476,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
saveUpdate({
_: 'updateNewMessage',
message: apiMessage,
pts: curState.pts
pts: curState.pts,
pts_count: 0
});
});
@ -3445,55 +3489,100 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -3445,55 +3489,100 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
console.log(dT(), 'apply diff', curState.seq, curState.pts);
if (differenceResult._ == 'updates.differenceSlice') {
getDifference(true);
getDifference();
} else {
isSynchronizing = false;
syncLoading = false;
}
});
}
function saveUpdate (update) {
if (update.pts) {
curState.pts = update.pts;
function processUpdate (update, options) {
if (syncLoading) {
return false;
}
$rootScope.$broadcast('apiUpdate', update);
}
function saveSeq (seq, seqStart) {
seqStart = seqStart || seq;
if (!seqStart) {
return true;
if (update._ == 'updateNewMessage') {
var message = update.message;
if (message.from_id && !AppUsersManager.hasUser(message.from_id) ||
message.fwd_from_id && !AppUsersManager.hasUser(message.fwd_from_id) ||
message.to_id.user_id && !AppUsersManager.hasUser(message.to_id.user_id) ||
message.to_id.chat_id && !AppChatsManager.hasChat(message.to_id.chat_id)) {
console.warn(dT(), 'Short update not enough data', message);
forceGetDifference();
return false;
}
}
if (isSynchronizing) {
console.log(dT(), 'Seq decline', seqStart);
return false;
}
var popPts, popSeq;
if (seqStart != curState.seq + 1) {
if (seqStart > curState.seq) {
console.warn(dT(), 'Seq hole', seqStart, getDifferencePending && getDifferencePending.seqAwaiting);
if (!getDifferencePending) {
getDifferencePending = {
seqAwaiting: seqStart,
if (update.pts) {
var newPts = curState.pts + (update.pts_count || 0);
if (newPts < update.pts) {
console.log(dT(), 'Pts hole', curState, update);
pendingPtsUpdates.push(update);
if (!syncPending) {
syncPending = {
timeout: setTimeout(function () {
getDifference();
}, 5000)
};
}
syncPending.ptsAwaiting = true;
return false;
}
return false;
} else {
// console.log(dT(), 'Seq apply', seqStart);
curState.pts = update.pts;
popPts = true;
}
else if (options.seq > 0) {
var seq = options.seq;
var seqStart = options.seqStart || seq;
curState.seq = seq;
if (seqStart != curState.seq + 1) {
if (seqStart > curState.seq) {
console.warn(dT(), 'Seq hole', curState, syncPending && syncPending.seqAwaiting);
return true;
if (pendingSeqUpdates[seqStart] === undefined) {
pendingSeqUpdates[seqStart] = {seq: seq, date: options.date, updates: []};
}
pendingSeqUpdates[seqStart].updates.push(update);
if (!syncPending) {
syncPending = {
timeout: setTimeout(function () {
getDifference();
}, 5000)
};
}
if (!syncPending.seqAwaiting ||
syncPending.seqAwaiting < seqStart) {
syncPending.seqAwaiting = seqStart;
}
return false;
}
}
if (curState.seq != seq) {
curState.seq = seq;
if (options.date && curState.date < options.date) {
curState.date = options.date;
}
popSeq = true;
}
}
saveUpdate (update);
if (popPts) {
popPendingPtsUpdate();
}
else if (popSeq) {
popPendingSeqUpdate();
}
}
function saveUpdate (update) {
$rootScope.$broadcast('apiUpdate', update);
}
function attach () {
@ -3503,7 +3592,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -3503,7 +3592,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
curState.pts = stateResult.pts;
curState.date = stateResult.date;
setTimeout(function () {
isSynchronizing = false;
syncLoading = false;
}, 1000);
})
}

4
app/partials/desktop/message.html

@ -19,7 +19,7 @@ @@ -19,7 +19,7 @@
</div>
<div ng-switch-default class="im_content_message_wrap" ng-class="::[historyMessage.out ? 'im_message_out' : 'im_message_in', historyMessage._ == 'messageForwarded' ? 'im_message_fwd' : '']">
<div ng-switch-default class="im_content_message_wrap" ng-class="::[historyMessage.out ? 'im_message_out' : 'im_message_in', historyMessage.fwd_from_id > 0 ? 'im_message_fwd' : '']">
<div class="im_content_message_select_area">
<i class="icon icon-select-tick"></i>
</div>
@ -41,7 +41,7 @@ @@ -41,7 +41,7 @@
<a class="im_message_author" my-user-link="historyMessage.from_id" short="!historyMessage.to_id.chat_id" color="historyMessage.to_id.chat_id > 0" no-watch="true"></a>
<div ng-if="::historyMessage._ == 'messageForwarded' || false" class="im_message_fwd_from">
<div ng-if="::historyMessage.fwd_from_id > 0" class="im_message_fwd_from">
<a class="im_message_fwd_photo pull-left" my-user-photolink="historyMessage.fwd_from_id" img-class="im_message_fwd_photo"></a>
<div class="im_message_fwd_author_wrap">
<a class="im_message_fwd_author" my-user-link="historyMessage.fwd_from_id" short="true" no-watch="true"></a><span class="im_message_fwd_date" ng-bind="::historyMessage.fwd_date | dateOrTime"></span>

2
app/partials/mobile/message.html

@ -33,7 +33,7 @@ @@ -33,7 +33,7 @@
<a class="im_message_author" my-user-link="historyMessage.from_id" short="!historyMessage.to_id.chat_id" color="historyMessage.to_id.chat_id > 0" no-watch="true"></a>
<div ng-if="::historyMessage._ == 'messageForwarded' &amp;&amp; !historyMessage.media" class="im_message_fwd_header" my-i18n="message_forwarded_message_mobile">
<div ng-if="::historyMessage.fwd_from_id > 0 &amp;&amp; !historyMessage.media" class="im_message_fwd_header" my-i18n="message_forwarded_message_mobile">
<a my-i18n-param="from" class="im_message_fwd_author" my-user-link="historyMessage.fwd_from_id" no-watch="true"></a>
<span my-i18n-param="date" class="im_message_fwd_date" ng-bind="::historyMessage.fwd_date | dateOrTime"></span>
</div>

2
webogram.sublime-project vendored

@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
{
"follow_symlinks": true,
"path": ".",
"folder_exclude_patterns": ["*dist", "node_modules", "releases"],
"folder_exclude_patterns": ["*dist", "node_modules", "releases", ".tx"],
"file_exclude_patterns": ["*.zip", "templates.js"]
}
]

Loading…
Cancel
Save