diff --git a/TMessagesProj/build.gradle b/TMessagesProj/build.gradle index ed0db1e8e..691671542 100644 --- a/TMessagesProj/build.gradle +++ b/TMessagesProj/build.gradle @@ -5,7 +5,7 @@ repositories { } dependencies { - compile 'com.android.support:support-v4:22.2.+' + compile 'com.android.support:support-v4:23.0.+' compile 'com.google.android.gms:play-services:3.2.+' compile 'net.hockeyapp.android:HockeySDK:3.5.+' compile 'com.googlecode.mp4parser:isoparser:1.0.+' @@ -13,7 +13,7 @@ dependencies { android { compileSdkVersion 22 - buildToolsVersion '22.0.1' + buildToolsVersion '23.0.0' compileOptions { sourceCompatibility JavaVersion.VERSION_1_7 @@ -73,7 +73,7 @@ android { defaultConfig { minSdkVersion 8 targetSdkVersion 22 - versionCode 586 - versionName "3.1.2" + versionCode 592 + versionName "3.1.3" } } diff --git a/TMessagesProj/src/main/assets/fonts/ritalic.ttf b/TMessagesProj/src/main/assets/fonts/ritalic.ttf new file mode 100755 index 000000000..ff6046d5b Binary files /dev/null and b/TMessagesProj/src/main/assets/fonts/ritalic.ttf differ diff --git a/TMessagesProj/src/main/java/jawnae/pyronet/PyroClient.java b/TMessagesProj/src/main/java/jawnae/pyronet/PyroClient.java index 1044c9c6e..8f2b03d57 100755 --- a/TMessagesProj/src/main/java/jawnae/pyronet/PyroClient.java +++ b/TMessagesProj/src/main/java/jawnae/pyronet/PyroClient.java @@ -58,7 +58,7 @@ public class PyroClient { this.key.attach(this); this.outbound = new ByteStream(); - this.listeners = new CopyOnWriteArrayList(); + this.listeners = new CopyOnWriteArrayList<>(); this.lastEventTime = System.currentTimeMillis(); } diff --git a/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java b/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java index 7569f9cb0..f43e09a44 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessageObject.java @@ -9,6 +9,7 @@ package org.telegram.android; import android.graphics.Paint; +import android.graphics.Typeface; import android.text.Layout; import android.text.Spannable; import android.text.SpannableStringBuilder; @@ -16,6 +17,7 @@ import android.text.Spanned; import android.text.StaticLayout; import android.text.TextPaint; import android.text.TextUtils; +import android.text.style.URLSpan; import android.text.util.Linkify; import org.telegram.messenger.ConnectionsManager; @@ -24,8 +26,10 @@ import org.telegram.messenger.FileLog; import org.telegram.messenger.TLRPC; import org.telegram.messenger.R; import org.telegram.messenger.UserConfig; +import org.telegram.ui.Components.TypefaceSpan; import org.telegram.ui.Components.URLSpanNoUnderline; import org.telegram.ui.Components.URLSpanNoUnderlineBold; +import org.telegram.ui.Components.URLSpanReplacement; import java.util.AbstractMap; import java.util.ArrayList; @@ -397,7 +401,7 @@ public class MessageObject { int dateYear = rightNow.get(Calendar.YEAR); int dateMonth = rightNow.get(Calendar.MONTH); dateKey = String.format("%d_%02d_%02d", dateYear, dateMonth, dateDay); - if (contentType == 1 || contentType == 2) { + if (contentType == 1 || contentType == 2 || contentType == 0) { monthKey = String.format("%d_%02d", dateYear, dateMonth); } @@ -666,7 +670,54 @@ public class MessageObject { generateLinkDescription(); textLayoutBlocks = new ArrayList<>(); - addLinks(messageText); + boolean useManualParse = messageOwner.entities.isEmpty() && ( + messageOwner instanceof TLRPC.TL_message_old || + messageOwner instanceof TLRPC.TL_message_old2 || + messageOwner instanceof TLRPC.TL_message_old3 || + messageOwner instanceof TLRPC.TL_message_old4 || + messageOwner instanceof TLRPC.TL_messageForwarded_old || + messageOwner instanceof TLRPC.TL_messageForwarded_old2 || + messageOwner instanceof TLRPC.TL_message_secret || + isOut() && messageOwner.send_state != MESSAGE_SEND_STATE_SENT || messageOwner.id < 0); + + if (useManualParse) { + addLinks(messageText); + } + + if (messageText instanceof Spannable) { + Spannable spannable = (Spannable) messageText; + int count = messageOwner.entities.size(); + for (int a = 0; a < count; a++) { + TLRPC.MessageEntity entity = messageOwner.entities.get(a); + if (entity.length <= 0 || entity.offset < 0 || entity.offset >= messageOwner.message.length()) { + continue; + } else if (entity.offset + entity.length > messageOwner.message.length()) { + entity.length = messageOwner.message.length() - entity.offset; + } + if (entity instanceof TLRPC.TL_messageEntityBold) { + spannable.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")), entity.offset, entity.offset + entity.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } else if (entity instanceof TLRPC.TL_messageEntityItalic) { + spannable.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/ritalic.ttf")), entity.offset, entity.offset + entity.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } else if (entity instanceof TLRPC.TL_messageEntityCode) { + spannable.setSpan(new TypefaceSpan(Typeface.MONOSPACE), entity.offset, entity.offset + entity.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } else if (!useManualParse) { + String url = messageOwner.message.substring(entity.offset, entity.offset + entity.length); + if (entity instanceof TLRPC.TL_messageEntityBotCommand || entity instanceof TLRPC.TL_messageEntityHashtag || entity instanceof TLRPC.TL_messageEntityMention) { + spannable.setSpan(new URLSpanNoUnderline(url), entity.offset, entity.offset + entity.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } else if (entity instanceof TLRPC.TL_messageEntityEmail) { + spannable.setSpan(new URLSpanReplacement("mailto:" + url), entity.offset, entity.offset + entity.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } else if (entity instanceof TLRPC.TL_messageEntityUrl) { + if (!url.toLowerCase().startsWith("http")) { + spannable.setSpan(new URLSpan("http://" + url), entity.offset, entity.offset + entity.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } else { + spannable.setSpan(new URLSpan(url), entity.offset, entity.offset + entity.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } + } else if (entity instanceof TLRPC.TL_messageEntityTextUrl) { + spannable.setSpan(new URLSpanReplacement(entity.url), entity.offset, entity.offset + entity.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } + } + } + } int maxWidth; if (AndroidUtilities.isTablet()) { diff --git a/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java b/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java index 6bcaf3359..04f01735c 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/MessagesController.java @@ -268,13 +268,10 @@ public class MessagesController implements NotificationCenter.NotificationCenter TLRPC.InputUser inputUser; if (user.id == UserConfig.getClientUserId()) { inputUser = new TLRPC.TL_inputUserSelf(); - } else if (user.access_hash != 0) { - inputUser = new TLRPC.TL_inputUserForeign(); + } else { + inputUser = new TLRPC.TL_inputUser(); inputUser.user_id = user.id; inputUser.access_hash = user.access_hash; - } else { - inputUser = new TLRPC.TL_inputUserContact(); - inputUser.user_id = user.id; } return inputUser; } @@ -512,7 +509,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter return; } boolean updateStatus = false; - for (TLRPC.User user : users) { + int count = users.size(); + for (int a = 0; a < count; a++) { + TLRPC.User user = users.get(a); if (putUser(user, fromCache)) { updateStatus = true; } @@ -531,9 +530,13 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (chat == null) { return; } - if (fromCache) { - chats.putIfAbsent(chat.id, chat); - } else { + TLRPC.Chat oldChat = chats.get(chat.id); + if (!fromCache) { + if (oldChat != null && chat.version != oldChat.version) { + loadedFullChats.remove((Integer) chat.id); + } + chats.put(chat.id, chat); + } else if (oldChat == null) { chats.put(chat.id, chat); } } @@ -542,7 +545,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (chats == null || chats.isEmpty()) { return; } - for (TLRPC.Chat chat : chats) { + int count = chats.size(); + for (int a = 0; a < count; a++) { + TLRPC.Chat chat = chats.get(a); putChat(chat, fromCache); } } @@ -562,7 +567,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (encryptedChats == null || encryptedChats.isEmpty()) { return; } - for (TLRPC.EncryptedChat encryptedChat : encryptedChats) { + int count = encryptedChats.size(); + for (int a = 0; a < count; a++) { + TLRPC.EncryptedChat encryptedChat = encryptedChats.get(a); putEncryptedChat(encryptedChat, fromCache); } } @@ -1143,12 +1150,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (user == null) { return; } - if (user.access_hash != 0) { - req.peer = new TLRPC.TL_inputPeerForeign(); - req.peer.access_hash = user.access_hash; - } else { - req.peer = new TLRPC.TL_inputPeerContact(); - } + req.peer = new TLRPC.TL_inputPeerUser(); + req.peer.access_hash = user.access_hash; req.peer.user_id = lower_part; } ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { @@ -1447,14 +1450,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (user == null) { return; } - if (user.access_hash != 0) { - req.peer = new TLRPC.TL_inputPeerForeign(); - req.peer.user_id = user.id; - req.peer.access_hash = user.access_hash; - } else { - req.peer = new TLRPC.TL_inputPeerContact(); - req.peer.user_id = user.id; - } + req.peer = new TLRPC.TL_inputPeerUser(); + req.peer.user_id = user.id; + req.peer.access_hash = user.access_hash; } if (action == 0) { req.action = new TLRPC.TL_sendMessageTypingAction(); @@ -1534,14 +1532,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (user == null) { return; } - if (user.access_hash != 0) { - req.peer = new TLRPC.TL_inputPeerForeign(); - req.peer.user_id = user.id; - req.peer.access_hash = user.access_hash; - } else { - req.peer = new TLRPC.TL_inputPeerContact(); - req.peer.user_id = user.id; - } + req.peer = new TLRPC.TL_inputPeerUser(); + req.peer.user_id = user.id; + req.peer.access_hash = user.access_hash; } if (load_type == 3) { req.offset = -count / 2; @@ -2016,14 +2009,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (user == null) { return; } - if (user.access_hash != 0) { - req.peer = new TLRPC.TL_inputPeerForeign(); - req.peer.user_id = user.id; - req.peer.access_hash = user.access_hash; - } else { - req.peer = new TLRPC.TL_inputPeerContact(); - req.peer.user_id = user.id; - } + req.peer = new TLRPC.TL_inputPeerUser(); + req.peer.user_id = user.id; + req.peer.access_hash = user.access_hash; } req.max_id = max_positive_id; req.offset = offset; @@ -3006,6 +2994,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter message.to_id.chat_id = updates.chat_id; message.dialog_id = -updates.chat_id; } + message.entities = updates.entities; message.message = updates.message; message.date = updates.date; message.flags = updates.flags; diff --git a/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java b/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java index 5983c3855..851945891 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java +++ b/TMessagesProj/src/main/java/org/telegram/android/NotificationsController.java @@ -1370,12 +1370,8 @@ public class NotificationsController { if (user == null) { return; } - if (user.access_hash != 0) { - ((TLRPC.TL_inputNotifyPeer)req.peer).peer = new TLRPC.TL_inputPeerForeign(); - ((TLRPC.TL_inputNotifyPeer)req.peer).peer.access_hash = user.access_hash; - } else { - ((TLRPC.TL_inputNotifyPeer)req.peer).peer = new TLRPC.TL_inputPeerContact(); - } + ((TLRPC.TL_inputNotifyPeer)req.peer).peer = new TLRPC.TL_inputPeerUser(); + ((TLRPC.TL_inputNotifyPeer)req.peer).peer.access_hash = user.access_hash; ((TLRPC.TL_inputNotifyPeer)req.peer).peer.user_id = (int)dialog_id; } diff --git a/TMessagesProj/src/main/java/org/telegram/android/SecretChatHelper.java b/TMessagesProj/src/main/java/org/telegram/android/SecretChatHelper.java index 5d793ea3d..9498d2d64 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/SecretChatHelper.java +++ b/TMessagesProj/src/main/java/org/telegram/android/SecretChatHelper.java @@ -559,7 +559,6 @@ public class SecretChatHelper { newMsg.media.video.h = video.h; newMsg.media.video.date = video.date; newMsg.media.caption = video.caption != null ? video.caption : ""; - newMsg.media.video.user_id = video.user_id; newMsg.media.video.size = file.size; newMsg.media.video.id = file.id; newMsg.media.video.access_hash = file.access_hash; @@ -897,9 +896,7 @@ public class SecretChatHelper { newMessage.media = new TLRPC.TL_messageMediaPhoto(); newMessage.media.caption = ""; newMessage.media.photo = new TLRPC.TL_photo(); - newMessage.media.photo.user_id = newMessage.from_id; newMessage.media.photo.date = newMessage.date; - newMessage.media.photo.geo = new TLRPC.TL_geoPointEmpty(); byte[] thumb = ((TLRPC.TL_decryptedMessageMediaPhoto) decryptedMessage.media).thumb; if (thumb != null && thumb.length != 0 && thumb.length <= 6000 && decryptedMessage.media.thumb_w <= 100 && decryptedMessage.media.thumb_h <= 100) { TLRPC.TL_photoCachedSize small = new TLRPC.TL_photoCachedSize(); @@ -948,7 +945,6 @@ public class SecretChatHelper { newMessage.media.video.w = decryptedMessage.media.w; newMessage.media.video.h = decryptedMessage.media.h; newMessage.media.video.date = date; - newMessage.media.video.user_id = from_id; newMessage.media.video.size = file.size; newMessage.media.video.id = file.id; newMessage.media.video.access_hash = file.access_hash; diff --git a/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java b/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java index 230497db8..74ea3b93b 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java +++ b/TMessagesProj/src/main/java/org/telegram/android/SendMessagesHelper.java @@ -540,14 +540,9 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter if (sendToUser == null) { return; } - if (sendToUser.access_hash != 0) { - sendToPeer = new TLRPC.TL_inputPeerForeign(); - sendToPeer.user_id = sendToUser.id; - sendToPeer.access_hash = sendToUser.access_hash; - } else { - sendToPeer = new TLRPC.TL_inputPeerContact(); - sendToPeer.user_id = sendToUser.id; - } + sendToPeer = new TLRPC.TL_inputPeerUser(); + sendToPeer.user_id = sendToUser.id; + sendToPeer.access_hash = sendToUser.access_hash; } ArrayList objArr = new ArrayList<>(); @@ -575,6 +570,10 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter newMsg.message = msgObj.messageOwner.message; newMsg.fwd_msg_id = msgObj.getId(); newMsg.attachPath = msgObj.messageOwner.attachPath; + newMsg.entities = msgObj.messageOwner.entities; + if (!newMsg.entities.isEmpty()) { + newMsg.flags |= TLRPC.MESSAGE_FLAG_HAS_ENTITIES; + } if (newMsg.attachPath == null) { newMsg.attachPath = ""; } @@ -965,14 +964,9 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter if ((sendToUser.flags & TLRPC.USER_FLAG_BOT) != 0) { newMsg.flags &= ~TLRPC.MESSAGE_FLAG_UNREAD; } - if (sendToUser.access_hash != 0) { - sendToPeer = new TLRPC.TL_inputPeerForeign(); - sendToPeer.user_id = sendToUser.id; - sendToPeer.access_hash = sendToUser.access_hash; - } else { - sendToPeer = new TLRPC.TL_inputPeerContact(); - sendToPeer.user_id = sendToUser.id; - } + sendToPeer = new TLRPC.TL_inputPeerUser(); + sendToPeer.user_id = sendToUser.id; + sendToPeer.access_hash = sendToUser.access_hash; } } } else { @@ -1563,6 +1557,10 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter newMsgObj.local_id = newMsgObj.id = res.id; newMsgObj.date = res.date; newMsgObj.media = res.media; + newMsgObj.entities = res.entities; + if (!newMsgObj.entities.isEmpty()) { + newMsgObj.flags |= TLRPC.MESSAGE_FLAG_HAS_ENTITIES; + } if (res instanceof TLRPC.TL_messages_sentMessage) { MessagesController.getInstance().processNewDifferenceParams(-1, res.pts, res.date, res.pts_count); } else if (res instanceof TLRPC.TL_messages_sentMessageLink) { @@ -1849,10 +1847,8 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter } else { UserConfig.saveConfig(false); TLRPC.TL_photo photo = new TLRPC.TL_photo(); - photo.user_id = UserConfig.getClientUserId(); photo.date = ConnectionsManager.getInstance().getCurrentTime(); photo.sizes = sizes; - photo.geo = new TLRPC.TL_geoPointEmpty(); return photo; } } @@ -2218,9 +2214,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter } if (photo == null) { photo = new TLRPC.TL_photo(); - photo.user_id = UserConfig.getClientUserId(); photo.date = ConnectionsManager.getInstance().getCurrentTime(); - photo.geo = new TLRPC.TL_geoPointEmpty(); TLRPC.TL_photoSize photoSize = new TLRPC.TL_photoSize(); photoSize.w = searchImage.width; photoSize.h = searchImage.height; diff --git a/TMessagesProj/src/main/java/org/telegram/android/query/MessagesSearchQuery.java b/TMessagesProj/src/main/java/org/telegram/android/query/MessagesSearchQuery.java index c1f9f39c7..c662c27ea 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/query/MessagesSearchQuery.java +++ b/TMessagesProj/src/main/java/org/telegram/android/query/MessagesSearchQuery.java @@ -83,12 +83,8 @@ public class MessagesSearchQuery { if (user == null) { return; } - if (user.access_hash != 0) { - req.peer = new TLRPC.TL_inputPeerForeign(); - req.peer.access_hash = user.access_hash; - } else { - req.peer = new TLRPC.TL_inputPeerContact(); - } + req.peer = new TLRPC.TL_inputPeerUser(); + req.peer.access_hash = user.access_hash; req.peer.user_id = lower_part; } req.q = query; diff --git a/TMessagesProj/src/main/java/org/telegram/android/query/SharedMediaQuery.java b/TMessagesProj/src/main/java/org/telegram/android/query/SharedMediaQuery.java index f7275f504..a95bdefc8 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/query/SharedMediaQuery.java +++ b/TMessagesProj/src/main/java/org/telegram/android/query/SharedMediaQuery.java @@ -61,12 +61,8 @@ public class SharedMediaQuery { if (user == null) { return; } - if (user.access_hash != 0) { - req.peer = new TLRPC.TL_inputPeerForeign(); - req.peer.access_hash = user.access_hash; - } else { - req.peer = new TLRPC.TL_inputPeerContact(); - } + req.peer = new TLRPC.TL_inputPeerUser(); + req.peer.access_hash = user.access_hash; req.peer.user_id = lower_part; } long reqId = ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { @@ -109,12 +105,8 @@ public class SharedMediaQuery { if (user == null) { return; } - if (user.access_hash != 0) { - req.peer = new TLRPC.TL_inputPeerForeign(); - req.peer.access_hash = user.access_hash; - } else { - req.peer = new TLRPC.TL_inputPeerContact(); - } + req.peer = new TLRPC.TL_inputPeerUser(); + req.peer.access_hash = user.access_hash; req.peer.user_id = lower_part; } long reqId = ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() { @@ -158,8 +150,13 @@ public class SharedMediaQuery { } } else if (message.media instanceof TLRPC.TL_messageMediaAudio) { return MEDIA_AUDIO; - } else if (message.media instanceof TLRPC.TL_messageMediaWebPage) { - return MEDIA_URL; + } else if (!message.entities.isEmpty()) { + for (int a = 0; a < message.entities.size(); a++) { + TLRPC.MessageEntity entity = message.entities.get(a); + if (entity instanceof TLRPC.TL_messageEntityUrl || entity instanceof TLRPC.TL_messageEntityTextUrl || entity instanceof TLRPC.TL_messageEntityEmail) { + return MEDIA_URL; + } + } } return -1; } @@ -170,9 +167,15 @@ public class SharedMediaQuery { } else if (message.media instanceof TLRPC.TL_messageMediaPhoto || message.media instanceof TLRPC.TL_messageMediaVideo || message.media instanceof TLRPC.TL_messageMediaDocument || - message.media instanceof TLRPC.TL_messageMediaAudio/* || - message.media instanceof TLRPC.TL_messageMediaWebPage && !(message.media.webpage instanceof TLRPC.TL_webPageEmpty)*/) { + message.media instanceof TLRPC.TL_messageMediaAudio) { return true; + } else if (!message.entities.isEmpty()) { + for (int a = 0; a < message.entities.size(); a++) { + TLRPC.MessageEntity entity = message.entities.get(a); + if (entity instanceof TLRPC.TL_messageEntityUrl || entity instanceof TLRPC.TL_messageEntityTextUrl || entity instanceof TLRPC.TL_messageEntityEmail) { + return true; + } + } } return false; } diff --git a/TMessagesProj/src/main/java/org/telegram/android/query/StickersQuery.java b/TMessagesProj/src/main/java/org/telegram/android/query/StickersQuery.java index 29ceb0438..2857d547d 100644 --- a/TMessagesProj/src/main/java/org/telegram/android/query/StickersQuery.java +++ b/TMessagesProj/src/main/java/org/telegram/android/query/StickersQuery.java @@ -271,66 +271,70 @@ public class StickersQuery { } } if (res != null) { - final ArrayList stickerSetsNew = new ArrayList<>(); - final HashMap stickerSetsByIdNew = new HashMap<>(); - final HashMap stickersByEmojiNew = new HashMap<>(); - final HashMap stickersByIdNew = new HashMap<>(); - final HashMap> allStickersNew = new HashMap<>(); + try { + final ArrayList stickerSetsNew = new ArrayList<>(); + final HashMap stickerSetsByIdNew = new HashMap<>(); + final HashMap stickersByEmojiNew = new HashMap<>(); + final HashMap stickersByIdNew = new HashMap<>(); + final HashMap> allStickersNew = new HashMap<>(); - for (int a = 0; a < res.size(); a++) { - TLRPC.TL_messages_stickerSet stickerSet = res.get(a); - if (stickerSet == null) { - continue; - } - stickerSetsNew.add(stickerSet); - stickerSetsByIdNew.put(stickerSet.set.id, stickerSet); - - for (int b = 0; b < stickerSet.documents.size(); b++) { - TLRPC.Document document = stickerSet.documents.get(b); - if (document == null || document instanceof TLRPC.TL_documentEmpty) { + for (int a = 0; a < res.size(); a++) { + TLRPC.TL_messages_stickerSet stickerSet = res.get(a); + if (stickerSet == null) { continue; } - stickersByIdNew.put(document.id, document); - } - if ((stickerSet.set.flags & 2) == 0) { - for (int b = 0; b < stickerSet.packs.size(); b++) { - TLRPC.TL_stickerPack stickerPack = stickerSet.packs.get(b); - if (stickerPack == null || stickerPack.emoticon == null) { + stickerSetsNew.add(stickerSet); + stickerSetsByIdNew.put(stickerSet.set.id, stickerSet); + + for (int b = 0; b < stickerSet.documents.size(); b++) { + TLRPC.Document document = stickerSet.documents.get(b); + if (document == null || document instanceof TLRPC.TL_documentEmpty) { continue; } - stickerPack.emoticon = stickerPack.emoticon.replace("\uFE0F", ""); - ArrayList arrayList = allStickersNew.get(stickerPack.emoticon); - if (arrayList == null) { - arrayList = new ArrayList<>(); - allStickersNew.put(stickerPack.emoticon, arrayList); - } - for (int c = 0; c < stickerPack.documents.size(); c++) { - Long id = stickerPack.documents.get(c); - if (!stickersByEmojiNew.containsKey(id)) { - stickersByEmojiNew.put(id, stickerPack.emoticon); + stickersByIdNew.put(document.id, document); + } + if ((stickerSet.set.flags & 2) == 0) { + for (int b = 0; b < stickerSet.packs.size(); b++) { + TLRPC.TL_stickerPack stickerPack = stickerSet.packs.get(b); + if (stickerPack == null || stickerPack.emoticon == null) { + continue; + } + stickerPack.emoticon = stickerPack.emoticon.replace("\uFE0F", ""); + ArrayList arrayList = allStickersNew.get(stickerPack.emoticon); + if (arrayList == null) { + arrayList = new ArrayList<>(); + allStickersNew.put(stickerPack.emoticon, arrayList); + } + for (int c = 0; c < stickerPack.documents.size(); c++) { + Long id = stickerPack.documents.get(c); + if (!stickersByEmojiNew.containsKey(id)) { + stickersByEmojiNew.put(id, stickerPack.emoticon); + } + arrayList.add(stickersByIdNew.get(id)); } - arrayList.add(stickersByIdNew.get(id)); } } } - } - if (!cache) { - putStickersToCache(stickerSetsNew, date, hash); - } - AndroidUtilities.runOnUIThread(new Runnable() { - @Override - public void run() { - stickersById = stickersByIdNew; - stickerSetsById = stickerSetsByIdNew; - stickerSets = stickerSetsNew; - allStickers = allStickersNew; - stickersByEmoji = stickersByEmojiNew; - loadHash = hash; - loadDate = date; - NotificationCenter.getInstance().postNotificationName(NotificationCenter.stickersDidLoaded); + if (!cache) { + putStickersToCache(stickerSetsNew, date, hash); } - }); + AndroidUtilities.runOnUIThread(new Runnable() { + @Override + public void run() { + stickersById = stickersByIdNew; + stickerSetsById = stickerSetsByIdNew; + stickerSets = stickerSetsNew; + allStickers = allStickersNew; + stickersByEmoji = stickersByEmojiNew; + loadHash = hash; + loadDate = date; + NotificationCenter.getInstance().postNotificationName(NotificationCenter.stickersDidLoaded); + } + }); + } catch (Throwable e) { + FileLog.e("tmessages", e); + } } } }); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java b/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java index 58c244048..3b5b46a4c 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/BuildVars.java @@ -1,16 +1,16 @@ /* - * This is the source code of Telegram for Android v. 1.3.x. + * This is the source code of Telegram for Android v. 2.x.x. * It is licensed under GNU GPL v. 2 or later. * You should have received a copy of the license in this archive (see LICENSE). * - * Copyright Nikolai Kudashov, 2013-2014. + * Copyright Nikolai Kudashov, 2013-2015. */ package org.telegram.messenger; public class BuildVars { public static boolean DEBUG_VERSION = false; - public static int BUILD_VERSION = 586; + public static int BUILD_VERSION = 592; public static int APP_ID = 0; //obtain your own APP_ID at https://core.telegram.org/api/obtaining_api_id public static String APP_HASH = ""; //obtain your own APP_HASH at https://core.telegram.org/api/obtaining_api_id public static String HOCKEY_APP_HASH = "your-hockeyapp-api-key-here"; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/TLClassStore.java b/TMessagesProj/src/main/java/org/telegram/messenger/TLClassStore.java index 1c855859e..7174476a0 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/TLClassStore.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/TLClassStore.java @@ -78,11 +78,13 @@ public class TLClassStore { classStore.put(TLRPC.TL_video_old2.constructor, TLRPC.TL_video_old2.class); classStore.put(TLRPC.TL_video_old.constructor, TLRPC.TL_video_old.class); classStore.put(TLRPC.TL_videoEncrypted.constructor, TLRPC.TL_videoEncrypted.class); + classStore.put(TLRPC.TL_video_old3.constructor, TLRPC.TL_video_old3.class); classStore.put(TLRPC.TL_audio.constructor, TLRPC.TL_audio.class); classStore.put(TLRPC.TL_audioEncrypted.constructor, TLRPC.TL_audioEncrypted.class); classStore.put(TLRPC.TL_audioEmpty.constructor, TLRPC.TL_audioEmpty.class); classStore.put(TLRPC.TL_audio_old.constructor, TLRPC.TL_audio_old.class); + classStore.put(TLRPC.TL_audio_old2.constructor, TLRPC.TL_audio_old2.class); classStore.put(TLRPC.TL_document.constructor, TLRPC.TL_document.class); classStore.put(TLRPC.TL_documentEmpty.constructor, TLRPC.TL_documentEmpty.class); @@ -96,6 +98,7 @@ public class TLClassStore { classStore.put(TLRPC.TL_photoSizeEmpty.constructor, TLRPC.TL_photoSizeEmpty.class); classStore.put(TLRPC.TL_photoCachedSize.constructor, TLRPC.TL_photoCachedSize.class); classStore.put(TLRPC.TL_photo_old.constructor, TLRPC.TL_photo_old.class); + classStore.put(TLRPC.TL_photo_old2.constructor, TLRPC.TL_photo_old2.class); } static TLClassStore store = null; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/TLRPC.java b/TMessagesProj/src/main/java/org/telegram/messenger/TLRPC.java index c660c1dd1..3a69447df 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/TLRPC.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/TLRPC.java @@ -38,8 +38,10 @@ public class TLRPC { public static final int MESSAGE_FLAG_REPLY = 0x00000008; public static final int MESSAGE_FLAG_MENTION = 0x00000010; public static final int MESSAGE_FLAG_CONTENT_UNREAD = 0x00000020; + public static final int MESSAGE_FLAG_HAS_MARKUP = 0x00000040; + public static final int MESSAGE_FLAG_HAS_ENTITIES = 0x00000080; - public static final int LAYER = 32; + public static final int LAYER = 34; public static class TL_inputEncryptedChat extends TLObject { public static int constructor = 0xf141b5e1; @@ -5407,6 +5409,7 @@ public class TLRPC { public int id; public int date; public MessageMedia media; + public ArrayList entities = new ArrayList<>(); public int pts; public int pts_count; public ArrayList links = new ArrayList<>(); @@ -5415,7 +5418,7 @@ public class TLRPC { public static messages_SentMessage TLdeserialize(AbsSerializedData stream, int constructor, boolean exception) { messages_SentMessage result = null; switch(constructor) { - case 0x4c3d47f3: + case 0x8a99d8e0: result = new TL_messages_sentMessage(); break; case 0x35a1a663: @@ -5433,13 +5436,28 @@ public class TLRPC { } public static class TL_messages_sentMessage extends messages_SentMessage { - public static int constructor = 0x4c3d47f3; + public static int constructor = 0x8a99d8e0; public void readParams(AbsSerializedData stream, boolean exception) { id = stream.readInt32(exception); date = stream.readInt32(exception); media = MessageMedia.TLdeserialize(stream, stream.readInt32(exception), exception); + int magic = stream.readInt32(exception); + if (magic != 0x1cb5c415) { + if (exception) { + throw new RuntimeException(String.format("wrong Vector magic, got %x", magic)); + } + return; + } + int count = stream.readInt32(exception); + for (int a = 0; a < count; a++) { + MessageEntity object = MessageEntity.TLdeserialize(stream, stream.readInt32(exception), exception); + if (object == null) { + return; + } + entities.add(object); + } pts = stream.readInt32(exception); pts_count = stream.readInt32(exception); } @@ -5449,6 +5467,12 @@ public class TLRPC { stream.writeInt32(id); stream.writeInt32(date); media.serializeToStream(stream); + stream.writeInt32(0x1cb5c415); + int count = entities.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + entities.get(a).serializeToStream(stream); + } stream.writeInt32(pts); stream.writeInt32(pts_count); } @@ -5601,14 +5625,14 @@ public class TLRPC { public static class InputPeer extends TLObject { public int user_id; - public int chat_id; public long access_hash; + public int chat_id; public static InputPeer TLdeserialize(AbsSerializedData stream, int constructor, boolean exception) { InputPeer result = null; switch(constructor) { - case 0x1023dbe8: - result = new TL_inputPeerContact(); + case 0x7b8e7de6: + result = new TL_inputPeerUser(); break; case 0x179be863: result = new TL_inputPeerChat(); @@ -5619,9 +5643,6 @@ public class TLRPC { case 0x7da07ec9: result = new TL_inputPeerSelf(); break; - case 0x9b447325: - result = new TL_inputPeerForeign(); - break; } if (result == null && exception) { throw new RuntimeException(String.format("can't parse magic %x in InputPeer", constructor)); @@ -5633,17 +5654,19 @@ public class TLRPC { } } - public static class TL_inputPeerContact extends InputPeer { - public static int constructor = 0x1023dbe8; + public static class TL_inputPeerUser extends InputPeer { + public static int constructor = 0x7b8e7de6; public void readParams(AbsSerializedData stream, boolean exception) { user_id = stream.readInt32(exception); + access_hash = stream.readInt64(exception); } public void serializeToStream(AbsSerializedData stream) { stream.writeInt32(constructor); stream.writeInt32(user_id); + stream.writeInt64(access_hash); } } @@ -5679,22 +5702,6 @@ public class TLRPC { } } - public static class TL_inputPeerForeign extends InputPeer { - public static int constructor = 0x9b447325; - - - public void readParams(AbsSerializedData stream, boolean exception) { - user_id = stream.readInt32(exception); - access_hash = stream.readInt64(exception); - } - - public void serializeToStream(AbsSerializedData stream) { - stream.writeInt32(constructor); - stream.writeInt32(user_id); - stream.writeInt64(access_hash); - } - } - public static class TL_msg_copy extends TLObject { public static int constructor = 0xe06046b2; @@ -6542,17 +6549,14 @@ public class TLRPC { public static InputUser TLdeserialize(AbsSerializedData stream, int constructor, boolean exception) { InputUser result = null; switch(constructor) { - case 0xf7c1b13f: - result = new TL_inputUserSelf(); - break; - case 0x655e74ff: - result = new TL_inputUserForeign(); - break; case 0xb98886cf: result = new TL_inputUserEmpty(); break; - case 0x86e94f65: - result = new TL_inputUserContact(); + case 0xf7c1b13f: + result = new TL_inputUserSelf(); + break; + case 0xd8292816: + result = new TL_inputUser(); break; } if (result == null && exception) { @@ -6565,6 +6569,15 @@ public class TLRPC { } } + public static class TL_inputUserEmpty extends InputUser { + public static int constructor = 0xb98886cf; + + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + } + } + public static class TL_inputUserSelf extends InputUser { public static int constructor = 0xf7c1b13f; @@ -6574,8 +6587,8 @@ public class TLRPC { } } - public static class TL_inputUserForeign extends InputUser { - public static int constructor = 0x655e74ff; + public static class TL_inputUser extends InputUser { + public static int constructor = 0xd8292816; public void readParams(AbsSerializedData stream, boolean exception) { @@ -6590,29 +6603,6 @@ public class TLRPC { } } - public static class TL_inputUserEmpty extends InputUser { - public static int constructor = 0xb98886cf; - - - public void serializeToStream(AbsSerializedData stream) { - stream.writeInt32(constructor); - } - } - - public static class TL_inputUserContact extends InputUser { - public static int constructor = 0x86e94f65; - - - public void readParams(AbsSerializedData stream, boolean exception) { - user_id = stream.readInt32(exception); - } - - public void serializeToStream(AbsSerializedData stream) { - stream.writeInt32(constructor); - stream.writeInt32(user_id); - } - } - public static class TL_chatParticipant extends TLObject { public static int constructor = 0xc8d7493e; @@ -7080,9 +7070,12 @@ public class TLRPC { case 0x2331b22d: result = new TL_photoEmpty(); break; - case 0xc3838076: + case 0xcded42fe: result = new TL_photo(); break; + case 0xc3838076: + result = new TL_photo_old2(); + break; case 0x22b56751: result = new TL_photo_old(); break; @@ -7112,6 +7105,45 @@ public class TLRPC { } public static class TL_photo extends Photo { + public static int constructor = 0xcded42fe; + + + public void readParams(AbsSerializedData stream, boolean exception) { + id = stream.readInt64(exception); + access_hash = stream.readInt64(exception); + date = stream.readInt32(exception); + int magic = stream.readInt32(exception); + if (magic != 0x1cb5c415) { + if (exception) { + throw new RuntimeException(String.format("wrong Vector magic, got %x", magic)); + } + return; + } + int count = stream.readInt32(exception); + for (int a = 0; a < count; a++) { + PhotoSize object = PhotoSize.TLdeserialize(stream, stream.readInt32(exception), exception); + if (object == null) { + return; + } + sizes.add(object); + } + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt64(id); + stream.writeInt64(access_hash); + stream.writeInt32(date); + stream.writeInt32(0x1cb5c415); + int count = sizes.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + sizes.get(a).serializeToStream(stream); + } + } + } + + public static class TL_photo_old2 extends TL_photo { public static int constructor = 0xc3838076; @@ -9383,9 +9415,12 @@ public class TLRPC { public static Video TLdeserialize(AbsSerializedData stream, int constructor, boolean exception) { Video result = null; switch(constructor) { - case 0xee9f4a4d: + case 0xf72887d3: result = new TL_video(); break; + case 0xee9f4a4d: + result = new TL_video_old3(); + break; case 0x55555553: result = new TL_videoEncrypted(); break; @@ -9410,6 +9445,38 @@ public class TLRPC { } public static class TL_video extends Video { + public static int constructor = 0xf72887d3; + + + public void readParams(AbsSerializedData stream, boolean exception) { + id = stream.readInt64(exception); + access_hash = stream.readInt64(exception); + date = stream.readInt32(exception); + duration = stream.readInt32(exception); + mime_type = stream.readString(exception); + size = stream.readInt32(exception); + thumb = PhotoSize.TLdeserialize(stream, stream.readInt32(exception), exception); + dc_id = stream.readInt32(exception); + w = stream.readInt32(exception); + h = stream.readInt32(exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt64(id); + stream.writeInt64(access_hash); + stream.writeInt32(date); + stream.writeInt32(duration); + stream.writeString(mime_type); + stream.writeInt32(size); + thumb.serializeToStream(stream); + stream.writeInt32(dc_id); + stream.writeInt32(w); + stream.writeInt32(h); + } + } + + public static class TL_video_old3 extends TL_video { public static int constructor = 0xee9f4a4d; @@ -9818,6 +9885,52 @@ public class TLRPC { } } + public static class help_AppChangelog extends TLObject { + public String text; + + public static help_AppChangelog TLdeserialize(AbsSerializedData stream, int constructor, boolean exception) { + help_AppChangelog result = null; + switch(constructor) { + case 0xaf7e0394: + result = new TL_help_appChangelogEmpty(); + break; + case 0x4668e6bd: + result = new TL_help_appChangelog(); + break; + } + if (result == null && exception) { + throw new RuntimeException(String.format("can't parse magic %x in help_AppChangelog", constructor)); + } + if (result != null) { + result.readParams(stream, exception); + } + return result; + } + } + + public static class TL_help_appChangelogEmpty extends help_AppChangelog { + public static int constructor = 0xaf7e0394; + + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + } + } + + public static class TL_help_appChangelog extends help_AppChangelog { + public static int constructor = 0x4668e6bd; + + + public void readParams(AbsSerializedData stream, boolean exception) { + text = stream.readString(exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeString(text); + } + } + public static class TL_keyboardButton extends TLObject { public static int constructor = 0xa2fa4880; @@ -10349,6 +10462,7 @@ public class TLRPC { public int fwd_from_id; public int fwd_date; public int reply_to_msg_id; + public ArrayList entities = new ArrayList<>(); public ArrayList updates = new ArrayList<>(); public ArrayList users = new ArrayList<>(); public ArrayList chats = new ArrayList<>(); @@ -10360,13 +10474,13 @@ public class TLRPC { public static Updates TLdeserialize(AbsSerializedData stream, int constructor, boolean exception) { Updates result = null; switch(constructor) { - case 0x52238b3c: + case 0xf9409b3d: result = new TL_updateShortChatMessage(); break; case 0x74ae4240: result = new TL_updates(); break; - case 0xed5c2127: + case 0x3f32d858: result = new TL_updateShortMessage(); break; case 0x78d4dec1: @@ -10390,7 +10504,7 @@ public class TLRPC { } public static class TL_updateShortChatMessage extends Updates { - public static int constructor = 0x52238b3c; + public static int constructor = 0xf9409b3d; public void readParams(AbsSerializedData stream, boolean exception) { @@ -10411,6 +10525,23 @@ public class TLRPC { if ((flags & 8) != 0) { reply_to_msg_id = stream.readInt32(exception); } + if ((flags & 128) != 0) { + int magic = stream.readInt32(exception); + if (magic != 0x1cb5c415) { + if (exception) { + throw new RuntimeException(String.format("wrong Vector magic, got %x", magic)); + } + return; + } + int count = stream.readInt32(exception); + for (int a = 0; a < count; a++) { + MessageEntity object = MessageEntity.TLdeserialize(stream, stream.readInt32(exception), exception); + if (object == null) { + return; + } + entities.add(object); + } + } } public void serializeToStream(AbsSerializedData stream) { @@ -10432,6 +10563,14 @@ public class TLRPC { if ((flags & 8) != 0) { stream.writeInt32(reply_to_msg_id); } + if ((flags & 128) != 0) { + stream.writeInt32(0x1cb5c415); + int count = entities.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + entities.get(a).serializeToStream(stream); + } + } } } @@ -10515,7 +10654,7 @@ public class TLRPC { } public static class TL_updateShortMessage extends Updates { - public static int constructor = 0xed5c2127; + public static int constructor = 0x3f32d858; public void readParams(AbsSerializedData stream, boolean exception) { @@ -10535,6 +10674,23 @@ public class TLRPC { if ((flags & 8) != 0) { reply_to_msg_id = stream.readInt32(exception); } + if ((flags & 128) != 0) { + int magic = stream.readInt32(exception); + if (magic != 0x1cb5c415) { + if (exception) { + throw new RuntimeException(String.format("wrong Vector magic, got %x", magic)); + } + return; + } + int count = stream.readInt32(exception); + for (int a = 0; a < count; a++) { + MessageEntity object = MessageEntity.TLdeserialize(stream, stream.readInt32(exception), exception); + if (object == null) { + return; + } + entities.add(object); + } + } } public void serializeToStream(AbsSerializedData stream) { @@ -10555,6 +10711,14 @@ public class TLRPC { if ((flags & 8) != 0) { stream.writeInt32(reply_to_msg_id); } + if ((flags & 128) != 0) { + stream.writeInt32(0x1cb5c415); + int count = entities.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + entities.get(a).serializeToStream(stream); + } + } } } @@ -11217,17 +11381,20 @@ public class TLRPC { public static Audio TLdeserialize(AbsSerializedData stream, int constructor, boolean exception) { Audio result = null; switch(constructor) { + case 0x586988d8: + result = new TL_audioEmpty(); + break; case 0x427425e7: result = new TL_audio_old(); break; - case 0xc7ac6496: + case 0xf9e35055: result = new TL_audio(); break; case 0x555555F6: result = new TL_audioEncrypted(); break; - case 0x586988d8: - result = new TL_audioEmpty(); + case 0xc7ac6496: + result = new TL_audio_old2(); break; } if (result == null && exception) { @@ -11266,7 +11433,7 @@ public class TLRPC { } } - public static class TL_audio extends Audio { + public static class TL_audio_old2 extends TL_audio { public static int constructor = 0xc7ac6496; @@ -11294,6 +11461,32 @@ public class TLRPC { } } + public static class TL_audio extends Audio { + public static int constructor = 0xf9e35055; + + + public void readParams(AbsSerializedData stream, boolean exception) { + id = stream.readInt64(exception); + access_hash = stream.readInt64(exception); + date = stream.readInt32(exception); + duration = stream.readInt32(exception); + mime_type = stream.readString(exception); + size = stream.readInt32(exception); + dc_id = stream.readInt32(exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt64(id); + stream.writeInt64(access_hash); + stream.writeInt32(date); + stream.writeInt32(duration); + stream.writeString(mime_type); + stream.writeInt32(size); + stream.writeInt32(dc_id); + } + } + public static class TL_audioEncrypted extends TL_audio { public static int constructor = 0x555555F6; @@ -12950,6 +13143,239 @@ public class TLRPC { } } + public static class MessageEntity extends TLObject { + public int offset; + public int length; + public String language; + public String url; + + public static MessageEntity TLdeserialize(AbsSerializedData stream, int constructor, boolean exception) { + MessageEntity result = null; + switch(constructor) { + case 0x6ed02538: + result = new TL_messageEntityUrl(); + break; + case 0xbd610bc9: + result = new TL_messageEntityBold(); + break; + case 0x826f8b60: + result = new TL_messageEntityItalic(); + break; + case 0x64e475c2: + result = new TL_messageEntityEmail(); + break; + case 0x73924be0: + result = new TL_messageEntityPre(); + break; + case 0x76a6d327: + result = new TL_messageEntityTextUrl(); + break; + case 0xbb92ba95: + result = new TL_messageEntityUnknown(); + break; + case 0x6f635b0d: + result = new TL_messageEntityHashtag(); + break; + case 0x6cef8ac7: + result = new TL_messageEntityBotCommand(); + break; + case 0x28a20571: + result = new TL_messageEntityCode(); + break; + case 0xfa04579d: + result = new TL_messageEntityMention(); + break; + } + if (result == null && exception) { + throw new RuntimeException(String.format("can't parse magic %x in MessageEntity", constructor)); + } + if (result != null) { + result.readParams(stream, exception); + } + return result; + } + } + + public static class TL_messageEntityUrl extends MessageEntity { + public static int constructor = 0x6ed02538; + + + public void readParams(AbsSerializedData stream, boolean exception) { + offset = stream.readInt32(exception); + length = stream.readInt32(exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(offset); + stream.writeInt32(length); + } + } + + public static class TL_messageEntityBold extends MessageEntity { + public static int constructor = 0xbd610bc9; + + + public void readParams(AbsSerializedData stream, boolean exception) { + offset = stream.readInt32(exception); + length = stream.readInt32(exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(offset); + stream.writeInt32(length); + } + } + + public static class TL_messageEntityItalic extends MessageEntity { + public static int constructor = 0x826f8b60; + + + public void readParams(AbsSerializedData stream, boolean exception) { + offset = stream.readInt32(exception); + length = stream.readInt32(exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(offset); + stream.writeInt32(length); + } + } + + public static class TL_messageEntityEmail extends MessageEntity { + public static int constructor = 0x64e475c2; + + + public void readParams(AbsSerializedData stream, boolean exception) { + offset = stream.readInt32(exception); + length = stream.readInt32(exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(offset); + stream.writeInt32(length); + } + } + + public static class TL_messageEntityPre extends MessageEntity { + public static int constructor = 0x73924be0; + + + public void readParams(AbsSerializedData stream, boolean exception) { + offset = stream.readInt32(exception); + length = stream.readInt32(exception); + language = stream.readString(exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(offset); + stream.writeInt32(length); + stream.writeString(language); + } + } + + public static class TL_messageEntityTextUrl extends MessageEntity { + public static int constructor = 0x76a6d327; + + + public void readParams(AbsSerializedData stream, boolean exception) { + offset = stream.readInt32(exception); + length = stream.readInt32(exception); + url = stream.readString(exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(offset); + stream.writeInt32(length); + stream.writeString(url); + } + } + + public static class TL_messageEntityUnknown extends MessageEntity { + public static int constructor = 0xbb92ba95; + + + public void readParams(AbsSerializedData stream, boolean exception) { + offset = stream.readInt32(exception); + length = stream.readInt32(exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(offset); + stream.writeInt32(length); + } + } + + public static class TL_messageEntityHashtag extends MessageEntity { + public static int constructor = 0x6f635b0d; + + + public void readParams(AbsSerializedData stream, boolean exception) { + offset = stream.readInt32(exception); + length = stream.readInt32(exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(offset); + stream.writeInt32(length); + } + } + + public static class TL_messageEntityBotCommand extends MessageEntity { + public static int constructor = 0x6cef8ac7; + + + public void readParams(AbsSerializedData stream, boolean exception) { + offset = stream.readInt32(exception); + length = stream.readInt32(exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(offset); + stream.writeInt32(length); + } + } + + public static class TL_messageEntityCode extends MessageEntity { + public static int constructor = 0x28a20571; + + + public void readParams(AbsSerializedData stream, boolean exception) { + offset = stream.readInt32(exception); + length = stream.readInt32(exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(offset); + stream.writeInt32(length); + } + } + + public static class TL_messageEntityMention extends MessageEntity { + public static int constructor = 0xfa04579d; + + + public void readParams(AbsSerializedData stream, boolean exception) { + offset = stream.readInt32(exception); + length = stream.readInt32(exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(offset); + stream.writeInt32(length); + } + } + public static class TL_destroy_sessions_res extends TLObject { public static int constructor = 0xfb95abcd; @@ -13826,7 +14252,7 @@ public class TLRPC { } public static class TL_messages_sendMessage extends TLObject { - public static int constructor = 0xfc55e6b5; + public static int constructor = 0xdf12390; public int flags; public InputPeer peer; @@ -13834,6 +14260,7 @@ public class TLRPC { public String message; public long random_id; public ReplyMarkup reply_markup; + public ArrayList entities = new ArrayList<>(); public TLObject deserializeResponse(AbsSerializedData stream, int constructor, boolean exception) { return messages_SentMessage.TLdeserialize(stream, constructor, exception); @@ -13851,6 +14278,14 @@ public class TLRPC { if ((flags & 4) != 0) { reply_markup.serializeToStream(stream); } + if ((flags & 8) != 0) { + stream.writeInt32(0x1cb5c415); + int count = entities.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + entities.get(a).serializeToStream(stream); + } + } } } @@ -14236,11 +14671,11 @@ public class TLRPC { } public static class TL_photos_getUserPhotos extends TLObject { - public static int constructor = 0xb7ee553c; + public static int constructor = 0x91cd32a8; public InputUser user_id; public int offset; - public int max_id; + public long max_id; public int limit; public TLObject deserializeResponse(AbsSerializedData stream, int constructor, boolean exception) { @@ -14251,7 +14686,7 @@ public class TLRPC { stream.writeInt32(constructor); user_id.serializeToStream(stream); stream.writeInt32(offset); - stream.writeInt32(max_id); + stream.writeInt64(max_id); stream.writeInt32(limit); } } @@ -15175,6 +15610,27 @@ public class TLRPC { } } + public static class TL_help_getAppChangelog extends TLObject { + public static int constructor = 0x5bab7fb2; + + public String device_model; + public String system_version; + public String app_version; + public String lang_code; + + public TLObject deserializeResponse(AbsSerializedData stream, int constructor, boolean exception) { + return help_AppChangelog.TLdeserialize(stream, constructor, exception); + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeString(device_model); + stream.writeString(system_version); + stream.writeString(app_version); + stream.writeString(lang_code); + } + } + //manually created //EncryptedChat start @@ -15252,6 +15708,7 @@ public class TLRPC { public String message; public MessageMedia media; public int flags; + public ArrayList entities = new ArrayList<>(); public ReplyMarkup reply_markup; public int send_state = 0; //custom public int fwd_msg_id = 0; //custom @@ -15276,11 +15733,14 @@ public class TLRPC { result = new TL_message_old3(); break; case 0xc3060325: - result = new TL_message(); + result = new TL_message_old4(); break; case 0x83e5de54: result = new TL_messageEmpty(); break; + case 0xf07814c8: + result = new TL_message(); + break; case 0xa367e716: result = new TL_messageForwarded_old2(); //custom break; @@ -15352,6 +15812,91 @@ public class TLRPC { } public static class TL_message extends Message { + public static int constructor = 0xf07814c8; + + + public void readParams(AbsSerializedData stream, boolean exception) { + flags = stream.readInt32(exception); + id = stream.readInt32(exception); + from_id = stream.readInt32(exception); + to_id = Peer.TLdeserialize(stream, stream.readInt32(exception), exception); + if ((flags & 4) != 0) { + fwd_from_id = stream.readInt32(exception); + } + if ((flags & 4) != 0) { + fwd_date = stream.readInt32(exception); + } + if ((flags & 8) != 0) { + reply_to_msg_id = stream.readInt32(exception); + } + date = stream.readInt32(exception); + message = stream.readString(exception); + media = MessageMedia.TLdeserialize(stream, stream.readInt32(exception), exception); + if ((flags & 64) != 0) { + reply_markup = ReplyMarkup.TLdeserialize(stream, stream.readInt32(exception), exception); + } + if ((flags & 128) != 0) { + int magic = stream.readInt32(exception); + if (magic != 0x1cb5c415) { + if (exception) { + throw new RuntimeException(String.format("wrong Vector magic, got %x", magic)); + } + return; + } + int count = stream.readInt32(exception); + for (int a = 0; a < count; a++) { + MessageEntity object = MessageEntity.TLdeserialize(stream, stream.readInt32(exception), exception); + if (object == null) { + return; + } + entities.add(object); + } + } + if (id < 0 || (media != null && !(media instanceof TL_messageMediaEmpty) && !(media instanceof TL_messageMediaWebPage) && message != null && message.length() != 0 && message.startsWith("-1"))) { + attachPath = stream.readString(exception); + } + if ((flags & MESSAGE_FLAG_FWD) != 0 && id < 0) { + fwd_msg_id = stream.readInt32(exception); + } + } + + public void serializeToStream(AbsSerializedData stream) { + stream.writeInt32(constructor); + stream.writeInt32(flags); + stream.writeInt32(id); + stream.writeInt32(from_id); + to_id.serializeToStream(stream); + if ((flags & 4) != 0) { + stream.writeInt32(fwd_from_id); + } + if ((flags & 4) != 0) { + stream.writeInt32(fwd_date); + } + if ((flags & 8) != 0) { + stream.writeInt32(reply_to_msg_id); + } + stream.writeInt32(date); + stream.writeString(message); + media.serializeToStream(stream); + if ((flags & 64) != 0) { + reply_markup.serializeToStream(stream); + } + if ((flags & 128) != 0) { + stream.writeInt32(0x1cb5c415); + int count = entities.size(); + stream.writeInt32(count); + for (int a = 0; a < count; a++) { + entities.get(a).serializeToStream(stream); + } + } + stream.writeString(attachPath); + if ((flags & MESSAGE_FLAG_FWD) != 0 && id < 0) { + stream.writeInt32(fwd_msg_id); + } + } + } + + public static class TL_message_old4 extends TL_message { public static int constructor = 0xc3060325; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatBaseCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatBaseCell.java index 12ffdd918..077761f28 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatBaseCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatBaseCell.java @@ -47,7 +47,7 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo void didPressedCancelSendButton(ChatBaseCell cell); void didLongPressed(ChatBaseCell cell); void didPressReplyMessage(ChatBaseCell cell, int id); - void didPressUrl(MessageObject messageObject, String url); + void didPressUrl(MessageObject messageObject, ClickableSpan url); void needOpenWebView(String url, String title, String originalUrl, int w, int h); void didClickedImage(ChatBaseCell cell); boolean canPerformActions(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java index 3fc8394b1..e827be68e 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMediaCell.java @@ -38,7 +38,6 @@ import org.telegram.android.MessageObject; import org.telegram.ui.Components.RadialProgress; import org.telegram.ui.Components.ResourceLoader; import org.telegram.ui.Components.StaticLayoutEx; -import org.telegram.ui.Components.URLSpanNoUnderline; import org.telegram.ui.PhotoViewer; import org.telegram.ui.Components.GifDrawable; import org.telegram.android.ImageReceiver; @@ -205,16 +204,7 @@ public class ChatMediaCell extends ChatBaseCell { } } else if (linkPreviewPressed) { try { - if (pressedLink instanceof URLSpanNoUnderline) { - String url = ((URLSpanNoUnderline) pressedLink).getURL(); - if (url.startsWith("@") || url.startsWith("#") || url.startsWith("/")) { - if (delegate != null) { - delegate.didPressUrl(currentMessageObject, url); - } - } - } else { - pressedLink.onClick(this); - } + delegate.didPressUrl(currentMessageObject, pressedLink); } catch (Exception e) { FileLog.e("tmessages", e); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java index f3cdfdf43..f1051b027 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatMessageCell.java @@ -38,7 +38,6 @@ import org.telegram.messenger.TLRPC; import org.telegram.ui.Components.RadialProgress; import org.telegram.ui.Components.ResourceLoader; import org.telegram.ui.Components.StaticLayoutEx; -import org.telegram.ui.Components.URLSpanNoUnderline; import java.io.File; import java.util.Locale; @@ -131,16 +130,7 @@ public class ChatMessageCell extends ChatBaseCell { } else { if (link[0] == pressedLink) { try { - if (pressedLink instanceof URLSpanNoUnderline) { - String url = ((URLSpanNoUnderline) pressedLink).getURL(); - if (url.startsWith("@") || url.startsWith("#") || url.startsWith("/")) { - if (delegate != null) { - delegate.didPressUrl(currentMessageObject, url); - } - } - } else { - pressedLink.onClick(this); - } + delegate.didPressUrl(currentMessageObject, pressedLink); } catch (Exception e) { FileLog.e("tmessages", e); } @@ -215,7 +205,10 @@ public class ChatMessageCell extends ChatBaseCell { pressedLink.onClick(this); } else { if (drawImageButton && delegate != null) { - delegate.didClickedImage(this); + if (buttonState == -1) { + playSoundEffect(SoundEffectConstants.CLICK); + delegate.didClickedImage(this); + } } else { TLRPC.WebPage webPage = currentMessageObject.messageOwner.media.webpage; if (Build.VERSION.SDK_INT >= 16 && webPage.embed_url != null && webPage.embed_url.length() != 0) { @@ -839,7 +832,7 @@ public class ChatMessageCell extends ChatBaseCell { if (drawImageButton) { int size = AndroidUtilities.dp(48); buttonX = (int) (linkImageView.getImageX() + (linkImageView.getImageWidth() - size) / 2.0f); - buttonY = (int) (linkImageView.getImageY() + (linkImageView.getImageHeight() - size) / 2.0f) + namesOffset; + buttonY = (int) (linkImageView.getImageY() + (linkImageView.getImageHeight() - size) / 2.0f); radialProgress.setProgressRect(buttonX, buttonY, buttonX + AndroidUtilities.dp(48), buttonY + AndroidUtilities.dp(48)); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedLinkCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedLinkCell.java index f69c00d9c..7ac477244 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedLinkCell.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/SharedLinkCell.java @@ -10,45 +10,73 @@ package org.telegram.ui.Cells; import android.annotation.SuppressLint; import android.content.Context; +import android.content.Intent; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Build; +import android.provider.Browser; import android.text.Layout; import android.text.StaticLayout; import android.text.TextPaint; import android.text.TextUtils; -import android.view.View; +import android.view.Gravity; +import android.view.MotionEvent; +import android.widget.FrameLayout; import org.telegram.android.AndroidUtilities; import org.telegram.android.ImageReceiver; +import org.telegram.android.LocaleController; import org.telegram.android.MediaController; import org.telegram.android.MessageObject; import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLog; +import org.telegram.messenger.R; import org.telegram.messenger.TLRPC; +import org.telegram.ui.Components.CheckBox; +import org.telegram.ui.Components.LayoutHelper; +import org.telegram.ui.Components.LetterDrawable; +import org.telegram.ui.Components.LinkPath; import java.io.File; +import java.util.ArrayList; import java.util.Locale; -public class SharedLinkCell extends View { +public class SharedLinkCell extends FrameLayout { + + public interface SharedLinkCellDelegate { + void needOpenWebView(TLRPC.WebPage webPage); + boolean canPerformActions(); + } + + private boolean linkPreviewPressed; + private LinkPath urlPath = new LinkPath(); + private static Paint urlPaint; + private int pressedLink; private ImageReceiver linkImageView; private boolean drawLinkImageView; + private LetterDrawable letterDrawable; + private CheckBox checkBox; + + private SharedLinkCellDelegate delegate; private boolean needDivider; - private int linkX; + ArrayList links = new ArrayList<>(); private int linkY; - private StaticLayout linkLayout; + private ArrayList linkLayout = new ArrayList<>(); - private int titleX; - private int titleY; + private int titleY = AndroidUtilities.dp(7); private StaticLayout titleLayout; - private int descriptionX; - private int descriptionY; + private int descriptionY = AndroidUtilities.dp(27); private StaticLayout descriptionLayout; + private int description2Y = AndroidUtilities.dp(27); + private StaticLayout descriptionLayout2; + private MessageObject message; private static TextPaint titleTextPaint; @@ -70,8 +98,18 @@ public class SharedLinkCell extends View { paint = new Paint(); paint.setColor(0xffd9d9d9); paint.setStrokeWidth(1); + + urlPaint = new Paint(); + urlPaint.setColor(0x33316f9f); } + + setWillNotDraw(false); linkImageView = new ImageReceiver(this); + letterDrawable = new LetterDrawable(); + + checkBox = new CheckBox(context, R.drawable.round_check2); + checkBox.setVisibility(INVISIBLE); + addView(checkBox, LayoutHelper.createFrame(22, 22, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 44, 44, LocaleController.isRTL ? 44 : 0, 0)); } @SuppressLint("DrawAllocation") @@ -80,16 +118,17 @@ public class SharedLinkCell extends View { drawLinkImageView = false; descriptionLayout = null; titleLayout = null; - linkLayout = null; - descriptionX = 0; - titleX = 0; - linkX = 0; + descriptionLayout2 = null; + description2Y = descriptionY; + linkLayout.clear(); + links.clear(); - int maxWidth = MeasureSpec.getSize(widthMeasureSpec) - AndroidUtilities.dp(32); + int maxWidth = MeasureSpec.getSize(widthMeasureSpec) - AndroidUtilities.dp(AndroidUtilities.leftBaseline) - AndroidUtilities.dp(8); - String title = ""; - String description = ""; - String link = ""; + String title = null; + String description = null; + String description2 = null; + String webPageLink = null; boolean hasPhoto = false; if (message.messageOwner.media instanceof TLRPC.TL_messageMediaWebPage && message.messageOwner.media.webpage instanceof TLRPC.TL_webPage) { @@ -103,57 +142,135 @@ public class SharedLinkCell extends View { title = webPage.site_name; } description = webPage.description; - link = webPage.url; + webPageLink = webPage.url; + } + if (!message.messageOwner.entities.isEmpty()) { + for (int a = 0; a < message.messageOwner.entities.size(); a++) { + TLRPC.MessageEntity entity = message.messageOwner.entities.get(a); + if (entity.length <= 0 || entity.offset < 0 || entity.offset >= message.messageOwner.message.length()) { + continue; + } else if (entity.offset + entity.length > message.messageOwner.message.length()) { + entity.length = message.messageOwner.message.length() - entity.offset; + } + if (a == 0 && webPageLink != null && !(entity.offset == 0 && entity.length == message.messageOwner.message.length())) { + if (message.messageOwner.entities.size() == 1) { + if (description == null) { + description2 = message.messageOwner.message; + } + } else { + description2 = message.messageOwner.message; + } + } + try { + String link = null; + if (entity instanceof TLRPC.TL_messageEntityTextUrl || entity instanceof TLRPC.TL_messageEntityUrl) { + if (entity instanceof TLRPC.TL_messageEntityUrl) { + link = message.messageOwner.message.substring(entity.offset, entity.offset + entity.length); + } else { + link = entity.url; + } + if (title == null || title.length() == 0) { + title = link; + Uri uri = Uri.parse(title); + title = uri.getHost(); + if (title == null) { + title = link; + } + int index; + if (title != null && (index = title.lastIndexOf('.')) >= 0) { + title = title.substring(0, index); + if ((index = title.lastIndexOf('.')) >= 0) { + title = title.substring(index + 1); + } + title = title.substring(0, 1).toUpperCase() + title.substring(1); + } + if (entity.offset != 0 || entity.length != message.messageOwner.message.length()) { + description = message.messageOwner.message; + } + } + } else if (entity instanceof TLRPC.TL_messageEntityEmail) { + if (title == null || title.length() == 0) { + link = "mailto:" + message.messageOwner.message.substring(entity.offset, entity.offset + entity.length); + title = message.messageOwner.message.substring(entity.offset, entity.offset + entity.length); + if (entity.offset != 0 || entity.length != message.messageOwner.message.length()) { + description = message.messageOwner.message; + } + } + } + if (link != null) { + if (link.toLowerCase().indexOf("http") != 0 && link.toLowerCase().indexOf("mailto") != 0) { + links.add("http://" + link); + } else { + links.add(link); + } + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + } + if (webPageLink != null && links.isEmpty()) { + links.add(webPageLink); } if (title != null) { try { int width = (int) Math.ceil(titleTextPaint.measureText(title)); - CharSequence titleFinal = TextUtils.ellipsize(title.replace("\n", " "), titleTextPaint, Math.min(width, maxWidth - (hasPhoto ? AndroidUtilities.dp(56) : 0)), TextUtils.TruncateAt.END); + CharSequence titleFinal = TextUtils.ellipsize(title.replace("\n", " "), titleTextPaint, Math.min(width, maxWidth), TextUtils.TruncateAt.END); titleLayout = new StaticLayout(titleFinal, titleTextPaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); - titleX = (int) Math.ceil(-titleLayout.getLineLeft(0)) + AndroidUtilities.dp(16); - titleY = AndroidUtilities.dp(8); } catch (Exception e) { FileLog.e("tmessages", e); } + letterDrawable.setTitle(title); } if (description != null) { try { - descriptionLayout = ChatMessageCell.generateStaticLayout(description, descriptionTextPaint, maxWidth, maxWidth - (hasPhoto ? AndroidUtilities.dp(56) : 0), 2, 6); + descriptionLayout = ChatMessageCell.generateStaticLayout(description, descriptionTextPaint, maxWidth, maxWidth, 0, 3); int height = descriptionLayout.getLineBottom(descriptionLayout.getLineCount() - 1); - for (int a = 0; a < descriptionLayout.getLineCount(); a++) { - int lineLeft = (int) Math.ceil(descriptionLayout.getLineLeft(a)); - if (descriptionX == 0) { - descriptionX = -lineLeft; - } else { - descriptionX = Math.max(descriptionX, -lineLeft); - } + if (descriptionLayout.getLineCount() > 0) { + description2Y = descriptionY + descriptionLayout.getLineBottom(descriptionLayout.getLineCount() - 1) + AndroidUtilities.dp(1); } - descriptionX += AndroidUtilities.dp(16); - descriptionY = AndroidUtilities.dp(28); } catch (Exception e) { FileLog.e("tmessages", e); } } - if (link != null) { + if (description2 != null) { try { - int width = (int) Math.ceil(descriptionTextPaint.measureText(link)); - CharSequence linkFinal = TextUtils.ellipsize(link.replace("\n", " "), descriptionTextPaint, Math.min(width, maxWidth), TextUtils.TruncateAt.END); - linkLayout = new StaticLayout(linkFinal, descriptionTextPaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); - linkX = (int) Math.ceil(-linkLayout.getLineLeft(0)) + AndroidUtilities.dp(16); - linkY = descriptionY; - if (descriptionLayout != null && descriptionLayout.getLineCount() != 0) { - linkY += descriptionLayout.getLineBottom(descriptionLayout.getLineCount() - 1) + AndroidUtilities.dp(1); + descriptionLayout2 = ChatMessageCell.generateStaticLayout(description2, descriptionTextPaint, maxWidth, maxWidth, 0, 3); + int height = descriptionLayout2.getLineBottom(descriptionLayout2.getLineCount() - 1); + if (descriptionLayout != null) { + description2Y += AndroidUtilities.dp(10); } } catch (Exception e) { FileLog.e("tmessages", e); } } + if (!links.isEmpty()) { + for (int a = 0; a < links.size(); a++) { + try { + String link = links.get(a); + int width = (int) Math.ceil(descriptionTextPaint.measureText(link)); + CharSequence linkFinal = TextUtils.ellipsize(link.replace("\n", " "), descriptionTextPaint, Math.min(width, maxWidth), TextUtils.TruncateAt.MIDDLE); + StaticLayout layout = new StaticLayout(linkFinal, descriptionTextPaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); + linkY = description2Y; + if (descriptionLayout2 != null && descriptionLayout2.getLineCount() != 0) { + linkY += descriptionLayout2.getLineBottom(descriptionLayout2.getLineCount() - 1) + AndroidUtilities.dp(1); + } + linkLayout.add(layout); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + } + + int maxPhotoWidth = AndroidUtilities.dp(52); + int x = LocaleController.isRTL ? MeasureSpec.getSize(widthMeasureSpec) - AndroidUtilities.dp(10) - maxPhotoWidth : AndroidUtilities.dp(10); + letterDrawable.setBounds(x, AndroidUtilities.dp(10), x + maxPhotoWidth, AndroidUtilities.dp(62)); + if (hasPhoto) { - int maxPhotoWidth = AndroidUtilities.dp(48); TLRPC.PhotoSize currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(message.photoThumbs, maxPhotoWidth, true); TLRPC.PhotoSize currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(message.photoThumbs, 80); if (currentPhotoObjectThumb == currentPhotoObject) { @@ -163,7 +280,7 @@ public class SharedLinkCell extends View { if (currentPhotoObjectThumb != null) { currentPhotoObjectThumb.size = -1; } - linkImageView.setImageCoords(maxWidth - AndroidUtilities.dp(32), AndroidUtilities.dp(8), maxPhotoWidth, maxPhotoWidth); + linkImageView.setImageCoords(x, AndroidUtilities.dp(10), maxPhotoWidth, maxPhotoWidth); String fileName = FileLoader.getAttachFileName(currentPhotoObject); boolean photoExist = true; File cacheFile = FileLoader.getPathToAttach(currentPhotoObject, true); @@ -190,32 +307,143 @@ public class SharedLinkCell extends View { if (descriptionLayout != null && descriptionLayout.getLineCount() != 0) { height += descriptionLayout.getLineBottom(descriptionLayout.getLineCount() - 1); } - if (linkLayout != null && linkLayout.getLineCount() != 0) { - height += linkLayout.getLineBottom(linkLayout.getLineCount() - 1); + if (descriptionLayout2 != null && descriptionLayout2.getLineCount() != 0) { + height += descriptionLayout2.getLineBottom(descriptionLayout2.getLineCount() - 1); + if (descriptionLayout != null) { + height += AndroidUtilities.dp(10); + } + } + for (int a = 0; a < linkLayout.size(); a++) { + StaticLayout layout = linkLayout.get(a); + if (layout.getLineCount() > 0) { + height += layout.getLineBottom(layout.getLineCount() - 1); + } } if (hasPhoto) { height = Math.max(AndroidUtilities.dp(48), height); } - - setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.makeMeasureSpec(height + AndroidUtilities.dp(16) + (needDivider ? 1 : 0), MeasureSpec.EXACTLY)); + checkBox.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(22), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(22), MeasureSpec.EXACTLY)); + setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), Math.max(AndroidUtilities.dp(72), height + AndroidUtilities.dp(16)) + (needDivider ? 1 : 0)); } public void setLink(MessageObject messageObject, boolean divider) { needDivider = divider; + resetPressedLink(); message = messageObject; requestLayout(); } + public void setDelegate(SharedLinkCellDelegate sharedLinkCellDelegate) { + delegate = sharedLinkCellDelegate; + } + public MessageObject getMessage() { return message; } + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + if (drawLinkImageView) { + linkImageView.onDetachedFromWindow(); + } + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + if (drawLinkImageView) { + linkImageView.onAttachedToWindow(); + } + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + boolean result = false; + if (message != null && !linkLayout.isEmpty() && delegate.canPerformActions()) { + if (event.getAction() == MotionEvent.ACTION_DOWN || linkPreviewPressed && event.getAction() == MotionEvent.ACTION_UP) { + int x = (int) event.getX(); + int y = (int) event.getY(); + int offset = 0; + boolean ok = false; + for (int a = 0; a < linkLayout.size(); a++) { + StaticLayout layout = linkLayout.get(a); + if (layout.getLineCount() > 0) { + int height = layout.getLineBottom(layout.getLineCount() - 1); + int linkPosX = AndroidUtilities.dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline); + if (x >= linkPosX + layout.getLineLeft(0) && x <= linkPosX + layout.getLineWidth(0) && y >= linkY + offset && y <= linkY + offset + height) { + ok = true; + if (event.getAction() == MotionEvent.ACTION_DOWN) { + resetPressedLink(); + pressedLink = a; + linkPreviewPressed = true; + try { + urlPath.setCurrentLayout(layout, 0); + layout.getSelectionPath(0, layout.getText().length(), urlPath); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + result = true; + } else if (linkPreviewPressed) { + try { + TLRPC.WebPage webPage = pressedLink == 0 && message.messageOwner.media != null ? message.messageOwner.media.webpage : null; + if (webPage != null && Build.VERSION.SDK_INT >= 16 && webPage.embed_url != null && webPage.embed_url.length() != 0) { + delegate.needOpenWebView(webPage); + } else { + Uri uri = Uri.parse(links.get(pressedLink)); + Intent intent = new Intent(Intent.ACTION_VIEW, uri); + intent.putExtra(Browser.EXTRA_APPLICATION_ID, getContext().getPackageName()); + getContext().startActivity(intent); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + resetPressedLink(); + result = true; + } + break; + } + offset += height; + } + } + if (!ok) { + resetPressedLink(); + } + } else if (event.getAction() == MotionEvent.ACTION_CANCEL) { + resetPressedLink(); + } + } else { + resetPressedLink(); + } + return result || super.onTouchEvent(event); + } + + public String getLink(int num) { + if (num < 0 || num >= links.size()) { + return null; + } + return links.get(num); + } + + protected void resetPressedLink() { + pressedLink = -1; + linkPreviewPressed = false; + invalidate(); + } + + public void setChecked(boolean checked, boolean animated) { + if (checkBox.getVisibility() != VISIBLE) { + checkBox.setVisibility(VISIBLE); + } + checkBox.setChecked(checked, animated); + } + @Override protected void onDraw(Canvas canvas) { if (titleLayout != null) { canvas.save(); - canvas.translate(titleX, titleY); + canvas.translate(AndroidUtilities.dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline), titleY); titleLayout.draw(canvas); canvas.restore(); } @@ -223,25 +451,48 @@ public class SharedLinkCell extends View { if (descriptionLayout != null) { descriptionTextPaint.setColor(0xff212121); canvas.save(); - canvas.translate(descriptionX, descriptionY); + canvas.translate(AndroidUtilities.dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline), descriptionY); descriptionLayout.draw(canvas); canvas.restore(); } - if (linkLayout != null) { - descriptionTextPaint.setColor(0xff316f9f); + if (descriptionLayout2 != null) { + descriptionTextPaint.setColor(0xff212121); canvas.save(); - canvas.translate(linkX, linkY); - linkLayout.draw(canvas); + canvas.translate(AndroidUtilities.dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline), description2Y); + descriptionLayout2.draw(canvas); canvas.restore(); } + if (!linkLayout.isEmpty()) { + descriptionTextPaint.setColor(0xff316f9f); + int offset = 0; + for (int a = 0; a < linkLayout.size(); a++) { + StaticLayout layout = linkLayout.get(a); + if (layout.getLineCount() > 0) { + canvas.save(); + canvas.translate(AndroidUtilities.dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline), linkY + offset); + if (pressedLink == a) { + canvas.drawPath(urlPath, urlPaint); + } + layout.draw(canvas); + canvas.restore(); + offset += layout.getLineBottom(layout.getLineCount() - 1); + } + } + } + + letterDrawable.draw(canvas); if (drawLinkImageView) { linkImageView.draw(canvas); } if (needDivider) { - canvas.drawLine(0, getHeight() - 1, getWidth(), getHeight() - 1, paint); + if (LocaleController.isRTL) { + canvas.drawLine(0, getMeasuredHeight() - 1, getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.leftBaseline), getMeasuredHeight() - 1, paint); + } else { + canvas.drawLine(AndroidUtilities.dp(AndroidUtilities.leftBaseline), getMeasuredHeight() - 1, getMeasuredWidth(), getMeasuredHeight() - 1, paint); + } } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java index 697d5c06b..9e8ca3575 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java @@ -27,6 +27,7 @@ import android.os.Bundle; import android.provider.ContactsContract; import android.provider.MediaStore; import android.text.TextUtils; +import android.text.style.ClickableSpan; import android.util.Base64; import android.util.SparseArray; import android.util.TypedValue; @@ -114,6 +115,8 @@ import org.telegram.ui.Components.SendingFileExDrawable; import org.telegram.ui.Components.SizeNotifierFrameLayout; import org.telegram.ui.Components.TimerDrawable; import org.telegram.ui.Components.TypingDotsDrawable; +import org.telegram.ui.Components.URLSpanNoUnderline; +import org.telegram.ui.Components.URLSpanReplacement; import org.telegram.ui.Components.WebFrameLayout; import java.io.File; @@ -1883,16 +1886,27 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } AlertDialog.Builder builder = null; if (currentUser != null && userBlocked) { - builder = new AlertDialog.Builder(getParentActivity()); - builder.setMessage(LocaleController.getString("AreYouSureUnblockContact", R.string.AreYouSureUnblockContact)); - builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - MessagesController.getInstance().unblockUser(currentUser.id); + if ((currentUser.flags & TLRPC.USER_FLAG_BOT) != 0) { + String botUserLast = botUser; + botUser = null; + MessagesController.getInstance().unblockUser(currentUser.id); + if (botUserLast != null && botUserLast.length() != 0) { + MessagesController.getInstance().sendBotStart(currentUser, botUserLast); + } else { + SendMessagesHelper.getInstance().sendMessage("/start", dialog_id, null, null, false); } - }); + } else { + builder = new AlertDialog.Builder(getParentActivity()); + builder.setMessage(LocaleController.getString("AreYouSureUnblockContact", R.string.AreYouSureUnblockContact)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + MessagesController.getInstance().unblockUser(currentUser.id); + } + }); + } } else if (currentUser != null && botUser != null) { - if (botUser.length() != 0) { + if (botUser != null && botUser.length() != 0) { MessagesController.getInstance().sendBotStart(currentUser, botUser); } else { SendMessagesHelper.getInstance().sendMessage("/start", dialog_id, null, null, false); @@ -2601,7 +2615,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not bottomOverlay.setVisibility(View.INVISIBLE); } if (hideKeyboard) { - chatActivityEnterView.hidePopup(); + chatActivityEnterView.hidePopup(false); if (getParentActivity() != null) { AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); } @@ -4363,10 +4377,14 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not bottomOverlayChatText.setText(LocaleController.getString("DeleteThisGroup", R.string.DeleteThisGroup)); } else { if (userBlocked) { - bottomOverlayChatText.setText(LocaleController.getString("Unblock", R.string.Unblock)); + if ((currentUser.flags & TLRPC.USER_FLAG_BOT) != 0) { + bottomOverlayChatText.setText(LocaleController.getString("BotUnblock", R.string.BotUnblock)); + } else { + bottomOverlayChatText.setText(LocaleController.getString("Unblock", R.string.Unblock)); + } } else if (botUser != null) { bottomOverlayChatText.setText(LocaleController.getString("BotStart", R.string.BotStart)); - chatActivityEnterView.hidePopup(); + chatActivityEnterView.hidePopup(false); if (getParentActivity() != null) { AndroidUtilities.hideKeyboard(getParentActivity().getCurrentFocus()); } @@ -5039,7 +5057,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not updateVisibleRows(); return false; } else if (chatActivityEnterView.isPopupShowing()) { - chatActivityEnterView.hidePopup(); + chatActivityEnterView.hidePopup(true); return false; } return true; @@ -5345,15 +5363,36 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not } @Override - public void didPressUrl(MessageObject messageObject, String url) { - if (url.startsWith("@")) { - MessagesController.openByUserName(url.substring(1), ChatActivity.this, 0); - } else if (url.startsWith("#")) { - DialogsActivity fragment = new DialogsActivity(null); - fragment.setSearchString(url); - presentFragment(fragment); - } else if (url.startsWith("/")) { - chatActivityEnterView.setCommand(messageObject, url); + public void didPressUrl(MessageObject messageObject, final ClickableSpan url) { + if (url instanceof URLSpanNoUnderline) { + String str = ((URLSpanNoUnderline) url).getURL(); + if (str.startsWith("@")) { + MessagesController.openByUserName(str.substring(1), ChatActivity.this, 0); + } else if (str.startsWith("#")) { + DialogsActivity fragment = new DialogsActivity(null); + fragment.setSearchString(str); + presentFragment(fragment); + } else if (str.startsWith("/")) { + chatActivityEnterView.setCommand(messageObject, str); + } + } else if (url instanceof URLSpanReplacement) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + builder.setMessage(LocaleController.formatString("OpenUrlAlert", R.string.OpenUrlAlert, ((URLSpanReplacement) url).getURL())); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setPositiveButton(LocaleController.getString("Open", R.string.Open), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + try { + url.onClick(fragmentView); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showDialog(builder.create()); + } else { + url.onClick(fragmentView); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java index b939a3ec7..614fd741c 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/ChatActivityEnterView.java @@ -213,30 +213,46 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat messageEditText.setHintTextColor(0xffb2b2b2); frameLayout.addView(messageEditText, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM, 52, 0, isChat ? 50 : 2, 0)); messageEditText.setOnKeyListener(new View.OnKeyListener() { + + boolean ctrlPressed = false; + @Override public boolean onKey(View view, int i, KeyEvent keyEvent) { if (i == KeyEvent.KEYCODE_BACK && !keyboardVisible && isPopupShowing()) { if (keyEvent.getAction() == 1) { + if (currentPopupContentType == 1 && botButtonsMessageObject != null) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + preferences.edit().putInt("hidekeyboard_" + dialog_id, botButtonsMessageObject.getId()).commit(); + } showPopup(0, 0); } return true; - } else if (i == KeyEvent.KEYCODE_ENTER && sendByEnter && keyEvent.getAction() == KeyEvent.ACTION_DOWN) { + } else if (i == KeyEvent.KEYCODE_ENTER && (ctrlPressed || sendByEnter) && keyEvent.getAction() == KeyEvent.ACTION_DOWN) { sendMessage(); return true; + } else if (i == KeyEvent.KEYCODE_CTRL_LEFT || i == KeyEvent.KEYCODE_CTRL_RIGHT) { + ctrlPressed = keyEvent.getAction() == KeyEvent.ACTION_DOWN; + return true; } return false; } }); messageEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() { + + boolean ctrlPressed = false; + @Override public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { if (i == EditorInfo.IME_ACTION_SEND) { sendMessage(); return true; - } else if (sendByEnter) { - if (keyEvent != null && i == EditorInfo.IME_NULL && keyEvent.getAction() == KeyEvent.ACTION_DOWN) { + } else if (keyEvent != null && i == EditorInfo.IME_NULL) { + if ((ctrlPressed || sendByEnter) && keyEvent.getAction() == KeyEvent.ACTION_DOWN) { sendMessage(); return true; + } else if (i == KeyEvent.KEYCODE_CTRL_LEFT || i == KeyEvent.KEYCODE_CTRL_RIGHT) { + ctrlPressed = keyEvent.getAction() == KeyEvent.ACTION_DOWN; + return true; } } return false; @@ -319,7 +335,13 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat if (botReplyMarkup != null) { if (!isPopupShowing() || currentPopupContentType != 1) { showPopup(1, 1); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + preferences.edit().remove("hidekeyboard_" + dialog_id).commit(); } else { + if (currentPopupContentType == 1 && botButtonsMessageObject != null) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + preferences.edit().putInt("hidekeyboard_" + dialog_id, botButtonsMessageObject.getId()).commit(); + } openKeyboardInternal(); } } else if (hasBotCommands) { @@ -1184,13 +1206,14 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat botKeyboardView.setPanelHeight(AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y ? keyboardHeightLand : keyboardHeight); botKeyboardView.setButtons(botReplyMarkup != null ? botReplyMarkup : null); if (botReplyMarkup != null) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + boolean keyboardHidden = preferences.getInt("hidekeyboard_" + dialog_id, 0) == messageObject.getId(); if (botButtonsMessageObject != replyingMessageObject && (botReplyMarkup.flags & 2) != 0) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); if (preferences.getInt("answered_" + dialog_id, 0) == messageObject.getId()) { return; } } - if (messageEditText.length() == 0 && !isPopupShowing()) { + if (!keyboardHidden && messageEditText.length() == 0 && !isPopupShowing()) { showPopup(1, 1); } } else { @@ -1321,8 +1344,12 @@ public class ChatActivityEnterView extends FrameLayoutFixed implements Notificat } } - public void hidePopup() { + public void hidePopup(boolean byBackButton) { if (isPopupShowing()) { + if (currentPopupContentType == 1 && byBackButton && botButtonsMessageObject != null) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + preferences.edit().putInt("hidekeyboard_" + dialog_id, botButtonsMessageObject.getId()).commit(); + } showPopup(0, 0); } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/LetterDrawable.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/LetterDrawable.java new file mode 100644 index 000000000..e85661019 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/LetterDrawable.java @@ -0,0 +1,108 @@ +/* + * This is the source code of Telegram for Android v. 2.x.x. + * It is licensed under GNU GPL v. 2 or later. + * You should have received a copy of the license in this archive (see LICENSE). + * + * Copyright Nikolai Kudashov, 2013-2015. + */ + +package org.telegram.ui.Components; + +import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.Paint; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.text.Layout; +import android.text.StaticLayout; +import android.text.TextPaint; + +import org.telegram.android.AndroidUtilities; +import org.telegram.messenger.FileLog; + +public class LetterDrawable extends Drawable { + + private static Paint paint = new Paint(); + private static TextPaint namePaint; + + private StaticLayout textLayout; + private float textWidth; + private float textHeight; + private float textLeft; + private StringBuilder stringBuilder = new StringBuilder(5); + + public LetterDrawable() { + super(); + + if (namePaint == null) { + paint.setColor(0xffdfdfdf); + namePaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); + namePaint.setColor(0xffffffff); + namePaint.setTextSize(AndroidUtilities.dp(28)); + } + } + + public void setTitle(String title) { + stringBuilder.setLength(0); + if (title != null && title.length() > 0) { + stringBuilder.append(title.substring(0, 1)); + } + + if (stringBuilder.length() > 0) { + String text = stringBuilder.toString().toUpperCase(); + try { + textLayout = new StaticLayout(text, namePaint, AndroidUtilities.dp(100), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); + if (textLayout.getLineCount() > 0) { + textLeft = textLayout.getLineLeft(0); + textWidth = textLayout.getLineWidth(0); + textHeight = textLayout.getLineBottom(0); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } else { + textLayout = null; + } + } + + @Override + public void draw(Canvas canvas) { + Rect bounds = getBounds(); + if (bounds == null) { + return; + } + int size = bounds.width(); + canvas.save(); + canvas.drawRect(bounds.left, bounds.top, bounds.right, bounds.bottom, paint); + if (textLayout != null) { + canvas.translate(bounds.left + (size - textWidth) / 2 - textLeft, bounds.top + (size - textHeight) / 2); + textLayout.draw(canvas); + } + canvas.restore(); + } + + @Override + public void setAlpha(int alpha) { + + } + + @Override + public void setColorFilter(ColorFilter cf) { + + } + + @Override + public int getOpacity() { + return 0; + } + + @Override + public int getIntrinsicWidth() { + return 0; + } + + @Override + public int getIntrinsicHeight() { + return 0; + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Components/URLSpanReplacement.java b/TMessagesProj/src/main/java/org/telegram/ui/Components/URLSpanReplacement.java new file mode 100644 index 000000000..3f38b1a48 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Components/URLSpanReplacement.java @@ -0,0 +1,18 @@ +/* + * This is the source code of Telegram for Android v. 2.x.x. + * It is licensed under GNU GPL v. 2 or later. + * You should have received a copy of the license in this archive (see LICENSE). + * + * Copyright Nikolai Kudashov, 2013-2015. + */ + +package org.telegram.ui.Components; + +import android.text.style.URLSpan; + +public class URLSpanReplacement extends URLSpan { + + public URLSpanReplacement(String url) { + super(url); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java index 9ce96818c..1b6de6c7b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/MediaActivity.java @@ -289,6 +289,7 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No } MessagesController.getInstance().deleteMessages(ids, random_ids, currentEncryptedChat); actionBar.hideActionMode(); + actionBar.closeSearchField(); selectedFiles.clear(); } }); @@ -399,9 +400,9 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No dropDownContainer.setSubMenuOpenSide(1); dropDownContainer.addSubItem(shared_media_item, LocaleController.getString("SharedMediaTitle", R.string.SharedMediaTitle), 0); dropDownContainer.addSubItem(files_item, LocaleController.getString("DocumentsTitle", R.string.DocumentsTitle), 0); - //if ((int) dialog_id != 0) { - // dropDownContainer.addSubItem(links_item, LocaleController.getString("LinksTitle", R.string.LinksTitle), 0); - //} + if ((int) dialog_id != 0) { + dropDownContainer.addSubItem(links_item, LocaleController.getString("LinksTitle", R.string.LinksTitle), 0); + } actionBar.addView(dropDownContainer, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT, AndroidUtilities.isTablet() ? 64 : 56, 0, 40, 0)); dropDownContainer.setOnClickListener(new View.OnClickListener() { @Override @@ -510,6 +511,10 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No SharedDocumentCell cell = (SharedDocumentCell) view; MessageObject message = cell.getDocument(); return MediaActivity.this.onItemLongClick(message, view, 0); + } else if (selectedMode == 3 && view instanceof SharedLinkCell) { + SharedLinkCell cell = (SharedLinkCell) view; + MessageObject message = cell.getMessage(); + return MediaActivity.this.onItemLongClick(message, view, 0); } return false; } @@ -673,6 +678,14 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No } } + @Override + public void onPause() { + super.onPause(); + if (dropDownContainer != null) { + dropDownContainer.closeSubMenu(); + } + } + @Override public void onResume() { super.onResume(); @@ -828,12 +841,12 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No } else if (selectedMode == 3) { listView.setAdapter(linksAdapter); dropDown.setText(LocaleController.getString("LinksTitle", R.string.LinksTitle)); - emptyImageView.setImageResource(R.drawable.tip2); + emptyImageView.setImageResource(R.drawable.tip3); emptyTextView.setText(LocaleController.getString("NoSharedLinks", R.string.NoSharedLinks)); searchItem.setVisibility(!sharedMediaData[3].messages.isEmpty() ? View.VISIBLE : View.GONE); if (!sharedMediaData[selectedMode].loading && !sharedMediaData[selectedMode].endReached && sharedMediaData[selectedMode].messages.isEmpty()) { sharedMediaData[selectedMode].loading = true; - SharedMediaQuery.loadMedia(dialog_id, 0, 50, 0, SharedMediaQuery.MEDIA_URL, false, classGuid); + SharedMediaQuery.loadMedia(dialog_id, 0, 50, 0, SharedMediaQuery.MEDIA_URL, true, classGuid); } listView.setVisibility(View.VISIBLE); if (sharedMediaData[selectedMode].loading && sharedMediaData[selectedMode].messages.isEmpty()) { @@ -876,6 +889,8 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No ((SharedDocumentCell) view).setChecked(true, true); } else if (view instanceof SharedPhotoVideoCell) { ((SharedPhotoVideoCell) view).setChecked(a, true, true); + } else if (view instanceof SharedLinkCell) { + ((SharedLinkCell) view).setChecked(true, true); } actionBar.showActionMode(); return true; @@ -901,6 +916,8 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No ((SharedDocumentCell) view).setChecked(selectedFiles.containsKey(message.getId()), true); } else if (view instanceof SharedPhotoVideoCell) { ((SharedPhotoVideoCell) view).setChecked(a, selectedFiles.containsKey(message.getId()), true); + } else if (view instanceof SharedLinkCell) { + ((SharedLinkCell) view).setChecked(selectedFiles.containsKey(message.getId()), true); } } else { if (selectedMode == 0) { @@ -978,13 +995,20 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No } else if (selectedMode == 3) { try { TLRPC.WebPage webPage = message.messageOwner.media.webpage; - if (Build.VERSION.SDK_INT >= 16 && webPage.embed_url != null && webPage.embed_url.length() != 0) { - BottomSheet.Builder builder = new BottomSheet.Builder(getParentActivity()); - builder.setCustomView(new WebFrameLayout(getParentActivity(), builder.create(), webPage.title, webPage.url, webPage.embed_url, webPage.embed_width, webPage.embed_height)); - builder.setUseFullWidth(true); - showDialog(builder.create()); - } else { - Uri uri = Uri.parse(webPage.url); + String link = null; + if (webPage != null && !(webPage instanceof TLRPC.TL_webPageEmpty)) { + if (Build.VERSION.SDK_INT >= 16 && webPage.embed_url != null && webPage.embed_url.length() != 0) { + openWebView(webPage); + return; + } else { + link = webPage.url; + } + } + if (link == null) { + link = ((SharedLinkCell) view).getLink(0); + } + if (link != null) { + Uri uri = Uri.parse(link); Intent intent = new Intent(Intent.ACTION_VIEW, uri); intent.putExtra(Browser.EXTRA_APPLICATION_ID, getParentActivity().getPackageName()); getParentActivity().startActivity(intent); @@ -996,6 +1020,13 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No } } + private void openWebView(TLRPC.WebPage webPage) { + BottomSheet.Builder builder = new BottomSheet.Builder(getParentActivity()); + builder.setCustomView(new WebFrameLayout(getParentActivity(), builder.create(), webPage.title, webPage.url, webPage.embed_url, webPage.embed_width, webPage.embed_height)); + builder.setUseFullWidth(true); + showDialog(builder.create()); + } + private void fixLayoutInternal() { if (listView == null) { return; @@ -1090,15 +1121,26 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No } else { if (convertView == null) { convertView = new SharedLinkCell(mContext); + ((SharedLinkCell) convertView).setDelegate(new SharedLinkCell.SharedLinkCellDelegate() { + @Override + public void needOpenWebView(TLRPC.WebPage webPage) { + MediaActivity.this.openWebView(webPage); + } + + @Override + public boolean canPerformActions() { + return !actionBar.isActionModeShowed(); + } + }); } - SharedLinkCell sharedDocumentCell = (SharedLinkCell) convertView; + SharedLinkCell sharedLinkCell = (SharedLinkCell) convertView; MessageObject messageObject = messageObjects.get(position - 1); - sharedDocumentCell.setLink(messageObject, position != messageObjects.size() || section == sharedMediaData[3].sections.size() - 1 && sharedMediaData[3].loading); - /*if (actionBar.isActionModeShowed()) { - sharedDocumentCell.setChecked(selectedFiles.containsKey(messageObject.getId()), !scrolling); + sharedLinkCell.setLink(messageObject, position != messageObjects.size() || section == sharedMediaData[3].sections.size() - 1 && sharedMediaData[3].loading); + if (actionBar.isActionModeShowed()) { + sharedLinkCell.setChecked(selectedFiles.containsKey(messageObject.getId()), !scrolling); } else { - sharedDocumentCell.setChecked(false, !scrolling); - }*/ + sharedLinkCell.setChecked(false, !scrolling); + } } } else { if (convertView == null) { @@ -1392,12 +1434,8 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No if (user == null) { return; } - if (user.access_hash != 0) { - req.peer = new TLRPC.TL_inputPeerForeign(); - req.peer.access_hash = user.access_hash; - } else { - req.peer = new TLRPC.TL_inputPeerContact(); - } + req.peer = new TLRPC.TL_inputPeerUser(); + req.peer.access_hash = user.access_hash; req.peer.user_id = uid; } final int currentReqId = ++lastReqId; @@ -1528,7 +1566,7 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No @Override public boolean isEnabled(int i) { - return i != searchResult.size(); + return i != searchResult.size() + globalSearch.size(); } @Override @@ -1588,15 +1626,26 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No } else if (currentType == 3) { if (view == null) { view = new SharedLinkCell(mContext); + ((SharedLinkCell) view).setDelegate(new SharedLinkCell.SharedLinkCellDelegate() { + @Override + public void needOpenWebView(TLRPC.WebPage webPage) { + MediaActivity.this.openWebView(webPage); + } + + @Override + public boolean canPerformActions() { + return !actionBar.isActionModeShowed(); + } + }); } SharedLinkCell sharedLinkCell = (SharedLinkCell) view; MessageObject messageObject = getItem(i); sharedLinkCell.setLink(messageObject, i != getCount() - 1); - /*if (actionBar.isActionModeShowed()) { - sharedDocumentCell.setChecked(selectedFiles.containsKey(messageObject.getId()), !scrolling); + if (actionBar.isActionModeShowed()) { + sharedLinkCell.setChecked(selectedFiles.containsKey(messageObject.getId()), !scrolling); } else { - sharedDocumentCell.setChecked(false, !scrolling); - }*/ + sharedLinkCell.setChecked(false, !scrolling); + } } return view; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PhotoAlbumPickerActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PhotoAlbumPickerActivity.java index 303bc9f85..6c9c09275 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PhotoAlbumPickerActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PhotoAlbumPickerActivity.java @@ -288,6 +288,14 @@ public class PhotoAlbumPickerActivity extends BaseFragment implements Notificati return fragmentView; } + @Override + public void onPause() { + super.onPause(); + if (dropDownContainer != null) { + dropDownContainer.closeSubMenu(); + } + } + @Override public void onResume() { super.onResume(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java index 0404394b7..e84a49d44 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/PopupNotificationActivity.java @@ -1066,7 +1066,7 @@ public class PopupNotificationActivity extends Activity implements NotificationC @Override public void onBackPressed() { if (chatActivityEnterView.isPopupShowing()) { - chatActivityEnterView.hidePopup(); + chatActivityEnterView.hidePopup(true); return; } super.onBackPressed(); @@ -1089,7 +1089,7 @@ public class PopupNotificationActivity extends Activity implements NotificationC super.onPause(); overridePendingTransition(0, 0); if (chatActivityEnterView != null) { - chatActivityEnterView.hidePopup(); + chatActivityEnterView.hidePopup(false); chatActivityEnterView.setFieldFocused(false); } ConnectionsManager.getInstance().setAppPaused(true, false); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java index ecc42b868..a1593b02b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ProfileActivity.java @@ -261,25 +261,39 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. if (id == -1) { finishFragment(); } else if (id == block_contact) { - AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); - if (!userBlocked) { - builder.setMessage(LocaleController.getString("AreYouSureBlockContact", R.string.AreYouSureBlockContact)); - } else { - builder.setMessage(LocaleController.getString("AreYouSureUnblockContact", R.string.AreYouSureUnblockContact)); + TLRPC.User user = MessagesController.getInstance().getUser(user_id); + if (user == null) { + return; } - builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); - builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - if (!userBlocked) { - MessagesController.getInstance().blockUser(user_id); - } else { - MessagesController.getInstance().unblockUser(user_id); - } + if ((user.flags & TLRPC.USER_FLAG_BOT) == 0) { + AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity()); + if (!userBlocked) { + builder.setMessage(LocaleController.getString("AreYouSureBlockContact", R.string.AreYouSureBlockContact)); + } else { + builder.setMessage(LocaleController.getString("AreYouSureUnblockContact", R.string.AreYouSureUnblockContact)); } - }); - builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); - showDialog(builder.create()); + builder.setTitle(LocaleController.getString("AppName", R.string.AppName)); + builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + if (!userBlocked) { + MessagesController.getInstance().blockUser(user_id); + } else { + MessagesController.getInstance().unblockUser(user_id); + } + } + }); + builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); + showDialog(builder.create()); + } else { + if (!userBlocked) { + MessagesController.getInstance().blockUser(user_id); + } else { + MessagesController.getInstance().unblockUser(user_id); + SendMessagesHelper.getInstance().sendMessage("/start", user_id, null, null, false); + finishFragment(); + } + } } else if (id == add_contact) { TLRPC.User user = MessagesController.getInstance().getUser(user_id); Bundle args = new Bundle(); @@ -1308,6 +1322,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. menu.clearItems(); if (user_id != 0) { + if (ContactsController.getInstance().contactsDict.get(user_id) == null) { TLRPC.User user = MessagesController.getInstance().getUser(user_id); if (user == null) { @@ -1325,7 +1340,11 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. item.addSubItem(share_contact, LocaleController.getString("ShareContact", R.string.ShareContact), 0); item.addSubItem(block_contact, !userBlocked ? LocaleController.getString("BlockContact", R.string.BlockContact) : LocaleController.getString("Unblock", R.string.Unblock), 0); } else { - item.addSubItem(block_contact, !userBlocked ? LocaleController.getString("BlockContact", R.string.BlockContact) : LocaleController.getString("Unblock", R.string.Unblock), 0); + if ((user.flags & TLRPC.USER_FLAG_BOT) != 0) { + item.addSubItem(block_contact, !userBlocked ? LocaleController.getString("BotStop", R.string.BotStop) : LocaleController.getString("BotRestart", R.string.BotRestart), 0); + } else { + item.addSubItem(block_contact, !userBlocked ? LocaleController.getString("BlockContact", R.string.BlockContact) : LocaleController.getString("Unblock", R.string.Unblock), 0); + } } } else { ActionBarMenuItem item = menu.addItem(0, R.drawable.ic_ab_other); @@ -1361,7 +1380,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. args.putBoolean("scrollToTopOnResume", true); NotificationCenter.getInstance().removeObserver(this, NotificationCenter.closeChats); NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats); - int lower_part = (int)dialog_id; + int lower_part = (int) dialog_id; if (lower_part != 0) { if (lower_part > 0) { args.putInt("user_id", lower_part); @@ -1369,7 +1388,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter. args.putInt("chat_id", -lower_part); } } else { - args.putInt("enc_id", (int)(dialog_id >> 32)); + args.putInt("enc_id", (int) (dialog_id >> 32)); } presentFragment(new ChatActivity(args), true); removeSelfFromStack(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java index f5f02e4fd..ab40394ba 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/VideoEditorActivity.java @@ -87,6 +87,7 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur private int resultWidth = 0; private int resultHeight = 0; private int bitrate = 0; + private int originalBitrate = 0; private float videoDuration = 0; private long startTime = 0; private long endTime = 0; @@ -247,7 +248,7 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur } if (delegate != null) { if (compressVideo.getVisibility() == View.GONE || compressVideo.getVisibility() == View.VISIBLE && !compressVideo.isChecked()) { - delegate.didFinishEditVideo(videoPath, startTime, endTime, originalWidth, originalHeight, rotationValue, originalWidth, originalHeight, bitrate, estimatedSize, esimatedDuration); + delegate.didFinishEditVideo(videoPath, startTime, endTime, originalWidth, originalHeight, rotationValue, originalWidth, originalHeight, originalBitrate, estimatedSize, esimatedDuration); } else { delegate.didFinishEditVideo(videoPath, startTime, endTime, resultWidth, resultHeight, rotationValue, originalWidth, originalHeight, bitrate, estimatedSize, esimatedDuration); } @@ -742,7 +743,7 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur TrackHeaderBox headerBox = trackBox.getTrackHeaderBox(); if (headerBox.getWidth() != 0 && headerBox.getHeight() != 0) { trackHeaderBox = headerBox; - bitrate = (int)(trackBitrate / 100000 * 100000); + originalBitrate = bitrate = (int)(trackBitrate / 100000 * 100000); if (bitrate > 900000) { bitrate = 900000; } diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tip1.png b/TMessagesProj/src/main/res/drawable-hdpi/tip1.png old mode 100755 new mode 100644 index d979e349f..16abb9b9f Binary files a/TMessagesProj/src/main/res/drawable-hdpi/tip1.png and b/TMessagesProj/src/main/res/drawable-hdpi/tip1.png differ diff --git a/TMessagesProj/src/main/res/drawable-hdpi/tip3.png b/TMessagesProj/src/main/res/drawable-hdpi/tip3.png new file mode 100644 index 000000000..241f3c1ec Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-hdpi/tip3.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/tip1.png b/TMessagesProj/src/main/res/drawable-mdpi/tip1.png old mode 100755 new mode 100644 index 40ae2af83..af62d2e32 Binary files a/TMessagesProj/src/main/res/drawable-mdpi/tip1.png and b/TMessagesProj/src/main/res/drawable-mdpi/tip1.png differ diff --git a/TMessagesProj/src/main/res/drawable-mdpi/tip3.png b/TMessagesProj/src/main/res/drawable-mdpi/tip3.png new file mode 100644 index 000000000..db501192a Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-mdpi/tip3.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/tip1.png b/TMessagesProj/src/main/res/drawable-xhdpi/tip1.png old mode 100755 new mode 100644 index a6a75ed78..98934f271 Binary files a/TMessagesProj/src/main/res/drawable-xhdpi/tip1.png and b/TMessagesProj/src/main/res/drawable-xhdpi/tip1.png differ diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/tip3.png b/TMessagesProj/src/main/res/drawable-xhdpi/tip3.png new file mode 100644 index 000000000..4f128e892 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xhdpi/tip3.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/tip1.png b/TMessagesProj/src/main/res/drawable-xxhdpi/tip1.png old mode 100755 new mode 100644 index 5d9960e33..f126139a5 Binary files a/TMessagesProj/src/main/res/drawable-xxhdpi/tip1.png and b/TMessagesProj/src/main/res/drawable-xxhdpi/tip1.png differ diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/tip3.png b/TMessagesProj/src/main/res/drawable-xxhdpi/tip3.png new file mode 100644 index 000000000..3fe466657 Binary files /dev/null and b/TMessagesProj/src/main/res/drawable-xxhdpi/tip3.png differ diff --git a/TMessagesProj/src/main/res/values-ar/strings.xml b/TMessagesProj/src/main/res/values-ar/strings.xml index c9ea54895..2a7f290b5 100644 --- a/TMessagesProj/src/main/res/values-ar/strings.xml +++ b/TMessagesProj/src/main/res/values-ar/strings.xml @@ -137,6 +137,7 @@ فتح في المتصفح انسخ الرابط أرسل %1$s + هل ترغب في فتح الرابط باستخدام %1$s ؟ %1$s قام بتعيين عداد التدمير الذاتي إلى to %2$s لقد قمت بتعيين التدمير الذاتي إلى %1$s @@ -549,6 +550,9 @@ لا يستطيع الوصول للرسائل ماذا يستطيع هذا البوت عمله؟ إبدأ + إعادة تشغيل + إيقاف البوت + إعادة تعيين البوت التالي رجوع @@ -837,6 +841,6 @@ h:mm a %1$s الساعة %2$s - تم تحديث تيليجرام نسخة الاندرويد. الجديد في نسخة ٣.١.٢: \n\n- كلمات البحث الحديثة. \n- اضغط باستمرار لاستعراض الملصق قبل إرساله. - 583 + تم تحديث تيليجرام نسخة الآندرويد. الجديد في نسخة 3.1.3:\n\n- قسم جديد للروابط المشاركة في معلومات المحادثة \n- استعراض لروابط الصور داخل التطبيق. + 590 \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values-de/strings.xml b/TMessagesProj/src/main/res/values-de/strings.xml index 0f7e23337..cc76b4bd6 100644 --- a/TMessagesProj/src/main/res/values-de/strings.xml +++ b/TMessagesProj/src/main/res/values-de/strings.xml @@ -137,6 +137,7 @@ Im Browser öffnen URL kopieren %1$s senden + URL %1$s öffnen? %1$s hat den Selbstzerstörungs-Timer auf %2$s gesetzt Du hast den Selbstzerstörungs-Timer auf %1$s gesetzt @@ -549,6 +550,9 @@ kein Zugriff auf Nachrichten Was kann dieser Bot? STARTEN + NEUSTART + Bot Anhalten + Bot Neu Starten Weiter Zurück @@ -837,6 +841,6 @@ h:mm a %1$s um %2$s - Telegram für Android wurde aktualisiert. Neu in Version 3.1.2:\n\n- Die letzte Suche wird gespeichert\n- Stickervorschau: Sticker vor dem Senden antippen und halten - 583 + Telegram für Android wurde aktualisiert. Neu in Version 3.1.3:\n\n- Neuer \"Geteilte Links\" Bereich in der Chat Info\n- In-App Vorschau für Links von Bildern. + 590 \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values-es/strings.xml b/TMessagesProj/src/main/res/values-es/strings.xml index b80c0fced..50d1d4e3b 100644 --- a/TMessagesProj/src/main/res/values-es/strings.xml +++ b/TMessagesProj/src/main/res/values-es/strings.xml @@ -137,6 +137,7 @@ Abrir en el navegador Copiar URL Enviar %1$s + ¿Abrir %1$s? %1$s activó la autodestrucción en %2$s Activaste la autodestrucción en %1$s @@ -549,6 +550,9 @@ no tiene acceso a los mensajes ¿Qué puede hacer este bot? INICIAR + REINICIAR + Detener bot + Reiniciar bot Siguiente Atrás @@ -837,6 +841,6 @@ h:mm a %1$s a las %2$s - Telegram para Android fue actualizada. Novedades en la versión 3.1.2:\n\n- Búsquedas recientes\n- Mantén pulsado sobre un sticker para obtener una vista previa antes de enviarlo - 583 + Telegram para Android ha sido actualizada. Novedades en la versión 3.1.3:\n\n- Nueva sección de \'Enlaces\' en la información del chat\n- Vista previa en la app para enlaces a fotos + 590 \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values-it/strings.xml b/TMessagesProj/src/main/res/values-it/strings.xml index ce4cf1766..8920fdbc8 100644 --- a/TMessagesProj/src/main/res/values-it/strings.xml +++ b/TMessagesProj/src/main/res/values-it/strings.xml @@ -137,6 +137,7 @@ Apri nel Browser Copia URL Invia %1$s + Aprire url %1$s? %1$s ha impostato il timer di autodistruzione a %2$s Hai impostato il timer di autodistruzione a %1$s @@ -549,6 +550,9 @@ non ha accesso ai messaggi Cosa può fare questo bot? AVVIA + RIAVVIA + Arresta bot + Riavvia bot Avanti Indietro @@ -837,6 +841,6 @@ h:mm a %1$s alle %2$s - Telegram per Android si è aggiornato. Nuovo nella versione 3.1.2:\n\n- Risultati recenti nella ricerca\n- Tieni premuto su uno sticker per visualizzare l\'anteprima prima di inviarlo - 583 + Telegram per Android si è aggiornato. Nuovo nella versione 3.1.3:\n\n- Nuova sezione \"Link condivisi\" nelle info della chat\n- Anteprima in-app delle foto dei link + 590 \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values-ko/strings.xml b/TMessagesProj/src/main/res/values-ko/strings.xml index 9640fd27e..2518212ce 100644 --- a/TMessagesProj/src/main/res/values-ko/strings.xml +++ b/TMessagesProj/src/main/res/values-ko/strings.xml @@ -137,6 +137,7 @@ 브라우져에서 열기 URL 복사 %1$s 전송 + %1$s 링크를 여시겠습니까? %1$s님이 자동삭제를 %2$s 후로 설정했습니다 자동삭제를 %1$s 후로 설정했습니다 @@ -549,6 +550,9 @@ 메시지 접근 권한이 없습니다 이 봇은 무엇을 할 수 있나요? 시작 + 재시작 + 봇 정지 + 봇 재시작 다음 뒤로 @@ -837,6 +841,6 @@ a h:mm %1$s %2$s - 텔레그램 안드로이드 버전이 업데이트 되었습니다. 새로운 버전은 3.1.2 입니다:\n\n- 최신 검색 결과\n- 스티커를 꾹 누를 경우 미리보기 기능 - 583 + 텔레그램 안드로이드 버전이 업데이트 되었습니다. 새로운 버전은 3.1.3 입니다:\n\n- 채팅방 정보내 \'공유된 링크\' 추가 \n- 사진 링크 프리뷰 기능 + 590 \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values-nl/strings.xml b/TMessagesProj/src/main/res/values-nl/strings.xml index be14001e0..94cd3cf67 100644 --- a/TMessagesProj/src/main/res/values-nl/strings.xml +++ b/TMessagesProj/src/main/res/values-nl/strings.xml @@ -137,6 +137,7 @@ Openen in browser Link kopiëren %1$s versturen + URL %1$s openen? %1$s heeft de zelfvernietigingstimer ingesteld op %2$s Je hebt de zelfvernietigingstimer ingesteld op %1$s @@ -170,7 +171,7 @@ %1$s heeft je verwijderd uit de groep %2$s %1$s heeft de groep %2$s verlaten %1$s heeft nu Telegram! - %1$s,\nEr is op je account ingelogd vanaf een nieuw apparaat op %2$s\n\nApparaat: %3$s\nLocatie: %4$s\n\nAls jij dit niet was, kun je die sessie beëindigen via Instellingen - Privacy en veiligheid - Sessies.\n\nAls je dat denkt dat iemand anders zonder jouw toestemming is ingelogd kun je twee-staps-verificatie activeren via instellingen - privacy en veiligheid .\n\nBedankt,\nHet Telegram-team + %1$s,\nEr is op je account ingelogd vanaf een nieuw apparaat op %2$s\n\nApparaat: %3$s\nLocatie: %4$s\n\nAls jij dit niet was, kun je die sessie beëindigen via Instellingen - Privacy en veiligheid - Sessies.\n\nAls je dat denkt dat iemand anders zonder jouw toestemming is ingelogd kun je twee-staps-verificatie activeren via instellingen - privacy en veiligheid.\n\nBedankt,\nHet Telegram-team %1$s heeft zijn/haar profielfoto gewijzigd %1$s neemt deel aan de groep %2$s via uitnodigingslink Antwoord @@ -366,7 +367,7 @@ Actieve sessies Huidige sessie Geen andere actieve sessies - Je kunt in Telegram inloggen vanaf andere apparaten (mobiel,tablet,desktop) met hetzelfde telefoonnummer. Al je data zal direct worden gesynchroniseerd. + Je kunt in Telegram inloggen vanaf andere apparaten (mobiel, tablet, desktop) met hetzelfde telefoonnummer. Al je data zal direct worden gesynchroniseerd. Actieve sessies Beheer je sessies van andere apparaten. Tik op een sessie om deze te beëindigen. @@ -549,6 +550,9 @@ geen toegang tot berichten Wat kan deze bot? BEGIN + HERSTART + Bot stoppen + Bot herstarten Volgende Vorige @@ -837,6 +841,6 @@ h:mm a %1$s om %2$s - Telegram voor Android is bijgewerkt. Nieuw in versie 3.1.2:\n\n- Recente zoekresultaten\n- Stickers aantikken en vasthouden om een voorbeeld weer te geven voor het versturen. - 583 + Telegram voor Android is bijgewerkt. Nieuw in versie 3.1.3:\n\n- Nieuw \'Gedeelde links\'-gedeelte in chatinformatie\n- In-app voorvertoning voor links naar foto\'s + 590 \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values-pt-rBR/strings.xml b/TMessagesProj/src/main/res/values-pt-rBR/strings.xml index e5d5d4454..02e816c13 100644 --- a/TMessagesProj/src/main/res/values-pt-rBR/strings.xml +++ b/TMessagesProj/src/main/res/values-pt-rBR/strings.xml @@ -46,8 +46,8 @@ Você entrou no chat secreto Limpar histórico Apagar e sair - Excluir conversa - Excluir Conta + Apagar conversa + Conta Excluída Selecione um Chat Toque e segure para ver %1$s está usando uma versão mais antiga do Telegram, por isso fotos secretas serão mostradas em modo de compatibilidade.\n\nAssim que %2$s atualizar o Telegram, fotos com timers de 1 minuto ou menos passarão a funcionar no modo ‘Toque e segure para ver’, e você será notificado caso a outra pessoa salve a tela. @@ -137,6 +137,7 @@ Abrir no Navegador Copiar URL Enviar %1$s + Abrir URL em %1$s? %1$s estabeleceu o tempo de autodestruição para %2$s Você estabeleceu o tempo de autodestruição para %1$s @@ -549,6 +550,9 @@ não tem acesso as mensagens O que esse bot pode fazer? COMEÇAR + REINICIAR + Parar bot + Reiniciar bot Próximo Voltar @@ -837,6 +841,6 @@ h:mm a %1$s às %2$s - Seu Telegram para Android acaba de ser atualizado. Novo na versão 3.1.2\n\n- Resultados das buscas recentes\n- Pressione e mantenha em um sticker para pré-visualizar antes do envio - 583 + Telegram para Android foi atualizado. Novidade na versão 3.1.3\n\n- Nova sessão \"Links Compartilhados\" na informação do chat\n- Pré-visualizaçãp de fotos em links no aplicativo. + 590 \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values-pt-rPT/strings.xml b/TMessagesProj/src/main/res/values-pt-rPT/strings.xml index 3f82bb00e..aca1cf4af 100644 --- a/TMessagesProj/src/main/res/values-pt-rPT/strings.xml +++ b/TMessagesProj/src/main/res/values-pt-rPT/strings.xml @@ -46,8 +46,8 @@ Você entrou no chat secreto Limpar histórico Apagar e sair - Excluir conversa - Excluir Conta + Apagar conversa + Conta Excluída Selecione um Chat Toque e segure para ver %1$s está usando uma versão mais antiga do Telegram, por isso fotos secretas serão mostradas em modo de compatibilidade.\n\nAssim que %2$s atualizar o Telegram, fotos com timers de 1 minuto ou menos passarão a funcionar no modo ‘Toque e segure para ver’, e você será notificado caso a outra pessoa salve a tela. @@ -137,6 +137,7 @@ Abrir no Navegador Copiar URL Enviar %1$s + Abrir URL em %1$s? %1$s estabeleceu o tempo de autodestruição para %2$s Você estabeleceu o tempo de autodestruição para %1$s @@ -549,6 +550,9 @@ não tem acesso as mensagens O que esse bot pode fazer? COMEÇAR + REINICIAR + Parar bot + Reiniciar bot Próximo Voltar @@ -837,6 +841,6 @@ h:mm a %1$s às %2$s - Seu Telegram para Android acaba de ser atualizado. Novo na versão 3.1.2\n\n- Resultados das buscas recentes\n- Pressione e mantenha em um sticker para pré-visualizar antes do envio - 583 + Telegram para Android foi atualizado. Novidade na versão 3.1.3\n\n- Nova sessão \"Links Compartilhados\" na informação do chat\n- Pré-visualizaçãp de fotos em links no aplicativo. + 590 \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values/strings.xml b/TMessagesProj/src/main/res/values/strings.xml index 0562882b0..7c70bbe05 100644 --- a/TMessagesProj/src/main/res/values/strings.xml +++ b/TMessagesProj/src/main/res/values/strings.xml @@ -137,6 +137,7 @@ Open in Browser Copy URL Send %1$s + Open url %1$s? %1$s set the self-destruct timer to %2$s You set the self-destruct timer to %1$s @@ -549,6 +550,9 @@ has no access to messages What can this bot do? START + RESTART + Stop bot + Restart bot Next Back @@ -837,6 +841,6 @@ h:mm a %1$s at %2$s - Telegram for Android has been updated. New in version 3.1.2:\n\n- Recent search results\n- Tap and hold sticker to preview before sending - 583 + Telegram for Android has been updated. New in version 3.1.3:\n\n- New \'Shared Links\' section in chat info\n- In-app preview for links to photos + 590 \ No newline at end of file