From 9814a6e927fa087794ec8b6776ea63e3877772c7 Mon Sep 17 00:00:00 2001 From: DrKLO Date: Tue, 4 Feb 2014 22:36:55 +0400 Subject: [PATCH] update to 1.3.19 Spanish localization by Borja Campina Applied pull request by Yuri Orlov (https://github.com/DrKLO/Telegram/pull/27) --- TMessagesProj/build.gradle | 6 +- TMessagesProj/src/main/AndroidManifest.xml | 64 +- .../main/java/org/telegram/TL/TLObject.java | 2 +- .../messenger/ConnectionsManager.java | 166 +- .../messenger/ContactsController.java | 1310 ++++++++++++ .../org/telegram/messenger/DispatchQueue.java | 14 +- .../messenger/ExportAuthorizationAction.java | 4 +- .../telegram/messenger/FileLoadOperation.java | 10 +- .../org/telegram/messenger/FileLoader.java | 147 +- .../java/org/telegram/messenger/FileLog.java | 2 + .../messenger/FileUploadOperation.java | 11 +- .../messenger/GcmBroadcastReceiver.java | 163 +- .../messenger/MessagesController.java | 1866 +++++++---------- .../telegram/messenger/MessagesStorage.java | 369 +++- .../messenger/NotificationCenter.java | 65 +- .../org/telegram/messenger/RPCRequest.java | 2 + .../org/telegram/messenger/SmsListener.java | 5 +- .../org/telegram/messenger/TcpConnection.java | 72 +- .../org/telegram/messenger/UserConfig.java | 8 +- .../org/telegram/messenger/Utilities.java | 160 +- .../org/telegram/objects/MessageObject.java | 45 +- .../org/telegram/objects/PhotoObject.java | 4 +- .../org/telegram/ui/ApplicationActivity.java | 19 +- .../org/telegram/ui/ApplicationLoader.java | 77 +- .../java/org/telegram/ui/Cells/BaseCell.java | 36 + .../org/telegram/ui/Cells/ChatOrUserCell.java | 464 ++++ .../org/telegram/ui/Cells/DialogCell.java | 684 ++++++ .../java/org/telegram/ui/ChatActivity.java | 501 +++-- .../org/telegram/ui/ChatProfileActivity.java | 82 +- .../ui/ChatProfileChangeNameActivity.java | 2 +- .../org/telegram/ui/ContactAddActivity.java | 22 +- .../org/telegram/ui/ContactsActivity.java | 318 +-- .../telegram/ui/CountrySelectActivity.java | 8 +- .../telegram/ui/DocumentSelectActivity.java | 26 +- .../org/telegram/ui/GalleryImageViewer.java | 44 +- .../org/telegram/ui/GroupCreateActivity.java | 39 +- .../telegram/ui/GroupCreateFinalActivity.java | 76 +- .../java/org/telegram/ui/IntroActivity.java | 11 +- .../java/org/telegram/ui/LaunchActivity.java | 74 +- .../org/telegram/ui/LocationActivity.java | 5 +- .../java/org/telegram/ui/LoginActivity.java | 1 - .../telegram/ui/LoginActivityPhoneView.java | 36 +- .../ui/LoginActivityRegisterView.java | 37 +- .../org/telegram/ui/LoginActivitySmsView.java | 151 +- .../org/telegram/ui/MessagesActivity.java | 412 +--- .../org/telegram/ui/SettingsActivity.java | 212 +- .../org/telegram/ui/SettingsBlockedUsers.java | 84 +- .../ui/SettingsChangeNameActivity.java | 7 +- .../ui/SettingsNotificationsActivity.java | 35 +- .../ui/SettingsWallpapersActivity.java | 4 +- .../org/telegram/ui/UserProfileActivity.java | 77 +- .../org/telegram/ui/Views/ImageReceiver.java | 169 ++ .../telegram/ui/Views/NotificationView.java | 53 +- .../ui/Views/PagerSlidingTabStrip.java | 17 +- .../org/telegram/ui/Views/TightTextView.java | 6 + .../main/res/drawable-hdpi/photocancel.png | Bin 0 -> 1154 bytes .../res/drawable-hdpi/photocancel_pressed.png | Bin 0 -> 1165 bytes .../src/main/res/drawable-hdpi/photoload.png | Bin 0 -> 952 bytes .../res/drawable-hdpi/photoload_pressed.png | Bin 0 -> 967 bytes .../main/res/drawable-ldpi/photocancel.png | Bin 0 -> 709 bytes .../res/drawable-ldpi/photocancel_pressed.png | Bin 0 -> 715 bytes .../src/main/res/drawable-ldpi/photoload.png | Bin 0 -> 464 bytes .../res/drawable-ldpi/photoload_pressed.png | Bin 0 -> 475 bytes .../main/res/drawable-mdpi/photocancel.png | Bin 0 -> 812 bytes .../res/drawable-mdpi/photocancel_pressed.png | Bin 0 -> 848 bytes .../src/main/res/drawable-mdpi/photoload.png | Bin 0 -> 688 bytes .../res/drawable-mdpi/photoload_pressed.png | Bin 0 -> 722 bytes .../main/res/drawable-xhdpi/ic_launcher.png | Bin 7863 -> 5485 bytes .../main/res/drawable-xhdpi/ic_lock_green.png | Bin 343 -> 296 bytes .../main/res/drawable-xhdpi/photocancel.png | Bin 0 -> 1401 bytes .../drawable-xhdpi/photocancel_pressed.png | Bin 0 -> 1466 bytes .../src/main/res/drawable-xhdpi/photoload.png | Bin 0 -> 1270 bytes .../res/drawable-xhdpi/photoload_pressed.png | Bin 0 -> 1304 bytes .../main/res/drawable-xxhdpi/ic_launcher.png | Bin 12857 -> 9023 bytes .../main/res/drawable-xxhdpi/photocancel.png | Bin 0 -> 2106 bytes .../drawable-xxhdpi/photocancel_pressed.png | Bin 0 -> 2119 bytes .../main/res/drawable-xxhdpi/photoload.png | Bin 0 -> 1967 bytes .../res/drawable-xxhdpi/photoload_pressed.png | Bin 0 -> 1981 bytes .../res/drawable/messages_list_divider.xml | 10 + .../drawable/photo_download_cancel_states.xml | 7 + .../res/drawable/photo_download_states.xml | 7 + .../main/res/layout-ar/contact_add_layout.xml | 7 +- .../src/main/res/layout-ar/messages_list.xml | 3 + .../main/res/layout-ar/messages_list_row.xml | 141 -- .../layout-ar/messages_search_chat_layout.xml | 36 - .../layout-ar/messages_search_user_layout.xml | 51 - .../layout-ar/settings_row_check_layout.xml | 2 +- .../settings_row_check_notify_layout.xml | 2 +- .../chat_group_incoming_location_layout.xml | 2 - .../chat_group_incoming_photo_layout.xml | 103 +- .../chat_group_incoming_video_layout.xml | 2 - .../layout/chat_incoming_location_layout.xml | 2 - .../res/layout/chat_incoming_photo_layout.xml | 103 +- .../res/layout/chat_incoming_video_layout.xml | 2 - .../layout/chat_outgoing_location_layout.xml | 2 - .../res/layout/chat_outgoing_photo_layout.xml | 170 +- .../res/layout/chat_outgoing_video_layout.xml | 2 - .../main/res/layout/contact_add_layout.xml | 9 +- .../src/main/res/layout/messages_list.xml | 8 +- .../src/main/res/layout/messages_list_row.xml | 139 -- .../layout/messages_search_chat_layout.xml | 35 - .../layout/messages_search_user_layout.xml | 49 - .../res/layout/settings_row_check_layout.xml | 2 +- .../settings_row_check_notify_layout.xml | 2 +- .../src/main/res/menu/messages_list_menu.xml | 35 +- .../res/menu/user_profile_contact_menu.xml | 8 +- .../src/main/res/values-ar/strings.xml | 74 +- .../src/main/res/values-es/strings.xml | 353 ++++ TMessagesProj/src/main/res/values/strings.xml | 38 +- gradle/wrapper/gradle-wrapper.properties | 5 +- 110 files changed, 6238 insertions(+), 3457 deletions(-) create mode 100644 TMessagesProj/src/main/java/org/telegram/messenger/ContactsController.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Cells/BaseCell.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatOrUserCell.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java create mode 100644 TMessagesProj/src/main/java/org/telegram/ui/Views/ImageReceiver.java create mode 100755 TMessagesProj/src/main/res/drawable-hdpi/photocancel.png create mode 100755 TMessagesProj/src/main/res/drawable-hdpi/photocancel_pressed.png create mode 100755 TMessagesProj/src/main/res/drawable-hdpi/photoload.png create mode 100755 TMessagesProj/src/main/res/drawable-hdpi/photoload_pressed.png create mode 100755 TMessagesProj/src/main/res/drawable-ldpi/photocancel.png create mode 100755 TMessagesProj/src/main/res/drawable-ldpi/photocancel_pressed.png create mode 100755 TMessagesProj/src/main/res/drawable-ldpi/photoload.png create mode 100755 TMessagesProj/src/main/res/drawable-ldpi/photoload_pressed.png create mode 100755 TMessagesProj/src/main/res/drawable-mdpi/photocancel.png create mode 100755 TMessagesProj/src/main/res/drawable-mdpi/photocancel_pressed.png create mode 100755 TMessagesProj/src/main/res/drawable-mdpi/photoload.png create mode 100755 TMessagesProj/src/main/res/drawable-mdpi/photoload_pressed.png mode change 100644 => 100755 TMessagesProj/src/main/res/drawable-xhdpi/ic_lock_green.png create mode 100755 TMessagesProj/src/main/res/drawable-xhdpi/photocancel.png create mode 100755 TMessagesProj/src/main/res/drawable-xhdpi/photocancel_pressed.png create mode 100755 TMessagesProj/src/main/res/drawable-xhdpi/photoload.png create mode 100755 TMessagesProj/src/main/res/drawable-xhdpi/photoload_pressed.png create mode 100755 TMessagesProj/src/main/res/drawable-xxhdpi/photocancel.png create mode 100755 TMessagesProj/src/main/res/drawable-xxhdpi/photocancel_pressed.png create mode 100755 TMessagesProj/src/main/res/drawable-xxhdpi/photoload.png create mode 100755 TMessagesProj/src/main/res/drawable-xxhdpi/photoload_pressed.png create mode 100644 TMessagesProj/src/main/res/drawable/messages_list_divider.xml create mode 100644 TMessagesProj/src/main/res/drawable/photo_download_cancel_states.xml create mode 100644 TMessagesProj/src/main/res/drawable/photo_download_states.xml delete mode 100644 TMessagesProj/src/main/res/layout-ar/messages_list_row.xml delete mode 100644 TMessagesProj/src/main/res/layout-ar/messages_search_chat_layout.xml delete mode 100644 TMessagesProj/src/main/res/layout-ar/messages_search_user_layout.xml delete mode 100644 TMessagesProj/src/main/res/layout/messages_list_row.xml delete mode 100644 TMessagesProj/src/main/res/layout/messages_search_chat_layout.xml delete mode 100644 TMessagesProj/src/main/res/layout/messages_search_user_layout.xml create mode 100644 TMessagesProj/src/main/res/values-es/strings.xml diff --git a/TMessagesProj/build.gradle b/TMessagesProj/build.gradle index 22d52f6fc..869bae73d 100644 --- a/TMessagesProj/build.gradle +++ b/TMessagesProj/build.gradle @@ -3,7 +3,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:0.7.+' + classpath 'com.android.tools.build:gradle:0.8.+' } } apply plugin: 'android' @@ -31,7 +31,7 @@ tasks.withType(JavaCompile) { } dependencies { - compile 'com.google.android.gms:play-services:4.0.+' + compile 'com.google.android.gms:play-services:4.1.+' compile 'net.hockeyapp.android:HockeySDK:3.0.1' compile 'com.android.support:support-v4:19.0.+' compile 'com.android.support:appcompat-v7:19.0.+' @@ -40,7 +40,7 @@ dependencies { android { compileSdkVersion 19 - buildToolsVersion '19.0.0' + buildToolsVersion '19.0.1' signingConfigs { debug { diff --git a/TMessagesProj/src/main/AndroidManifest.xml b/TMessagesProj/src/main/AndroidManifest.xml index 3b163ccc0..12755bb70 100644 --- a/TMessagesProj/src/main/AndroidManifest.xml +++ b/TMessagesProj/src/main/AndroidManifest.xml @@ -1,18 +1,18 @@ - + android:versionCode="148" + android:versionName="1.3.19"> + - + android:smallScreens="true" + android:normalScreens="true" + android:largeScreens="true" + android:resizeable="true" + android:xlargeScreens="true"/> + - + @@ -23,7 +23,7 @@ - + @@ -49,10 +49,10 @@ - + - + - + - + + + android:name="org.telegram.ui.LaunchActivity" + android:windowSoftInputMode="adjustResize" + android:configChanges="keyboard|keyboardHidden|orientation|screenSize"> @@ -124,48 +125,47 @@ android:theme="@style/Theme.TMessages.Gallery" android:configChanges="keyboard|keyboardHidden|orientation|screenSize"> - - + + - + - + + android:name="org.telegram.messenger.GcmBroadcastReceiver" + android:permission="com.google.android.c2dm.permission.SEND" > - + + android:resource="@xml/auth"/> - + + android:resource="@xml/sync_contacts" /> + android:resource="@xml/contacts" /> - + - - + diff --git a/TMessagesProj/src/main/java/org/telegram/TL/TLObject.java b/TMessagesProj/src/main/java/org/telegram/TL/TLObject.java index 6f92a935b..8d4ced3b0 100644 --- a/TMessagesProj/src/main/java/org/telegram/TL/TLObject.java +++ b/TMessagesProj/src/main/java/org/telegram/TL/TLObject.java @@ -32,7 +32,7 @@ public class TLObject { } public int layer () { - return 8; + return 11; } public void parseVector(TLRPC.Vector vector, SerializedData data) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java b/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java index c0c176695..d9007a68f 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ConnectionsManager.java @@ -15,6 +15,7 @@ import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.Build; import android.util.Base64; +import android.util.Log; import org.telegram.TL.TLClassStore; import org.telegram.TL.TLObject; @@ -33,7 +34,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.TcpConnectionDelegate { - public static boolean DEBUG_VERSION = false; + public static boolean DEBUG_VERSION = true; public static int APP_ID = 2458; public static String APP_HASH = "5bce48dc7d331e62c955669eb7233217"; public static String HOCKEY_APP_HASH = "your-hockeyapp-api-key-here"; @@ -100,35 +101,55 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. public void run() { long currentTime = System.currentTimeMillis(); if (ApplicationLoader.lastPauseTime != 0 && ApplicationLoader.lastPauseTime < currentTime - nextSleepTimeout) { - if (!paused) { - FileLog.e("tmessages", "pausing network and timers by sleep time = " + nextSleepTimeout); - for (Datacenter datacenter : datacenters.values()) { - if (datacenter.connection != null) { - datacenter.connection.suspendConnection(true); - } - if (datacenter.uploadConnection != null) { - datacenter.uploadConnection.suspendConnection(true); - } - if (datacenter.downloadConnection != null) { - datacenter.downloadConnection.suspendConnection(true); + boolean dontSleep = false; + for (RPCRequest request : runningRequests) { + if (request.retryCount < 10 && (request.runningStartTime + 60 > (int)(currentTime / 1000)) && ((request.flags & RPCRequest.RPCRequestClassDownloadMedia) != 0 || (request.flags & RPCRequest.RPCRequestClassUploadMedia) != 0)) { + dontSleep = true; + break; + } + } + if (!dontSleep) { + for (RPCRequest request : requestQueue) { + if ((request.flags & RPCRequest.RPCRequestClassDownloadMedia) != 0 || (request.flags & RPCRequest.RPCRequestClassUploadMedia) != 0) { + dontSleep = true; + break; } } } - try { - paused = true; - if (ApplicationLoader.lastPauseTime < currentTime - nextSleepTimeout - nextWakeUpTimeout) { - ApplicationLoader.lastPauseTime = currentTime; - nextSleepTimeout = 30000; - FileLog.e("tmessages", "wakeup network in background by wakeup time = " + nextWakeUpTimeout); - if (nextWakeUpTimeout < 30 * 60 * 1000) { - nextWakeUpTimeout *= 2; + if (!dontSleep) { + if (!paused) { + FileLog.e("tmessages", "pausing network and timers by sleep time = " + nextSleepTimeout); + for (Datacenter datacenter : datacenters.values()) { + if (datacenter.connection != null) { + datacenter.connection.suspendConnection(true); + } + if (datacenter.uploadConnection != null) { + datacenter.uploadConnection.suspendConnection(true); + } + if (datacenter.downloadConnection != null) { + datacenter.downloadConnection.suspendConnection(true); + } } - } else { - Thread.sleep(500); - return; } - } catch (Exception e) { - FileLog.e("tmessages", e); + try { + paused = true; + if (ApplicationLoader.lastPauseTime < currentTime - nextSleepTimeout - nextWakeUpTimeout) { + ApplicationLoader.lastPauseTime = currentTime; + nextSleepTimeout = 30000; + FileLog.e("tmessages", "wakeup network in background by wakeup time = " + nextWakeUpTimeout); + if (nextWakeUpTimeout < 30 * 60 * 1000) { + nextWakeUpTimeout *= 2; + } + } else { + Thread.sleep(500); + return; + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } else { + ApplicationLoader.lastPauseTime += 30 * 1000; + FileLog.e("tmessages", "don't sleep 30 seconds because of upload or download request"); } } if (paused) { @@ -240,8 +261,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. if (datacenterSetId == useDifferentBackend) { currentDatacenterId = preferences.getInt("currentDatacenterId", 0); timeDifference = preferences.getInt("timeDifference", 0); - lastDcUpdateTime = preferences.getInt("lastDcUpdateTime", 0); //TODO uncomment - //lastDcUpdateTime = 0; + lastDcUpdateTime = preferences.getInt("lastDcUpdateTime", 0); try { sessionsToDestroy.clear(); String sessionsString = preferences.getString("sessionsToDestroy", null); @@ -635,7 +655,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. TLObject wrapInLayer(TLObject object, int datacenterId, RPCRequest request) { if (object.layer() > 0) { Datacenter datacenter = datacenterWithId(datacenterId); - if (datacenter.lastInitVersion != currentAppVersion) { + if (datacenter == null || datacenter.lastInitVersion != currentAppVersion) { request.initRequest = true; TLRPC.initConnection invoke = new TLRPC.initConnection(); invoke.query = object; @@ -704,6 +724,12 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. requestQueue.add(request); + if (paused && ((request.flags & RPCRequest.RPCRequestClassDownloadMedia) != 0 || (request.flags & RPCRequest.RPCRequestClassUploadMedia) != 0)) { + ApplicationLoader.lastPauseTime = System.currentTimeMillis(); + nextSleepTimeout = 30000; + FileLog.e("tmessages", "wakeup by download or upload request"); + } + processRequestQueue(0, 0); } }); @@ -941,6 +967,12 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. Integer tokenIt = activeTransportTokens.get(requestDatacenter.datacenterId); int datacenterTransportToken = tokenIt != null ? tokenIt : 0; + Integer uploadTokenIt = activeUploadTransportTokens.get(requestDatacenter.datacenterId); + int datacenterUploadTransportToken = uploadTokenIt != null ? uploadTokenIt : 0; + + Integer downloadTokenIt = activeDownloadTransportTokens.get(requestDatacenter.datacenterId); + int datacenterDownloadTransportToken = downloadTokenIt != null ? downloadTokenIt : 0; + double maxTimeout = 8.0; if ((request.flags & RPCRequest.RPCRequestClassGeneric) != 0) { @@ -952,12 +984,18 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. FileLog.d("tmessages", "Don't have any network connection, skipping download request"); continue; } + if (datacenterDownloadTransportToken == 0) { + continue; + } maxTimeout = 40.0; } else if ((request.flags & RPCRequest.RPCRequestClassUploadMedia) != 0) { if (!haveNetwork) { FileLog.d("tmessages", "Don't have any network connection, skipping upload request"); continue; } + if (datacenterUploadTransportToken == 0) { + continue; + } maxTimeout = 30.0; } @@ -988,20 +1026,19 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. FileLog.d("tmessages", "Request token is valid, not retrying " + request.rawRequest); continue; } else if ((request.flags & RPCRequest.RPCRequestClassDownloadMedia) != 0) { - int downloadToken = requestDatacenter.downloadConnection.channelToken; - if (downloadToken != 0 && request.transportChannelToken == downloadToken) { + if (datacenterDownloadTransportToken != 0 && request.transportChannelToken == datacenterDownloadTransportToken) { FileLog.d("tmessages", "Request download token is valid, not retrying " + request.rawRequest); continue; } } else if ((request.flags & RPCRequest.RPCRequestClassUploadMedia) != 0) { - int uploadToken = requestDatacenter.uploadConnection.channelToken; - if (uploadToken != 0 && request.transportChannelToken == uploadToken) { + if (datacenterUploadTransportToken != 0 && request.transportChannelToken == datacenterUploadTransportToken) { FileLog.d("tmessages", "Request upload token is valid, not retrying " + request.rawRequest); continue; } } } + request.retryCount++; NetworkMessage networkMessage = new NetworkMessage(); networkMessage.protoMessage = new TLRPC.TL_protoMessage(); @@ -1022,10 +1059,12 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. request.transportChannelToken = datacenterTransportToken; addMessageToDatacenter(genericMessagesToDatacenters, requestDatacenter.datacenterId, networkMessage); } else if ((request.flags & RPCRequest.RPCRequestClassDownloadMedia) != 0) { + request.transportChannelToken = datacenterDownloadTransportToken; ArrayList arr = new ArrayList(); arr.add(networkMessage); proceedToSendingMessages(arr, sessionId, requestDatacenter.downloadConnection, false, false); } else if ((request.flags & RPCRequest.RPCRequestClassUploadMedia) != 0) { + request.transportChannelToken = datacenterUploadTransportToken; ArrayList arr = new ArrayList(); arr.add(networkMessage); proceedToSendingMessages(arr, sessionId, requestDatacenter.uploadConnection, false, false); @@ -1147,6 +1186,9 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. continue; } + Integer uploadTokenIt = activeUploadTransportTokens.get(requestDatacenter.datacenterId); + request.transportChannelToken = uploadTokenIt != null ? uploadTokenIt : 0; + uploadRunningRequestCount++; } else if ((request.flags & RPCRequest.RPCRequestClassDownloadMedia) != 0) { if (!haveNetwork) { @@ -1158,6 +1200,9 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. continue; } + Integer downloadTokenIt = activeDownloadTransportTokens.get(requestDatacenter.datacenterId); + request.transportChannelToken = downloadTokenIt != null ? downloadTokenIt : 0; + downloadRunningRequestCount++; } } @@ -1166,8 +1211,9 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. SerializedData os = new SerializedData(); request.rpcRequest.serializeToStream(os); + int requestLength = os.length(); - if (os.length() != 0) { + if (requestLength != 0) { long sessionId = 0; if ((request.flags & RPCRequest.RPCRequestClassGeneric) != 0) { sessionId = requestDatacenter.authSessionId; @@ -1177,18 +1223,31 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. sessionId = requestDatacenter.authUploadSessionId; } + if ((request.flags & RPCRequest.RPCRequestClassCanCompress) != 0) { + try { + byte[] data = Utilities.compress(os.toByteArray()); + if (data.length < requestLength) { + TLRPC.TL_gzip_packed packed = new TLRPC.TL_gzip_packed(); + packed.packed_data = data; + request.rpcRequest = packed; + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + NetworkMessage networkMessage = new NetworkMessage(); networkMessage.protoMessage = new TLRPC.TL_protoMessage(); networkMessage.protoMessage.msg_id = messageId; networkMessage.protoMessage.seqno = generateMessageSeqNo(sessionId, true); - networkMessage.protoMessage.bytes = os.length(); + networkMessage.protoMessage.bytes = requestLength; networkMessage.protoMessage.body = request.rpcRequest; networkMessage.rawRequest = request.rawRequest; networkMessage.requestId = request.token; request.runningMessageId = messageId; request.runningMessageSeqNo = networkMessage.protoMessage.seqno; - request.serializedLength = os.length(); + request.serializedLength = requestLength; request.runningStartTime = (int)(System.currentTimeMillis() / 1000); if (request.requiresCompletion) { runningRequests.add(request); @@ -1454,8 +1513,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. byte[] transportData = createConnectionData(currentMessages, sessionId, quickAckId, connection); if (transportData != null) { - if (reportAck && quickAckId.size() != 0) - { + if (reportAck && quickAckId.size() != 0) { ArrayList requestIds = new ArrayList(); for (NetworkMessage message : messagesToSend) { @@ -1933,13 +1991,15 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. isError = true; if (datacenter.datacenterId == currentDatacenterId || datacenter.datacenterId == movingToDatacenterId) { if ((request.flags & RPCRequest.RPCRequestClassGeneric) != 0) { - Utilities.RunOnUIThread(new Runnable() { - @Override - public void run() { - NotificationCenter.Instance.postNotificationName(1234); - UserConfig.clearConfig(); - } - }); + if (UserConfig.clientActivated) { + UserConfig.clearConfig(); + Utilities.RunOnUIThread(new Runnable() { + @Override + public void run() { + NotificationCenter.Instance.postNotificationName(1234); + } + }); + } } } else { datacenter.authorized = false; @@ -2078,7 +2138,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. TLObject result = Utilities.decompress(packet.packed_data, getRequestWithMessageId(messageId)); processMessage(result, messageId, messageSeqNo, messageSalt, connection, sessionId, innerMsgId, containerMessageId); } else if (message instanceof TLRPC.Updates) { - MessagesController.Instance.processUpdates((TLRPC.Updates)message); + MessagesController.Instance.processUpdates((TLRPC.Updates)message, false); } else { FileLog.e("tmessages", "***** Error: unknown message class " + message); } @@ -2275,6 +2335,20 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. } else { connectionState = 1; } + if (DEBUG_VERSION) { + try { + ConnectivityManager cm = (ConnectivityManager)ApplicationLoader.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo[] networkInfos = cm.getAllNetworkInfo(); + for (NetworkInfo info : networkInfos) { + FileLog.e("tmessages", "Network: " + info.getTypeName() + " status: " + info.getState() + " info: " + info.getExtraInfo() + " object: " + info.getDetailedState() + " other: " + info); + } + if (networkInfos.length == 0) { + FileLog.e("tmessages", "no network available"); + } + } catch (Exception e) { + FileLog.e("tmessages", "NETWORK STATE GET ERROR"); + } + } final int stateCopy = connectionState; Utilities.RunOnUIThread(new Runnable() { @Override @@ -2477,7 +2551,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. public void run() { moveToDatacenter(datacenterId); } - }, 1000); + }, 1000, false); } } }, null, true, RPCRequest.RPCRequestClassGeneric, currentDatacenterId); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ContactsController.java b/TMessagesProj/src/main/java/org/telegram/messenger/ContactsController.java new file mode 100644 index 000000000..cd6a66eca --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ContactsController.java @@ -0,0 +1,1310 @@ +/* + * This is the source code of Telegram for Android v. 1.3.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. + */ + +package org.telegram.messenger; + +import android.accounts.Account; +import android.accounts.AccountManager; +import android.content.ContentProviderOperation; +import android.content.ContentProviderResult; +import android.content.ContentResolver; +import android.database.ContentObserver; +import android.database.Cursor; +import android.net.Uri; +import android.provider.BaseColumns; +import android.provider.ContactsContract; +import android.util.SparseArray; + +import org.telegram.PhoneFormat.PhoneFormat; +import org.telegram.TL.TLObject; +import org.telegram.TL.TLRPC; +import org.telegram.ui.ApplicationLoader; + +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; + +public class ContactsController { + public static ContactsController Instance = new ContactsController(); + private Account currentAccount; + public boolean loadingContacts = false; + private boolean ignoreChanges = false; + private boolean contactsSyncInProgress = false; + private final Integer observerLock = 1; + private HashMap delayedDontactsToDelete = null; + public boolean contactsLoaded = false; + private boolean contactsBookLoaded = false; + private ArrayList delayedContactsUpdate = new ArrayList(); + + public static class Contact { + public int id; + public ArrayList phones = new ArrayList(); + public ArrayList phoneTypes = new ArrayList(); + public ArrayList shortPhones = new ArrayList(); + public ArrayList phoneDeleted = new ArrayList(); + public String first_name; + public String last_name; + } + + private String[] projectioPhones = { + ContactsContract.CommonDataKinds.Phone.CONTACT_ID, + ContactsContract.CommonDataKinds.Phone.NUMBER, + ContactsContract.CommonDataKinds.Phone.TYPE, + ContactsContract.CommonDataKinds.Phone.LABEL + }; + private String[] projectionNames = { + ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID, + ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, + ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, + ContactsContract.Data.DISPLAY_NAME, + ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME + }; + + public HashMap contactsBook = new HashMap(); + public HashMap contactsBookSPhones = new HashMap(); + public HashMap> contactsSectionsDict = new HashMap>(); + public ArrayList sortedContactsSectionsArray = new ArrayList(); + + public ArrayList contacts = new ArrayList(); + public SparseArray contactsDict = new SparseArray(); + public HashMap> usersSectionsDict = new HashMap>(); + public ArrayList sortedUsersSectionsArray = new ArrayList(); + + private class MyContentObserver extends ContentObserver { + + public MyContentObserver() { + super(null); + } + + @Override + public void onChange(boolean selfChange) { + super.onChange(selfChange); + synchronized (observerLock) { + if (ignoreChanges) { + FileLog.e("tmessages", "contacts changed - ignore"); + return; + } + } + + Utilities.stageQueue.postRunnable(new Runnable() { + @Override + public void run() { + MessagesController.Instance.scheduleContactsReload = System.currentTimeMillis() + 2000; + FileLog.e("tmessages", "contacts changed schedule - apply in " + MessagesController.Instance.scheduleContactsReload); + } + }); + } + + @Override + public boolean deliverSelfNotifications() { + return false; + } + } + + public ContactsController() { + Utilities.globalQueue.postRunnable(new Runnable() { + @Override + public void run() { + ApplicationLoader.applicationContext.getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, new MyContentObserver()); + } + }); + } + + public void cleanup() { + contactsBook.clear(); + contactsBookSPhones.clear(); + contactsSectionsDict.clear(); + sortedContactsSectionsArray.clear(); + contacts.clear(); + contactsDict.clear(); + usersSectionsDict.clear(); + sortedUsersSectionsArray.clear(); + delayedContactsUpdate.clear(); + + delayedDontactsToDelete = null; + loadingContacts = false; + contactsSyncInProgress = false; + contactsLoaded = false; + contactsBookLoaded = false; + } + + public void checkAppAccount() { + AccountManager am = AccountManager.get(ApplicationLoader.applicationContext); + Account[] accounts = am.getAccountsByType("org.telegram.messenger.account"); + boolean recreateAccount = false; + if (UserConfig.currentUser != null) { + if (accounts.length == 1) { + Account acc = accounts[0]; + if (!acc.name.equals(UserConfig.currentUser.phone)) { + recreateAccount = true; + } else { + currentAccount = acc; + } + } else { + recreateAccount = true; + } + readContacts(); + } else { + if (accounts.length > 0) { + recreateAccount = true; + } + } + if (recreateAccount) { + for (Account c : accounts) { + am.removeAccount(c, null, null); + } + if (UserConfig.currentUser != null) { + currentAccount = new Account(UserConfig.currentUser.phone, "org.telegram.messenger.account"); + am.addAccountExplicitly(currentAccount, "", null); + } + } + } + + public void readContacts() { + Utilities.stageQueue.postRunnable(new Runnable() { + @Override + public void run() { + if (contactsBook.size() != 0 || contactsSyncInProgress) { + return; + } + contactsSyncInProgress = true; + MessagesStorage.Instance.getCachedPhoneBook(); + } + }); + } + + private HashMap readContactsFromPhoneBook() { + HashMap contactsMap = new HashMap(); + ContentResolver cr = ApplicationLoader.applicationContext.getContentResolver(); + String ids = ""; + Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projectioPhones, null, null, null); + if (pCur != null) { + if (pCur.getCount() > 0) { + while (pCur.moveToNext()) { + String number = pCur.getString(1); + if (number == null || number.length() == 0) { + continue; + } + number = PhoneFormat.stripExceptNumbers(number); + if (number.length() == 0) { + continue; + } + Integer id = pCur.getInt(0); + if (ids.length() != 0) { + ids += ","; + } + ids += id; + + int type = pCur.getInt(2); + Contact contact = contactsMap.get(id); + if (contact == null) { + contact = new Contact(); + contact.first_name = ""; + contact.last_name = ""; + contact.id = id; + contactsMap.put(id, contact); + } + + boolean addNumber = true; + if (number.length() > 8) { + String shortNumber = number.substring(number.length() - 8); + if (contact.shortPhones.contains(shortNumber)) { + addNumber = false; + } else { + contact.shortPhones.add(shortNumber); + } + } else { + if (contact.shortPhones.contains(number)) { + addNumber = false; + } else { + contact.shortPhones.add(number); + } + } + if (addNumber) { + contact.phones.add(number); + contact.phoneDeleted.add(0); + } + + if (type == ContactsContract.CommonDataKinds.Phone.TYPE_CUSTOM) { + contact.phoneTypes.add(pCur.getString(3)); + } else if (type == ContactsContract.CommonDataKinds.Phone.TYPE_HOME) { + contact.phoneTypes.add(ApplicationLoader.applicationContext.getString(R.string.PhoneHome)); + } else if (type == ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE) { + contact.phoneTypes.add(ApplicationLoader.applicationContext.getString(R.string.PhoneMobile)); + } else if (type == ContactsContract.CommonDataKinds.Phone.TYPE_WORK) { + contact.phoneTypes.add(ApplicationLoader.applicationContext.getString(R.string.PhoneWork)); + } else if (type == ContactsContract.CommonDataKinds.Phone.TYPE_MAIN) { + contact.phoneTypes.add(ApplicationLoader.applicationContext.getString(R.string.PhoneMain)); + } else { + contact.phoneTypes.add(ApplicationLoader.applicationContext.getString(R.string.PhoneOther)); + } + } + } + pCur.close(); + } + + pCur = cr.query(ContactsContract.Data.CONTENT_URI, projectionNames, ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID + " IN (" + ids + ") AND " + ContactsContract.Data.MIMETYPE + " = '" + ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE + "'", null, null); + if (pCur != null && pCur.getCount() > 0) { + while (pCur.moveToNext()) { + int id = pCur.getInt(0); + String fname = pCur.getString(1); + String sname = pCur.getString(2); + String sname2 = pCur.getString(3); + String mname = pCur.getString(4); + Contact contact = contactsMap.get(id); + if (contact != null) { + contact.first_name = fname; + contact.last_name = sname; + if (contact.first_name == null) { + contact.first_name = ""; + } + if (mname != null && mname.length() != 0) { + if (contact.first_name.length() != 0) { + contact.first_name += " " + mname; + } else { + contact.first_name = mname; + } + } + if (contact.last_name == null) { + contact.last_name = ""; + } + if (contact.last_name.length() == 0 && contact.first_name.length() == 0 && sname2 != null && sname2.length() != 0) { + contact.first_name = sname2; + } + } + } + pCur.close(); + } + return contactsMap; + } + + public HashMap getContactsCopy(HashMap original) { + HashMap ret = new HashMap(); + for (HashMap.Entry entry : original.entrySet()) { + Contact copyContact = new Contact(); + Contact originalContact = entry.getValue(); + copyContact.phoneDeleted.addAll(originalContact.phoneDeleted); + copyContact.phones.addAll(originalContact.phones); + copyContact.phoneTypes.addAll(originalContact.phoneTypes); + copyContact.shortPhones.addAll(originalContact.shortPhones); + copyContact.first_name = originalContact.first_name; + copyContact.last_name = originalContact.last_name; + copyContact.id = originalContact.id; + ret.put(copyContact.id, copyContact); + } + return ret; + } + + public void performSyncPhoneBook(final HashMap contactHashMap, final boolean request, final boolean first) { + Utilities.globalQueue.postRunnable(new Runnable() { + @Override + public void run() { + FileLog.e("tmessages", "start read contacts from phone"); + final HashMap contactsMap = readContactsFromPhoneBook(); + final HashMap contactsBookShort = new HashMap(); + int oldCount = contactHashMap.size(); + + ArrayList toImport = new ArrayList(); + if (!contactHashMap.isEmpty()) { + HashMap contactsMapCopy = new HashMap(contactsMap); + for (HashMap.Entry pair : contactsMap.entrySet()) { + Integer id = pair.getKey(); + Contact value = pair.getValue(); + Contact existing = contactHashMap.get(id); + + if (existing == null || existing != null && (!existing.first_name.equals(value.first_name) || !existing.last_name.equals(value.last_name))) { + for (int a = 0; a < value.phones.size(); a++) { + String sphone = value.shortPhones.get(a); + contactsBookShort.put(sphone, value); + if (existing != null) { + int index = existing.shortPhones.indexOf(sphone); + if (index != -1) { + Integer deleted = existing.phoneDeleted.get(index); + value.phoneDeleted.set(a, deleted); + if (deleted == 1) { + continue; + } + } + } + if (request) { + TLRPC.TL_inputPhoneContact imp = new TLRPC.TL_inputPhoneContact(); + imp.client_id = id; + imp.first_name = value.first_name; + imp.last_name = value.last_name; + imp.phone = value.phones.get(a); + toImport.add(imp); + } + } + if (existing != null) { + contactHashMap.remove(id); + } + } else { + for (int a = 0; a < value.phones.size(); a++) { + String sphone = value.shortPhones.get(a); + contactsBookShort.put(sphone, value); + int index = existing.shortPhones.indexOf(sphone); + if (index == -1) { + if (request) { + TLRPC.TL_inputPhoneContact imp = new TLRPC.TL_inputPhoneContact(); + imp.client_id = id; + imp.first_name = value.first_name; + imp.last_name = value.last_name; + imp.phone = value.phones.get(a); + toImport.add(imp); + } + } else { + value.phoneDeleted.set(a, existing.phoneDeleted.get(index)); + existing.phones.remove(index); + existing.shortPhones.remove(index); + existing.phoneDeleted.remove(index); + } + } + if (existing.phones.isEmpty()) { + contactHashMap.remove(id); + } + } + } + if (!first && contactHashMap.isEmpty() && toImport.isEmpty() && oldCount == contactsMap.size()) { + FileLog.e("tmessages", "contacts not changed!"); + return; + } + if (request && !contactHashMap.isEmpty() && !contactsMap.isEmpty()) { + if (toImport.isEmpty()) { + MessagesStorage.Instance.putCachedPhoneBook(contactsMap); + } + Utilities.stageQueue.postRunnable(new Runnable() { + @Override + public void run() { + delayedDontactsToDelete = contactHashMap; + FileLog.e("tmessages", "need delete contacts"); + } + }); + } + } else if (request) { + for (HashMap.Entry pair : contactsMap.entrySet()) { + Contact value = pair.getValue(); + int id = pair.getKey(); + for (int a = 0; a < value.phones.size(); a++) { + TLRPC.TL_inputPhoneContact imp = new TLRPC.TL_inputPhoneContact(); + imp.client_id = id; + imp.first_name = value.first_name; + imp.last_name = value.last_name; + imp.phone = value.phones.get(a); + toImport.add(imp); + } + } + } + + Utilities.stageQueue.postRunnable(new Runnable() { + @Override + public void run() { + contactsBookSPhones = contactsBookShort; + contactsBook = contactsMap; + contactsSyncInProgress = false; + contactsBookLoaded = true; + } + }); + + FileLog.e("tmessages", "done procrssing contacts"); + + if (request) { + if (!toImport.isEmpty()) { + FileLog.e("tmessages", "start import contacts"); + TLRPC.TL_contacts_importContacts req = new TLRPC.TL_contacts_importContacts(); + req.contacts = toImport; + req.replace = false; + ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(TLObject response, TLRPC.TL_error error) { + if (error == null) { + FileLog.e("tmessages", "contacts imported"); + MessagesStorage.Instance.putCachedPhoneBook(contactsMap); + TLRPC.TL_contacts_importedContacts res = (TLRPC.TL_contacts_importedContacts)response; + MessagesStorage.Instance.putUsersAndChats(res.users, null, true, true); + ArrayList cArr = new ArrayList(); + for (TLRPC.TL_importedContact c : res.imported) { + TLRPC.TL_contact contact = new TLRPC.TL_contact(); + contact.user_id = c.user_id; + cArr.add(contact); + } + processLoadedContacts(cArr, res.users, 2); + } else { + FileLog.e("tmessages", "import contacts error " + error.text); + } + } + }, null, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors | RPCRequest.RPCRequestClassCanCompress); + } else if (first) { + Utilities.stageQueue.postRunnable(new Runnable() { + @Override + public void run() { + loadContacts(true); + } + }); + } else { + Utilities.RunOnUIThread(new Runnable() { + @Override + public void run() { + updateUnregisteredContacts(contacts); + NotificationCenter.Instance.postNotificationName(MessagesController.contactsDidLoaded); + ArrayList toDelete = getContactsToDelete(contacts, MessagesController.Instance.users, 0); + if (!toDelete.isEmpty()) { + deleteContact(toDelete); + } + } + }); + } + } else { + MessagesStorage.Instance.putCachedPhoneBook(contactsMap); + } + } + }); + } + + public void loadContacts(boolean fromCache) { + Utilities.RunOnUIThread(new Runnable() { + @Override + public void run() { + loadingContacts = true; + } + }); + if (fromCache) { + FileLog.e("tmessages", "load contacts from cache"); + MessagesStorage.Instance.getContacts(); + } else { + FileLog.e("tmessages", "load contacts from server"); + TLRPC.TL_contacts_getContacts req = new TLRPC.TL_contacts_getContacts(); + req.hash = UserConfig.contactsHash; + ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(TLObject response, TLRPC.TL_error error) { + if (error == null) { + TLRPC.contacts_Contacts res = (TLRPC.contacts_Contacts)response; + if (res instanceof TLRPC.TL_contacts_contactsNotModified) { + delayedDontactsToDelete = null; + contactsLoaded = true; + if (!delayedContactsUpdate.isEmpty() && contactsLoaded && contactsBookLoaded) { + applyContactsUpdates(delayedContactsUpdate, null, null, null); + delayedContactsUpdate.clear(); + } + Utilities.RunOnUIThread(new Runnable() { + @Override + public void run() { + loadingContacts = false; + NotificationCenter.Instance.postNotificationName(MessagesController.contactsDidLoaded); + } + }); + return; + } + processLoadedContacts(res.contacts, res.users, 0); + } + } + }, null, true, RPCRequest.RPCRequestClassGeneric); + } + } + + private ArrayList getContactsToDelete(ArrayList contactsArr, AbstractMap usersDict, int from) { + final ArrayList toDelete = new ArrayList(); + if (delayedDontactsToDelete != null && !delayedDontactsToDelete.isEmpty()) { + try { + final HashMap contactsPhonesShort = new HashMap(); + + for (TLRPC.TL_contact value : contactsArr) { + TLRPC.User user = usersDict.get(value.user_id); + if (user == null || user.phone == null || user.phone.length() == 0) { + continue; + } + if (user.phone.length() > 8) { + String shortPhone = user.phone.substring(user.phone.length() - 8); + contactsPhonesShort.put(shortPhone, user); + } else { + contactsPhonesShort.put(user.phone, user); + } + } + int removed = 0; + for (HashMap.Entry entry : delayedDontactsToDelete.entrySet()) { + Contact contact = entry.getValue(); + boolean was = false; + for (int a = 0; a < contact.shortPhones.size(); a++) { + String phone = contact.shortPhones.get(a); + TLRPC.User user = contactsPhonesShort.get(phone); + if (user != null) { + was = true; + toDelete.add(user); + contact.shortPhones.remove(a); + a--; + } + } + if (!was || contact.shortPhones.size() == 0) { + removed++; + } + } + if (from != 2 || removed == delayedDontactsToDelete.size()) { + delayedDontactsToDelete = null; + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + return toDelete; + } + + public void processLoadedContacts(final ArrayList contactsArr, final ArrayList usersArr, final int from) { + //from: + //0 - from server + //1 - from db + //2 - from imported contacts + Utilities.stageQueue.postRunnable(new Runnable() { + @Override + public void run() { + FileLog.e("tmessages", "done loading contacts"); + if (from == 1 && contactsArr.isEmpty()) { + loadContacts(false); + return; + } + final HashMap usersDict = new HashMap(); + for (TLRPC.User user : usersArr) { + usersDict.put(user.id, user); + } + if (from == 1) { + for (TLRPC.TL_contact contact : contactsArr) { + if (usersDict.get(contact.user_id) == null) { + loadContacts(false); + FileLog.e("tmessages", "contacts are broken, load from server"); + return; + } + } + } + + if (from == 0 || from == 2) { + MessagesStorage.Instance.putUsersAndChats(usersArr, null, true, true); + MessagesStorage.Instance.putContacts(contactsArr, true); + Collections.sort(contactsArr, new Comparator() { + @Override + public int compare(TLRPC.TL_contact tl_contact, TLRPC.TL_contact tl_contact2) { + if (tl_contact.user_id > tl_contact2.user_id) { + return 1; + } else if (tl_contact.user_id < tl_contact2.user_id) { + return -1; + } + return 0; + } + }); + String ids = ""; + for (TLRPC.TL_contact aContactsArr : contactsArr) { + if (ids.length() != 0) { + ids += ","; + } + ids += aContactsArr.user_id; + } + UserConfig.contactsHash = Utilities.MD5(ids); + UserConfig.saveConfig(false); + if (from == 2) { + loadContacts(false); + } + } + + Collections.sort(contactsArr, new Comparator() { + @Override + public int compare(TLRPC.TL_contact tl_contact, TLRPC.TL_contact tl_contact2) { + TLRPC.User user1 = usersDict.get(tl_contact.user_id); + TLRPC.User user2 = usersDict.get(tl_contact2.user_id); + String name1 = user1.first_name; + if (name1 == null || name1.length() == 0) { + name1 = user1.last_name; + } + String name2 = user2.first_name; + if (name2 == null || name2.length() == 0) { + name2 = user2.last_name; + } + return name1.compareTo(name2); + } + }); + + final SparseArray contactsDictionary = new SparseArray(); + final HashMap> sectionsDict = new HashMap>(); + final ArrayList sortedSectionsArray = new ArrayList(); + + for (TLRPC.TL_contact value : contactsArr) { + TLRPC.User user = usersDict.get(value.user_id); + if (user == null) { + continue; + } + contactsDictionary.put(value.user_id, value); + + String key = user.first_name; + if (key == null || key.length() == 0) { + key = user.last_name; + } + if (key.length() == 0) { + key = "#"; + } else { + key = key.toUpperCase(); + } + if (key.length() > 1) { + key = key.substring(0, 1); + } + ArrayList arr = sectionsDict.get(key); + if (arr == null) { + arr = new ArrayList(); + sectionsDict.put(key, arr); + sortedSectionsArray.add(key); + } + arr.add(value); + } + + Collections.sort(sortedSectionsArray, new Comparator() { + @Override + public int compare(String s, String s2) { + char cv1 = s.charAt(0); + char cv2 = s2.charAt(0); + if (cv1 == '#') { + return 1; + } else if (cv2 == '#') { + return -1; + } + return s.compareTo(s2); + } + }); + + final ArrayList toDelete = getContactsToDelete(contactsArr, usersDict, from); + + if (from != 2) { + contactsLoaded = true; + } + + if (!delayedContactsUpdate.isEmpty() && contactsLoaded && contactsBookLoaded) { + applyContactsUpdates(delayedContactsUpdate, null, null, null); + delayedContactsUpdate.clear(); + } + + Utilities.RunOnUIThread(new Runnable() { + @Override + public void run() { + for (TLRPC.User user : usersArr) { + if (from == 1) { + MessagesController.Instance.users.putIfAbsent(user.id, user); + } else { + MessagesController.Instance.users.put(user.id, user); + if (user.id == UserConfig.clientUserId) { + UserConfig.currentUser = user; + } + } + } + contacts = contactsArr; + contactsDict = contactsDictionary; + usersSectionsDict = sectionsDict; + sortedUsersSectionsArray = sortedSectionsArray; + if (from != 2) { + loadingContacts = false; + } + performWriteContactsToPhoneBook(); + updateUnregisteredContacts(contactsArr); + + NotificationCenter.Instance.postNotificationName(MessagesController.contactsDidLoaded); + + if (!toDelete.isEmpty()) { + deleteContact(toDelete); + } + } + }); + } + }); + } + + private void updateUnregisteredContacts(final ArrayList contactsArr) { + final HashMap contactsPhonesShort = new HashMap(); + + for (TLRPC.TL_contact value : contactsArr) { + TLRPC.User user = MessagesController.Instance.users.get(value.user_id); + if (user == null || user.phone == null || user.phone.length() == 0) { + continue; + } + if (user.phone.length() > 8) { + String shortPhone = user.phone.substring(user.phone.length() - 8); + contactsPhonesShort.put(shortPhone, value); + } else { + contactsPhonesShort.put(user.phone, value); + } + } + + final HashMap> sectionsPhoneDict = new HashMap>(); + final ArrayList sortedSectionsPhoneArray = new ArrayList(); + for (HashMap.Entry pair : contactsBook.entrySet()) { + Contact value = pair.getValue(); + int id = pair.getKey(); + + boolean skip = false; + for (int a = 0; a < value.phones.size(); a++) { + String sphone = value.shortPhones.get(a); + if (contactsPhonesShort.containsKey(sphone) || value.phoneDeleted.get(a) == 1) { + skip = true; + break; + } + } + if (skip) { + continue; + } + + String key = value.first_name; + if (key.length() == 0) { + key = value.last_name; + } + if (key.length() == 0) { + key = "#"; + if (value.phones.size() != 0) { + value.first_name = "+" + value.phones.get(0); + } + } else { + key = key.toUpperCase(); + } + if (key.length() > 1) { + key = key.substring(0, 1); + } + ArrayList arr = sectionsPhoneDict.get(key); + if (arr == null) { + arr = new ArrayList(); + sectionsPhoneDict.put(key, arr); + sortedSectionsPhoneArray.add(key); + } + arr.add(value); + } + for (HashMap.Entry> entry : sectionsPhoneDict.entrySet()) { + Collections.sort(entry.getValue(), new Comparator() { + @Override + public int compare(Contact contact, Contact contact2) { + String toComapre1 = contact.first_name; + if (toComapre1.length() == 0) { + toComapre1 = contact.last_name; + } + String toComapre2 = contact2.first_name; + if (toComapre2.length() == 0) { + toComapre2 = contact2.last_name; + } + return toComapre1.compareTo(toComapre2); + } + }); + } + Collections.sort(sortedSectionsPhoneArray, new Comparator() { + @Override + public int compare(String s, String s2) { + char cv1 = s.charAt(0); + char cv2 = s2.charAt(0); + if (cv1 == '#') { + return 1; + } else if (cv2 == '#') { + return -1; + } + return s.compareTo(s2); + } + }); + + contactsSectionsDict = sectionsPhoneDict; + sortedContactsSectionsArray = sortedSectionsPhoneArray; + } + + private void buildContactsSectionsArrays(boolean sort) { + if (sort) { + Collections.sort(contacts, new Comparator() { + @Override + public int compare(TLRPC.TL_contact tl_contact, TLRPC.TL_contact tl_contact2) { + TLRPC.User user1 = MessagesController.Instance.users.get(tl_contact.user_id); + TLRPC.User user2 = MessagesController.Instance.users.get(tl_contact2.user_id); + String name1 = user1.first_name; + if (name1 == null || name1.length() == 0) { + name1 = user1.last_name; + } + String name2 = user2.first_name; + if (name2 == null || name2.length() == 0) { + name2 = user2.last_name; + } + return name1.compareTo(name2); + } + }); + } + + String ids = ""; + final HashMap> sectionsDict = new HashMap>(); + final ArrayList sortedSectionsArray = new ArrayList(); + + for (TLRPC.TL_contact value : contacts) { + TLRPC.User user = MessagesController.Instance.users.get(value.user_id); + if (user == null) { + continue; + } + + String key = user.first_name; + if (key == null || key.length() == 0) { + key = user.last_name; + } + if (key.length() == 0) { + key = "#"; + } else { + key = key.toUpperCase(); + } + if (key.length() > 1) { + key = key.substring(0, 1); + } + ArrayList arr = sectionsDict.get(key); + if (arr == null) { + arr = new ArrayList(); + sectionsDict.put(key, arr); + sortedSectionsArray.add(key); + } + arr.add(value); + if (ids.length() != 0) { + ids += ","; + } + ids += value.user_id; + } + UserConfig.contactsHash = Utilities.MD5(ids); + UserConfig.saveConfig(false); + + Collections.sort(sortedSectionsArray, new Comparator() { + @Override + public int compare(String s, String s2) { + char cv1 = s.charAt(0); + char cv2 = s2.charAt(0); + if (cv1 == '#') { + return 1; + } else if (cv2 == '#') { + return -1; + } + return s.compareTo(s2); + } + }); + + usersSectionsDict = sectionsDict; + sortedUsersSectionsArray = sortedSectionsArray; + } + + private void performWriteContactsToPhoneBook() { + Utilities.globalQueue.postRunnable(new Runnable() { + @Override + public void run() { + try { + Uri rawContactUri = ContactsContract.RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, currentAccount.name).appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, currentAccount.type).build(); + Cursor c1 = ApplicationLoader.applicationContext.getContentResolver().query(rawContactUri, new String[]{BaseColumns._ID, ContactsContract.RawContacts.SYNC2}, null, null, null); + HashMap bookContacts = new HashMap(); + if (c1 != null) { + while (c1.moveToNext()) { + bookContacts.put(c1.getInt(1), c1.getLong(0)); + } + c1.close(); + + for (TLRPC.TL_contact u : contacts) { + if (!bookContacts.containsKey(u.user_id)) { + TLRPC.User user = MessagesController.Instance.users.get(u.user_id); + addContactToPhoneBook(user); + } + } + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + } + + private void applyContactsUpdates(ArrayList ids, ConcurrentHashMap userDict, ArrayList newC, ArrayList contactsTD) { + if (newC == null || contactsTD == null) { + newC = new ArrayList(); + contactsTD = new ArrayList(); + for (Integer uid : ids) { + if (uid > 0) { + TLRPC.TL_contact contact = new TLRPC.TL_contact(); + contact.user_id = uid; + newC.add(contact); + if (!delayedContactsUpdate.isEmpty()) { + int idx = delayedContactsUpdate.indexOf(-uid); + if (idx != -1) { + delayedContactsUpdate.remove(idx); + } + } + } else if (uid < 0) { + contactsTD.add(-uid); + if (!delayedContactsUpdate.isEmpty()) { + int idx = delayedContactsUpdate.indexOf(-uid); + if (idx != -1) { + delayedContactsUpdate.remove(idx); + } + } + } + } + } + FileLog.e("tmessages", "process update - contacts add = " + newC.size() + " delete = " + contactsTD.size()); + + String toAdd = ""; + String toDelete = ""; + boolean reloadContacts = false; + + for (TLRPC.TL_contact newContact : newC) { + TLRPC.User user = null; + if (userDict != null) { + user = userDict.get(newContact.user_id); + } + if (user == null) { + user = MessagesController.Instance.users.get(newContact.user_id); + } + if (user == null || user.phone == null && user.phone.length() == 0) { + reloadContacts = true; + continue; + } + + String phone = user.phone; + if (phone.length() > 8) { + phone = phone.substring(phone.length() - 8); + } + Contact contact = contactsBookSPhones.get(phone); + if (contact != null) { + int index = contact.shortPhones.indexOf(phone); + if (index != -1) { + contact.phoneDeleted.set(index, 0); + } + } + if (toAdd.length() != 0) { + toAdd += ","; + } + toAdd += phone; + } + + for (final Integer uid : contactsTD) { + Utilities.globalQueue.postRunnable(new Runnable() { + @Override + public void run() { + deleteContactFromPhoneBook(uid); + } + }); + + TLRPC.User user = null; + if (userDict != null) { + user = userDict.get(uid); + } + if (user == null) { + user = MessagesController.Instance.users.get(uid); + } + if (user == null) { + reloadContacts = true; + continue; + } + + if (user.phone != null && user.phone.length() > 0) { + String phone = user.phone; + if (phone.length() > 8) { + phone = phone.substring(phone.length() - 8); + } + Contact contact = contactsBookSPhones.get(phone); + if (contact != null) { + int index = contact.shortPhones.indexOf(phone); + if (index != -1) { + contact.phoneDeleted.set(index, 1); + } + } + if (toDelete.length() != 0) { + toDelete += ","; + } + toDelete += phone; + } + } + + if (toAdd.length() != 0 || toDelete.length() != 0) { + MessagesStorage.Instance.applyPhoneBookUpdates(toAdd, toDelete); + } + + if (reloadContacts) { + Utilities.stageQueue.postRunnable(new Runnable() { + @Override + public void run() { + loadContacts(false); + } + }); + } else { + final ArrayList newContacts = newC; + final ArrayList contactsToDelete = contactsTD; + Utilities.RunOnUIThread(new Runnable() { + @Override + public void run() { + for (TLRPC.TL_contact contact : newContacts) { + if (contactsDict.get(contact.user_id) == null) { + contacts.add(contact); + contactsDict.put(contact.user_id, contact); + } + } + for (Integer uid : contactsToDelete) { + TLRPC.TL_contact contact = contactsDict.get(uid); + if (contact != null) { + contacts.remove(contact); + contactsDict.remove(uid); + } + } + if (!newContacts.isEmpty()) { + updateUnregisteredContacts(contacts); + performWriteContactsToPhoneBook(); + } + performSyncPhoneBook(getContactsCopy(contactsBook), false, false); + buildContactsSectionsArrays(!newContacts.isEmpty()); + NotificationCenter.Instance.postNotificationName(MessagesController.contactsDidLoaded); + } + }); + } + } + + public void processContactsUpdates(ArrayList ids, ConcurrentHashMap userDict) { + final ArrayList newContacts = new ArrayList(); + final ArrayList contactsToDelete = new ArrayList(); + for (Integer uid : ids) { + if (uid > 0) { + TLRPC.TL_contact contact = new TLRPC.TL_contact(); + contact.user_id = uid; + newContacts.add(contact); + if (!delayedContactsUpdate.isEmpty()) { + int idx = delayedContactsUpdate.indexOf(-uid); + if (idx != -1) { + delayedContactsUpdate.remove(idx); + } + } + } else if (uid < 0) { + contactsToDelete.add(-uid); + if (!delayedContactsUpdate.isEmpty()) { + int idx = delayedContactsUpdate.indexOf(-uid); + if (idx != -1) { + delayedContactsUpdate.remove(idx); + } + } + } + } + if (!contactsToDelete.isEmpty()) { + MessagesStorage.Instance.deleteContacts(contactsToDelete); + } + if (!newContacts.isEmpty()) { + MessagesStorage.Instance.putContacts(newContacts, false); + } + if (!contactsLoaded || !contactsBookLoaded) { + delayedContactsUpdate.addAll(ids); + FileLog.e("tmessages", "delay update - contacts add = " + newContacts.size() + " delete = " + contactsToDelete.size()); + } else { + applyContactsUpdates(ids, userDict, newContacts, contactsToDelete); + } + } + + public long addContactToPhoneBook(TLRPC.User user) { + if (currentAccount == null || user == null || user.phone == null || user.phone.length() == 0) { + return -1; + } + long res = -1; + synchronized (observerLock) { + ignoreChanges = true; + } + ArrayList query = new ArrayList(); + + ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI); + builder.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, currentAccount.name); + builder.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, currentAccount.type); + builder.withValue(ContactsContract.RawContacts.SYNC1, user.phone); + builder.withValue(ContactsContract.RawContacts.SYNC2, user.id); + query.add(builder.build()); + + builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI); + builder.withValueBackReference(ContactsContract.CommonDataKinds.StructuredName.RAW_CONTACT_ID, 0); + builder.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE); + builder.withValue(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, user.first_name); + builder.withValue(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, user.last_name); + query.add(builder.build()); + + builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI); + builder.withValueBackReference(ContactsContract.CommonDataKinds.StructuredName.RAW_CONTACT_ID, 0); + builder.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE); + builder.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, "+" + user.phone); + builder.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE); + query.add(builder.build()); + + builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI); + builder.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0); + builder.withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/vnd.org.telegram.messenger.android.profile"); + builder.withValue(ContactsContract.Data.DATA1, "+" + user.phone); + builder.withValue(ContactsContract.Data.DATA2, "Telegram Profile"); + builder.withValue(ContactsContract.Data.DATA3, "+" + user.phone); + builder.withValue(ContactsContract.Data.DATA4, user.id); + query.add(builder.build()); + try { + ContentProviderResult[] result = ApplicationLoader.applicationContext.getContentResolver().applyBatch(ContactsContract.AUTHORITY, query); + res = Long.parseLong(result[0].uri.getLastPathSegment()); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + synchronized (observerLock) { + ignoreChanges = false; + } + return res; + } + + private void deleteContactFromPhoneBook(int uid) { + ContentResolver contentResolver = ApplicationLoader.applicationContext.getContentResolver(); + synchronized (observerLock) { + ignoreChanges = true; + } + try { + Uri rawContactUri = ContactsContract.RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true").appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, currentAccount.name).appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_TYPE, currentAccount.type).build(); + int value = contentResolver.delete(rawContactUri, ContactsContract.RawContacts.SYNC2 + " = " + uid, null); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + synchronized (observerLock) { + ignoreChanges = false; + } + } + + public void addContact(TLRPC.User user) { + if (user == null) { + return; + } + + TLRPC.TL_contacts_importContacts req = new TLRPC.TL_contacts_importContacts(); + ArrayList contactsParams = new ArrayList(); + TLRPC.TL_inputPhoneContact c = new TLRPC.TL_inputPhoneContact(); + c.phone = user.phone; + c.first_name = user.first_name; + c.last_name = user.last_name; + c.client_id = 0; + contactsParams.add(c); + req.contacts = contactsParams; + req.replace = false; + ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(TLObject response, TLRPC.TL_error error) { + if (error != null) { + return; + } + final TLRPC.TL_contacts_importedContacts res = (TLRPC.TL_contacts_importedContacts)response; + MessagesStorage.Instance.putUsersAndChats(res.users, null, true, true); + + for (final TLRPC.User u : res.users) { + Utilities.globalQueue.postRunnable(new Runnable() { + @Override + public void run() { + addContactToPhoneBook(u); + } + }); + TLRPC.TL_contact newContact = new TLRPC.TL_contact(); + newContact.user_id = u.id; + ArrayList arrayList = new ArrayList(); + arrayList.add(newContact); + MessagesStorage.Instance.putContacts(arrayList, false); + + if (u.phone != null && u.phone.length() > 0) { + String name = Utilities.formatName(u.first_name, u.last_name); + String phone = u.phone; + if (phone.length() > 8) { + phone = phone.substring(phone.length() - 8); + } + MessagesStorage.Instance.applyPhoneBookUpdates(phone, ""); + Contact contact = contactsBookSPhones.get(phone); + if (contact != null) { + int index = contact.shortPhones.indexOf(phone); + if (index != -1) { + contact.phoneDeleted.set(index, 0); + } + } + } + } + + performSyncPhoneBook(getContactsCopy(contactsBook), false, false); + + Utilities.RunOnUIThread(new Runnable() { + @Override + public void run() { + for (TLRPC.User u : res.users) { + MessagesController.Instance.users.put(u.id, u); + if (contactsDict.get(u.id) == null) { + TLRPC.TL_contact newContact = new TLRPC.TL_contact(); + newContact.user_id = u.id; + contacts.add(newContact); + contactsDict.put(newContact.user_id, newContact); + } + } + buildContactsSectionsArrays(true); + NotificationCenter.Instance.postNotificationName(MessagesController.contactsDidLoaded); + } + }); + } + }, null, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors | RPCRequest.RPCRequestClassCanCompress); + } + + public void deleteContact(final ArrayList users) { + if (users == null || users.isEmpty()) { + return; + } + TLRPC.TL_contacts_deleteContacts req = new TLRPC.TL_contacts_deleteContacts(); + final ArrayList uids = new ArrayList(); + for (TLRPC.User user : users) { + TLRPC.InputUser inputUser = MessagesController.getInputUser(user); + if (inputUser == null) { + continue; + } + uids.add(user.id); + req.id.add(inputUser); + } + ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(TLObject response, TLRPC.TL_error error) { + if (error != null) { + return; + } + MessagesStorage.Instance.deleteContacts(uids); + Utilities.globalQueue.postRunnable(new Runnable() { + @Override + public void run() { + for (TLRPC.User user : users) { + deleteContactFromPhoneBook(user.id); + } + } + }); + + for (TLRPC.User user : users) { + if (user.phone != null && user.phone.length() > 0) { + String name = Utilities.formatName(user.first_name, user.last_name); + String phone = user.phone; + if (phone.length() > 8) { + phone = phone.substring(phone.length() - 8); + } + MessagesStorage.Instance.applyPhoneBookUpdates(phone, ""); + Contact contact = contactsBookSPhones.get(phone); + if (contact != null) { + int index = contact.shortPhones.indexOf(phone); + if (index != -1) { + contact.phoneDeleted.set(index, 1); + } + } + } + } + + Utilities.RunOnUIThread(new Runnable() { + @Override + public void run() { + boolean remove = false; + for (TLRPC.User user : users) { + TLRPC.TL_contact contact = contactsDict.get(user.id); + if (contact != null) { + remove = true; + contacts.remove(contact); + contactsDict.remove(user.id); + } + } + if (remove) { + buildContactsSectionsArrays(false); + } + NotificationCenter.Instance.postNotificationName(MessagesController.updateInterfaces, MessagesController.UPDATE_MASK_NAME); + NotificationCenter.Instance.postNotificationName(MessagesController.contactsDidLoaded); + } + }); + } + }, null, true, RPCRequest.RPCRequestClassGeneric); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/DispatchQueue.java b/TMessagesProj/src/main/java/org/telegram/messenger/DispatchQueue.java index 00d974daa..d4d6ed09e 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/DispatchQueue.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/DispatchQueue.java @@ -42,10 +42,14 @@ public class DispatchQueue extends Thread { } public void postRunnable(Runnable runnable) { - postRunnable(runnable, 0); + postRunnable(runnable, 0, false); } - public void postRunnable(Runnable runnable, int delay) { + public void postRunnable(Runnable runnable, boolean inFront) { + postRunnable(runnable, 0, true); + } + + public void postRunnable(Runnable runnable, int delay, boolean inFront) { if (handler == null) { try { synchronized (handlerSyncObject) { @@ -58,7 +62,11 @@ public class DispatchQueue extends Thread { if (handler != null) { if (delay <= 0) { - handler.post(runnable); + if (inFront) { + handler.postAtFrontOfQueue(runnable); + } else { + handler.post(runnable); + } } else { handler.postDelayed(runnable, delay); } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/ExportAuthorizationAction.java b/TMessagesProj/src/main/java/org/telegram/messenger/ExportAuthorizationAction.java index 355dd8512..9fe4965f3 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/ExportAuthorizationAction.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/ExportAuthorizationAction.java @@ -53,7 +53,7 @@ public class ExportAuthorizationAction extends Action { public void run() { beginExport(); } - }, retryCount * 1500); + }, retryCount * 1500, false); } } } @@ -84,7 +84,7 @@ public class ExportAuthorizationAction extends Action { public void run() { beginExport(); } - }, retryCount * 1500); + }, retryCount * 1500, false); } } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java index f6d38bc08..93f2b9568 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoadOperation.java @@ -420,7 +420,12 @@ public class FileLoadOperation { if (renamed) { image = BitmapFactory.decodeStream(new FileInputStream(cacheFileFinal), null, opts); } else { - image = BitmapFactory.decodeStream(new FileInputStream(cacheFileTemp), null, opts); + try { + image = BitmapFactory.decodeStream(new FileInputStream(cacheFileTemp), null, opts); + } catch (Exception e) { + FileLog.e("tmessages", e); + image = BitmapFactory.decodeStream(new FileInputStream(cacheFileFinal), null, opts); + } } if (filter != null && image != null) { float bitmapW = image.getWidth(); @@ -440,10 +445,11 @@ public class FileLoadOperation { if (FileLoader.Instance.runtimeHack != null) { FileLoader.Instance.runtimeHack.trackFree(image.getRowBytes() * image.getHeight()); } + delegate.didFinishLoadingFile(FileLoadOperation.this); } catch (Exception e) { FileLog.e("tmessages", e); + delegate.didFailedLoadingFile(FileLoadOperation.this); } - delegate.didFinishLoadingFile(FileLoadOperation.this); } }); } else { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java index 13fb988fc..1bd9f831b 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileLoader.java @@ -15,13 +15,12 @@ import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.media.ExifInterface; import android.os.Build; -import android.view.View; -import android.widget.ImageView; import org.telegram.TL.TLRPC; import org.telegram.objects.MessageObject; import org.telegram.ui.ApplicationLoader; import org.telegram.ui.Views.BackupImageView; +import org.telegram.ui.Views.ImageReceiver; import java.io.ByteArrayOutputStream; import java.io.File; @@ -134,29 +133,28 @@ public class FileLoader { private class CacheImage { public String key; - public ArrayList imageViewArray; + final public ArrayList imageViewArray = new ArrayList(); public FileLoadOperation loadOperation; - public void addImageView(View imageView) { - if (imageViewArray == null) { - imageViewArray = new ArrayList(); - } - boolean exist = false; - for (View v : imageViewArray) { - if (v == imageView) { - exist = true; - break; + public void addImageView(Object imageView) { + synchronized (imageViewArray) { + boolean exist = false; + for (Object v : imageViewArray) { + if (v == imageView) { + exist = true; + break; + } + } + if (!exist) { + imageViewArray.add(imageView); } - } - if (!exist) { - imageViewArray.add(imageView); } } - public void removeImageView(View imageView) { - if (imageViewArray != null) { + public void removeImageView(Object imageView) { + synchronized (imageViewArray) { for (int a = 0; a < imageViewArray.size(); a++) { - View obj = imageViewArray.get(a); + Object obj = imageViewArray.get(a); if (obj == null || obj == imageView) { imageViewArray.remove(a); a--; @@ -166,19 +164,23 @@ public class FileLoader { } public void callAndClear(Bitmap image) { - if (image != null) { - for (View imgView : imageViewArray) { - if (imgView instanceof BackupImageView) { - ((BackupImageView)imgView).setImageBitmap(image, key); - } else if (imgView instanceof ImageView) { - ((ImageView)imgView).setImageBitmap(image); + synchronized (imageViewArray) { + if (image != null) { + for (Object imgView : imageViewArray) { + if (imgView instanceof BackupImageView) { + ((BackupImageView)imgView).setImageBitmap(image, key); + } else if (imgView instanceof ImageReceiver) { + ((ImageReceiver)imgView).setImageBitmap(image, key); + } } } } Utilities.imageLoadQueue.postRunnable(new Runnable() { @Override public void run() { - imageViewArray.clear(); + synchronized (imageViewArray) { + imageViewArray.clear(); + } loadOperation = null; } }); @@ -189,7 +191,9 @@ public class FileLoader { loadOperation.cancel(); loadOperation = null; } - imageViewArray.clear(); + synchronized (imageViewArray) { + imageViewArray.clear(); + } } } @@ -548,25 +552,42 @@ public class FileLoader { memCache.evictAll(); } - public void cancelLoadingForImageView(final View imageView) { + private Integer getTag(Object obj) { + if (obj instanceof BackupImageView) { + return (Integer)((BackupImageView)obj).getTag(R.string.CacheTag); + } else if (obj instanceof ImageReceiver) { + return ((ImageReceiver)obj).TAG; + } + return 0; + } + + private void setTag(Object obj, Integer tag) { + if (obj instanceof BackupImageView) { + ((BackupImageView)obj).setTag(R.string.CacheTag, tag); + } else if (obj instanceof ImageReceiver) { + ((ImageReceiver)obj).TAG = tag; + } + } + + public void cancelLoadingForImageView(final Object imageView) { if (imageView == null) { return; } Utilities.imageLoadQueue.postRunnable(new Runnable() { @Override public void run() { - Integer num = (Integer)imageView.getTag(R.string.CacheTag); - if (num == null) { - num = lastImageNum; - imageView.setTag(R.string.CacheTag, num); + Integer TAG = getTag(imageView); + if (TAG == null) { + TAG = lastImageNum; + setTag(imageView, TAG); lastImageNum++; if (lastImageNum == Integer.MAX_VALUE) { lastImageNum = 0; } } - CacheImage ei = imageLoadingByKeys.get(num); + CacheImage ei = imageLoadingByKeys.get(TAG); if (ei != null) { - imageLoadingByKeys.remove(num); + imageLoadingByKeys.remove(TAG); ei.removeImageView(imageView); if (ei.imageViewArray.size() == 0) { checkOperationsAndClear(ei.loadOperation); @@ -578,17 +599,18 @@ public class FileLoader { }); } - public Bitmap getImageFromMemory(TLRPC.FileLocation url, View imageView, String filter, boolean cancel) { + public Bitmap getImageFromMemory(TLRPC.FileLocation url, Object imageView, String filter, boolean cancel) { return getImageFromMemory(url, null, imageView, filter, cancel); } - public Bitmap getImageFromMemory(String url, View imageView, String filter, boolean cancel) { + public Bitmap getImageFromMemory(String url, Object imageView, String filter, boolean cancel) { return getImageFromMemory(null, url, imageView, filter, cancel); } - public Bitmap getImageFromMemory(TLRPC.FileLocation url, String httpUrl, View imageView, String filter, boolean cancel) { - if ((url == null && httpUrl == null) || imageView == null) + public Bitmap getImageFromMemory(TLRPC.FileLocation url, String httpUrl, Object imageView, String filter, boolean cancel) { + if (url == null && httpUrl == null) { return null; + } String key; if (httpUrl != null) { key = Utilities.MD5(httpUrl); @@ -600,7 +622,7 @@ public class FileLoader { } Bitmap img = imageFromKey(key); - if (img != null && cancel) { + if (imageView != null && img != null && cancel) { cancelLoadingForImageView(imageView); } return img; @@ -637,19 +659,19 @@ public class FileLoader { }); } - public void loadImage(final String url, final View imageView, final String filter, final boolean cancel) { + public void loadImage(final String url, final Object imageView, final String filter, final boolean cancel) { loadImage(null, url, imageView, filter, cancel, 0); } - public void loadImage(final TLRPC.FileLocation url, final View imageView, final String filter, final boolean cancel) { + public void loadImage(final TLRPC.FileLocation url, final Object imageView, final String filter, final boolean cancel) { loadImage(url, null, imageView, filter, cancel, 0); } - public void loadImage(final TLRPC.FileLocation url, final View imageView, final String filter, final boolean cancel, final int size) { + public void loadImage(final TLRPC.FileLocation url, final Object imageView, final String filter, final boolean cancel, final int size) { loadImage(url, null, imageView, filter, cancel, size); } - public void loadImage(final TLRPC.FileLocation url, final String httpUrl, final View imageView, final String filter, final boolean cancel, final int size) { + public void loadImage(final TLRPC.FileLocation url, final String httpUrl, final Object imageView, final String filter, final boolean cancel, final int size) { if ((url == null && httpUrl == null) || imageView == null || (url != null && !(url instanceof TLRPC.TL_fileLocation) && !(url instanceof TLRPC.TL_fileEncryptedLocation))) { return; } @@ -666,10 +688,10 @@ public class FileLoader { key += "@" + filter; } - Integer num = (Integer)imageView.getTag(R.string.CacheTag); - if (num == null) { - num = lastImageNum; - imageView.setTag(R.string.CacheTag, num); + Integer TAG = getTag(imageView); + if (TAG == null) { + TAG = lastImageNum; + setTag(imageView, TAG); lastImageNum++; if (lastImageNum == Integer.MAX_VALUE) lastImageNum = 0; @@ -679,7 +701,7 @@ public class FileLoader { boolean addToByKeys = true; CacheImage alreadyLoadingImage = imageLoading.get(key); if (cancel) { - CacheImage ei = imageLoadingByKeys.get(num); + CacheImage ei = imageLoadingByKeys.get(TAG); if (ei != null) { if (ei != alreadyLoadingImage) { ei.removeImageView(imageView); @@ -697,7 +719,7 @@ public class FileLoader { if (alreadyLoadingImage != null && addToByKeys) { alreadyLoadingImage.addImageView(imageView); - imageLoadingByKeys.put(num, alreadyLoadingImage); + imageLoadingByKeys.put(TAG, alreadyLoadingImage); added = true; } @@ -705,7 +727,7 @@ public class FileLoader { final CacheImage img = new CacheImage(); img.key = key; img.addImageView(imageView); - imageLoadingByKeys.put(num, img); + imageLoadingByKeys.put(TAG, img); imageLoading.put(key, img); final String arg2 = key; @@ -744,9 +766,8 @@ public class FileLoader { Utilities.imageLoadQueue.postRunnable(new Runnable() { @Override public void run() { - for (View view : img.imageViewArray) { - Integer num = (Integer)view.getTag(R.string.CacheTag); - imageLoadingByKeys.remove(num); + for (Object view : img.imageViewArray) { + imageLoadingByKeys.remove(getTag(view)); imageLoading.remove(arg2); checkOperationsAndClear(operation); } @@ -814,15 +835,16 @@ public class FileLoader { } } - public void processImage(Bitmap image, View imageView, String filter, boolean cancel) { + public void processImage(Bitmap image, Object imageView, String filter, boolean cancel) { if (filter == null || imageView == null) { return; } - Integer num = (Integer)imageView.getTag(R.string.CacheTag); - if (num == null) { - num = lastImageNum; - imageView.setTag(R.string.CacheTag, num); + + Integer TAG = getTag(imageView); + if (TAG == null) { + TAG = lastImageNum; + setTag(image, TAG); lastImageNum++; if (lastImageNum == Integer.MAX_VALUE) lastImageNum = 0; @@ -832,7 +854,7 @@ public class FileLoader { boolean addToByKeys = true; CacheImage alreadyLoadingImage = imageLoading.get(filter); if (cancel) { - CacheImage ei = imageLoadingByKeys.get(num); + CacheImage ei = imageLoadingByKeys.get(TAG); if (ei != null) { if (ei != alreadyLoadingImage) { ei.removeImageView(imageView); @@ -850,7 +872,7 @@ public class FileLoader { if (alreadyLoadingImage != null && addToByKeys) { alreadyLoadingImage.addImageView(imageView); - imageLoadingByKeys.put(num, alreadyLoadingImage); + imageLoadingByKeys.put(TAG, alreadyLoadingImage); added = true; } @@ -858,7 +880,7 @@ public class FileLoader { CacheImage img = new CacheImage(); img.key = filter; img.addImageView(imageView); - imageLoadingByKeys.put(num, img); + imageLoadingByKeys.put(TAG, img); imageLoading.put(filter, img); enqueueImageProcessingOperationWithImage(image, filter, filter, img); @@ -873,9 +895,8 @@ public class FileLoader { Utilities.imageLoadQueue.postRunnable(new Runnable() { @Override public void run() { - for (View v : img.imageViewArray) { - Integer num = (Integer)v.getTag(R.string.CacheTag); - imageLoadingByKeys.remove(num); + for (Object v : img.imageViewArray) { + imageLoadingByKeys.remove(getTag(v)); } checkOperationsAndClear(img.loadOperation); imageLoading.remove(key); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileLog.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileLog.java index 00ce841ef..c4679fe80 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileLog.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileLog.java @@ -118,6 +118,8 @@ public class FileLog { } } }); + } else { + e.printStackTrace(); } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/FileUploadOperation.java b/TMessagesProj/src/main/java/org/telegram/messenger/FileUploadOperation.java index ea1877655..9077a8a2e 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/FileUploadOperation.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/FileUploadOperation.java @@ -109,7 +109,16 @@ public class FileUploadOperation { isBigFile = true; } - uploadChunkSize = (int)Math.max(32, Math.ceil(totalFileSize / (1024.0f * 3000))) * 1024; + uploadChunkSize = (int)Math.max(32, Math.ceil(totalFileSize / (1024.0f * 3000))); + if (1024 % uploadChunkSize != 0) { + int chunkSize = 64; + while (uploadChunkSize > chunkSize) { + chunkSize *= 2; + } + uploadChunkSize = chunkSize; + } + + uploadChunkSize *= 1024; totalPartsCount = (int)Math.ceil((float)totalFileSize / (float)uploadChunkSize); readBuffer = new byte[uploadChunkSize]; } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/GcmBroadcastReceiver.java b/TMessagesProj/src/main/java/org/telegram/messenger/GcmBroadcastReceiver.java index 22b8a1096..e045bfc92 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/GcmBroadcastReceiver.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/GcmBroadcastReceiver.java @@ -14,6 +14,7 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; +import android.os.PowerManager; import com.google.android.gms.gcm.GoogleCloudMessaging; @@ -27,6 +28,10 @@ public class GcmBroadcastReceiver extends BroadcastReceiver { setResultCode(Activity.RESULT_OK); if (intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) { + PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE); + final PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "lock"); + wl.acquire(); + SharedPreferences preferences = context.getSharedPreferences("Notifications", Context.MODE_PRIVATE); boolean globalEnabled = preferences.getBoolean("EnableAll", true); if (!globalEnabled) { @@ -38,12 +43,13 @@ public class GcmBroadcastReceiver extends BroadcastReceiver { public void run() { GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context); String messageType = gcm.getMessageType(intent); - sendNotification(context, intent.getExtras()); + ConnectionsManager.Instance.resumeNetworkMaybe(); + wl.release(); } }); thread.setPriority(Thread.MAX_PRIORITY); thread.start(); - } else if (intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) { + } else if (intent.getAction().equals("com.google.android.c2dm.intent.REGISTRATION")) { String registration = intent.getStringExtra("registration_id"); if (intent.getStringExtra("error") != null) { FileLog.e("tmessages", "Registration failed, should try again later."); @@ -54,157 +60,4 @@ public class GcmBroadcastReceiver extends BroadcastReceiver { } } } - - private void sendNotification(Context context, Bundle extras) { - ConnectionsManager.Instance.resumeNetworkMaybe(); - /*if (!UserConfig.clientActivated || context == null || extras == null) { - return; - } - SharedPreferences preferences = context.getSharedPreferences("Notifications", Context.MODE_PRIVATE); - - boolean groupEnabled = preferences.getBoolean("EnableGroup", true); - boolean globalVibrate = preferences.getBoolean("EnableVibrateAll", true); - boolean groupVibrate = preferences.getBoolean("EnableVibrateGroup", true); - - - if (ApplicationLoader.Instance != null && (ApplicationLoader.lastPauseTime == 0 || ApplicationLoader.lastPauseTime > System.currentTimeMillis() - 200)) { - return; - } - - String defaultPath = null; - Uri defaultUri = Settings.System.DEFAULT_NOTIFICATION_URI; - if (defaultUri != null) { - defaultPath = defaultUri.getPath(); - } - - String globalSound = preferences.getString("GlobalSoundPath", defaultPath); - String chatSound = preferences.getString("GroupSoundPath", defaultPath); - String userSoundPath = null; - String chatSoundPath = null; - - NotificationManager mNotificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE); - Intent intent = new Intent(context, LaunchActivity.class); - String msg = extras.getString("message"); - - try { - String to_id = extras.getString("user_id"); - int to = Integer.parseInt(to_id); - if (to != UserConfig.clientUserId) { - return; - } - } catch (Exception e) { - FileLog.e("tmessages", e); - } - - int chat_id = 0; - int user_id = 0; - String custom = extras.getString("custom"); - try { - if (custom != null) { - JSONObject obj = new JSONObject(custom); - if (obj.has("chat_id")) { - Object object = obj.get("chat_id"); - if (object instanceof Integer) { - chat_id = (Integer)object; - } else if (object instanceof String) { - chat_id = Integer.parseInt((String)object); - } - if (chat_id != 0) { - intent.putExtra("chatId", chat_id); - } - } else if (obj.has("from_id")) { - Object object = obj.get("from_id"); - if (object instanceof Integer) { - user_id = (Integer)object; - } else if (object instanceof String) { - user_id = Integer.parseInt((String)object); - } - if (user_id != 0) { - intent.putExtra("userId", user_id); - } - } - } - } catch (Exception e) { - FileLog.e("tmessages", e); - } - - if (user_id != 0) { - String key = "notify_" + user_id; - boolean value = preferences.getBoolean(key, true); - if (!value) { - return; - } - userSoundPath = preferences.getString("sound_path_" + user_id, null); - } - if (chat_id != 0) { - if (!groupEnabled) { - return; - } - String key = "notify_" + (-chat_id); - boolean value = preferences.getBoolean(key, true); - if (!value) { - return; - } - chatSoundPath = preferences.getString("sound_chat_path_" + chat_id, null); - } - - boolean needVibrate; - String choosenSoundPath = null; - - if (chat_id != 0) { - needVibrate = groupVibrate; - } else { - needVibrate = globalVibrate; - } - - if (user_id != 0) { - if (userSoundPath != null) { - choosenSoundPath = userSoundPath; - } else if (globalSound != null) { - choosenSoundPath = globalSound; - } - } else if (chat_id != 0) { - if (chatSoundPath != null) { - choosenSoundPath = chatSoundPath; - } else if (chatSound != null) { - choosenSoundPath = chatSound; - } - } else { - choosenSoundPath = globalSound; - } - - intent.setAction("com.tmessages.openchat" + Math.random() + Integer.MAX_VALUE); - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); - //intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); - PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_ONE_SHOT); - - NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context) - .setContentTitle(ApplicationLoader.applicationContext.getString(R.string.AppName)) - .setSmallIcon(R.drawable.notification) - .setStyle(new NotificationCompat.BigTextStyle() - .bigText(msg)) - .setContentText(msg) - .setAutoCancel(true) - .setTicker(msg); - - if (needVibrate) { - mBuilder.setVibrate(new long[]{0, 100, 0, 100}); - } - if (choosenSoundPath != null && !choosenSoundPath.equals("NoSound")) { - if (choosenSoundPath.equals(defaultPath)) { - mBuilder.setSound(defaultUri); - } else { - mBuilder.setSound(Uri.parse(choosenSoundPath)); - } - } - - mBuilder.setContentIntent(contentIntent); - mNotificationManager.cancel(NOTIFICATION_ID); - Notification notification = mBuilder.build(); - notification.ledARGB = 0xff00ff00; - notification.ledOnMS = 1000; - notification.ledOffMS = 1000; - notification.flags |= Notification.FLAG_SHOW_LIGHTS; - mNotificationManager.notify(NOTIFICATION_ID, notification);*/ - } } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java index 2d8445efd..c27eecf49 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesController.java @@ -10,45 +10,39 @@ package org.telegram.messenger; import android.accounts.Account; import android.accounts.AccountManager; +import android.app.Activity; import android.app.AlertDialog; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.ProgressDialog; -import android.content.ContentProviderOperation; -import android.content.ContentProviderResult; -import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageInfo; -import android.database.Cursor; import android.graphics.Bitmap; import android.media.AudioManager; import android.media.SoundPool; import android.net.Uri; import android.os.Build; import android.os.Vibrator; -import android.provider.BaseColumns; -import android.provider.ContactsContract; import android.provider.Settings; import android.support.v4.app.NotificationCompat; import android.support.v7.app.ActionBarActivity; import android.text.Html; import android.util.SparseArray; -import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.TL.TLClassStore; import org.telegram.TL.TLObject; import org.telegram.TL.TLRPC; import org.telegram.objects.MessageObject; +import org.telegram.objects.PhotoObject; import org.telegram.ui.ApplicationLoader; import org.telegram.ui.LaunchActivity; import java.io.File; import java.io.FileInputStream; import java.math.BigInteger; -import java.security.MessageDigest; import java.security.SecureRandom; import java.util.ArrayList; import java.util.Collections; @@ -73,6 +67,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter public SparseArray sendingMessages = new SparseArray(); public SparseArray hidenAddToContacts = new SparseArray(); private SparseArray acceptingChats = new SparseArray(); + private ArrayList updatesQueue = new ArrayList(); + private long updatesStartWaitTime = 0; private boolean gettingNewDeleteTask = false; private int currentDeletingTaskTime = 0; @@ -89,13 +85,17 @@ public class MessagesController implements NotificationCenter.NotificationCenter public boolean registeringForPush = false; private long lastSoundPlay = 0; private long lastStatusUpdateTime = 0; - public boolean loadingContacts = true; private boolean offlineSended = false; private String uploadingAvatar = null; private SoundPool soundPool; private int sound; public static SecureRandom random = new SecureRandom(); - private Account currentAccount; + public boolean enableJoined = true; + public long scheduleContactsReload = 0; + + private class UserActionUpdates extends TLRPC.Updates { + + } static { try { @@ -110,7 +110,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } - public static final int MESSAGE_SEND_STATE_SENDING = 1; public static final int MESSAGE_SEND_STATE_SENT = 0; public static final int MESSAGE_SEND_STATE_SEND_ERROR = 2; @@ -118,7 +117,12 @@ public class MessagesController implements NotificationCenter.NotificationCenter public static final int UPDATE_MASK_NAME = 1; public static final int UPDATE_MASK_AVATAR = 2; public static final int UPDATE_MASK_STATUS = 4; - public static final int UPDATE_MASK_ALL = UPDATE_MASK_AVATAR | UPDATE_MASK_STATUS | UPDATE_MASK_NAME; + public static final int UPDATE_MASK_CHAT_AVATAR = 8; + public static final int UPDATE_MASK_CHAT_NAME = 16; + public static final int UPDATE_MASK_CHAT_MEMBERS = 32; + public static final int UPDATE_MASK_USER_PRINT = 64; + public static final int UPDATE_MASK_USER_PHONE = 128; + public static final int UPDATE_MASK_ALL = UPDATE_MASK_AVATAR | UPDATE_MASK_STATUS | UPDATE_MASK_NAME | UPDATE_MASK_CHAT_AVATAR | UPDATE_MASK_CHAT_NAME | UPDATE_MASK_CHAT_MEMBERS | UPDATE_MASK_USER_PRINT | UPDATE_MASK_USER_PHONE; public long openned_dialog_id; @@ -138,29 +142,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter public TLRPC.EncryptedChat encryptedChat; } - public static class Contact { - public int id; - public ArrayList phones = new ArrayList(); - public ArrayList phoneTypes = new ArrayList(); - public String first_name; - public String last_name; - } - - public HashMap contactsBook = new HashMap(); - public HashMap> contactsSectionsDict = new HashMap>(); - public ArrayList sortedContactsSectionsArray = new ArrayList(); - - public ArrayList contacts = new ArrayList(); - public SparseArray contactsDict = new SparseArray(); - public HashMap contactsByPhones = new HashMap(); - public HashMap> usersSectionsDict = new HashMap>(); - public ArrayList sortedUsersSectionsArray = new ArrayList(); - public static MessagesController Instance = new MessagesController(); public static final int didReceivedNewMessages = 1; - public static final int userPrintUpdate = 2; - public static final int userPrintUpdateAll = 19; public static final int updateInterfaces = 3; public static final int dialogsNeedReload = 4; public static final int closeChats = 5; @@ -175,7 +159,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter public static final int reloadSearchResults = 12; public static final int contactsDidLoaded = 13; - public static final int contactsBookDidLoaded = 14; public static final int chatDidCreated = 15; public static final int chatDidFailCreate = 16; @@ -197,6 +180,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter NotificationCenter.Instance.addObserver(this, FileLoader.FileDidFailUpload); NotificationCenter.Instance.addObserver(this, 10); addSupportUser(); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + enableJoined = preferences.getBoolean("EnableContactJoined", true); try { soundPool = new SoundPool(1, AudioManager.STREAM_NOTIFICATION, 0); @@ -217,6 +202,24 @@ public class MessagesController implements NotificationCenter.NotificationCenter users.put(user.id, user); } + public static TLRPC.InputUser getInputUser(TLRPC.User user) { + if (user == null) { + return null; + } + TLRPC.InputUser inputUser = null; + if (user.id == UserConfig.clientUserId) { + inputUser = new TLRPC.TL_inputUserSelf(); + } else if (user instanceof TLRPC.TL_userForeign || user instanceof TLRPC.TL_userRequest) { + inputUser = new TLRPC.TL_inputUserForeign(); + inputUser.user_id = user.id; + inputUser.access_hash = user.access_hash; + } else { + inputUser = new TLRPC.TL_inputUserContact(); + inputUser.user_id = user.id; + } + return inputUser; + } + @Override public void didReceivedNotification(int id, Object... args) { if (id == FileLoader.FileDidUpload) { @@ -263,6 +266,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter } public void cleanUp() { + ContactsController.Instance.cleanup(); + dialogs_dict.clear(); dialogs.clear(); dialogsServerOnly.clear(); @@ -275,21 +280,15 @@ public class MessagesController implements NotificationCenter.NotificationCenter printingUsers.clear(); printingStrings.clear(); totalDialogsCount = 0; - contactsBook.clear(); - contactsSectionsDict.clear(); - sortedContactsSectionsArray.clear(); - contacts.clear(); - contactsDict.clear(); - usersSectionsDict.clear(); - sortedUsersSectionsArray.clear(); - contactsByPhones.clear(); hidenAddToContacts.clear(); + updatesQueue.clear(); + updatesStartWaitTime = 0; currentDeletingTaskTime = 0; + scheduleContactsReload = 0; currentDeletingTaskMids = null; gettingNewDeleteTask = false; currentDeletingTask = null; - loadingContacts = false; loadingDialogs = false; dialogsEndReached = false; gettingDifference = false; @@ -367,37 +366,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter }); } - public void checkAppAccount() { - AccountManager am = AccountManager.get(ApplicationLoader.applicationContext); - Account[] accounts = am.getAccountsByType("org.telegram.messenger.account"); - boolean recreateAccount = false; - if (UserConfig.currentUser != null) { - if (accounts.length == 1) { - Account acc = accounts[0]; - if (!acc.name.equals(UserConfig.currentUser.phone)) { - recreateAccount = true; - } else { - currentAccount = acc; - } - } else { - recreateAccount = true; - } - } else { - if (accounts.length > 0) { - recreateAccount = true; - } - } - if (recreateAccount) { - for (Account c : accounts) { - am.removeAccount(c, null, null); - } - if (UserConfig.currentUser != null) { - currentAccount = new Account(UserConfig.currentUser.phone, "org.telegram.messenger.account"); - am.addAccountExplicitly(currentAccount, "", null); - } - } - } - public void deleteAllAppAccounts() { try { AccountManager am = AccountManager.get(ApplicationLoader.applicationContext); @@ -422,16 +390,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter req.limit = count; req.offset = offset; req.max_id = (int)max_id; - TLRPC.InputUser inputUser; - if (user instanceof TLRPC.TL_userForeign || user instanceof TLRPC.TL_userRequest) { - inputUser = new TLRPC.TL_inputUserForeign(); - inputUser.user_id = user.id; - inputUser.access_hash = user.access_hash; - } else { - inputUser = new TLRPC.TL_inputUserContact(); - inputUser.user_id = user.id; - } - req.user_id = inputUser; + req.user_id = getInputUser(user); long reqId = ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() { @Override public void run(TLObject response, TLRPC.TL_error error) { @@ -617,293 +576,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } - public void readContacts() { - if (contactsBook.size() != 0) { - return; - } - Utilities.globalQueue.postRunnable(new Runnable() { - @Override - public void run() { - FileLog.e("tmessages", "start read contacts from phone"); - final HashMap contactsMap = new HashMap(); - final HashMap> sectionsDict = new HashMap>(); - final ArrayList sortedSectionsArray = new ArrayList(); - - ContentResolver cr = ApplicationLoader.applicationContext.getContentResolver(); - - String[] projectioPhones = { - ContactsContract.CommonDataKinds.Phone.CONTACT_ID, - ContactsContract.CommonDataKinds.Phone.NUMBER, - ContactsContract.CommonDataKinds.Phone.TYPE, - ContactsContract.CommonDataKinds.Phone.LABEL - }; - String ids = ""; - Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projectioPhones, null, null, null); - if (pCur != null) { - if (pCur.getCount() > 0) { - while (pCur.moveToNext()) { - String number = pCur.getString(1); - if (number == null || number.length() == 0) { - continue; - } - Integer id = pCur.getInt(0); - if (ids.length() != 0) { - ids += ","; - } - ids += id; - - int type = pCur.getInt(2); - Contact contact = contactsMap.get(id); - if (contact == null) { - contact = new Contact(); - contact.first_name = ""; - contact.last_name = ""; - contactsMap.put(id, contact); - contact.id = id; - } - - contact.phones.add(number); - if (type == ContactsContract.CommonDataKinds.Phone.TYPE_CUSTOM) { - contact.phoneTypes.add(pCur.getString(3)); - } else if (type == ContactsContract.CommonDataKinds.Phone.TYPE_HOME) { - contact.phoneTypes.add(ApplicationLoader.applicationContext.getString(R.string.PhoneHome)); - } else if (type == ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE) { - contact.phoneTypes.add(ApplicationLoader.applicationContext.getString(R.string.PhoneMobile)); - } else if (type == ContactsContract.CommonDataKinds.Phone.TYPE_WORK) { - contact.phoneTypes.add(ApplicationLoader.applicationContext.getString(R.string.PhoneWork)); - } else if (type == ContactsContract.CommonDataKinds.Phone.TYPE_MAIN) { - contact.phoneTypes.add(ApplicationLoader.applicationContext.getString(R.string.PhoneMain)); - } else { - contact.phoneTypes.add(ApplicationLoader.applicationContext.getString(R.string.PhoneOther)); - } - } - } - pCur.close(); - } - - - String[] projectionNames = { - ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID, - ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, - ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, - ContactsContract.Data.DISPLAY_NAME, - ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME - }; - pCur = cr.query(ContactsContract.Data.CONTENT_URI, projectionNames, ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID + " IN (" + ids + ") AND " + ContactsContract.Data.MIMETYPE + " = '" + ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE + "'", null, null); - if (pCur != null && pCur.getCount() > 0) { - while (pCur.moveToNext()) { - int id = pCur.getInt(0); - String fname = pCur.getString(1); - String sname = pCur.getString(2); - String sname2 = pCur.getString(3); - String mname = pCur.getString(4); - Contact contact = contactsMap.get(id); - if (contact != null) { - contact.first_name = fname; - contact.last_name = sname; - if (contact.first_name == null) { - contact.first_name = ""; - } - if (mname != null && mname.length() != 0) { - if (contact.first_name.length() != 0) { - contact.first_name += " " + mname; - } else { - contact.first_name = mname; - } - } - if (contact.last_name == null) { - contact.last_name = ""; - } - if (contact.last_name.length() == 0 && contact.first_name.length() == 0 && sname2 != null && sname2.length() != 0) { - contact.first_name = sname2; - } - } - } - pCur.close(); - } - - ArrayList toImport = new ArrayList(); - - String contactsImportHash = ""; - MessageDigest mdEnc = null; - try { - mdEnc = MessageDigest.getInstance("MD5"); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - for (HashMap.Entry pair : contactsMap.entrySet()) { - Contact value = pair.getValue(); - int id = pair.getKey(); - - for (int a = 0; a < value.phones.size(); a++) { - TLRPC.TL_inputPhoneContact imp = new TLRPC.TL_inputPhoneContact(); - imp.client_id = id; - imp.first_name = value.first_name; - imp.last_name = value.last_name; - imp.phone = PhoneFormat.stripExceptNumbers(value.phones.get(a)); - toImport.add(imp); - String str = imp.client_id + imp.first_name + imp.last_name + imp.phone; - if (mdEnc != null) { - mdEnc.update(str.getBytes()); - } - } - - String key = value.first_name; - if (key.length() == 0) { - key = value.last_name; - } - if (key.length() == 0) { - key = "#"; - if (value.phones.size() != 0) { - value.first_name = "+" + value.phones.get(0); - } - } else { - key = key.toUpperCase(); - } - if (key.length() > 1) { - key = key.substring(0, 1); - } - ArrayList arr = sectionsDict.get(key); - if (arr == null) { - arr = new ArrayList(); - sectionsDict.put(key, arr); - sortedSectionsArray.add(key); - } - arr.add(value); - } - for (HashMap.Entry> entry : sectionsDict.entrySet()) { - Collections.sort(entry.getValue(), new Comparator() { - @Override - public int compare(Contact contact, Contact contact2) { - String toComapre1 = contact.first_name; - if (toComapre1.length() == 0) { - toComapre1 = contact.last_name; - } - String toComapre2 = contact2.first_name; - if (toComapre2.length() == 0) { - toComapre2 = contact2.last_name; - } - return toComapre1.compareTo(toComapre2); - } - }); - } - Collections.sort(sortedSectionsArray, new Comparator() { - @Override - public int compare(String s, String s2) { - char cv1 = s.charAt(0); - char cv2 = s2.charAt(0); - if (cv1 == '#') { - return 1; - } else if (cv2 == '#') { - return -1; - }/* else if (cv1 >= 'A' && cv1 <= 'Z' && cv2 >= 'A' && cv2 <= 'Z') { - return s.compareTo(s2); - } else if (cv1 >= 'A' && cv1 <= 'Z' && !(cv2 >= 'A' && cv2 <= 'Z')) { - return 1; - } else if (!(cv1 >= 'A' && cv1 <= 'Z') && cv2 >= 'A' && cv2 <= 'Z') { - return -1; - }*/ - return s.compareTo(s2); - } - }); - - String importHash = String.format(Locale.US, "%32s", new BigInteger(1, mdEnc.digest()).toString(16)).replace(' ', '0'); - - if (!toImport.isEmpty() && !UserConfig.importHash.equals(importHash)) { - UserConfig.importHash = importHash; - UserConfig.saveConfig(false); - importContacts(toImport); - } else { - loadContacts(true); - } - - Utilities.RunOnUIThread(new Runnable() { - @Override - public void run() { - contactsBook = contactsMap; - contactsSectionsDict = sectionsDict; - sortedContactsSectionsArray = sortedSectionsArray; - NotificationCenter.Instance.postNotificationName(contactsBookDidLoaded); - } - }); - } - }); - - } - - private void performSyncContacts() { - Utilities.globalQueue.postRunnable(new Runnable() { - @Override - public void run() { - try { - Uri rawContactUri = ContactsContract.RawContacts.CONTENT_URI.buildUpon().appendQueryParameter(ContactsContract.RawContacts.ACCOUNT_NAME, currentAccount.name).appendQueryParameter( - ContactsContract.RawContacts.ACCOUNT_TYPE, currentAccount.type).build(); - Cursor c1 = ApplicationLoader.applicationContext.getContentResolver().query(rawContactUri, new String[]{BaseColumns._ID, ContactsContract.RawContacts.SYNC2}, null, null, null); - HashMap bookContacts = new HashMap(); - if (c1 != null) { - while (c1.moveToNext()) { - bookContacts.put(c1.getInt(1), c1.getLong(0)); - } - c1.close(); - - for (TLRPC.TL_contact u : contacts) { - if (!bookContacts.containsKey(u.user_id)) { - TLRPC.User user = users.get(u.user_id); - addContact(currentAccount, user, user.phone); - } - } - } - } catch (Exception e) { - FileLog.e("tmessages", e); - } - } - }); - } - - public static long addContact(Account account, TLRPC.User user, String phone) { - if (account == null || user == null || phone == null) { - return -1; - } - ArrayList query = new ArrayList(); - - ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI); - builder.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, account.name); - builder.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, account.type); - builder.withValue(ContactsContract.RawContacts.SYNC1, phone); - builder.withValue(ContactsContract.RawContacts.SYNC2, user.id); - query.add(builder.build()); - - builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI); - builder.withValueBackReference(ContactsContract.CommonDataKinds.StructuredName.RAW_CONTACT_ID, 0); - builder.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE); - builder.withValue(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, user.first_name); - builder.withValue(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, user.last_name); - query.add(builder.build()); - - builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI); - builder.withValueBackReference(ContactsContract.CommonDataKinds.StructuredName.RAW_CONTACT_ID, 0); - builder.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE); - builder.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, "+" + phone); - builder.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE); - query.add(builder.build()); - - builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI); - builder.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0); - builder.withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/vnd.org.telegram.messenger.android.profile"); - builder.withValue(ContactsContract.Data.DATA1, "+" + phone); - builder.withValue(ContactsContract.Data.DATA2, "Telegram Profile"); - builder.withValue(ContactsContract.Data.DATA3, "+" + phone); - builder.withValue(ContactsContract.Data.DATA4, user.id); - query.add(builder.build()); - try { - ContentProviderResult[] result = ApplicationLoader.applicationContext.getContentResolver().applyBatch(ContactsContract.AUTHORITY, query); - return Long.parseLong(result[0].uri.getLastPathSegment()); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - return -1; - } - public void deleteMessages(ArrayList messages) { for (Integer id : messages) { MessageObject obj = dialogMessage.get(id); @@ -980,7 +652,18 @@ public class MessagesController implements NotificationCenter.NotificationCenter MessagesStorage.lastPtsValue = res.pts; MessagesStorage.Instance.saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue); } else if (MessagesStorage.lastSeqValue != res.seq) { - getDifference(); + FileLog.e("tmessages", "need get diff TL_messages_deleteHistory, seq: " + MessagesStorage.lastSeqValue + " " + res.seq); + if (gettingDifference || updatesStartWaitTime == 0 || updatesStartWaitTime != 0 && updatesStartWaitTime + 1500 > System.currentTimeMillis()) { + if (updatesStartWaitTime == 0) { + updatesStartWaitTime = System.currentTimeMillis(); + } + FileLog.e("tmessages", "add TL_messages_deleteHistory to queue"); + UserActionUpdates updates = new UserActionUpdates(); + updates.seq = res.seq; + updatesQueue.add(updates); + } else { + getDifference(); + } } } } @@ -1052,6 +735,11 @@ public class MessagesController implements NotificationCenter.NotificationCenter checkDeletingTask(); if (UserConfig.clientUserId != 0) { + if (scheduleContactsReload != 0 && currentTime > scheduleContactsReload) { + ContactsController.Instance.performSyncPhoneBook(ContactsController.Instance.getContactsCopy(ContactsController.Instance.contactsBook), true, false); + scheduleContactsReload = 0; + } + if (ApplicationLoader.lastPauseTime == 0) { if (lastStatusUpdateTime != -1 && (lastStatusUpdateTime == 0 || lastStatusUpdateTime <= System.currentTimeMillis() - 55000 || offlineSended)) { lastStatusUpdateTime = -1; @@ -1075,9 +763,16 @@ public class MessagesController implements NotificationCenter.NotificationCenter }, null, true, RPCRequest.RPCRequestClassGeneric); offlineSended = true; } + + if (updatesStartWaitTime != 0 && updatesStartWaitTime + 1500 < currentTime) { + FileLog.e("tmessages", "UPDATES WAIT TIMEOUT - CHECK QUEUE"); + processUpdatesQueue(false); + } + } else { + scheduleContactsReload = 0; } - final ArrayList uidsToSend = new ArrayList(); if (!printingUsers.isEmpty()) { + boolean updated = false; ArrayList keys = new ArrayList(printingUsers.keySet()); for (int b = 0; b < keys.size(); b++) { Long key = keys.get(b); @@ -1085,9 +780,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter for (int a = 0; a < arr.size(); a++) { PrintingUser user = arr.get(a); if (user.lastTime + 5900 < currentTime) { - if (!uidsToSend.contains(key)) { - uidsToSend.add(key); - } + updated = true; arr.remove(user); a--; } @@ -1101,14 +794,11 @@ public class MessagesController implements NotificationCenter.NotificationCenter updatePrintingStrings(); - if (!uidsToSend.isEmpty()) { + if (updated) { Utilities.RunOnUIThread(new Runnable() { @Override public void run() { - for (Long uid : uidsToSend) { - NotificationCenter.Instance.postNotificationName(userPrintUpdate, uid); - } - NotificationCenter.Instance.postNotificationName(userPrintUpdateAll); + NotificationCenter.Instance.postNotificationName(updateInterfaces, UPDATE_MASK_USER_PRINT); } }); } @@ -1161,164 +851,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter }); } - public void processLoadedContacts(final ArrayList contactsArr, final ArrayList usersArr, final int from) { - Utilities.stageQueue.postRunnable(new Runnable() { - @Override - public void run() { - FileLog.e("tmessages", "done loading contacts"); - if (from == 1 && contactsArr.isEmpty()) { - loadContacts(false); - return; - } - if (from == 0 || from == 2 || from == 3) { - MessagesStorage.Instance.putUsersAndChats(usersArr, null, true, true); - MessagesStorage.Instance.putContacts(contactsArr, true); - Collections.sort(contacts, new Comparator() { - @Override - public int compare(TLRPC.TL_contact tl_contact, TLRPC.TL_contact tl_contact2) { - if (tl_contact.user_id > tl_contact2.user_id) { - return 1; - } else if (tl_contact.user_id < tl_contact2.user_id) { - return -1; - } - return 0; - } - }); - String ids = ""; - for (TLRPC.TL_contact aContactsArr : contactsArr) { - if (ids.length() != 0) { - ids += ","; - } - ids += aContactsArr.user_id; - } - UserConfig.contactsHash = Utilities.MD5(ids); - UserConfig.saveConfig(false); - if (from == 2) { - loadContacts(false); - } - } - final HashMap usersDict = new HashMap(); - for (TLRPC.User user : usersArr) { - usersDict.put(user.id, user); - } - Collections.sort(contactsArr, new Comparator() { - @Override - public int compare(TLRPC.TL_contact tl_contact, TLRPC.TL_contact tl_contact2) { - TLRPC.User user1 = usersDict.get(tl_contact.user_id); - TLRPC.User user2 = usersDict.get(tl_contact2.user_id); - String name1 = user1.first_name; - if (name1 == null || name1.length() == 0) { - name1 = user1.last_name; - } - String name2 = user2.first_name; - if (name2 == null || name2.length() == 0) { - name2 = user2.last_name; - } - return name1.compareTo(name2); - } - }); - - final HashMap> sectionsDict = new HashMap>(); - final SparseArray contactsDictionery = new SparseArray(); - final ArrayList sortedSectionsArray = new ArrayList(); - final HashMap contactsPhones = new HashMap(); - - for (TLRPC.TL_contact value : contactsArr) { - TLRPC.User user = usersDict.get(value.user_id); - if (user == null) { - continue; - } - contactsDictionery.put(value.user_id, value); - contactsPhones.put(user.phone, value); - - String key = user.first_name; - if (key == null || key.length() == 0) { - key = user.last_name; - } - if (key.length() == 0) { - key = "#"; - } else { - key = key.toUpperCase(); - } - if (key.length() > 1) { - key = key.substring(0, 1); - } - ArrayList arr = sectionsDict.get(key); - if (arr == null) { - arr = new ArrayList(); - sectionsDict.put(key, arr); - sortedSectionsArray.add(key); - } - arr.add(value); - } - for (HashMap.Entry> entry : sectionsDict.entrySet()) { - Collections.sort(entry.getValue(), new Comparator() { - @Override - public int compare(TLRPC.TL_contact contact, TLRPC.TL_contact contact2) { - TLRPC.User user1 = usersDict.get(contact.user_id); - TLRPC.User user2 = usersDict.get(contact2.user_id); - String toComapre1 = user1.first_name; - if (toComapre1 == null || toComapre1.length() == 0) { - toComapre1 = user1.last_name; - } - String toComapre2 = user2.first_name; - if (toComapre2 == null || toComapre2.length() == 0) { - toComapre2 = user2.last_name; - } - return toComapre1.compareTo(toComapre2); - } - }); - } - Collections.sort(sortedSectionsArray, new Comparator() { - @Override - public int compare(String s, String s2) { - char cv1 = s.charAt(0); - char cv2 = s2.charAt(0); - if (cv1 == '#') { - return 1; - } else if (cv2 == '#') { - return -1; - }/* else if (cv1 >= 'A' && cv1 <= 'Z' && cv2 >= 'A' && cv2 <= 'Z') { - return s.compareTo(s2); - } else if (cv1 >= 'A' && cv1 <= 'Z' && !(cv2 >= 'A' && cv2 <= 'Z')) { - return 1; - } else if (!(cv1 >= 'A' && cv1 <= 'Z') && cv2 >= 'A' && cv2 <= 'Z') { - return -1; - }*/ - return s.compareTo(s2); - } - }); - - Utilities.RunOnUIThread(new Runnable() { - @Override - public void run() { - for (TLRPC.User user : usersArr) { - if (from == 1) { - users.putIfAbsent(user.id, user); - } else { - users.put(user.id, user); - if (user.id == UserConfig.clientUserId) { - UserConfig.currentUser = user; - } - } - } - contacts = contactsArr; - contactsByPhones = contactsPhones; - contactsDict = contactsDictionery; - usersSectionsDict = sectionsDict; - sortedUsersSectionsArray = sortedSectionsArray; - if (from == 0) { - loadingContacts = false; - } - performSyncContacts(); - NotificationCenter.Instance.postNotificationName(contactsDidLoaded); - } - }); - } - }); - - } - public void sendTyping(long dialog_id, int classGuid) { if (dialog_id == 0) { return; @@ -1372,56 +904,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } - public void loadContacts(boolean fromCache) { - loadingContacts = true; - if (fromCache) { - FileLog.e("tmessages", "load contacts from cache"); - MessagesStorage.Instance.getContacts(); - } else { - FileLog.e("tmessages", "load contacts from server"); - TLRPC.TL_contacts_getContacts req = new TLRPC.TL_contacts_getContacts(); - req.hash = UserConfig.contactsHash; - ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() { - @Override - public void run(TLObject response, TLRPC.TL_error error) { - if (error == null) { - TLRPC.contacts_Contacts res = (TLRPC.contacts_Contacts)response; - if (res instanceof TLRPC.TL_contacts_contactsNotModified) { - return; - } - processLoadedContacts(res.contacts, res.users, 0); - } - } - }, null, true, RPCRequest.RPCRequestClassGeneric); - } - } - - public void importContacts(ArrayList contactsArr) { - TLRPC.TL_contacts_importContacts req = new TLRPC.TL_contacts_importContacts(); - req.contacts = contactsArr; - req.replace = false; - FileLog.e("tmessages", "start import contacts"); - ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() { - @Override - public void run(TLObject response, TLRPC.TL_error error) { - if (error == null) { - FileLog.e("tmessages", "contacts imported"); - TLRPC.TL_contacts_importedContacts res = (TLRPC.TL_contacts_importedContacts)response; - MessagesStorage.Instance.putUsersAndChats(res.users, null, true, true); - ArrayList cArr = new ArrayList(); - for (TLRPC.TL_importedContact c : res.imported) { - TLRPC.TL_contact contact = new TLRPC.TL_contact(); - contact.user_id = c.user_id; - cArr.add(contact); - } - processLoadedContacts(cArr, res.users, 2); - } else { - FileLog.e("tmessages", "import contacts error " + error.text); - } - } - }, null, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors); - } - public void loadMessages(final long dialog_id, final int offset, final int count, final int max_id, boolean fromCache, int midDate, final int classGuid, boolean from_unread, boolean forward) { int lower_part = (int)dialog_id; if (fromCache || lower_part == 0) { @@ -1879,20 +1361,42 @@ public class MessagesController implements NotificationCenter.NotificationCenter MessagesStorage.lastPtsValue = res.pts; MessagesStorage.Instance.saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue); } else if (MessagesStorage.lastSeqValue != res.seq) { - getDifference(); + FileLog.e("tmessages", "need get diff TL_messages_readHistory, seq: " + MessagesStorage.lastSeqValue + " " + res.seq); + if (gettingDifference || updatesStartWaitTime == 0 || updatesStartWaitTime != 0 && updatesStartWaitTime + 1500 > System.currentTimeMillis()) { + if (updatesStartWaitTime == 0) { + updatesStartWaitTime = System.currentTimeMillis(); + } + FileLog.e("tmessages", "add TL_messages_readHistory to queue"); + UserActionUpdates updates = new UserActionUpdates(); + updates.seq = res.seq; + updatesQueue.add(updates); + } else { + getDifference(); + } } } } }, null, true, RPCRequest.RPCRequestClassGeneric); } - if (offset == 0) { - TLRPC.TL_dialog dialog = dialogs_dict.get(dialog_id); - if (dialog != null) { - dialog.unread_count = 0; - NotificationCenter.Instance.postNotificationName(dialogsNeedReload); + MessagesStorage.Instance.storageQueue.postRunnable(new Runnable() { + @Override + public void run() { + Utilities.RunOnUIThread(new Runnable() { + @Override + public void run() { + if (offset == 0) { + TLRPC.TL_dialog dialog = dialogs_dict.get(dialog_id); + if (dialog != null) { + dialog.unread_count = 0; + NotificationCenter.Instance.postNotificationName(dialogsNeedReload); + } + } + } + }); } - + }); + if (offset == 0) { TLRPC.TL_messages_receivedMessages req2 = new TLRPC.TL_messages_receivedMessages(); req2.max_id = max_positive_id; ConnectionsManager.Instance.performRpc(req2, new RPCRequest.RPCRequestDelegate() { @@ -1923,11 +1427,22 @@ public class MessagesController implements NotificationCenter.NotificationCenter }, null, true, RPCRequest.RPCRequestClassGeneric); } MessagesStorage.Instance.processPendingRead(dialog_id, max_id, max_date, false); - TLRPC.TL_dialog dialog = dialogs_dict.get(dialog_id); - if (dialog != null) { - dialog.unread_count = 0; - NotificationCenter.Instance.postNotificationName(dialogsNeedReload); - } + + MessagesStorage.Instance.storageQueue.postRunnable(new Runnable() { + @Override + public void run() { + Utilities.RunOnUIThread(new Runnable() { + @Override + public void run() { + TLRPC.TL_dialog dialog = dialogs_dict.get(dialog_id); + if (dialog != null) { + dialog.unread_count = 0; + NotificationCenter.Instance.postNotificationName(dialogsNeedReload); + } + } + }); + } + }); if (chat.ttl > 0 && was) { int serverTime = Math.max(ConnectionsManager.Instance.getCurrentTime(), max_date); @@ -2531,7 +2046,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter }); } } - }, null, true, RPCRequest.RPCRequestClassGeneric); + }, null, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassCanCompress); } private void performSendMessageRequest(TLObject req, final MessageObject newMsgObj) { @@ -2550,8 +2065,19 @@ public class MessagesController implements NotificationCenter.NotificationCenter MessagesStorage.lastDateValue = res.date; MessagesStorage.lastPtsValue = res.pts; MessagesStorage.Instance.saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue); - } else { - getDifference(); + } else if (MessagesStorage.lastSeqValue != res.seq) { + FileLog.e("tmessages", "need get diff TL_messages_sentMessage, seq: " + MessagesStorage.lastSeqValue + " " + res.seq); + if (gettingDifference || updatesStartWaitTime == 0 || updatesStartWaitTime != 0 && updatesStartWaitTime + 1500 > System.currentTimeMillis()) { + if (updatesStartWaitTime == 0) { + updatesStartWaitTime = System.currentTimeMillis(); + } + FileLog.e("tmessages", "add TL_messages_sentMessage to queue"); + UserActionUpdates updates = new UserActionUpdates(); + updates.seq = res.seq; + updatesQueue.add(updates); + } else { + getDifference(); + } } } else if (response instanceof TLRPC.messages_StatedMessage) { TLRPC.messages_StatedMessage res = (TLRPC.messages_StatedMessage)response; @@ -2563,8 +2089,19 @@ public class MessagesController implements NotificationCenter.NotificationCenter MessagesStorage.lastPtsValue = res.pts; MessagesStorage.lastDateValue = res.message.date; MessagesStorage.Instance.saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue); - } else { - getDifference(); + } else if (MessagesStorage.lastSeqValue != res.seq) { + FileLog.e("tmessages", "need get diff messages_StatedMessage, seq: " + MessagesStorage.lastSeqValue + " " + res.seq); + if (gettingDifference || updatesStartWaitTime == 0 || updatesStartWaitTime != 0 && updatesStartWaitTime + 1500 > System.currentTimeMillis()) { + if (updatesStartWaitTime == 0) { + updatesStartWaitTime = System.currentTimeMillis(); + } + FileLog.e("tmessages", "add messages_StatedMessage to queue"); + UserActionUpdates updates = new UserActionUpdates(); + updates.seq = res.seq; + updatesQueue.add(updates); + } else { + getDifference(); + } } } else if (response instanceof TLRPC.messages_StatedMessages) { TLRPC.messages_StatedMessages res = (TLRPC.messages_StatedMessages)response; @@ -2574,12 +2111,23 @@ public class MessagesController implements NotificationCenter.NotificationCenter sendedMessages.add(message); processSendedMessage(newMsgObj.messageOwner, message, null, null); } - if(MessagesStorage.lastSeqValue + 1 == res.seq) { + if (MessagesStorage.lastSeqValue + 1 == res.seq) { MessagesStorage.lastSeqValue = res.seq; MessagesStorage.lastPtsValue = res.pts; MessagesStorage.Instance.saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue); - } else { - getDifference(); + } else if (MessagesStorage.lastSeqValue != res.seq) { + FileLog.e("tmessages", "need get diff messages_StatedMessages, seq: " + MessagesStorage.lastSeqValue + " " + res.seq); + if (gettingDifference || updatesStartWaitTime == 0 || updatesStartWaitTime != 0 && updatesStartWaitTime + 1500 > System.currentTimeMillis()) { + if (updatesStartWaitTime == 0) { + updatesStartWaitTime = System.currentTimeMillis(); + } + FileLog.e("tmessages", "add messages_StatedMessages to queue"); + UserActionUpdates updates = new UserActionUpdates(); + updates.seq = res.seq; + updatesQueue.add(updates); + } else { + getDifference(); + } } } MessagesStorage.Instance.updateMessageStateAndId(newMsgObj.messageOwner.random_id, oldId, newMsgObj.messageOwner.id, 0, true); @@ -2617,7 +2165,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter } }); } - }), true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors, ConnectionsManager.DEFAULT_DATACENTER_ID); + }), true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors | RPCRequest.RPCRequestClassCanCompress, ConnectionsManager.DEFAULT_DATACENTER_ID); } private void performSendDelayedMessage(final DelayedMessage message) { @@ -2686,263 +2234,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } - public void rebuildContactsWithNewUser(final TLRPC.User user, final long bookId) { - Utilities.stageQueue.postRunnable(new Runnable() { - @Override - public void run() { - final HashMap contactsMapBook = new HashMap(contactsBook); - final HashMap> sectionsDictBook = new HashMap>(); - final ArrayList sortedSectionsArrayBook = new ArrayList(); - Contact newContactBook = new Contact(); - newContactBook.first_name = user.first_name; - newContactBook.last_name = user.last_name; - newContactBook.id = (int)bookId; - newContactBook.phones = new ArrayList(); - newContactBook.phones.add(user.phone); - newContactBook.phoneTypes = new ArrayList(); - newContactBook.phoneTypes.add(ApplicationLoader.applicationContext.getString(R.string.PhoneMobile)); - contactsMapBook.put((int)bookId, newContactBook); - - String contactsImportHash = ""; - MessageDigest mdEnc = null; - try { - mdEnc = MessageDigest.getInstance("MD5"); - } catch (Exception e) { - FileLog.e("tmessages", e); - } - for (HashMap.Entry pair : contactsMapBook.entrySet()) { - Contact value = pair.getValue(); - int id = pair.getKey(); - - if (mdEnc != null) { - for (int a = 0; a < value.phones.size(); a++) { - String str = id + value.first_name + value.last_name + value.phones.get(a); - mdEnc.update(str.getBytes()); - } - } - - String key = value.last_name; - if (key.length() == 0) { - key = value.first_name; - } - if (key.length() == 0) { - key = "#"; - if (value.phones.size() != 0) { - value.first_name = "+" + value.phones.get(0); - } - } else { - key = key.toUpperCase(); - } - if (key.length() > 1) { - key = key.substring(0, 1); - } - ArrayList arr = sectionsDictBook.get(key); - if (arr == null) { - arr = new ArrayList(); - sectionsDictBook.put(key, arr); - sortedSectionsArrayBook.add(key); - } - arr.add(value); - } - for (HashMap.Entry> entry : sectionsDictBook.entrySet()) { - Collections.sort(entry.getValue(), new Comparator() { - @Override - public int compare(Contact contact, Contact contact2) { - String toComapre1 = contact.first_name; - if (toComapre1.length() == 0) { - toComapre1 = contact.last_name; - } - String toComapre2 = contact2.first_name; - if (toComapre2.length() == 0) { - toComapre2 = contact2.last_name; - } - return toComapre1.compareTo(toComapre2); - } - }); - } - Collections.sort(sortedSectionsArrayBook, new Comparator() { - @Override - public int compare(String s, String s2) { - char cv1 = s.charAt(0); - char cv2 = s2.charAt(0); - if (cv1 == '#') { - return 1; - } else if (cv2 == '#') { - return -1; - }/* else if (cv1 >= 'A' && cv1 <= 'Z' && cv2 >= 'A' && cv2 <= 'Z') { - return s.compareTo(s2); - } else if (cv1 >= 'A' && cv1 <= 'Z' && !(cv2 >= 'A' && cv2 <= 'Z')) { - return 1; - } else if (!(cv1 >= 'A' && cv1 <= 'Z') && cv2 >= 'A' && cv2 <= 'Z') { - return -1; - }*/ - return s.compareTo(s2); - } - }); - String importHash = String.format(Locale.US, "%32s", new BigInteger(1, mdEnc.digest()).toString(16)).replace(' ', '0'); - //end of phone book update - - - final ArrayList contactsArr = new ArrayList(contacts); - TLRPC.TL_contact newContact = new TLRPC.TL_contact(); - newContact.user_id = user.id; - contactsArr.add(newContact); - Collections.sort(contactsArr, new Comparator() { - @Override - public int compare(TLRPC.TL_contact tl_contact, TLRPC.TL_contact tl_contact2) { - TLRPC.User user1 = users.get(tl_contact.user_id); - TLRPC.User user2 = users.get(tl_contact2.user_id); - String name1 = user1.first_name; - if (name1 == null || name1.length() == 0) { - name1 = user1.last_name; - } - String name2 = user2.first_name; - if (name2 == null || name2.length() == 0) { - name2 = user2.last_name; - } - return name1.compareTo(name2); - } - }); - - final HashMap> sectionsDict = new HashMap>(); - final SparseArray contactsDictionery = new SparseArray(); - final ArrayList sortedSectionsArray = new ArrayList(); - final HashMap contactsPhones = new HashMap(); - - for (TLRPC.TL_contact value : contactsArr) { - TLRPC.User user = users.get(value.user_id); - contactsDictionery.put(value.user_id, value); - contactsPhones.put(user.phone, value); - - String key = user.last_name; - if (key == null || key.length() == 0) { - key = user.first_name; - } - if (key.length() == 0) { - key = "#"; - } else { - key = key.toUpperCase(); - } - if (key.length() > 1) { - key = key.substring(0, 1); - } - ArrayList arr = sectionsDict.get(key); - if (arr == null) { - arr = new ArrayList(); - sectionsDict.put(key, arr); - sortedSectionsArray.add(key); - } - arr.add(value); - } - for (HashMap.Entry> entry : sectionsDict.entrySet()) { - Collections.sort(entry.getValue(), new Comparator() { - @Override - public int compare(TLRPC.TL_contact contact, TLRPC.TL_contact contact2) { - TLRPC.User user1 = users.get(contact.user_id); - TLRPC.User user2 = users.get(contact2.user_id); - String toComapre1 = user1.first_name; - if (toComapre1 == null || toComapre1.length() == 0) { - toComapre1 = user1.last_name; - } - String toComapre2 = user2.first_name; - if (toComapre2 == null || toComapre2.length() == 0) { - toComapre2 = user2.last_name; - } - return toComapre1.compareTo(toComapre2); - } - }); - } - Collections.sort(sortedSectionsArray, new Comparator() { - @Override - public int compare(String s, String s2) { - char cv1 = s.charAt(0); - char cv2 = s2.charAt(0); - if (cv1 == '#') { - return 1; - } else if (cv2 == '#') { - return -1; - } -// } else if (cv1 >= 'A' && cv1 <= 'Z' && cv2 >= 'A' && cv2 <= 'Z') { -// return s.compareTo(s2); -// } else if (cv1 >= 'A' && cv1 <= 'Z' && !(cv2 >= 'A' && cv2 <= 'Z')) { -// return 1; -// } else if (!(cv1 >= 'A' && cv1 <= 'Z') && cv2 >= 'A' && cv2 <= 'Z') { -// return -1; -// } - return s.compareTo(s2); - } - }); - - final ArrayList contactsArrSortedByIds = new ArrayList(contactsArr); - Collections.sort(contactsArrSortedByIds, new Comparator() { - @Override - public int compare(TLRPC.TL_contact lhs, TLRPC.TL_contact rhs) { - Integer lid = lhs.user_id; - Integer rid = rhs.user_id; - return lid.compareTo(rid); - } - }); - - String ids = ""; - for (TLRPC.TL_contact aContactsArr : contactsArrSortedByIds) { - if (ids.length() != 0) { - ids += ","; - } - ids += aContactsArr.user_id; - } - UserConfig.contactsHash = Utilities.MD5(ids); - UserConfig.importHash = importHash; - UserConfig.saveConfig(false); - - MessagesStorage.Instance.putContacts(contactsArr, true); - ArrayList users = new ArrayList(); - users.add(user); - MessagesStorage.Instance.putUsersAndChats(users, null, true, true); - - Utilities.RunOnUIThread(new Runnable() { - @Override - public void run() { - contactsBook = contactsMapBook; - contactsSectionsDict = sectionsDictBook; - sortedContactsSectionsArray = sortedSectionsArrayBook; - NotificationCenter.Instance.postNotificationName(contactsBookDidLoaded); - contacts = contactsArr; - contactsByPhones = contactsPhones; - contactsDict = contactsDictionery; - usersSectionsDict = sectionsDict; - sortedUsersSectionsArray = sortedSectionsArray; - NotificationCenter.Instance.postNotificationName(contactsDidLoaded); - NotificationCenter.Instance.postNotificationName(updateInterfaces, UPDATE_MASK_ALL); - } - }); - } - }); - } - - public void addContact(TLRPC.User user) { - if (user == null) { - return; - } - long num = addContact(currentAccount, user, user.phone); - rebuildContactsWithNewUser(user, num); - - TLRPC.TL_contacts_importContacts req = new TLRPC.TL_contacts_importContacts(); - ArrayList contacts = new ArrayList(); - TLRPC.TL_inputPhoneContact c = new TLRPC.TL_inputPhoneContact(); - c.phone = user.phone; - c.first_name = user.first_name; - c.last_name = user.last_name; - c.client_id = num; - contacts.add(c); - req.contacts = contacts; - req.replace = false; - ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() { - @Override - public void run(TLObject response, TLRPC.TL_error error) { - } - }, null, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors); - } - public void fileDidUploaded(final String location, final TLRPC.InputFile file, final TLRPC.InputEncryptedFile encryptedFile) { if (uploadingAvatar != null && uploadingAvatar.equals(location)) { TLRPC.TL_photos_uploadProfilePhoto req = new TLRPC.TL_photos_uploadProfilePhoto(); @@ -2953,7 +2244,43 @@ public class MessagesController implements NotificationCenter.NotificationCenter ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() { @Override public void run(TLObject response, TLRPC.TL_error error) { - + if (error == null) { + TLRPC.User user = users.get(UserConfig.clientUserId); + if (user == null) { + user = UserConfig.currentUser; + users.put(user.id, user); + } else { + UserConfig.currentUser = user; + } + if (user == null) { + return; + } + TLRPC.TL_photos_photo photo = (TLRPC.TL_photos_photo)response; + ArrayList sizes = photo.photo.sizes; + TLRPC.PhotoSize smallSize = PhotoObject.getClosestPhotoSizeWithSize(sizes, 100, 100); + TLRPC.PhotoSize bigSize = PhotoObject.getClosestPhotoSizeWithSize(sizes, 1000, 1000); + user.photo = new TLRPC.TL_userProfilePhoto(); + user.photo.photo_id = photo.photo.id; + if (smallSize != null) { + user.photo.photo_small = smallSize.location; + } + if (bigSize != null) { + user.photo.photo_big = bigSize.location; + } else if (smallSize != null) { + user.photo.photo_small = smallSize.location; + } + MessagesStorage.Instance.clearUserPhotos(user.id); + ArrayList users = new ArrayList(); + users.add(user); + MessagesStorage.Instance.putUsersAndChats(users, null, false, true); + Utilities.RunOnUIThread(new Runnable() { + @Override + public void run() { + NotificationCenter.Instance.postNotificationName(updateInterfaces, UPDATE_MASK_AVATAR); + UserConfig.saveConfig(true); + } + }); + } } }, null, true, RPCRequest.RPCRequestClassGeneric); } else { @@ -2999,16 +2326,10 @@ public class MessagesController implements NotificationCenter.NotificationCenter req.title = title; for (Integer uid : selectedContacts) { TLRPC.User user = users.get(uid); - TLRPC.InputUser inputUser; - if (user instanceof TLRPC.TL_userForeign || user instanceof TLRPC.TL_userRequest) { - inputUser = new TLRPC.TL_inputUserForeign(); - inputUser.user_id = user.id; - inputUser.access_hash = user.access_hash; - } else { - inputUser = new TLRPC.TL_inputUserContact(); - inputUser.user_id = user.id; + if (user == null) { + continue; } - req.users.add(inputUser); + req.users.add(getInputUser(user)); } ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() { @Override @@ -3024,16 +2345,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter } final TLRPC.messages_StatedMessage res = (TLRPC.messages_StatedMessage)response; MessagesStorage.Instance.putUsersAndChats(res.users, res.chats, true, true); - final ArrayList messages = new ArrayList(); - messages.add(res.message); - MessagesStorage.Instance.putMessages(messages, true, true); - if (MessagesStorage.lastSeqValue + 1 == res.seq) { - MessagesStorage.lastSeqValue = res.seq; - MessagesStorage.lastPtsValue = res.pts; - MessagesStorage.Instance.saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue); - } else if (MessagesStorage.lastSeqValue != res.seq) { - getDifference(); - } + Utilities.RunOnUIThread(new Runnable() { @Override public void run() { @@ -3051,29 +2363,48 @@ public class MessagesController implements NotificationCenter.NotificationCenter TLRPC.Chat chat = res.chats.get(0); updateInterfaceWithMessages(-chat.id, messagesObj); NotificationCenter.Instance.postNotificationName(chatDidCreated, chat.id); + NotificationCenter.Instance.postNotificationName(dialogsNeedReload); if (uploadedAvatar != null) { changeChatAvatar(chat.id, uploadedAvatar); } } }); + final ArrayList messages = new ArrayList(); + messages.add(res.message); + MessagesStorage.Instance.putMessages(messages, true, true); + if (MessagesStorage.lastSeqValue + 1 == res.seq) { + MessagesStorage.lastSeqValue = res.seq; + MessagesStorage.lastPtsValue = res.pts; + MessagesStorage.Instance.saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue); + } else if (MessagesStorage.lastSeqValue != res.seq) { + FileLog.e("tmessages", "need get diff TL_messages_createChat, seq: " + MessagesStorage.lastSeqValue + " " + res.seq); + if (gettingDifference || updatesStartWaitTime == 0 || updatesStartWaitTime != 0 && updatesStartWaitTime + 1500 > System.currentTimeMillis()) { + if (updatesStartWaitTime == 0) { + updatesStartWaitTime = System.currentTimeMillis(); + } + FileLog.e("tmessages", "add TL_messages_createChat to queue"); + UserActionUpdates updates = new UserActionUpdates(); + updates.seq = res.seq; + updatesQueue.add(updates); + } else { + getDifference(); + } + } } }, null, true, RPCRequest.RPCRequestClassGeneric); } - public void addUserToChat(int chat_id, final int user_id, final TLRPC.ChatParticipants info) { + public void addUserToChat(int chat_id, final TLRPC.User user, final TLRPC.ChatParticipants info) { + if (user == null) { + return; + } + TLRPC.TL_messages_addChatUser req = new TLRPC.TL_messages_addChatUser(); req.chat_id = chat_id; req.fwd_limit = 50; - TLRPC.User user = users.get(user_id); - if (user instanceof TLRPC.TL_userForeign || user instanceof TLRPC.TL_userRequest) { - req.user_id = new TLRPC.TL_inputUserForeign(); - req.user_id.user_id = user.id; - req.user_id.access_hash = user.access_hash; - } else { - req.user_id = new TLRPC.TL_inputUserContact(); - req.user_id.user_id = user.id; - } + req.user_id = getInputUser(user); + ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() { @Override public void run(TLObject response, TLRPC.TL_error error) { @@ -3083,16 +2414,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter final TLRPC.messages_StatedMessage res = (TLRPC.messages_StatedMessage)response; MessagesStorage.Instance.putUsersAndChats(res.users, res.chats, true, true); - final ArrayList messages = new ArrayList(); - messages.add(res.message); - MessagesStorage.Instance.putMessages(messages, true, true); - if (MessagesStorage.lastSeqValue + 1 == res.seq) { - MessagesStorage.lastSeqValue = res.seq; - MessagesStorage.lastPtsValue = res.pts; - MessagesStorage.Instance.saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue); - } else if (MessagesStorage.lastSeqValue != res.seq) { - getDifference(); - } Utilities.RunOnUIThread(new Runnable() { @Override @@ -3111,16 +2432,17 @@ public class MessagesController implements NotificationCenter.NotificationCenter TLRPC.Chat chat = res.chats.get(0); chats.put(chat.id, chat); updateInterfaceWithMessages(-chat.id, messagesObj); - NotificationCenter.Instance.postNotificationName(updateInterfaces, UPDATE_MASK_ALL); + NotificationCenter.Instance.postNotificationName(updateInterfaces, UPDATE_MASK_CHAT_MEMBERS); + NotificationCenter.Instance.postNotificationName(dialogsNeedReload); if (info != null) { for (TLRPC.TL_chatParticipant p : info.participants) { - if (p.user_id == user_id) { + if (p.user_id == user.id) { return; } } TLRPC.TL_chatParticipant newPart = new TLRPC.TL_chatParticipant(); - newPart.user_id = user_id; + newPart.user_id = user.id; newPart.inviter_id = UserConfig.clientUserId; newPart.date = ConnectionsManager.Instance.getCurrentTime(); info.participants.add(0, newPart); @@ -3129,24 +2451,39 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } }); + + final ArrayList messages = new ArrayList(); + messages.add(res.message); + MessagesStorage.Instance.putMessages(messages, true, true); + if (MessagesStorage.lastSeqValue + 1 == res.seq) { + MessagesStorage.lastSeqValue = res.seq; + MessagesStorage.lastPtsValue = res.pts; + MessagesStorage.Instance.saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue); + } else if (MessagesStorage.lastSeqValue != res.seq) { + FileLog.e("tmessages", "need get diff TL_messages_addChatUser, seq: " + MessagesStorage.lastSeqValue + " " + res.seq); + if (gettingDifference || updatesStartWaitTime == 0 || updatesStartWaitTime != 0 && updatesStartWaitTime + 1500 > System.currentTimeMillis()) { + if (updatesStartWaitTime == 0) { + updatesStartWaitTime = System.currentTimeMillis(); + } + FileLog.e("tmessages", "add TL_messages_addChatUser to queue"); + UserActionUpdates updates = new UserActionUpdates(); + updates.seq = res.seq; + updatesQueue.add(updates); + } else { + getDifference(); + } + } } }, null, true, RPCRequest.RPCRequestClassGeneric); } - public void deleteUserFromChat(int chat_id, final int user_id, final TLRPC.ChatParticipants info) { + public void deleteUserFromChat(int chat_id, final TLRPC.User user, final TLRPC.ChatParticipants info) { + if (user == null) { + return; + } TLRPC.TL_messages_deleteChatUser req = new TLRPC.TL_messages_deleteChatUser(); req.chat_id = chat_id; - TLRPC.User user = users.get(user_id); - if (user instanceof TLRPC.TL_userForeign || user instanceof TLRPC.TL_userRequest) { - req.user_id = new TLRPC.TL_inputUserForeign(); - req.user_id.user_id = user.id; - req.user_id.access_hash = user.access_hash; - } else if (user instanceof TLRPC.TL_userSelf) { - req.user_id = new TLRPC.TL_inputUserSelf(); - } else { - req.user_id = new TLRPC.TL_inputUserContact(); - req.user_id.user_id = user.id; - } + req.user_id = getInputUser(user); ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() { @Override public void run(TLObject response, TLRPC.TL_error error) { @@ -3155,18 +2492,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter } final TLRPC.messages_StatedMessage res = (TLRPC.messages_StatedMessage)response; MessagesStorage.Instance.putUsersAndChats(res.users, res.chats, true, true); - if (user_id != UserConfig.clientUserId) { - final ArrayList messages = new ArrayList(); - messages.add(res.message); - MessagesStorage.Instance.putMessages(messages, true, true); - } - if (MessagesStorage.lastSeqValue + 1 == res.seq) { - MessagesStorage.lastSeqValue = res.seq; - MessagesStorage.lastPtsValue = res.pts; - MessagesStorage.Instance.saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue); - } else if (MessagesStorage.lastSeqValue != res.seq) { - getDifference(); - } Utilities.RunOnUIThread(new Runnable() { @Override @@ -3180,19 +2505,20 @@ public class MessagesController implements NotificationCenter.NotificationCenter for (TLRPC.Chat chat : res.chats) { chats.put(chat.id, chat); } - if (user_id != UserConfig.clientUserId) { + if (user.id != UserConfig.clientUserId) { final ArrayList messagesObj = new ArrayList(); messagesObj.add(new MessageObject(res.message, users)); TLRPC.Chat chat = res.chats.get(0); chats.put(chat.id, chat); updateInterfaceWithMessages(-chat.id, messagesObj); - NotificationCenter.Instance.postNotificationName(updateInterfaces, UPDATE_MASK_ALL); + NotificationCenter.Instance.postNotificationName(updateInterfaces, UPDATE_MASK_CHAT_MEMBERS); + NotificationCenter.Instance.postNotificationName(dialogsNeedReload); } boolean changed = false; if (info != null) { for (int a = 0; a < info.participants.size(); a++) { TLRPC.TL_chatParticipant p = info.participants.get(a); - if (p.user_id == user_id) { + if (p.user_id == user.id) { info.participants.remove(a); changed = true; break; @@ -3205,6 +2531,30 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } }); + + if (user.id != UserConfig.clientUserId) { + final ArrayList messages = new ArrayList(); + messages.add(res.message); + MessagesStorage.Instance.putMessages(messages, true, true); + } + if (MessagesStorage.lastSeqValue + 1 == res.seq) { + MessagesStorage.lastSeqValue = res.seq; + MessagesStorage.lastPtsValue = res.pts; + MessagesStorage.Instance.saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue); + } else if (MessagesStorage.lastSeqValue != res.seq) { + FileLog.e("tmessages", "need get diff TL_messages_deleteChatUser, seq: " + MessagesStorage.lastSeqValue + " " + res.seq); + if (gettingDifference || updatesStartWaitTime == 0 || updatesStartWaitTime != 0 && updatesStartWaitTime + 1500 > System.currentTimeMillis()) { + if (updatesStartWaitTime == 0) { + updatesStartWaitTime = System.currentTimeMillis(); + } + FileLog.e("tmessages", "add TL_messages_deleteChatUser to queue"); + UserActionUpdates updates = new UserActionUpdates(); + updates.seq = res.seq; + updatesQueue.add(updates); + } else { + getDifference(); + } + } } }, null, true, RPCRequest.RPCRequestClassGeneric); } @@ -3221,16 +2571,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter } final TLRPC.messages_StatedMessage res = (TLRPC.messages_StatedMessage)response; MessagesStorage.Instance.putUsersAndChats(res.users, res.chats, true, true); - final ArrayList messages = new ArrayList(); - messages.add(res.message); - MessagesStorage.Instance.putMessages(messages, true, true); - if (MessagesStorage.lastSeqValue + 1 == res.seq) { - MessagesStorage.lastSeqValue = res.seq; - MessagesStorage.lastPtsValue = res.pts; - MessagesStorage.Instance.saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue); - } else if (MessagesStorage.lastSeqValue != res.seq) { - getDifference(); - } Utilities.RunOnUIThread(new Runnable() { @Override @@ -3249,9 +2589,32 @@ public class MessagesController implements NotificationCenter.NotificationCenter TLRPC.Chat chat = res.chats.get(0); chats.put(chat.id, chat); updateInterfaceWithMessages(-chat.id, messagesObj); - NotificationCenter.Instance.postNotificationName(updateInterfaces, UPDATE_MASK_ALL); + NotificationCenter.Instance.postNotificationName(dialogsNeedReload); + NotificationCenter.Instance.postNotificationName(updateInterfaces, UPDATE_MASK_CHAT_NAME); } }); + + final ArrayList messages = new ArrayList(); + messages.add(res.message); + MessagesStorage.Instance.putMessages(messages, true, true); + if (MessagesStorage.lastSeqValue + 1 == res.seq) { + MessagesStorage.lastSeqValue = res.seq; + MessagesStorage.lastPtsValue = res.pts; + MessagesStorage.Instance.saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue); + } else if (MessagesStorage.lastSeqValue != res.seq) { + FileLog.e("tmessages", "need get diff TL_messages_editChatTitle, seq: " + MessagesStorage.lastSeqValue + " " + res.seq); + if (gettingDifference || updatesStartWaitTime == 0 || updatesStartWaitTime != 0 && updatesStartWaitTime + 1500 > System.currentTimeMillis()) { + if (updatesStartWaitTime == 0) { + updatesStartWaitTime = System.currentTimeMillis(); + } + FileLog.e("tmessages", "add TL_messages_editChatTitle to queue"); + UserActionUpdates updates = new UserActionUpdates(); + updates.seq = res.seq; + updatesQueue.add(updates); + } else { + getDifference(); + } + } } }, null, true, RPCRequest.RPCRequestClassGeneric); } @@ -3274,16 +2637,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter } final TLRPC.messages_StatedMessage res = (TLRPC.messages_StatedMessage)response; MessagesStorage.Instance.putUsersAndChats(res.users, res.chats, true, true); - final ArrayList messages = new ArrayList(); - messages.add(res.message); - MessagesStorage.Instance.putMessages(messages, true, true); - if (MessagesStorage.lastSeqValue + 1 == res.seq) { - MessagesStorage.lastSeqValue = res.seq; - MessagesStorage.lastPtsValue = res.pts; - MessagesStorage.Instance.saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue); - } else if (MessagesStorage.lastSeqValue != res.seq) { - getDifference(); - } Utilities.RunOnUIThread(new Runnable() { @Override @@ -3302,14 +2655,45 @@ public class MessagesController implements NotificationCenter.NotificationCenter TLRPC.Chat chat = res.chats.get(0); chats.put(chat.id, chat); updateInterfaceWithMessages(-chat.id, messagesObj); - NotificationCenter.Instance.postNotificationName(updateInterfaces, UPDATE_MASK_ALL); + NotificationCenter.Instance.postNotificationName(dialogsNeedReload); + NotificationCenter.Instance.postNotificationName(updateInterfaces, UPDATE_MASK_CHAT_AVATAR); } }); + + final ArrayList messages = new ArrayList(); + messages.add(res.message); + MessagesStorage.Instance.putMessages(messages, true, true); + if (MessagesStorage.lastSeqValue + 1 == res.seq) { + MessagesStorage.lastSeqValue = res.seq; + MessagesStorage.lastPtsValue = res.pts; + MessagesStorage.Instance.saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue); + } else if (MessagesStorage.lastSeqValue != res.seq) { + FileLog.e("tmessages", "need get diff TL_messages_editChatPhoto, seq: " + MessagesStorage.lastSeqValue + " " + res.seq); + if (gettingDifference || updatesStartWaitTime == 0 || updatesStartWaitTime != 0 && updatesStartWaitTime + 1500 > System.currentTimeMillis()) { + if (updatesStartWaitTime == 0) { + updatesStartWaitTime = System.currentTimeMillis(); + } + FileLog.e("tmessages", "add TL_messages_editChatPhoto to queue"); + UserActionUpdates updates = new UserActionUpdates(); + updates.seq = res.seq; + updatesQueue.add(updates); + } else { + getDifference(); + } + } } }, null, true, RPCRequest.RPCRequestClassGeneric); } public void unregistedPush() { + TLRPC.TL_auth_logOut req2 = new TLRPC.TL_auth_logOut(); + ConnectionsManager.Instance.performRpc(req2, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(TLObject response, TLRPC.TL_error error) { + + } + }, null, true, RPCRequest.RPCRequestClassGeneric); + if (!UserConfig.registeredForPush || UserConfig.pushString.length() == 0) { return; } @@ -3322,14 +2706,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter } }, null, true, RPCRequest.RPCRequestClassGeneric); - - TLRPC.TL_auth_logOut req2 = new TLRPC.TL_auth_logOut(); - ConnectionsManager.Instance.performRpc(req2, new RPCRequest.RPCRequestDelegate() { - @Override - public void run(TLObject response, TLRPC.TL_error error) { - - } - }, null, true, RPCRequest.RPCRequestClassGeneric); } public void registerForPush(final String regid) { @@ -3417,12 +2793,92 @@ public class MessagesController implements NotificationCenter.NotificationCenter MessagesStorage.lastQtsValue = res.qts; MessagesStorage.Instance.saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue); } else { - loadCurrentState(); + if (error.code != 401) { + loadCurrentState(); + } } } }, null, true, RPCRequest.RPCRequestClassGeneric); } + private int getUpdateSeq(TLRPC.Updates updates) { + if (updates instanceof TLRPC.TL_updatesCombined) { + return updates.seq_start; + } else { + return updates.seq; + } + } + + private void processUpdatesQueue(boolean getDifference) { + if (!updatesQueue.isEmpty()) { + Collections.sort(updatesQueue, new Comparator() { + @Override + public int compare(TLRPC.Updates updates, TLRPC.Updates updates2) { + int seq1 = getUpdateSeq(updates); + int seq2 = getUpdateSeq(updates2); + if (seq1 == seq2) { + return 0; + } else if (seq1 > seq2) { + return 1; + } + return -1; + } + }); + boolean anyProceed = false; + for (int a = 0; a < updatesQueue.size(); a++) { + TLRPC.Updates updates = updatesQueue.get(a); + int seq = getUpdateSeq(updates); + if (MessagesStorage.lastSeqValue + 1 == seq || MessagesStorage.lastSeqValue == seq) { + processUpdates(updates, true); + anyProceed = true; + updatesQueue.remove(a); + a--; + } else if (MessagesStorage.lastSeqValue < seq) { + if (updatesStartWaitTime != 0 && (anyProceed || updatesStartWaitTime + 1500 > System.currentTimeMillis())) { + FileLog.e("tmessages", "HOLE IN UPDATES QUEUE - will wait more time"); + if (anyProceed) { + updatesStartWaitTime = System.currentTimeMillis(); + } + return; + } else { + FileLog.e("tmessages", "HOLE IN UPDATES QUEUE - getDifference"); + updatesStartWaitTime = 0; + updatesQueue.clear(); + getDifference(); + return; + } + } else { + updatesQueue.remove(a); + a--; + } + } + updatesQueue.clear(); + FileLog.e("tmessages", "UPDATES QUEUE PROCEED - OK"); + updatesStartWaitTime = 0; + if (getDifference) { + final int stateCopy = ConnectionsManager.Instance.connectionState; + Utilities.RunOnUIThread(new Runnable() { + @Override + public void run() { + NotificationCenter.Instance.postNotificationName(703, stateCopy); + } + }); + } + } else { + if (getDifference) { + final int stateCopy = ConnectionsManager.Instance.connectionState; + Utilities.RunOnUIThread(new Runnable() { + @Override + public void run() { + NotificationCenter.Instance.postNotificationName(703, stateCopy); + } + }); + } else { + updatesStartWaitTime = 0; + } + } + } + public void getDifference() { registerForPush(UserConfig.pushString); if (MessagesStorage.lastDateValue == 0) { @@ -3441,6 +2897,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter req.pts = MessagesStorage.lastPtsValue; req.date = MessagesStorage.lastDateValue; req.qts = MessagesStorage.lastQtsValue; + FileLog.e("tmessages", "start getDifference with date = " + MessagesStorage.lastDateValue + " pts = " + MessagesStorage.lastPtsValue + " seq = " + MessagesStorage.lastSeqValue); if (ConnectionsManager.Instance.connectionState == 0) { ConnectionsManager.Instance.connectionState = 3; final int stateCopy = ConnectionsManager.Instance.connectionState; @@ -3454,7 +2911,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() { @Override public void run(TLObject response, TLRPC.TL_error error) { - gettingDifference = false; gettingDifferenceAgain = false; if (error == null) { final TLRPC.updates_Difference res = (TLRPC.updates_Difference)response; @@ -3529,8 +2985,10 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } - if ((dialog_id != openned_dialog_id || ApplicationLoader.lastPauseTime != 0) && !obj.messageOwner.out && (lastMessage == null || lastMessage.messageOwner.date < obj.messageOwner.date)) { - lastMessage = obj; + if (!(res instanceof TLRPC.TL_updates_differenceSlice)) { + if ((dialog_id != openned_dialog_id || ApplicationLoader.lastPauseTime != 0) && !obj.messageOwner.out && obj.messageOwner.unread && (lastMessage == null || lastMessage.messageOwner.date < obj.messageOwner.date)) { + lastMessage = obj; + } } long uid; if (message.dialog_id != 0) { @@ -3552,15 +3010,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter } arr.add(obj); } - MessagesStorage.Instance.storageQueue.postRunnable(new Runnable() { - @Override - public void run() { - MessagesStorage.Instance.startTransaction(false); - MessagesStorage.Instance.putMessages(res.new_messages, false, false); - MessagesStorage.Instance.putUsersAndChats(res.users, res.chats, false, false); - MessagesStorage.Instance.commitTransaction(false); - } - }); final MessageObject object = lastMessage; Utilities.RunOnUIThread(new Runnable() { @@ -3586,25 +3035,29 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } }); + MessagesStorage.Instance.storageQueue.postRunnable(new Runnable() { + @Override + public void run() { + MessagesStorage.Instance.startTransaction(false); + MessagesStorage.Instance.putMessages(res.new_messages, false, false); + MessagesStorage.Instance.putUsersAndChats(res.users, res.chats, false, false); + MessagesStorage.Instance.commitTransaction(false); + } + }); } if (res != null && !res.other_updates.isEmpty()) { processUpdateArray(res.other_updates, res.users, res.chats); } + gettingDifference = false; if (res instanceof TLRPC.TL_updates_difference) { MessagesStorage.lastSeqValue = res.state.seq; MessagesStorage.lastDateValue = res.state.date; MessagesStorage.lastPtsValue = res.state.pts; MessagesStorage.lastQtsValue = res.state.qts; ConnectionsManager.Instance.connectionState = 0; - final int stateCopy = ConnectionsManager.Instance.connectionState; - Utilities.RunOnUIThread(new Runnable() { - @Override - public void run() { - NotificationCenter.Instance.postNotificationName(703, stateCopy); - } - }); + processUpdatesQueue(true); } else if (res instanceof TLRPC.TL_updates_differenceSlice) { MessagesStorage.lastSeqValue = res.intermediate_state.seq; MessagesStorage.lastDateValue = res.intermediate_state.date; @@ -3616,23 +3069,17 @@ public class MessagesController implements NotificationCenter.NotificationCenter MessagesStorage.lastSeqValue = res.seq; MessagesStorage.lastDateValue = res.date; ConnectionsManager.Instance.connectionState = 0; - final int stateCopy = ConnectionsManager.Instance.connectionState; - Utilities.RunOnUIThread(new Runnable() { - @Override - public void run() { - NotificationCenter.Instance.postNotificationName(703, stateCopy); - } - }); + processUpdatesQueue(true); } MessagesStorage.Instance.saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue); + FileLog.e("tmessages", "received difference with date = " + MessagesStorage.lastDateValue + " pts = " + MessagesStorage.lastPtsValue + " seq = " + MessagesStorage.lastSeqValue); + FileLog.e("tmessages", "messages = " + res.new_messages.size() + " users = " + res.users.size() + " chats = " + res.chats.size() + " other updates = " + res.other_updates.size()); } }); } }); - - FileLog.e("tmessages", "received defference with date = " + MessagesStorage.lastDateValue + " pts = " + MessagesStorage.lastPtsValue + " seq = " + MessagesStorage.lastSeqValue); - FileLog.e("tmessages", "messages = " + res.new_messages.size() + " users = " + res.users.size() + " chats = " + res.chats.size() + " other updates = " + res.other_updates.size()); } else { + gettingDifference = false; loadCurrentState(); FileLog.e("tmessages", "get difference error, don't know what to do :("); } @@ -3640,16 +3087,17 @@ public class MessagesController implements NotificationCenter.NotificationCenter }, null, true, RPCRequest.RPCRequestClassGeneric); } - public void processUpdates(final TLRPC.Updates updates) { + public void processUpdates(final TLRPC.Updates updates, boolean fromQueue) { boolean needGetDiff = false; boolean needReceivedQueue = false; + boolean addedToQueue = false; if (updates instanceof TLRPC.TL_updateShort) { ArrayList arr = new ArrayList(); arr.add(updates.update); - //MessagesStorage.lastDateValue = updates.date; processUpdateArray(arr, null, null); } else if (updates instanceof TLRPC.TL_updateShortChatMessage) { - if (MessagesStorage.lastSeqValue + 1 == updates.seq && chats.get(updates.chat_id) != null && users.get(updates.from_id) != null) { + boolean missingData = chats.get(updates.chat_id) == null || users.get(updates.from_id) == null; + if (MessagesStorage.lastSeqValue + 1 == updates.seq && !missingData) { TLRPC.TL_message message = new TLRPC.TL_message(); message.from_id = updates.from_id; message.id = updates.id; @@ -3666,7 +3114,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter objArr.add(obj); ArrayList arr = new ArrayList(); arr.add(message); - MessagesStorage.Instance.putMessages(arr, false, true); final boolean printUpdate = updatePrintingUsersWithNewMessages(-updates.chat_id, objArr); if (printUpdate) { updatePrintingStrings(); @@ -3675,8 +3122,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter @Override public void run() { if (printUpdate) { - NotificationCenter.Instance.postNotificationName(userPrintUpdate, (long)(-updates.chat_id)); - NotificationCenter.Instance.postNotificationName(userPrintUpdateAll); + NotificationCenter.Instance.postNotificationName(updateInterfaces, UPDATE_MASK_USER_PRINT); } if (obj.messageOwner.from_id != UserConfig.clientUserId) { long dialog_id; @@ -3693,12 +3139,23 @@ public class MessagesController implements NotificationCenter.NotificationCenter NotificationCenter.Instance.postNotificationName(dialogsNeedReload); } }); - } else { + MessagesStorage.Instance.putMessages(arr, false, true); + } else if (!missingData && MessagesStorage.lastSeqValue != updates.seq) { FileLog.e("tmessages", "need get diff TL_updateShortChatMessage, seq: " + MessagesStorage.lastSeqValue + " " + updates.seq); - needGetDiff = true; + if (gettingDifference || updatesStartWaitTime == 0 || updatesStartWaitTime != 0 && updatesStartWaitTime + 1500 > System.currentTimeMillis()) { + if (updatesStartWaitTime == 0) { + updatesStartWaitTime = System.currentTimeMillis(); + } + FileLog.e("tmessages", "add TL_updateShortChatMessage to queue"); + updatesQueue.add(updates); + addedToQueue = true; + } else { + needGetDiff = true; + } } } else if (updates instanceof TLRPC.TL_updateShortMessage) { - if (MessagesStorage.lastSeqValue + 1 == updates.seq && users.get(updates.from_id) != null) { + boolean missingData = users.get(updates.from_id) == null; + if (MessagesStorage.lastSeqValue + 1 == updates.seq && !missingData) { TLRPC.TL_message message = new TLRPC.TL_message(); message.from_id = updates.from_id; message.id = updates.id; @@ -3716,7 +3173,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter objArr.add(obj); ArrayList arr = new ArrayList(); arr.add(message); - MessagesStorage.Instance.putMessages(arr, false, true); final boolean printUpdate = updatePrintingUsersWithNewMessages(updates.from_id, objArr); if (printUpdate) { updatePrintingStrings(); @@ -3725,8 +3181,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter @Override public void run() { if (printUpdate) { - NotificationCenter.Instance.postNotificationName(userPrintUpdate, (long)(updates.from_id)); - NotificationCenter.Instance.postNotificationName(userPrintUpdateAll); + NotificationCenter.Instance.postNotificationName(updateInterfaces, UPDATE_MASK_USER_PRINT); } if (obj.messageOwner.from_id != UserConfig.clientUserId) { long dialog_id; @@ -3743,12 +3198,22 @@ public class MessagesController implements NotificationCenter.NotificationCenter NotificationCenter.Instance.postNotificationName(dialogsNeedReload); } }); - } else { + MessagesStorage.Instance.putMessages(arr, false, true); + } else if (!missingData && MessagesStorage.lastSeqValue != updates.seq) { FileLog.e("tmessages", "need get diff TL_updateShortMessage, seq: " + MessagesStorage.lastSeqValue + " " + updates.seq); - needGetDiff = true; + if (gettingDifference || updatesStartWaitTime == 0 || updatesStartWaitTime != 0 && updatesStartWaitTime + 1500 > System.currentTimeMillis()) { + if (updatesStartWaitTime == 0) { + updatesStartWaitTime = System.currentTimeMillis(); + } + FileLog.e("tmessages", "add TL_updateShortMessage to queue"); + updatesQueue.add(updates); + addedToQueue = true; + } else { + needGetDiff = true; + } } } else if (updates instanceof TLRPC.TL_updatesCombined) { - if (MessagesStorage.lastSeqValue + 1 == updates.seq_start || updates.seq_start == 0 || MessagesStorage.lastSeqValue == updates.seq_start) { + if (MessagesStorage.lastSeqValue + 1 == updates.seq_start || MessagesStorage.lastSeqValue == updates.seq_start) { MessagesStorage.Instance.putUsersAndChats(updates.users, updates.chats, true, true); int lastPtsValue = MessagesStorage.lastPtsValue; int lastQtsValue = MessagesStorage.lastQtsValue; @@ -3766,7 +3231,16 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } else { FileLog.e("tmessages", "need get diff TL_updatesCombined, seq: " + MessagesStorage.lastSeqValue + " " + updates.seq_start); - needGetDiff = true; + if (gettingDifference || updatesStartWaitTime == 0 || updatesStartWaitTime != 0 && updatesStartWaitTime + 1500 > System.currentTimeMillis()) { + if (updatesStartWaitTime == 0) { + updatesStartWaitTime = System.currentTimeMillis(); + } + FileLog.e("tmessages", "add TL_updatesCombined to queue"); + updatesQueue.add(updates); + addedToQueue = true; + } else { + needGetDiff = true; + } } } else if (updates instanceof TLRPC.TL_updates) { if (MessagesStorage.lastSeqValue + 1 == updates.seq || updates.seq == 0 || updates.seq == MessagesStorage.lastSeqValue) { @@ -3780,21 +3254,36 @@ public class MessagesController implements NotificationCenter.NotificationCenter FileLog.e("tmessages", "need get diff inner TL_updates, seq: " + MessagesStorage.lastSeqValue + " " + updates.seq); } else { MessagesStorage.lastDateValue = updates.date; - MessagesStorage.lastSeqValue = updates.seq; + if (updates.seq != 0) { + MessagesStorage.lastSeqValue = updates.seq; + } if (MessagesStorage.lastQtsValue != lastQtsValue) { needReceivedQueue = true; } } } else { FileLog.e("tmessages", "need get diff TL_updates, seq: " + MessagesStorage.lastSeqValue + " " + updates.seq); - needGetDiff = true; + if (gettingDifference || updatesStartWaitTime == 0 || updatesStartWaitTime != 0 && updatesStartWaitTime + 1500 > System.currentTimeMillis()) { + if (updatesStartWaitTime == 0) { + updatesStartWaitTime = System.currentTimeMillis(); + } + FileLog.e("tmessages", "add TL_updates to queue"); + updatesQueue.add(updates); + addedToQueue = true; + } else { + needGetDiff = true; + } } } else if (updates instanceof TLRPC.TL_updatesTooLong) { FileLog.e("tmessages", "need get diff TL_updatesTooLong"); needGetDiff = true; + } else if (updates instanceof UserActionUpdates) { + MessagesStorage.lastSeqValue = updates.seq; } - if (needGetDiff) { + if (needGetDiff && !fromQueue) { getDifference(); + } else if (!fromQueue && !updatesQueue.isEmpty()) { + processUpdatesQueue(false); } if (needReceivedQueue) { TLRPC.TL_messages_receivedQueue req = new TLRPC.TL_messages_receivedQueue(); @@ -3815,15 +3304,16 @@ public class MessagesController implements NotificationCenter.NotificationCenter } long currentTime = System.currentTimeMillis(); - final HashMap> messages = new HashMap>(); //to chats+ - final ArrayList messagesArr = new ArrayList(); //to db+ - final ArrayList markAsReadMessages = new ArrayList(); //to db+ and chats+ and dialogs+ - final HashMap markAsReadEncrypted = new HashMap(); //to db+ and chats+ and dialogs+ - final ArrayList deletedMessages = new ArrayList(); //to db+ and chats+ and dialogs+ - final ArrayList printChanges = new ArrayList(); //to chats+ and dialogs - final ArrayList chatInfoToUpdate = new ArrayList(); //to db+ and chats - final ArrayList updatesOnMainThread = new ArrayList(); //to db+ and every interface+ + final HashMap> messages = new HashMap>(); + final ArrayList messagesArr = new ArrayList(); + final ArrayList markAsReadMessages = new ArrayList(); + final HashMap markAsReadEncrypted = new HashMap(); + final ArrayList deletedMessages = new ArrayList(); + final ArrayList printChanges = new ArrayList(); + final ArrayList chatInfoToUpdate = new ArrayList(); + final ArrayList updatesOnMainThread = new ArrayList(); final ArrayList tasks = new ArrayList(); + final ArrayList contactsIds = new ArrayList(); MessageObject lastMessage = null; boolean usersAdded = false; @@ -3849,8 +3339,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter chatsDict = chats; } - boolean chatAvatarUpdated = false; - boolean reloadContacts = false; + int interfaceUpdateMask = 0; for (TLRPC.Update update : updates) { if (update instanceof TLRPC.TL_updateNewMessage) { @@ -3863,7 +3352,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter messagesArr.add(upd.message); MessageObject obj = new MessageObject(upd.message, usersDict); if (obj.type == 11) { - chatAvatarUpdated = true; + interfaceUpdateMask |= UPDATE_MASK_CHAT_AVATAR; + } else if (obj.type == 10) { + interfaceUpdateMask |= UPDATE_MASK_CHAT_NAME; } long uid; if (upd.message.to_id.chat_id != 0) { @@ -3926,12 +3417,17 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } } else if (update instanceof TLRPC.TL_updateChatParticipants) { + interfaceUpdateMask |= UPDATE_MASK_CHAT_MEMBERS; chatInfoToUpdate.add(update.participants); } else if (update instanceof TLRPC.TL_updateUserStatus) { + interfaceUpdateMask |= UPDATE_MASK_STATUS; updatesOnMainThread.add(update); } else if (update instanceof TLRPC.TL_updateUserName) { + interfaceUpdateMask |= UPDATE_MASK_NAME; updatesOnMainThread.add(update); } else if (update instanceof TLRPC.TL_updateUserPhoto) { + interfaceUpdateMask |= UPDATE_MASK_AVATAR; + MessagesStorage.Instance.clearUserPhotos(update.user_id); /*if (!(update.photo instanceof TLRPC.TL_userProfilePhotoEmpty)) { DEPRECATED if (usersDict.containsKey(update.user_id)) { TLRPC.TL_messageService newMessage = new TLRPC.TL_messageService(); @@ -3965,7 +3461,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter updatesOnMainThread.add(update); } else if (update instanceof TLRPC.TL_updateContactRegistered) { - if (usersDict.containsKey(update.user_id)) { + if (enableJoined && usersDict.containsKey(update.user_id)) { TLRPC.TL_messageService newMessage = new TLRPC.TL_messageService(); newMessage.action = new TLRPC.TL_messageActionUserJoined(); newMessage.local_id = newMessage.id = UserConfig.getNewMessageId(); @@ -3992,20 +3488,29 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } } - - reloadContacts = true; - //updateContactRegistered#2575bbb9 user_id:int date:int = Update; - //updateContactRegistered Импортированный ранее контакт зарегистрировался - +// if (!contactsIds.contains(update.user_id)) { +// contactsIds.add(update.user_id); +// } } else if (update instanceof TLRPC.TL_updateContactLink) { - reloadContacts = true; - //updateContactLink#51a48a9a user_id:int my_link:contacts.MyLink foreign_link:contacts.ForeignLink = Update; - //updateContactLink Изменилась связь с пользователем - + if (update.my_link instanceof TLRPC.TL_contacts_myLinkContact || update.my_link instanceof TLRPC.TL_contacts_myLinkRequested && update.my_link.contact) { + int idx = contactsIds.indexOf(-update.user_id); + if (idx != -1) { + contactsIds.remove(idx); + } + if (!contactsIds.contains(update.user_id)) { + contactsIds.add(update.user_id); + } + } else { + int idx = contactsIds.indexOf(update.user_id); + if (idx != -1) { + contactsIds.remove(idx); + } + if (!contactsIds.contains(update.user_id)) { + contactsIds.add(-update.user_id); + } + } } else if (update instanceof TLRPC.TL_updateActivation) { - //updateActivation#6f690963 user_id:int = Update; - //updateActivation Пользователь активировал свой аккаунт - + //DEPRECATED } else if (update instanceof TLRPC.TL_updateNewAuthorization) { TLRPC.TL_messageService newMessage = new TLRPC.TL_messageService(); newMessage.action = new TLRPC.TL_messageActionLoginUnknownLocation(); @@ -4035,7 +3540,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } } else if (update instanceof TLRPC.TL_updateNewGeoChatMessage) { - //TODO + //DEPRECATED } else if (update instanceof TLRPC.TL_updateNewEncryptedMessage) { MessagesStorage.lastQtsValue = update.qts; TLRPC.Message message = decryptMessage(((TLRPC.TL_updateNewEncryptedMessage)update).message); @@ -4083,6 +3588,12 @@ public class MessagesController implements NotificationCenter.NotificationCenter } else if (update instanceof TLRPC.TL_updateEncryptedMessagesRead) { markAsReadEncrypted.put(update.chat_id, Math.max(update.max_date, update.date)); tasks.add((TLRPC.TL_updateEncryptedMessagesRead)update); + } else if (update instanceof TLRPC.TL_updateChatParticipantAdd) { + MessagesStorage.Instance.updateChatInfo(update.chat_id, update.user_id, false, update.inviter_id, update.version); + } else if (update instanceof TLRPC.TL_updateChatParticipantDelete) { + MessagesStorage.Instance.updateChatInfo(update.chat_id, update.user_id, true, 0, update.version); + } else if (update instanceof TLRPC.TL_updateDcOptions) { + ConnectionsManager.Instance.updateDcSettings(); } else if (update instanceof TLRPC.TL_updateEncryption) { final TLRPC.EncryptedChat newChat = update.chat; long dialog_id = ((long)newChat.id) << 32; @@ -4196,26 +3707,28 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } } - if (reloadContacts) { - loadContacts(false); - } if (!printChanges.isEmpty()) { updatePrintingStrings(); } final MessageObject lastMessageArg = lastMessage; - final boolean reloadInterfaceForce = chatAvatarUpdated; + final int interfaceUpdateMaskFinal = interfaceUpdateMask; + + if (!contactsIds.isEmpty()) { + ContactsController.Instance.processContactsUpdates(contactsIds, usersDict); + } if (!messagesArr.isEmpty()) { MessagesStorage.Instance.putMessages(messagesArr, true, true); } final boolean usersAddedConst = usersAdded; - if (!messages.isEmpty() || !markAsReadMessages.isEmpty() || !deletedMessages.isEmpty() || !printChanges.isEmpty() || !chatInfoToUpdate.isEmpty() || !updatesOnMainThread.isEmpty() || !markAsReadEncrypted.isEmpty()) { + if (!messages.isEmpty() || !markAsReadMessages.isEmpty() || !deletedMessages.isEmpty() || !printChanges.isEmpty() || !chatInfoToUpdate.isEmpty() || !updatesOnMainThread.isEmpty() || !markAsReadEncrypted.isEmpty() || !contactsIds.isEmpty()) { Utilities.RunOnUIThread(new Runnable() { @Override public void run() { + int updateMask = interfaceUpdateMaskFinal; if (!usersAddedConst) { if (usersArr != null) { for (TLRPC.User user : usersArr) { @@ -4284,6 +3797,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter ArrayList value = entry.getValue(); updateInterfaceWithMessages(key, value); } + NotificationCenter.Instance.postNotificationName(dialogsNeedReload); } if (!markAsReadMessages.isEmpty()) { for (Integer id : markAsReadMessages) { @@ -4317,10 +3831,11 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } if (!printChanges.isEmpty()) { - for (Long uid : printChanges) { - NotificationCenter.Instance.postNotificationName(userPrintUpdate, uid); - } - NotificationCenter.Instance.postNotificationName(userPrintUpdateAll); + updateMask |= UPDATE_MASK_USER_PRINT; + } + if (!contactsIds.isEmpty()) { + updateMask |= UPDATE_MASK_NAME; + updateMask |= UPDATE_MASK_USER_PHONE; } if (!chatInfoToUpdate.isEmpty()) { for (TLRPC.ChatParticipants info : chatInfoToUpdate) { @@ -4328,10 +3843,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter NotificationCenter.Instance.postNotificationName(chatInfoDidLoaded, info.chat_id, info); } } - if (avatarsUpdate || reloadInterfaceForce) { - NotificationCenter.Instance.postNotificationName(updateInterfaces, UPDATE_MASK_ALL); - } else { - NotificationCenter.Instance.postNotificationName(updateInterfaces, UPDATE_MASK_NAME | UPDATE_MASK_STATUS); + if (updateMask != 0) { + NotificationCenter.Instance.postNotificationName(updateInterfaces, updateMask); } if (lastMessageArg != null) { showInAppNotification(lastMessageArg); @@ -4411,6 +3924,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter } private void showInAppNotification(MessageObject messageObject) { + if (!UserConfig.clientActivated) { + return; + } if (ApplicationLoader.lastPauseTime != 0) { ApplicationLoader.lastPauseTime = System.currentTimeMillis(); FileLog.e("tmessages", "reset sleep timeout by recieved message"); @@ -4508,9 +4024,12 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (chat_id != 0 && !globalEnabled) { return; } + TLRPC.FileLocation photoPath = null; boolean globalVibrate = preferences.getBoolean("EnableVibrateAll", true); boolean groupVibrate = preferences.getBoolean("EnableVibrateGroup", true); + boolean groupPreview = preferences.getBoolean("EnablePreviewGroup", true); + boolean userPreview = preferences.getBoolean("EnablePreviewAll", true); String defaultPath = null; Uri defaultUri = Settings.System.DEFAULT_NOTIFICATION_URI; @@ -4536,38 +4055,49 @@ public class MessagesController implements NotificationCenter.NotificationCenter } if (chat_id == 0 && user_id != 0) { + TLRPC.User u = users.get(user_id); if (u == null) { return; } - if (messageObject.messageOwner instanceof TLRPC.TL_messageService) { - if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionUserJoined) { - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationContactJoined, Utilities.formatName(u.first_name, u.last_name)); - } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) { - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationContactNewPhoto, Utilities.formatName(u.first_name, u.last_name)); - } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionLoginUnknownLocation) { - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationUnrecognizedDevice, messageObject.messageOwner.action.title, messageObject.messageOwner.action.address); + + if (u.photo != null && u.photo.photo_small != null && u.photo.photo_small.volume_id != 0 && u.photo.photo_small.local_id != 0) { + photoPath = u.photo.photo_small; + } + + if (userPreview) { + if (messageObject.messageOwner instanceof TLRPC.TL_messageService) { + if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionUserJoined) { + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationContactJoined, Utilities.formatName(u.first_name, u.last_name)); + } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) { + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationContactNewPhoto, Utilities.formatName(u.first_name, u.last_name)); + } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionLoginUnknownLocation) { + String date = String.format("%s %s %s", Utilities.formatterYear.format(((long)messageObject.messageOwner.date) * 1000), ApplicationLoader.applicationContext.getString(R.string.OtherAt), Utilities.formatterDay.format(((long)messageObject.messageOwner.date) * 1000)); + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationUnrecognizedDevice, UserConfig.currentUser.first_name, date, messageObject.messageOwner.action.title, messageObject.messageOwner.action.address); + } + } else { + if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty) { + if (messageObject.messageOwner.message != null && messageObject.messageOwner.message.length() != 0) { + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageText, Utilities.formatName(u.first_name, u.last_name), messageObject.messageOwner.message); + } else { + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageNoText, Utilities.formatName(u.first_name, u.last_name)); + } + } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) { + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessagePhoto, Utilities.formatName(u.first_name, u.last_name)); + } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) { + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageVideo, Utilities.formatName(u.first_name, u.last_name)); + } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaContact) { + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageContact, Utilities.formatName(u.first_name, u.last_name)); + } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGeo) { + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageMap, Utilities.formatName(u.first_name, u.last_name)); + } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument) { + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageDocument, Utilities.formatName(u.first_name, u.last_name)); + } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaAudio) { + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageAudio, Utilities.formatName(u.first_name, u.last_name)); + } } } else { - if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty) { - if (messageObject.messageOwner.message != null && messageObject.messageOwner.message.length() != 0) { - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageText, Utilities.formatName(u.first_name, u.last_name), messageObject.messageOwner.message); - } else { - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageNoText, Utilities.formatName(u.first_name, u.last_name)); - } - } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) { - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessagePhoto, Utilities.formatName(u.first_name, u.last_name)); - } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) { - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageVideo, Utilities.formatName(u.first_name, u.last_name)); - } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaContact) { - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageContact, Utilities.formatName(u.first_name, u.last_name)); - } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGeo) { - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageMap, Utilities.formatName(u.first_name, u.last_name)); - } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument) { - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageDocument, Utilities.formatName(u.first_name, u.last_name)); - } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaAudio) { - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageAudio, Utilities.formatName(u.first_name, u.last_name)); - } + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageNoText, Utilities.formatName(u.first_name, u.last_name)); } } else if (chat_id != 0 && user_id == 0) { TLRPC.Chat chat = chats.get(chat_id); @@ -4578,58 +4108,69 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (u == null) { return; } - if (messageObject.messageOwner instanceof TLRPC.TL_messageService) { - if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatAddUser) { - if (messageObject.messageOwner.action.user_id == UserConfig.clientUserId) { - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationInvitedToGroup, Utilities.formatName(u.first_name, u.last_name), chat.title); - } else { - TLRPC.User u2 = users.get(messageObject.messageOwner.action.user_id); - if (u2 == null) { - return; + + if (u.photo != null && u.photo.photo_small != null && u.photo.photo_small.volume_id != 0 && u.photo.photo_small.local_id != 0) { + photoPath = u.photo.photo_small; + } + + if (groupPreview) { + if (messageObject.messageOwner instanceof TLRPC.TL_messageService) { + if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatAddUser) { + if (messageObject.messageOwner.action.user_id == UserConfig.clientUserId) { + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationInvitedToGroup, Utilities.formatName(u.first_name, u.last_name), chat.title); + } else { + TLRPC.User u2 = users.get(messageObject.messageOwner.action.user_id); + if (u2 == null) { + return; + } + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationGroupAddMember, Utilities.formatName(u.first_name, u.last_name), chat.title, Utilities.formatName(u2.first_name, u2.last_name)); + } + } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatEditTitle) { + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationEditedGroupName, Utilities.formatName(u.first_name, u.last_name), messageObject.messageOwner.action.title); + } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatEditPhoto || messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatDeletePhoto) { + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationEditedGroupPhoto, Utilities.formatName(u.first_name, u.last_name), chat.title); + } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatDeleteUser) { + if (messageObject.messageOwner.action.user_id == UserConfig.clientUserId) { + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationGroupKickYou, Utilities.formatName(u.first_name, u.last_name), chat.title); + } else if (messageObject.messageOwner.action.user_id == u.id) { + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationGroupLeftMember, Utilities.formatName(u.first_name, u.last_name), chat.title); + } else { + TLRPC.User u2 = users.get(messageObject.messageOwner.action.user_id); + if (u2 == null) { + return; + } + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationGroupKickMember, Utilities.formatName(u.first_name, u.last_name), chat.title, Utilities.formatName(u2.first_name, u2.last_name)); } - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationGroupAddMember, Utilities.formatName(u.first_name, u.last_name), chat.title, Utilities.formatName(u2.first_name, u2.last_name)); } - } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatEditTitle) { - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationEditedGroupName, Utilities.formatName(u.first_name, u.last_name), messageObject.messageOwner.action.title); - } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatEditPhoto || messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatDeletePhoto) { - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationEditedGroupPhoto, Utilities.formatName(u.first_name, u.last_name), chat.title); - } else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatDeleteUser) { - if (messageObject.messageOwner.action.user_id == UserConfig.clientUserId) { - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationGroupKickYou, Utilities.formatName(u.first_name, u.last_name), chat.title); - } else if (messageObject.messageOwner.action.user_id == u.id) { - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationGroupLeftMember, Utilities.formatName(u.first_name, u.last_name), chat.title); - } else { - TLRPC.User u2 = users.get(messageObject.messageOwner.action.user_id); - if (u2 == null) { - return; + } else { + if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty) { + if (messageObject.messageOwner.message != null && messageObject.messageOwner.message.length() != 0) { + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageGroupText, Utilities.formatName(u.first_name, u.last_name), chat.title, messageObject.messageOwner.message); + } else { + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageGroupNoText, Utilities.formatName(u.first_name, u.last_name), chat.title); } - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationGroupKickMember, Utilities.formatName(u.first_name, u.last_name), chat.title, Utilities.formatName(u2.first_name, u2.last_name)); + } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) { + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageGroupPhoto, Utilities.formatName(u.first_name, u.last_name), chat.title); + } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) { + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageGroupVideo, Utilities.formatName(u.first_name, u.last_name), chat.title); + } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaContact) { + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageGroupContact, Utilities.formatName(u.first_name, u.last_name), chat.title); + } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGeo) { + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageGroupMap, Utilities.formatName(u.first_name, u.last_name), chat.title); + } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument) { + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageGroupDocument, Utilities.formatName(u.first_name, u.last_name), chat.title); + } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaAudio) { + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageGroupAudio, Utilities.formatName(u.first_name, u.last_name), chat.title); } } } else { - if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty) { - if (messageObject.messageOwner.message != null && messageObject.messageOwner.message.length() != 0) { - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageGroupText, Utilities.formatName(u.first_name, u.last_name), chat.title, messageObject.messageOwner.message); - } else { - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageGroupNoText, Utilities.formatName(u.first_name, u.last_name), chat.title); - } - } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) { - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageGroupPhoto, Utilities.formatName(u.first_name, u.last_name), chat.title); - } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaVideo) { - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageGroupVideo, Utilities.formatName(u.first_name, u.last_name), chat.title); - } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaContact) { - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageGroupContact, Utilities.formatName(u.first_name, u.last_name), chat.title); - } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGeo) { - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageGroupMap, Utilities.formatName(u.first_name, u.last_name), chat.title); - } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument) { - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageGroupDocument, Utilities.formatName(u.first_name, u.last_name), chat.title); - } else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaAudio) { - msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageGroupAudio, Utilities.formatName(u.first_name, u.last_name), chat.title); - } + msg = ApplicationLoader.applicationContext.getString(R.string.NotificationMessageGroupNoText, Utilities.formatName(u.first_name, u.last_name), chat.title); } } } else { msg = ApplicationLoader.applicationContext.getString(R.string.YouHaveNewMessage); + int enc_id = (int)(dialog_id >> 32); + intent.putExtra("encId", enc_id); } if (msg == null) { return; @@ -4677,6 +4218,18 @@ public class MessagesController implements NotificationCenter.NotificationCenter .setAutoCancel(true) .setTicker(msg); + if (photoPath != null) { + Bitmap img = FileLoader.Instance.getImageFromMemory(photoPath, null, null, "50_50", false); +// String fileNameFinal = u.photo.photo_small.volume_id + "_" + u.photo.photo_small.local_id + ".jpg"; +// File cacheFileFinal = new File(Utilities.getCacheDir(), fileNameFinal); +// if (cacheFileFinal.exists()) { +// photoPath +// } + if (img != null) { + mBuilder.setLargeIcon(img); + } + } + if (needVibrate) { mBuilder.setVibrate(new long[]{0, 100, 0, 100}); } @@ -4703,8 +4256,22 @@ public class MessagesController implements NotificationCenter.NotificationCenter } } + public void dialogsUnreadCountIncr(final HashMap values) { + Utilities.RunOnUIThread(new Runnable() { + @Override + public void run() { + for (HashMap.Entry entry : values.entrySet()) { + TLRPC.TL_dialog dialog = dialogs_dict.get(entry.getKey()); + if (dialog != null) { + dialog.unread_count += entry.getValue(); + } + } + NotificationCenter.Instance.postNotificationName(dialogsNeedReload); + } + }); + } + private void updateInterfaceWithMessages(long uid, ArrayList messages) { - int unreadCount = 0; MessageObject lastMessage = null; int lastDate = 0; TLRPC.TL_dialog dialog = dialogs_dict.get(uid); @@ -4712,9 +4279,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter NotificationCenter.Instance.postNotificationName(didReceivedNewMessages, uid, messages); for (MessageObject message : messages) { - if (message.messageOwner.unread && message.messageOwner.from_id != UserConfig.clientUserId) { - unreadCount++; - } if (lastMessage == null || message.messageOwner.date > lastDate) { lastMessage = message; lastDate = message.messageOwner.date; @@ -4724,7 +4288,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter if (dialog == null) { dialog = new TLRPC.TL_dialog(); dialog.id = uid; - dialog.unread_count = unreadCount; + dialog.unread_count = 0; dialog.top_message = lastMessage.messageOwner.id; dialog.last_message_date = lastMessage.messageOwner.date; dialogs_dict.put(uid, dialog); @@ -4732,7 +4296,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter dialogMessage.put(lastMessage.messageOwner.id, lastMessage); } else { dialogMessage.remove(dialog.top_message); - dialog.unread_count += unreadCount; dialog.top_message = lastMessage.messageOwner.id; dialog.last_message_date = lastMessage.messageOwner.date; dialogMessage.put(lastMessage.messageOwner.id, lastMessage); @@ -4936,8 +4499,14 @@ public class MessagesController implements NotificationCenter.NotificationCenter MessagesStorage.Instance.updateEncryptedChatTTL(chat); return newMessage; } + } else { + FileLog.e("tmessages", "unkown message " + object); } + } else { + FileLog.e("tmessages", "unkown TLObject"); } + } else { + FileLog.e("tmessages", "fingerprint mismatch"); } return null; } @@ -5108,7 +4677,10 @@ public class MessagesController implements NotificationCenter.NotificationCenter }, null, true, RPCRequest.RPCRequestClassGeneric); } - public void startSecretChat(final Context context, final int user_id) { + public void startSecretChat(final Context context, final TLRPC.User user) { + if (user == null) { + return; + } final ProgressDialog progressDialog = new ProgressDialog(context); progressDialog.setMessage(context.getString(R.string.Loading)); progressDialog.setCanceledOnTouchOutside(false); @@ -5127,8 +4699,12 @@ public class MessagesController implements NotificationCenter.NotificationCenter Utilities.RunOnUIThread(new Runnable() { @Override public void run() { - if (!((ActionBarActivity)context).isFinishing()) { - progressDialog.dismiss(); + try { + if (!((ActionBarActivity)context).isFinishing()) { + progressDialog.dismiss(); + } + } catch (Exception e) { + FileLog.e("tmessages", e); } } }); @@ -5153,19 +4729,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter g_a = correctedAuth; } - final TLRPC.User user = users.get(user_id); - TLRPC.InputUser inputUser; - if (user instanceof TLRPC.TL_userForeign || user instanceof TLRPC.TL_userRequest) { - inputUser = new TLRPC.TL_inputUserForeign(); - inputUser.user_id = user.id; - inputUser.access_hash = user.access_hash; - } else { - inputUser = new TLRPC.TL_inputUserContact(); - inputUser.user_id = user.id; - } TLRPC.TL_messages_requestEncryption req2 = new TLRPC.TL_messages_requestEncryption(); req2.g_a = g_a; - req2.user_id = inputUser; + req2.user_id = getInputUser(user); req2.random_id = (int)(random.nextDouble() * Integer.MAX_VALUE); ConnectionsManager.Instance.performRpc(req2, new RPCRequest.RPCRequestDelegate() { @Override @@ -5175,7 +4741,11 @@ public class MessagesController implements NotificationCenter.NotificationCenter @Override public void run() { if (!((ActionBarActivity)context).isFinishing()) { - progressDialog.dismiss(); + try { + progressDialog.dismiss(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } } TLRPC.EncryptedChat chat = (TLRPC.EncryptedChat)response; chat.user_id = chat.participant_id; @@ -5216,7 +4786,11 @@ public class MessagesController implements NotificationCenter.NotificationCenter @Override public void run() { if (!((ActionBarActivity)context).isFinishing()) { - progressDialog.dismiss(); + try { + progressDialog.dismiss(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle(context.getString(R.string.AppName)); builder.setMessage(String.format(context.getString(R.string.CreateEncryptedChatOutdatedError), user.first_name, user.first_name)); @@ -5233,7 +4807,11 @@ public class MessagesController implements NotificationCenter.NotificationCenter @Override public void run() { if (!((ActionBarActivity)context).isFinishing()) { - progressDialog.dismiss(); + try { + progressDialog.dismiss(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } } } }); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java index 996edea6c..e1e9cf2c3 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/MessagesStorage.java @@ -9,7 +9,6 @@ package org.telegram.messenger; import android.text.Html; -import android.util.Log; import android.util.SparseArray; import org.telegram.SQLite.SQLiteCursor; @@ -74,6 +73,11 @@ public class MessagesStorage { database.executeFast("INSERT INTO params VALUES(1, 0, 0, 0, 0, 0, 0, NULL)").stepThis().dispose(); database.executeFast("CREATE TABLE user_photos(uid INTEGER, id INTEGER, data BLOB, PRIMARY KEY (uid, id))").stepThis().dispose(); + database.executeFast("CREATE TABLE user_contacts_v6(uid INTEGER PRIMARY KEY, fname TEXT, sname TEXT)").stepThis().dispose(); + database.executeFast("CREATE TABLE user_phones_v6(uid INTEGER, phone TEXT, sphone TEXT, deleted INTEGER, PRIMARY KEY (uid, phone))").stepThis().dispose(); + + database.executeFast("CREATE INDEX IF NOT EXISTS sphone_deleted_idx_user_phones ON user_phones_v6(sphone, deleted);").stepThis().dispose(); + database.executeFast("CREATE INDEX IF NOT EXISTS date_idx_dialogs ON dialogs(date);").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS date_idx_enc_tasks ON enc_tasks(date);").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS last_mid_idx_dialogs ON dialogs(last_mid);").stepThis().dispose(); @@ -133,6 +137,10 @@ public class MessagesStorage { database.executeFast("CREATE INDEX IF NOT EXISTS mid_out_idx_messages ON messages(mid, out);").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS task_idx_messages ON messages(uid, out, read_state, ttl, date, send_state);").stepThis().dispose(); database.executeFast("CREATE INDEX IF NOT EXISTS uid_date_mid_idx_messages ON messages(uid, date, mid);").stepThis().dispose(); + + database.executeFast("CREATE TABLE IF NOT EXISTS user_contacts_v6(uid INTEGER PRIMARY KEY, fname TEXT, sname TEXT)").stepThis().dispose(); + database.executeFast("CREATE TABLE IF NOT EXISTS user_phones_v6(uid INTEGER, phone TEXT, sphone TEXT, deleted INTEGER, PRIMARY KEY (uid, phone))").stepThis().dispose(); + database.executeFast("CREATE INDEX IF NOT EXISTS sphone_deleted_idx_user_phones ON user_phones_v6(sphone, deleted);").stepThis().dispose(); } } catch (Exception e) { FileLog.e("tmessages", e); @@ -291,37 +299,55 @@ public class MessagesStorage { } public void getUserPhotos(final int uid, final int offset, final int count, final long max_id, final int classGuid) { - try { - SQLiteCursor cursor; + storageQueue.postRunnable(new Runnable() { + @Override + public void run() { + try { + SQLiteCursor cursor; - if (max_id != 0) { - cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM user_photos WHERE uid = %d AND id < %d ORDER BY id DESC LIMIT %d", uid, max_id, count)); - } else { - cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM user_photos WHERE uid = %d ORDER BY id DESC LIMIT %d,%d", uid, offset, count)); - } + if (max_id != 0) { + cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM user_photos WHERE uid = %d AND id < %d ORDER BY id DESC LIMIT %d", uid, max_id, count)); + } else { + cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM user_photos WHERE uid = %d ORDER BY id DESC LIMIT %d,%d", uid, offset, count)); + } - final TLRPC.photos_Photos res = new TLRPC.photos_Photos(); + final TLRPC.photos_Photos res = new TLRPC.photos_Photos(); - while (cursor.next()) { - byte[] messageData = cursor.byteArrayValue(0); - if (messageData != null) { - SerializedData data = new SerializedData(messageData); - TLRPC.Photo photo = (TLRPC.Photo)TLClassStore.Instance().TLdeserialize(data, data.readInt32()); - res.photos.add(photo); + while (cursor.next()) { + byte[] messageData = cursor.byteArrayValue(0); + if (messageData != null) { + SerializedData data = new SerializedData(messageData); + TLRPC.Photo photo = (TLRPC.Photo)TLClassStore.Instance().TLdeserialize(data, data.readInt32()); + res.photos.add(photo); + } + } + cursor.dispose(); + + Utilities.stageQueue.postRunnable(new Runnable() { + @Override + public void run() { + MessagesController.Instance.processLoadedUserPhotos(res, uid, offset, count, max_id, true, classGuid); + } + }); + + } catch (Exception e) { + FileLog.e("tmessages", e); } } - cursor.dispose(); + }, true); + } - Utilities.stageQueue.postRunnable(new Runnable() { - @Override - public void run() { - MessagesController.Instance.processLoadedUserPhotos(res, uid, offset, count, max_id, true, classGuid); + public void clearUserPhotos(final int uid) { + storageQueue.postRunnable(new Runnable() { + @Override + public void run() { + try { + database.executeFast("DELETE FROM user_photos WHERE uid = " + uid).stepThis().dispose(); + } catch (Exception e) { + FileLog.e("tmessages", e); } - }); - - } catch (Exception e) { - FileLog.e("tmessages", e); - } + } + }); } public void putUserPhotos(final int uid, final TLRPC.photos_Photos photos) { @@ -394,10 +420,11 @@ public class MessagesStorage { int minDate = Integer.MAX_VALUE; SparseArray> messages = new SparseArray>(); String mids = ""; - SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT mid, ttl FROM messages WHERE uid = %d AND out = %d AND read_state = 1 AND ttl > 0 AND date <= %d AND send_state = 0", ((long)chat_id) << 32, isOut, time)); + SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT mid, ttl, read_state FROM messages WHERE uid = %d AND out = %d AND ttl > 0 AND date <= %d AND send_state = 0", ((long)chat_id) << 32, isOut, time)); while (cursor.next()) { int mid = cursor.intValue(0); int ttl = cursor.intValue(1); + int read_state = cursor.intValue(2); int date = readTime + ttl; minDate = Math.min(minDate, date); ArrayList arr = messages.get(date); @@ -690,6 +717,63 @@ public class MessagesStorage { }); } + public void updateChatInfo(final int chat_id, final int user_id, final boolean deleted, final int invited_id, final int version) { + storageQueue.postRunnable(new Runnable() { + @Override + public void run() { + try { + SQLiteCursor cursor = database.queryFinalized("SELECT participants FROM chat_settings WHERE uid = " + chat_id); + TLRPC.ChatParticipants info = null; + ArrayList loadedUsers = new ArrayList(); + if (cursor.next()) { + byte[] userData = cursor.byteArrayValue(0); + if (userData != null) { + SerializedData data = new SerializedData(userData); + info = (TLRPC.ChatParticipants)TLClassStore.Instance().TLdeserialize(data, data.readInt32()); + } + } + cursor.dispose(); + if (info != null) { + if (deleted) { + for (int a = 0; a < info.participants.size(); a++) { + TLRPC.TL_chatParticipant participant = info.participants.get(a); + if (participant.user_id == user_id) { + info.participants.remove(a); + break; + } + } + } else { + TLRPC.TL_chatParticipant participant = new TLRPC.TL_chatParticipant(); + participant.user_id = user_id; + participant.inviter_id = invited_id; + participant.date = ConnectionsManager.Instance.getCurrentTime(); + info.participants.add(participant); + } + info.version = version; + + final TLRPC.ChatParticipants finalInfo = info; + Utilities.RunOnUIThread(new Runnable() { + @Override + public void run() { + NotificationCenter.Instance.postNotificationName(MessagesController.chatInfoDidLoaded, finalInfo.chat_id, finalInfo); + } + }); + + SQLitePreparedStatement state = database.executeFast("REPLACE INTO chat_settings VALUES(?, ?)"); + SerializedData data = new SerializedData(); + info.serializeToStream(data); + state.bindInteger(1, chat_id); + state.bindByteArray(2, data.toByteArray()); + state.step(); + state.dispose(); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + } + public void loadChatInfo(final int chat_id) { storageQueue.postRunnable(new Runnable() { @Override @@ -883,7 +967,7 @@ public class MessagesStorage { FileLog.e("tmessages", e); } } - }); + }, true); } public void putContacts(final ArrayList contacts, final boolean deleteAll) { @@ -914,6 +998,118 @@ public class MessagesStorage { }); } + public void deleteContacts(final ArrayList uids) { + if (uids == null || uids.isEmpty()) { + return; + } + storageQueue.postRunnable(new Runnable() { + @Override + public void run() { + try { + String ids = ""; + for (Integer uid : uids) { + if (ids.length() != 0) { + ids += ","; + } + ids += "" + uid; + } + database.executeFast("DELETE FROM contacts WHERE uid IN (" + ids + ")").stepThis().dispose(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + } + + public void applyPhoneBookUpdates(final String adds, final String deletes) { + if (adds.length() == 0 && deletes.length() == 0) { + return; + } + storageQueue.postRunnable(new Runnable() { + @Override + public void run() { + try { + if (adds.length() != 0) { + database.executeFast(String.format(Locale.US, "UPDATE user_phones_v6 SET deleted = 0 WHERE sphone IN (%s)", adds)).stepThis().dispose(); + } + if (deletes.length() != 0) { + database.executeFast(String.format(Locale.US, "UPDATE user_phones_v6 SET deleted = 1 WHERE sphone IN (%s)", deletes)).stepThis().dispose(); + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + } + + public void putCachedPhoneBook(final HashMap contactHashMap) { + storageQueue.postRunnable(new Runnable() { + @Override + public void run() { + try { + database.executeFast("DELETE FROM user_contacts_v6 WHERE 1").stepThis().dispose(); + database.executeFast("DELETE FROM user_phones_v6 WHERE 1").stepThis().dispose(); + database.beginTransaction(); + SQLitePreparedStatement state = database.executeFast("REPLACE INTO user_contacts_v6 VALUES(?, ?, ?)"); + SQLitePreparedStatement state2 = database.executeFast("REPLACE INTO user_phones_v6 VALUES(?, ?, ?, ?)"); + for (HashMap.Entry entry : contactHashMap.entrySet()) { + ContactsController.Contact contact = entry.getValue(); + state.requery(); + state.bindInteger(1, contact.id); + state.bindString(2, contact.first_name); + state.bindString(3, contact.last_name); + state.step(); + for (int a = 0; a < contact.phones.size(); a++) { + state2.requery(); + state2.bindInteger(1, contact.id); + state2.bindString(2, contact.phones.get(a)); + state2.bindString(3, contact.shortPhones.get(a)); + state2.bindInteger(4, contact.phoneDeleted.get(a)); + state2.step(); + } + } + state.dispose(); + state2.dispose(); + database.commitTransaction(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } + } + }); + } + + public void getCachedPhoneBook() { + storageQueue.postRunnable(new Runnable() { + @Override + public void run() { + HashMap contactHashMap = new HashMap(); + try { + SQLiteCursor cursor = database.queryFinalized("SELECT us.uid, us.fname, us.sname, up.phone, up.sphone, up.deleted FROM user_contacts_v6 as us LEFT JOIN user_phones_v6 as up ON us.uid = up.uid WHERE 1"); + while (cursor.next()) { + int uid = cursor.intValue(0); + ContactsController.Contact contact = contactHashMap.get(uid); + if (contact == null) { + contact = new ContactsController.Contact(); + contact.first_name = cursor.stringValue(1); + contact.last_name = cursor.stringValue(2); + contact.id = uid; + contactHashMap.put(uid, contact); + } + contact.phones.add(cursor.stringValue(3)); + contact.shortPhones.add(cursor.stringValue(4)); + contact.phoneDeleted.add(cursor.intValue(5)); + contact.phoneTypes.add(""); + } + cursor.dispose(); + } catch (Exception e) { + FileLog.e("tmessages", e); + } finally { + ContactsController.Instance.performSyncPhoneBook(contactHashMap, true, true); + } + } + }, true); + } + public void getContacts() { storageQueue.postRunnable(new Runnable() { @Override @@ -954,12 +1150,12 @@ public class MessagesStorage { } cursor.dispose(); } - MessagesController.Instance.processLoadedContacts(contacts, users, 1); + ContactsController.Instance.processLoadedContacts(contacts, users, 1); } catch (Exception e) { FileLog.e("tmessages", e); } } - }); + }, true); } public void putMediaCount(final long uid, final int count) { @@ -1007,7 +1203,7 @@ public class MessagesStorage { FileLog.e("tmessages", e); } } - }); + }, true); } public void loadMedia(final long uid, final int offset, final int count, final int max_id, final int classGuid) { @@ -1083,7 +1279,7 @@ public class MessagesStorage { MessagesController.Instance.processLoadedMedia(res, uid, offset, count, max_id, true, classGuid); } } - }); + }, true); } public void putMedia(final long uid, final ArrayList messages) { @@ -1103,8 +1299,6 @@ public class MessagesStorage { state2.bindInteger(3, message.date); state2.bindByteArray(4, data.toByteArray()); state2.step(); - } else { - Log.e("tmessages", "test"); } } state2.dispose(); @@ -1136,7 +1330,7 @@ public class MessagesStorage { if (lower_id != 0) { if (forward) { - cursor = database.queryFinalized(String.format(Locale.US, "SELECT read_state, data, send_state, mid, date FROM messages WHERE uid = %d AND mid > %d ORDER BY date ASC, mid ASC LIMIT %d", dialog_id, max_id, count_query)); + cursor = database.queryFinalized(String.format(Locale.US, "SELECT read_state, data, send_state, mid, date FROM messages WHERE uid = %d AND date >= %d AND mid > %d ORDER BY date ASC, mid ASC LIMIT %d", dialog_id, minDate, max_id, count_query)); } else if (minDate != 0) { if (max_id != 0) { cursor = database.queryFinalized(String.format(Locale.US, "SELECT read_state, data, send_state, mid, date FROM messages WHERE uid = %d AND date < %d AND mid < %d ORDER BY date DESC, mid DESC LIMIT %d", dialog_id, minDate, max_id, count_query)); @@ -1275,7 +1469,7 @@ public class MessagesStorage { MessagesController.Instance.processLoadedMessages(res, dialog_id, offset, count_query, max_id, true, classGuid, min_unread_id, max_unread_id, count_unread, max_unread_date, forward); } } - }); + }, true); } public void startTransaction(boolean useQueue) { @@ -1559,9 +1753,87 @@ public class MessagesStorage { HashMap messagesMap = new HashMap(); HashMap messagesCounts = new HashMap(); HashMap mediaCounts = new HashMap(); + HashMap messagesIdsMap = new HashMap(); + HashMap messagesMediaIdsMap = new HashMap(); + String messageIds = ""; + String messageMediaIds = ""; SQLitePreparedStatement state = database.executeFast("REPLACE INTO messages VALUES(?, ?, ?, ?, ?, ?, ?, ?)"); SQLitePreparedStatement state2 = database.executeFast("REPLACE INTO media VALUES(?, ?, ?, ?)"); SQLitePreparedStatement state3 = database.executeFast("REPLACE INTO randoms VALUES(?, ?)"); + + for (TLRPC.Message message : messages) { + long dialog_id = 0; + if (message.unread && !message.out) { + if (messageIds.length() > 0) { + messageIds += ","; + } + messageIds += message.id; + + dialog_id = message.dialog_id; + if (dialog_id == 0) { + if (message.to_id.chat_id != 0) { + dialog_id = -message.to_id.chat_id; + } else if (message.to_id.user_id != 0) { + dialog_id = message.to_id.user_id; + } + } + + messagesIdsMap.put(message.id, dialog_id); + } + + if (message.media instanceof TLRPC.TL_messageMediaVideo || message.media instanceof TLRPC.TL_messageMediaPhoto) { + if (dialog_id == 0) { + dialog_id = message.dialog_id; + if (dialog_id == 0) { + if (message.to_id.chat_id != 0) { + dialog_id = -message.to_id.chat_id; + } else if (message.to_id.user_id != 0) { + dialog_id = message.to_id.user_id; + } + } + } + if (messageMediaIds.length() > 0) { + messageMediaIds += ","; + } + messageMediaIds += message.id; + messagesMediaIdsMap.put(message.id, dialog_id); + } + } + + if (messageIds.length() > 0) { + SQLiteCursor cursor = database.queryFinalized("SELECT mid FROM messages WHERE mid IN(" + messageIds + ")"); + while (cursor.next()) { + int mid = cursor.intValue(0); + messagesIdsMap.remove(mid); + } + cursor.dispose(); + for (Long dialog_id : messagesIdsMap.values()) { + Integer count = messagesCounts.get(dialog_id); + if (count == null) { + count = 0; + } + count++; + messagesCounts.put(dialog_id, count); + } + } + + if (messageMediaIds.length() > 0) { + SQLiteCursor cursor = database.queryFinalized("SELECT mid FROM media WHERE mid IN(" + messageMediaIds + ")"); + while (cursor.next()) { + int mid = cursor.intValue(0); + messagesMediaIdsMap.remove(mid); + } + cursor.dispose(); + for (Long dialog_id : messagesMediaIdsMap.values()) { + Integer count = mediaCounts.get(dialog_id); + if (count == null) { + count = 0; + } + count++; + mediaCounts.put(dialog_id, count); + } + } + for (TLRPC.Message message : messages) { long dialog_id = message.dialog_id; if (dialog_id == 0) { @@ -1584,14 +1856,6 @@ public class MessagesStorage { if (lastMessage == null || message.date > lastMessage.date) { messagesMap.put(dialog_id, message); } - if (message.unread && !message.out) { - Integer count = messagesCounts.get(dialog_id); - if (count == null) { - count = 0; - } - count++; - messagesCounts.put(dialog_id, count); - } state.bindInteger(1, messageId); state.bindLong(2, dialog_id); state.bindInteger(3, (message.unread ? 0 : 1)); @@ -1611,28 +1875,12 @@ public class MessagesStorage { } if (message.media instanceof TLRPC.TL_messageMediaVideo || message.media instanceof TLRPC.TL_messageMediaPhoto) { - boolean exist = false; - SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT mid FROM media WHERE mid = %d LIMIT 1", message.id)); - if (cursor.next()) { - exist = true; - } - cursor.dispose(); - state2.requery(); state2.bindInteger(1, messageId); state2.bindLong(2, dialog_id); state2.bindInteger(3, message.date); state2.bindByteArray(4, bytes); state2.step(); - - if (!exist) { - Integer count = mediaCounts.get(dialog_id); - if (count == null) { - count = 0; - } - count++; - mediaCounts.put(dialog_id, count); - } } } state.dispose(); @@ -1662,6 +1910,7 @@ public class MessagesStorage { if (withTransaction) { database.commitTransaction(); } + MessagesController.Instance.dialogsUnreadCountIncr(messagesCounts); if (!mediaCounts.isEmpty()) { state = database.executeFast("REPLACE INTO media_counts VALUES(?, ?)"); @@ -2442,7 +2691,7 @@ public class MessagesStorage { MessagesController.Instance.processLoadedDialogs(dialogs, encryptedChats, 0, 0, 100, true, true); } } - }); + }, true); } public void putDialogs(final TLRPC.messages_Dialogs dialogs) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/NotificationCenter.java b/TMessagesProj/src/main/java/org/telegram/messenger/NotificationCenter.java index 66ab8f68b..c104d050e 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/NotificationCenter.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/NotificationCenter.java @@ -12,42 +12,41 @@ import java.util.ArrayList; import java.util.HashMap; public class NotificationCenter { + + public static NotificationCenter Instance = new NotificationCenter(); + final private HashMap> observers = new HashMap>(); - final private HashMap memCache = new HashMap(); - final private HashMap memCacheString = new HashMap(); - private boolean broadcasting = false; + + final private HashMap memCache = new HashMap(); + final private HashMap removeAfterBroadcast = new HashMap(); + final private HashMap addAfterBroadcast = new HashMap(); + + private boolean broadcasting = false; public interface NotificationCenterDelegate { public abstract void didReceivedNotification(int id, Object... args); } - public static NotificationCenter Instance = new NotificationCenter(); - public void addToMemCache(int id, Object object) { - memCache.put(id, object); + addToMemCache(String.valueOf(id), object); } public void addToMemCache(String id, Object object) { - memCacheString.put(id, object); + memCache.put(id, object); } public Object getFromMemCache(int id) { - Object obj = memCache.get(id); - if (obj != null) { - memCache.remove(id); - } - return obj; + return getFromMemCache(String.valueOf(id), null); } public Object getFromMemCache(String id, Object defaultValue) { - Object obj = memCacheString.get(id); + Object obj = memCache.get(id); if (obj != null) { - memCacheString.remove(id); - } else { - return defaultValue; + memCache.remove(id); + return obj; } - return obj; + return defaultValue; } public void postNotificationName(int id, Object... args) { @@ -66,15 +65,24 @@ public class NotificationCenter { } removeAfterBroadcast.clear(); } + if (!addAfterBroadcast.isEmpty()) { + for (HashMap.Entry entry : addAfterBroadcast.entrySet()) { + addObserver(entry.getValue(), entry.getKey()); + } + addAfterBroadcast.clear(); + } } } public void addObserver(Object observer, int id) { synchronized (observers) { + if (broadcasting) { + addAfterBroadcast.put(id, observer); + return; + } ArrayList objects = observers.get(id); if (objects == null) { - objects = new ArrayList(); - observers.put(id, objects); + observers.put(id, (objects = new ArrayList())); } if (objects.contains(observer)) { return; @@ -83,25 +91,6 @@ public class NotificationCenter { } } -// public void removeObserver(Object observer) { -// synchronized (observers) { -// if (broadcasting) { -// removeAfterBroadcast.put(-1, observer); -// return; -// } -// Integer[] keyArr = (Integer[])observers.keySet().toArray(); -// for (int a = 0; a < observers.size(); a++) { -// Integer id = keyArr[a]; -// ArrayList objects = observers.get(id); -// objects.remove(observer); -// if (objects.size() == 0) { -// observers.remove(id); -// a--; -// } -// } -// } -// } - public void removeObserver(Object observer, int id) { synchronized (observers) { if (broadcasting) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/RPCRequest.java b/TMessagesProj/src/main/java/org/telegram/messenger/RPCRequest.java index fb3626386..5dd298265 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/RPCRequest.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/RPCRequest.java @@ -29,6 +29,7 @@ public class RPCRequest { public static int RPCRequestClassUploadMedia = 4; public static int RPCRequestClassEnableUnauthorized = 8; public static int RPCRequestClassFailOnServerErrors = 16; + public static int RPCRequestClassCanCompress = 32; static int RPCRequestClassTransportMask = (RPCRequestClassGeneric | RPCRequestClassDownloadMedia | RPCRequestClassUploadMedia); @@ -37,6 +38,7 @@ public class RPCRequest { int serverFailureCount; int flags; + public int retryCount = 0; TLObject rawRequest; TLObject rpcRequest; diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/SmsListener.java b/TMessagesProj/src/main/java/org/telegram/messenger/SmsListener.java index 56cd372a8..ce3377d19 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/SmsListener.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/SmsListener.java @@ -15,8 +15,6 @@ import android.content.SharedPreferences; import android.os.Bundle; import android.telephony.SmsMessage; -import org.telegram.messenger.NotificationCenter; - import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -27,6 +25,9 @@ public class SmsListener extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) { + if (!Utilities.isWaitingForSms()) { + return; + } Bundle bundle = intent.getExtras(); SmsMessage[] msgs; if (bundle != null) { diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/TcpConnection.java b/TMessagesProj/src/main/java/org/telegram/messenger/TcpConnection.java index e4c675548..a1484ff4c 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/TcpConnection.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/TcpConnection.java @@ -50,6 +50,7 @@ public class TcpConnection extends PyroClientAdapter { private boolean hasSomeDataSinceLastConnect = false; private int willRetryConnectCount = 5; private boolean isNextPort = false; + private final Integer timerSync = 1; public int transportRequestClass; @@ -86,9 +87,11 @@ public class TcpConnection extends PyroClientAdapter { connectionState = TcpConnectionState.TcpConnectionStageConnecting; try { try { - if (reconnectTimer != null) { - reconnectTimer.cancel(); - reconnectTimer = null; + synchronized (timerSync) { + if (reconnectTimer != null) { + reconnectTimer.cancel(); + reconnectTimer = null; + } } } catch (Exception e2) { FileLog.e("tmessages", e2); @@ -115,19 +118,22 @@ public class TcpConnection extends PyroClientAdapter { selector.wakeup(); } catch (Exception e) { try { - if (reconnectTimer != null) { - reconnectTimer.cancel(); - reconnectTimer = null; + synchronized (timerSync) { + if (reconnectTimer != null) { + reconnectTimer.cancel(); + reconnectTimer = null; + } } } catch (Exception e2) { FileLog.e("tmessages", e2); } connectionState = TcpConnectionState.TcpConnectionStageReconnecting; if (delegate != null) { + final TcpConnectionDelegate finalDelegate = delegate; Utilities.stageQueue.postRunnable(new Runnable() { @Override public void run() { - delegate.tcpConnectionClosed(TcpConnection.this); + finalDelegate.tcpConnectionClosed(TcpConnection.this); } }); } @@ -160,9 +166,11 @@ public class TcpConnection extends PyroClientAdapter { @Override public void run() { try { - if (reconnectTimer != null) { - reconnectTimer.cancel(); - reconnectTimer = null; + synchronized (timerSync) { + if (reconnectTimer != null) { + reconnectTimer.cancel(); + reconnectTimer = null; + } } } catch (Exception e2) { FileLog.e("tmessages", e2); @@ -181,9 +189,11 @@ public class TcpConnection extends PyroClientAdapter { } private void suspendConnectionInternal() { - if (reconnectTimer != null) { - reconnectTimer.cancel(); - reconnectTimer = null; + synchronized (timerSync) { + if (reconnectTimer != null) { + reconnectTimer.cancel(); + reconnectTimer = null; + } } if (connectionState == TcpConnectionState.TcpConnectionStageIdle || connectionState == TcpConnectionState.TcpConnectionStageSuspended) { return; @@ -196,10 +206,11 @@ public class TcpConnection extends PyroClientAdapter { client = null; } if (delegate != null) { + final TcpConnectionDelegate finalDelegate = delegate; Utilities.stageQueue.postRunnable(new Runnable() { @Override public void run() { - delegate.tcpConnectionClosed(TcpConnection.this); + finalDelegate.tcpConnectionClosed(TcpConnection.this); } }); } @@ -314,10 +325,11 @@ public class TcpConnection extends PyroClientAdapter { buffer.order(ByteOrder.BIG_ENDIAN); final int ackId = buffer.getInt() & (~(1 << 31)); if (delegate != null) { + final TcpConnectionDelegate finalDelegate = delegate; Utilities.stageQueue.postRunnable(new Runnable() { @Override public void run() { - delegate.tcpConnectionQuiackAckReceived(TcpConnection.this, ackId); + finalDelegate.tcpConnectionQuiackAckReceived(TcpConnection.this, ackId); } }); } @@ -360,12 +372,13 @@ public class TcpConnection extends PyroClientAdapter { } if (lastMessageId != -1 && lastMessageId != 0) { if (delegate != null) { + final TcpConnectionDelegate finalDelegate = delegate; final int arg2 = buffer.remaining(); final int arg3 = currentPacketLength; Utilities.stageQueue.postRunnable(new Runnable() { @Override public void run() { - delegate.tcpConnectionProgressChanged(TcpConnection.this, lastMessageId, arg2, arg3); + finalDelegate.tcpConnectionProgressChanged(TcpConnection.this, lastMessageId, arg2, arg3); } }); } @@ -383,10 +396,11 @@ public class TcpConnection extends PyroClientAdapter { buffer.get(packetData); if (delegate != null) { + final TcpConnectionDelegate finalDelegate = delegate; Utilities.stageQueue.postRunnable(new Runnable() { @Override public void run() { - delegate.tcpConnectionReceivedData(TcpConnection.this, packetData); + finalDelegate.tcpConnectionReceivedData(TcpConnection.this, packetData); } }); } @@ -394,9 +408,11 @@ public class TcpConnection extends PyroClientAdapter { } public void handleDisconnect(PyroClient client, Exception e) { - if (reconnectTimer != null) { - reconnectTimer.cancel(); - reconnectTimer = null; + synchronized (timerSync) { + if (reconnectTimer != null) { + reconnectTimer.cancel(); + reconnectTimer = null; + } } if (e != null) { FileLog.d("tmessages", "Disconnected " + TcpConnection.this + " with error " + e); @@ -410,12 +426,11 @@ public class TcpConnection extends PyroClientAdapter { connectionState = TcpConnectionState.TcpConnectionStageIdle; } if (delegate != null) { + final TcpConnectionDelegate finalDelegate = delegate; Utilities.stageQueue.postRunnable(new Runnable() { @Override public void run() { - if (delegate != null) { - delegate.tcpConnectionClosed(TcpConnection.this); - } + finalDelegate.tcpConnectionClosed(TcpConnection.this); } }); } @@ -447,9 +462,11 @@ public class TcpConnection extends PyroClientAdapter { @Override public void run() { try { - if (reconnectTimer != null) { - reconnectTimer.cancel(); - reconnectTimer = null; + synchronized (timerSync) { + if (reconnectTimer != null) { + reconnectTimer.cancel(); + reconnectTimer = null; + } } } catch (Exception e2) { FileLog.e("tmessages", e2); @@ -471,10 +488,11 @@ public class TcpConnection extends PyroClientAdapter { channelToken = generateChannelToken(); FileLog.d("tmessages", String.format(TcpConnection.this + " Connected (%s:%d)", hostAddress, hostPort)); if (delegate != null) { + final TcpConnectionDelegate finalDelegate = delegate; Utilities.stageQueue.postRunnable(new Runnable() { @Override public void run() { - delegate.tcpConnectionConnected(TcpConnection.this); + finalDelegate.tcpConnectionConnected(TcpConnection.this); } }); } diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java b/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java index af4a79067..e17b045af 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/UserConfig.java @@ -27,7 +27,6 @@ public class UserConfig { public static int lastSendMessageId = -210000; public static int lastLocalId = -210000; public static String contactsHash = ""; - public static String importHash = ""; private final static Integer sync = 1; public static boolean saveIncomingPhotos = false; @@ -55,7 +54,6 @@ public class UserConfig { editor.putInt("lastSendMessageId", lastSendMessageId); editor.putInt("lastLocalId", lastLocalId); editor.putString("contactsHash", contactsHash); - editor.putString("importHash", importHash); editor.putBoolean("saveIncomingPhotos", saveIncomingPhotos); if (withFile) { SerializedData data = new SerializedData(); @@ -71,7 +69,6 @@ public class UserConfig { editor.putInt("lastSendMessageId", lastSendMessageId); editor.putInt("lastLocalId", lastLocalId); editor.putString("contactsHash", contactsHash); - editor.putString("importHash", importHash); editor.putBoolean("saveIncomingPhotos", saveIncomingPhotos); editor.remove("user"); } @@ -105,7 +102,7 @@ public class UserConfig { lastSendMessageId = data.readInt32(); lastLocalId = data.readInt32(); contactsHash = data.readString(); - importHash = data.readString(); + data.readString(); saveIncomingPhotos = data.readBool(); if (currentUser.status != null) { if (currentUser.status.expires != 0) { @@ -139,7 +136,6 @@ public class UserConfig { lastSendMessageId = preferences.getInt("lastSendMessageId", -210000); lastLocalId = preferences.getInt("lastLocalId", -210000); contactsHash = preferences.getString("contactsHash", ""); - importHash = preferences.getString("importHash", ""); saveIncomingPhotos = preferences.getBoolean("saveIncomingPhotos", false); } if (lastLocalId > -210000) { @@ -164,7 +160,6 @@ public class UserConfig { lastSendMessageId = preferences.getInt("lastSendMessageId", -210000); lastLocalId = preferences.getInt("lastLocalId", -210000); contactsHash = preferences.getString("contactsHash", ""); - importHash = preferences.getString("importHash", ""); saveIncomingPhotos = preferences.getBoolean("saveIncomingPhotos", false); String user = preferences.getString("user", null); if (user != null) { @@ -191,7 +186,6 @@ public class UserConfig { registeredForPush = false; contactsHash = ""; lastLocalId = -210000; - importHash = ""; lastSendMessageId = -210000; saveIncomingPhotos = false; saveConfig(true); diff --git a/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java b/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java index a31bd7075..3fb5ce76d 100644 --- a/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java +++ b/TMessagesProj/src/main/java/org/telegram/messenger/Utilities.java @@ -10,13 +10,18 @@ package org.telegram.messenger; import android.app.Activity; import android.app.ProgressDialog; +import android.content.ContentUris; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.database.Cursor; import android.graphics.Typeface; import android.net.Uri; +import android.os.Build; import android.os.Environment; import android.os.Handler; +import android.provider.DocumentsContract; +import android.provider.MediaStore; import android.text.Html; import android.text.SpannableStringBuilder; import android.text.format.DateFormat; @@ -49,7 +54,10 @@ import java.util.Calendar; import java.util.Date; import java.util.Hashtable; import java.util.Locale; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; import javax.crypto.Cipher; @@ -57,8 +65,13 @@ public class Utilities { public static Handler applicationHandler; public static int statusBarHeight = 0; public static float density = 1; + public static boolean isRTL = false; + public static Pattern pattern = Pattern.compile("[0-9]+"); private final static Integer lock = 1; + private static boolean waitingForSms = false; + private static final Integer smsLock = 2; + public static ArrayList goodPrimes = new ArrayList(); public static class TPFactorizedValue { @@ -74,6 +87,30 @@ public class Utilities { public native static long doPQNative(long _what); public native static byte[] aesIgeEncryption(byte[] _what, byte[] _key, byte[] _iv, boolean encrypt, boolean changeIv); + public static boolean isWaitingForSms() { + boolean value = false; + synchronized (smsLock) { + value = waitingForSms; + } + return value; + } + + public static void setWaitingForSms(boolean value) { + synchronized (smsLock) { + waitingForSms = value; + } + } + + public static Integer parseInt(String value) { + Integer val = 0; + Matcher matcher = pattern.matcher(value); + if (matcher.find()) { + String num = matcher.group(0); + val = Integer.parseInt(num); + } + return val; + } + static { density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density; SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("primes", Context.MODE_PRIVATE); @@ -360,6 +397,25 @@ public class Utilities { return null; } + public static byte[] compress(byte[] data) { + if (data == null) { + return null; + } + + byte[] packedData = null; + ByteArrayOutputStream bytesStream = new ByteArrayOutputStream(); + try { + GZIPOutputStream zip = new GZIPOutputStream(bytesStream); + zip.write(data); + zip.close(); + packedData = bytesStream.toByteArray(); + } catch (IOException e) { + FileLog.e("tmessages", e); + } + return packedData; + } + + private static final String TAG = "Typefaces"; private static final Hashtable cache = new Hashtable(); @@ -434,15 +490,25 @@ public class Utilities { public static FastDateFormat chatDate; public static FastDateFormat chatFullDate; - static { + public static void recreateFormatters() { Locale locale = Locale.getDefault(); String lang = locale.getLanguage(); + if (lang == null) { + lang = "en"; + } + isRTL = lang.toLowerCase().equals("ar"); if (lang.equals("en")) { formatterMonth = FastDateFormat.getInstance("MMM dd", locale); formatterYear = FastDateFormat.getInstance("dd.MM.yy", locale); formatterYearMax = FastDateFormat.getInstance("dd.MM.yyyy", locale); chatDate = FastDateFormat.getInstance("MMMM d", locale); chatFullDate = FastDateFormat.getInstance("MMMM d, yyyy", locale); + } else if (lang.startsWith("es")) { + formatterMonth = FastDateFormat.getInstance("dd 'de' MMM", locale); + formatterYear = FastDateFormat.getInstance("dd.MM.yy", locale); + formatterYearMax = FastDateFormat.getInstance("dd.MM.yyyy", locale); + chatDate = FastDateFormat.getInstance("d 'de' MMMM", locale); + chatFullDate = FastDateFormat.getInstance("d 'de' MMMM 'de' yyyy", locale); } else { formatterMonth = FastDateFormat.getInstance("dd MMM", locale); formatterYear = FastDateFormat.getInstance("dd.MM.yy", locale); @@ -467,6 +533,10 @@ public class Utilities { } } + static { + recreateFormatters(); + } + public static String formatDateChat(long date) { Calendar rightNow = Calendar.getInstance(); int year = rightNow.get(Calendar.YEAR); @@ -508,13 +578,13 @@ public class Utilities { int dateYear = rightNow.get(Calendar.YEAR); if (dateDay == day && year == dateYear) { - return String.format("%s %s", ApplicationLoader.applicationContext.getResources().getString(R.string.TodayAt), formatterDay.format(new Date(date * 1000))); + return String.format("%s %s %s", ApplicationLoader.applicationContext.getString(R.string.LastSeen), ApplicationLoader.applicationContext.getString(R.string.TodayAt), formatterDay.format(new Date(date * 1000))); } else if (dateDay + 1 == day && year == dateYear) { - return String.format("%s %s", ApplicationLoader.applicationContext.getResources().getString(R.string.YesterdayAt), formatterDay.format(new Date(date * 1000))); + return String.format("%s %s %s", ApplicationLoader.applicationContext.getString(R.string.LastSeen), ApplicationLoader.applicationContext.getString(R.string.YesterdayAt), formatterDay.format(new Date(date * 1000))); } else if (year == dateYear) { - return String.format("%s %s %s", formatterMonth.format(new Date(date * 1000)), ApplicationLoader.applicationContext.getResources().getString(R.string.OtherAt), formatterDay.format(new Date(date * 1000))); + return String.format("%s %s %s %s", ApplicationLoader.applicationContext.getString(R.string.LastSeenDate), formatterMonth.format(new Date(date * 1000)), ApplicationLoader.applicationContext.getString(R.string.OtherAt), formatterDay.format(new Date(date * 1000))); } else { - return String.format("%s %s %s", formatterYear.format(new Date(date * 1000)), ApplicationLoader.applicationContext.getResources().getString(R.string.OtherAt), formatterDay.format(new Date(date * 1000))); + return String.format("%s %s %s %s", ApplicationLoader.applicationContext.getString(R.string.LastSeenDate), formatterYear.format(new Date(date * 1000)), ApplicationLoader.applicationContext.getString(R.string.OtherAt), formatterDay.format(new Date(date * 1000))); } } @@ -556,9 +626,6 @@ public class Utilities { public static void RunOnUIThread(Runnable runnable) { synchronized (lock) { - if (applicationHandler == null) { - applicationHandler = new Handler(ApplicationLoader.applicationContext.getMainLooper()); - } applicationHandler.post(runnable); } } @@ -682,6 +749,83 @@ public class Utilities { return storageDir; } + public static String getPath(final Context context, final Uri uri) { + final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; + if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) { + if (isExternalStorageDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + if ("primary".equalsIgnoreCase(type)) { + return Environment.getExternalStorageDirectory() + "/" + split[1]; + } + } else if (isDownloadsDocument(uri)) { + final String id = DocumentsContract.getDocumentId(uri); + final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); + return getDataColumn(context, contentUri, null, null); + } else if (isMediaDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + Uri contentUri = null; + if ("image".equals(type)) { + contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + } else if ("video".equals(type)) { + contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; + } else if ("audio".equals(type)) { + contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; + } + + final String selection = "_id=?"; + final String[] selectionArgs = new String[] { + split[1] + }; + + return getDataColumn(context, contentUri, selection, selectionArgs); + } + } else if ("content".equalsIgnoreCase(uri.getScheme())) { + return getDataColumn(context, uri, null, null); + } else if ("file".equalsIgnoreCase(uri.getScheme())) { + return uri.getPath(); + } + + return null; + } + + public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { + + Cursor cursor = null; + final String column = "_data"; + final String[] projection = { + column + }; + + try { + cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); + if (cursor != null && cursor.moveToFirst()) { + final int column_index = cursor.getColumnIndexOrThrow(column); + return cursor.getString(column_index); + } + } finally { + if (cursor != null) + cursor.close(); + } + return null; + } + + public static boolean isExternalStorageDocument(Uri uri) { + return "com.android.externalstorage.documents".equals(uri.getAuthority()); + } + + public static boolean isDownloadsDocument(Uri uri) { + return "com.android.providers.downloads.documents".equals(uri.getAuthority()); + } + + public static boolean isMediaDocument(Uri uri) { + return "com.android.providers.media.documents".equals(uri.getAuthority()); + } + public static File generatePicturePath() { try { File storageDir = getAlbumDir(); diff --git a/TMessagesProj/src/main/java/org/telegram/objects/MessageObject.java b/TMessagesProj/src/main/java/org/telegram/objects/MessageObject.java index cb949b30f..95ce61df5 100644 --- a/TMessagesProj/src/main/java/org/telegram/objects/MessageObject.java +++ b/TMessagesProj/src/main/java/org/telegram/objects/MessageObject.java @@ -22,6 +22,7 @@ import org.telegram.ui.ApplicationLoader; import java.util.AbstractMap; import java.util.ArrayList; import java.util.Calendar; +import java.util.Date; import java.util.GregorianCalendar; public class MessageObject { @@ -33,6 +34,7 @@ public class MessageObject { public PhotoObject previewPhoto; public String dateKey; public boolean deleted = false; + public Object TAG; public MessageObject(TLRPC.Message message, AbstractMap users) { messageOwner = message; @@ -45,7 +47,7 @@ public class MessageObject { } if (message.action instanceof TLRPC.TL_messageActionChatCreate) { if (message.from_id == UserConfig.clientUserId) { - messageText = ApplicationLoader.applicationContext.getString(R.string.ActionCreateGroup).replace("un1", ApplicationLoader.applicationContext.getString(R.string.FromYou)); + messageText = ApplicationLoader.applicationContext.getString(R.string.ActionYouCreateGroup); } else { if (fromUser != null) { messageText = ApplicationLoader.applicationContext.getString(R.string.ActionCreateGroup).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); @@ -56,7 +58,7 @@ public class MessageObject { } else if (message.action instanceof TLRPC.TL_messageActionChatDeleteUser) { if (message.action.user_id == message.from_id) { if (message.from_id == UserConfig.clientUserId) { - messageText = ApplicationLoader.applicationContext.getString(R.string.ActionLeftUser).replace("un1", ApplicationLoader.applicationContext.getString(R.string.FromYou)); + messageText = ApplicationLoader.applicationContext.getString(R.string.ActionYouLeftUser); } else { if (fromUser != null) { messageText = ApplicationLoader.applicationContext.getString(R.string.ActionLeftUser).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); @@ -69,17 +71,16 @@ public class MessageObject { if (who == null) { MessagesController.Instance.users.get(message.action.user_id); } - String str = ApplicationLoader.applicationContext.getString(R.string.ActionKickUser); if (who != null && fromUser != null) { if (message.from_id == UserConfig.clientUserId) { - messageText = str.replace("un2", Utilities.formatName(who.first_name, who.last_name)).replace("un1", ApplicationLoader.applicationContext.getString(R.string.FromYou)); + messageText = ApplicationLoader.applicationContext.getString(R.string.ActionYouKickUser).replace("un2", Utilities.formatName(who.first_name, who.last_name)); } else if (message.action.user_id == UserConfig.clientUserId) { - messageText = str.replace("un2", ApplicationLoader.applicationContext.getString(R.string.FromYou)).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); + messageText = ApplicationLoader.applicationContext.getString(R.string.ActionKickUserYou).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); } else { - messageText = str.replace("un2", Utilities.formatName(who.first_name, who.last_name)).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); + messageText = ApplicationLoader.applicationContext.getString(R.string.ActionKickUser).replace("un2", Utilities.formatName(who.first_name, who.last_name)).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); } } else { - messageText = str.replace("un2", "").replace("un1", ""); + messageText = ApplicationLoader.applicationContext.getString(R.string.ActionKickUser).replace("un2", "").replace("un1", ""); } } } else if (message.action instanceof TLRPC.TL_messageActionChatAddUser) { @@ -87,17 +88,16 @@ public class MessageObject { if (whoUser == null) { MessagesController.Instance.users.get(message.action.user_id); } - String str = ApplicationLoader.applicationContext.getString(R.string.ActionAddUser); if (whoUser != null && fromUser != null) { if (message.from_id == UserConfig.clientUserId) { - messageText = str.replace("un2", Utilities.formatName(whoUser.first_name, whoUser.last_name)).replace("un1", ApplicationLoader.applicationContext.getString(R.string.FromYou)); + messageText = ApplicationLoader.applicationContext.getString(R.string.ActionYouAddUser).replace("un2", Utilities.formatName(whoUser.first_name, whoUser.last_name)); } else if (message.action.user_id == UserConfig.clientUserId) { - messageText = str.replace("un2", ApplicationLoader.applicationContext.getString(R.string.FromYou)).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); + messageText = ApplicationLoader.applicationContext.getString(R.string.ActionAddUserYou).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); } else { - messageText = str.replace("un2", Utilities.formatName(whoUser.first_name, whoUser.last_name)).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); + messageText = ApplicationLoader.applicationContext.getString(R.string.ActionAddUser).replace("un2", Utilities.formatName(whoUser.first_name, whoUser.last_name)).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); } } else { - messageText = str.replace("un2", "").replace("un1", ""); + messageText = ApplicationLoader.applicationContext.getString(R.string.ActionAddUser).replace("un2", "").replace("un1", ""); } } else if (message.action instanceof TLRPC.TL_messageActionChatEditPhoto) { photoThumbs = new ArrayList(); @@ -105,7 +105,7 @@ public class MessageObject { photoThumbs.add(new PhotoObject(size)); } if (message.from_id == UserConfig.clientUserId) { - messageText = ApplicationLoader.applicationContext.getString(R.string.ActionChangedPhoto).replace("un1", ApplicationLoader.applicationContext.getString(R.string.FromYou)); + messageText = ApplicationLoader.applicationContext.getString(R.string.ActionYouChangedPhoto); } else { if (fromUser != null) { messageText = ApplicationLoader.applicationContext.getString(R.string.ActionChangedPhoto).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); @@ -115,7 +115,7 @@ public class MessageObject { } } else if (message.action instanceof TLRPC.TL_messageActionChatEditTitle) { if (message.from_id == UserConfig.clientUserId) { - messageText = ApplicationLoader.applicationContext.getString(R.string.ActionChangedTitle).replace("un1", ApplicationLoader.applicationContext.getString(R.string.FromYou)).replace("un2", message.action.title); + messageText = ApplicationLoader.applicationContext.getString(R.string.ActionYouChangedTitle).replace("un2", message.action.title); } else { if (fromUser != null) { messageText = ApplicationLoader.applicationContext.getString(R.string.ActionChangedTitle).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)).replace("un2", message.action.title); @@ -125,7 +125,7 @@ public class MessageObject { } } else if (message.action instanceof TLRPC.TL_messageActionChatDeletePhoto) { if (message.from_id == UserConfig.clientUserId) { - messageText = ApplicationLoader.applicationContext.getString(R.string.ActionRemovedPhoto).replace("un1", ApplicationLoader.applicationContext.getString(R.string.FromYou)); + messageText = ApplicationLoader.applicationContext.getString(R.string.ActionYouRemovedPhoto); } else { if (fromUser != null) { messageText = ApplicationLoader.applicationContext.getString(R.string.ActionRemovedPhoto).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); @@ -162,7 +162,7 @@ public class MessageObject { } } else { if (message.from_id == UserConfig.clientUserId) { - messageText = String.format(ApplicationLoader.applicationContext.getString(R.string.MessageLifetimeRemoved), ApplicationLoader.applicationContext.getString(R.string.FromYou)); + messageText = String.format(ApplicationLoader.applicationContext.getString(R.string.MessageLifetimeYouRemoved)); } else { if (fromUser != null) { messageText = String.format(ApplicationLoader.applicationContext.getString(R.string.MessageLifetimeRemoved), fromUser.first_name); @@ -172,7 +172,8 @@ public class MessageObject { } } } else if (message.action instanceof TLRPC.TL_messageActionLoginUnknownLocation) { - messageText = ApplicationLoader.applicationContext.getString(R.string.NotificationUnrecognizedDevice, message.action.title, message.action.address); + String date = String.format("%s %s %s", Utilities.formatterYear.format(((long)message.date) * 1000), ApplicationLoader.applicationContext.getString(R.string.OtherAt), Utilities.formatterDay.format(((long)message.date) * 1000)); + messageText = ApplicationLoader.applicationContext.getString(R.string.NotificationUnrecognizedDevice, UserConfig.currentUser.first_name, date, message.action.title, message.action.address); } else if (message.action instanceof TLRPC.TL_messageActionUserJoined) { if (fromUser != null) { messageText = ApplicationLoader.applicationContext.getString(R.string.NotificationContactJoined, Utilities.formatName(fromUser.first_name, fromUser.last_name)); @@ -266,9 +267,17 @@ public class MessageObject { } else { type = 17; } + } else if (message.media != null && message.media instanceof TLRPC.TL_messageMediaAudio) { + if (message.from_id == UserConfig.clientUserId) { + type = 0; + } else { + type = 1; + } } } else if (message instanceof TLRPC.TL_messageService) { - if (message.action instanceof TLRPC.TL_messageActionChatEditPhoto || message.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) { + if (message.action instanceof TLRPC.TL_messageActionLoginUnknownLocation) { + type = 1; + } else if (message.action instanceof TLRPC.TL_messageActionChatEditPhoto || message.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) { type = 11; } else { type = 10; diff --git a/TMessagesProj/src/main/java/org/telegram/objects/PhotoObject.java b/TMessagesProj/src/main/java/org/telegram/objects/PhotoObject.java index 69542fa2f..e78c03a22 100644 --- a/TMessagesProj/src/main/java/org/telegram/objects/PhotoObject.java +++ b/TMessagesProj/src/main/java/org/telegram/objects/PhotoObject.java @@ -30,7 +30,7 @@ public class PhotoObject { opts.outWidth = photo.w; opts.outHeight = photo.h; image = BitmapFactory.decodeByteArray(photoOwner.bytes, 0, photoOwner.bytes.length, opts); - if (FileLoader.Instance.runtimeHack != null) { + if (image != null && FileLoader.Instance.runtimeHack != null) { FileLoader.Instance.runtimeHack.trackFree(image.getRowBytes() * image.getHeight()); } } @@ -46,7 +46,7 @@ public class PhotoObject { } int diffW = Math.abs(obj.photoOwner.w - width); int diffH = Math.abs(obj.photoOwner.h - height); - if (closestObject == null || closestWidth > diffW && closestHeight > diffH || closestObject.photoOwner instanceof TLRPC.TL_photoCachedSize) { + if (closestObject == null || closestWidth > diffW || closestHeight > diffH || closestObject.photoOwner instanceof TLRPC.TL_photoCachedSize) { closestObject = obj; closestWidth = diffW; closestHeight = diffH; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ApplicationActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ApplicationActivity.java index 57dd7b5d6..9c25274ee 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ApplicationActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ApplicationActivity.java @@ -25,6 +25,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.WindowManager; +import android.widget.EditText; import android.widget.TextView; import org.telegram.messenger.ConnectionsManager; @@ -196,7 +197,7 @@ public class ApplicationActivity extends ActionBarActivity implements Notificati method.invoke(field.get(getSupportActionBar()), false); } } catch (Exception e) { - FileLog.e("tmessages", e); + e.printStackTrace(); } } @@ -333,6 +334,10 @@ public class ApplicationActivity extends ActionBarActivity implements Notificati if (notificationView != null) { notificationView.hide(false); } + View focusView = getCurrentFocus(); + if (focusView instanceof EditText) { + focusView.clearFocus(); + } } @Override @@ -581,13 +586,13 @@ public class ApplicationActivity extends ActionBarActivity implements Notificati try { if (statusView.getLayoutParams() instanceof android.support.v7.app.ActionBar.LayoutParams) { android.support.v7.app.ActionBar.LayoutParams statusParams = (android.support.v7.app.ActionBar.LayoutParams)statusView.getLayoutParams(); - statusText.measure(View.MeasureSpec.makeMeasureSpec(800, View.MeasureSpec.AT_MOST), 100); - statusParams.width = (int)(statusText.getMeasuredWidth() + Utilities.dp(54)); + statusText.measure(View.MeasureSpec.makeMeasureSpec(800, View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.AT_MOST)); + statusParams.width = (statusText.getMeasuredWidth() + Utilities.dp(54)); statusView.setLayoutParams(statusParams); } else if (statusView.getLayoutParams() instanceof android.app.ActionBar.LayoutParams) { android.app.ActionBar.LayoutParams statusParams = (android.app.ActionBar.LayoutParams)statusView.getLayoutParams(); - statusText.measure(View.MeasureSpec.makeMeasureSpec(800, View.MeasureSpec.AT_MOST), 100); - statusParams.width = (int)(statusText.getMeasuredWidth() + Utilities.dp(54)); + statusText.measure(View.MeasureSpec.makeMeasureSpec(800, View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.AT_MOST)); + statusParams.width = (statusText.getMeasuredWidth() + Utilities.dp(54)); statusView.setLayoutParams(statusParams); } } catch (Exception e) { @@ -621,7 +626,7 @@ public class ApplicationActivity extends ActionBarActivity implements Notificati ApplicationLoader.fragmentsStack.remove(ApplicationLoader.fragmentsStack.size() - 1); current.onFragmentDestroy(); } - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); boolean animations = preferences.getBoolean("view_animations", true); if (animations) { if (bySwipe) { @@ -660,7 +665,7 @@ public class ApplicationActivity extends ActionBarActivity implements Notificati BaseFragment prev = ApplicationLoader.fragmentsStack.get(ApplicationLoader.fragmentsStack.size() - 2); FragmentManager fm = getSupportFragmentManager(); FragmentTransaction fTrans = fm.beginTransaction(); - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); boolean animations = preferences.getBoolean("view_animations", true); if (animations) { if (bySwipe) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ApplicationLoader.java b/TMessagesProj/src/main/java/org/telegram/ui/ApplicationLoader.java index 5da7a87b2..8e569011f 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ApplicationLoader.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ApplicationLoader.java @@ -8,13 +8,16 @@ package org.telegram.ui; +import android.app.Activity; import android.app.Application; import android.content.Context; import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.content.res.Configuration; import android.graphics.Bitmap; import android.os.AsyncTask; +import android.os.Handler; import android.view.ViewConfiguration; import com.google.android.gms.common.ConnectionResult; @@ -22,7 +25,6 @@ import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.gcm.GoogleCloudMessaging; import org.telegram.PhoneFormat.PhoneFormat; -import org.telegram.TL.TLRPC; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLog; import org.telegram.messenger.MessagesController; @@ -34,6 +36,7 @@ import org.telegram.ui.Views.BaseFragment; import java.io.IOException; import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Locale; import java.util.concurrent.atomic.AtomicInteger; public class ApplicationLoader extends Application { @@ -48,6 +51,7 @@ public class ApplicationLoader extends Application { public static long lastPauseTime; public static Bitmap cachedWallpaper = null; public static Context applicationContext; + private Locale currentLocale; public static ApplicationLoader Instance = null; @@ -56,42 +60,47 @@ public class ApplicationLoader extends Application { @Override public void onCreate() { super.onCreate(); + currentLocale = Locale.getDefault(); Instance = this; java.lang.System.setProperty("java.net.preferIPv4Stack", "true"); java.lang.System.setProperty("java.net.preferIPv6Addresses", "false"); applicationContext = getApplicationContext(); - Utilities.getTypeface("fonts/rmedium.ttf"); - UserConfig.loadConfig(); - SharedPreferences preferences = getSharedPreferences("Notifications", MODE_PRIVATE); - if (UserConfig.currentUser != null) { - int value = preferences.getInt("version", 0); - if (value != 15) { - UserConfig.contactsHash = ""; - MessagesStorage.lastDateValue = 0; - MessagesStorage.lastPtsValue = 0; - MessagesStorage.lastSeqValue = 0; - MessagesStorage.lastQtsValue = 0; - UserConfig.saveConfig(false); - MessagesStorage.Instance.cleanUp(); - ArrayList users = new ArrayList(); - users.add(UserConfig.currentUser); - MessagesStorage.Instance.putUsersAndChats(users, null, true, true); + Utilities.applicationHandler = new Handler(applicationContext.getMainLooper()); - SharedPreferences.Editor editor = preferences.edit(); - editor.putInt("version", 15); + UserConfig.loadConfig(); + if (UserConfig.currentUser != null) { + boolean changed = false; + SharedPreferences preferences = getSharedPreferences("Notifications", MODE_PRIVATE); + int v = preferences.getInt("v", 0); + if (v != 1) { + SharedPreferences preferences2 = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences2.edit(); + if (preferences.contains("view_animations")) { + editor.putBoolean("view_animations", preferences.getBoolean("view_animations", false)); + } + if (preferences.contains("selectedBackground")) { + editor.putInt("selectedBackground", preferences.getInt("selectedBackground", 1000001)); + } + if (preferences.contains("selectedColor")) { + editor.putInt("selectedColor", preferences.getInt("selectedColor", 0)); + } + if (preferences.contains("fons_size")) { + editor.putInt("fons_size", preferences.getInt("fons_size", 16)); + } + editor.commit(); + editor = preferences.edit(); + editor.putInt("v", 1); + editor.remove("view_animations"); + editor.remove("selectedBackground"); + editor.remove("selectedColor"); + editor.remove("fons_size"); editor.commit(); - } else { - MessagesStorage init = MessagesStorage.Instance; } + MessagesStorage init = MessagesStorage.Instance; MessagesController.Instance.users.put(UserConfig.clientUserId, UserConfig.currentUser); - } else { - SharedPreferences.Editor editor = preferences.edit(); - editor.putInt("version", 15); - editor.commit(); } - MessagesController.Instance.checkAppAccount(); try { ViewConfiguration config = ViewConfiguration.get(this); @@ -101,7 +110,7 @@ public class ApplicationLoader extends Application { menuKeyField.setBoolean(config, false); } } catch (Exception e) { - FileLog.e("tmessages", e); + e.printStackTrace(); } if (checkPlayServices()) { @@ -123,6 +132,20 @@ public class ApplicationLoader extends Application { FileLog.e("tmessages", "start application with time " + lastPauseTime); } + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + Locale newLocale = newConfig.locale; + if (newLocale != null) { + String d1 = newLocale.getDisplayName(); + String d2 = currentLocale.getDisplayName(); + if (d1 != null && d2 != null && !d1.equals(d2)) { + Utilities.recreateFormatters(); + } + currentLocale = newLocale; + } + } + public static void resetLastPauseTime() { lastPauseTime = 0; ConnectionsManager.Instance.applicationMovedToForeground(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/BaseCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/BaseCell.java new file mode 100644 index 000000000..4c17a2699 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/BaseCell.java @@ -0,0 +1,36 @@ +/* + * This is the source code of Telegram for Android v. 1.3.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. + */ + +package org.telegram.ui.Cells; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.View; + +public class BaseCell extends View { + public BaseCell(Context context) { + super(context); + } + + public BaseCell(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public BaseCell(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + protected void setDrawableBounds(Drawable drawable, int x, int y) { + setDrawableBounds(drawable, x, y, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); + } + + protected void setDrawableBounds(Drawable drawable, int x, int y, int w, int h) { + drawable.setBounds(x, y, x + w, y + h); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatOrUserCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatOrUserCell.java new file mode 100644 index 000000000..9e23350c6 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/ChatOrUserCell.java @@ -0,0 +1,464 @@ +/* + * This is the source code of Telegram for Android v. 1.3.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. + */ + +package org.telegram.ui.Cells; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.drawable.Drawable; +import android.text.Html; +import android.text.Layout; +import android.text.StaticLayout; +import android.text.TextPaint; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.View; + +import org.telegram.PhoneFormat.PhoneFormat; +import org.telegram.TL.TLRPC; +import org.telegram.messenger.ConnectionsManager; +import org.telegram.messenger.ContactsController; +import org.telegram.messenger.MessagesController; +import org.telegram.messenger.R; +import org.telegram.messenger.UserConfig; +import org.telegram.messenger.Utilities; +import org.telegram.ui.ApplicationLoader; +import org.telegram.ui.Views.ImageReceiver; + +import java.lang.ref.WeakReference; + +public class ChatOrUserCell extends BaseCell { + private static TextPaint namePaint; + private static TextPaint nameEncryptedPaint; + private static TextPaint onlinePaint; + private static TextPaint offlinePaint; + + private static Drawable lockDrawable; + private static Paint linePaint; + + private CharSequence currentName; + private ImageReceiver avatarImage; + private String subLabel; + + private ChatOrUserCellLayout cellLayout; + private TLRPC.User user = null; + private TLRPC.Chat chat = null; + private TLRPC.EncryptedChat encryptedChat = null; + + private String lastName = null; + private int lastStatus = 0; + private TLRPC.FileLocation lastAvatar = null; + + public boolean usePadding = true; + public boolean useBoldFont = false; + public boolean useSeparator = false; + public float drawAlpha = 1; + + public ChatOrUserCell(Context context) { + super(context); + init(); + } + + public ChatOrUserCell(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public ChatOrUserCell(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(); + } + + private void init() { + if (namePaint == null) { + namePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); + namePaint.setTextSize(Utilities.dp(18)); + namePaint.setColor(0xff222222); + } + + if (nameEncryptedPaint == null) { + nameEncryptedPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); + nameEncryptedPaint.setTextSize(Utilities.dp(18)); + nameEncryptedPaint.setColor(0xff00a60e); + } + + if (onlinePaint == null) { + onlinePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); + onlinePaint.setTextSize(Utilities.dp(15)); + onlinePaint.setColor(0xff316f9f); + } + + if (offlinePaint == null) { + offlinePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); + offlinePaint.setTextSize(Utilities.dp(15)); + offlinePaint.setColor(0xff999999); + } + + if (lockDrawable == null) { + lockDrawable = getResources().getDrawable(R.drawable.ic_lock_green); + } + + if (linePaint == null) { + linePaint = new Paint(); + linePaint.setColor(0xffdcdcdc); + } + + if (avatarImage == null) { + avatarImage = new ImageReceiver(); + avatarImage.parentView = new WeakReference(this); + } + + if (cellLayout == null) { + cellLayout = new ChatOrUserCellLayout(); + } + } + + public void setData(TLRPC.User u, TLRPC.Chat c, TLRPC.EncryptedChat ec, CharSequence n, String s) { + currentName = n; + user = u; + chat = c; + encryptedChat = ec; + subLabel = s; + update(0); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), Utilities.dp(64)); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + if (user == null && chat == null && encryptedChat == null) { + super.onLayout(changed, left, top, right, bottom); + return; + } + if (changed) { + buildLayout(); + } + } + + public void buildLayout() { + cellLayout.build(getMeasuredWidth(), getMeasuredHeight()); + } + + public void update(int mask) { + int placeHolderId = 0; + TLRPC.FileLocation photo = null; + if (user != null) { + if (user.photo != null) { + photo = user.photo.photo_small; + } + placeHolderId = Utilities.getUserAvatarForId(user.id); + } else if (chat != null) { + if (chat.photo != null) { + photo = chat.photo.photo_small; + } + placeHolderId = Utilities.getGroupAvatarForId(chat.id); + } + + if (mask != 0) { + boolean continueUpdate = false; + if ((mask & MessagesController.UPDATE_MASK_AVATAR) != 0 && user != null || (mask & MessagesController.UPDATE_MASK_CHAT_AVATAR) != 0 && chat != null) { + if (lastAvatar != null && photo == null || lastAvatar == null && photo != null && lastAvatar != null && photo != null && (lastAvatar.volume_id != photo.volume_id || lastAvatar.local_id != photo.local_id)) { + continueUpdate = true; + } + } + if (!continueUpdate && (mask & MessagesController.UPDATE_MASK_STATUS) != 0 && user != null) { + int newStatus = 0; + if (user.status != null) { + newStatus = user.status.expires; + if (lastStatus == 0) { + lastStatus = user.status.was_online; + } + } + if (newStatus != lastStatus) { + continueUpdate = true; + } + } + if (!continueUpdate && ((mask & MessagesController.UPDATE_MASK_NAME) != 0 && user != null) || (mask & MessagesController.UPDATE_MASK_CHAT_NAME) != 0 && chat != null) { + String newName; + if (user != null) { + newName = user.first_name + user.last_name; + } else { + newName = chat.title; + } + if (!newName.equals(lastName)) { + continueUpdate = true; + } + } + + if (!continueUpdate) { + return; + } + } + + if (user != null) { + if (user.status != null) { + lastStatus = user.status.expires; + if (lastStatus == 0) { + lastStatus = user.status.was_online; + } + } else { + lastStatus = 0; + } + lastName = user.first_name + user.last_name; + } else if (chat != null) { + lastName = chat.title; + } + + + lastAvatar = photo; + avatarImage.setImage(photo, "50_50", placeHolderId == 0 ? null : getResources().getDrawable(placeHolderId)); + + if (getMeasuredWidth() != 0 || getMeasuredHeight() != 0) { + buildLayout(); + } else { + requestLayout(); + } + postInvalidate(); + } + + @Override + protected void onDraw(Canvas canvas) { + if (user == null && chat == null && encryptedChat == null) { + return; + } + + if (cellLayout == null) { + requestLayout(); + return; + } + + if (drawAlpha != 1) { + canvas.saveLayerAlpha(0, 0, canvas.getWidth(), canvas.getHeight(), (int)(255 * drawAlpha), Canvas.HAS_ALPHA_LAYER_SAVE_FLAG); + } + + if (cellLayout.drawNameLock) { + setDrawableBounds(lockDrawable, cellLayout.nameLockLeft, cellLayout.nameLockTop); + lockDrawable.draw(canvas); + } + + canvas.save(); + canvas.translate(cellLayout.nameLeft, cellLayout.nameTop); + cellLayout.nameLayout.draw(canvas); + canvas.restore(); + + if (cellLayout.onlineLayout != null) { + canvas.save(); + canvas.translate(cellLayout.onlineLeft, cellLayout.onlineTop); + cellLayout.onlineLayout.draw(canvas); + canvas.restore(); + } + + avatarImage.draw(canvas, cellLayout.avatarLeft, cellLayout.avatarTop, Utilities.dp(50), Utilities.dp(50)); + + if (useSeparator) { + int h = getMeasuredHeight(); + if (!usePadding) { + canvas.drawLine(0, h - 1, getMeasuredWidth(), h, linePaint); + } else { + canvas.drawLine(Utilities.dp(11), h - 1, getMeasuredWidth() - Utilities.dp(11), h, linePaint); + } + } + } + + private class ChatOrUserCellLayout { + private int nameLeft; + private int nameTop; + private int nameWidth; + private StaticLayout nameLayout; + private boolean drawNameLock; + private int nameLockLeft; + private int nameLockTop = Utilities.dp(15); + + private int onlineLeft; + private int onlineTop = Utilities.dp(36); + private int onlineWidth; + private StaticLayout onlineLayout; + + private int avatarTop = Utilities.dp(7); + private int avatarLeft; + + public void build(int width, int height) { + CharSequence nameString = ""; + TextPaint currentNamePaint; + + if (encryptedChat != null) { + drawNameLock = true; + if (!Utilities.isRTL) { + nameLockLeft = Utilities.dp(61 + (usePadding ? 11 : 0)); + nameLeft = Utilities.dp(65 + (usePadding ? 11 : 0)) + lockDrawable.getIntrinsicWidth(); + } else { + nameLockLeft = width - Utilities.dp(63 + (usePadding ? 11 : 0)) - lockDrawable.getIntrinsicWidth(); + nameLeft = usePadding ? Utilities.dp(11) : 0; + } + } else { + drawNameLock = false; + if (!Utilities.isRTL) { + nameLeft = Utilities.dp(61 + (usePadding ? 11 : 0)); + } else { + nameLeft = usePadding ? Utilities.dp(11) : 0; + } + } + + if (currentName != null) { + nameString = currentName; + } else { + if (useBoldFont) { + if (user != null) { + if (user.first_name.length() != 0 && user.last_name.length() != 0) { + nameString = Html.fromHtml(user.first_name + " " + user.last_name + ""); + } else if (user.first_name.length() != 0) { + nameString = Html.fromHtml("" + user.first_name + ""); + } else { + nameString = Html.fromHtml("" + user.last_name + ""); + } + } + } else { + String nameString2 = ""; + if (chat != null) { + nameString2 = chat.title; + } else if (user != null) { + if (user.id != 333000 && ContactsController.Instance.contactsDict.get(user.id) == null) { + if (ContactsController.Instance.contactsDict.size() == 0 && ContactsController.Instance.loadingContacts) { + nameString2 = Utilities.formatName(user.first_name, user.last_name); + } else { + if (user.phone != null && user.phone.length() != 0) { + nameString2 = PhoneFormat.Instance.format("+" + user.phone); + } else { + nameString2 = Utilities.formatName(user.first_name, user.last_name); + } + } + } else { + nameString2 = Utilities.formatName(user.first_name, user.last_name); + } + } + nameString = nameString2.replace("\n", " "); + } + } + if (nameString.length() == 0) { + nameString = ApplicationLoader.applicationContext.getString(R.string.HiddenName); + } + if (encryptedChat != null) { + currentNamePaint = nameEncryptedPaint; + } else { + currentNamePaint = namePaint; + } + + if (!Utilities.isRTL) { + onlineWidth = nameWidth = width - nameLeft - Utilities.dp(3 + (usePadding ? 11 : 0)); + } else { + onlineWidth = nameWidth = width - nameLeft - Utilities.dp(61 + (usePadding ? 11 : 0)); + } + if (drawNameLock) { + nameWidth -= Utilities.dp(6) + lockDrawable.getIntrinsicWidth(); + } + + CharSequence nameStringFinal = TextUtils.ellipsize(nameString, currentNamePaint, nameWidth - Utilities.dp(12), TextUtils.TruncateAt.END); + nameLayout = new StaticLayout(nameStringFinal, currentNamePaint, nameWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); + + if (chat == null) { + if (!Utilities.isRTL) { + onlineLeft = Utilities.dp(61 + (usePadding ? 11 : 0)); + } else { + onlineLeft = usePadding ? Utilities.dp(11) : 0; + } + + String onlineString = ""; + TextPaint currentOnlinePaint = offlinePaint; + + if (subLabel != null) { + onlineString = subLabel; + } else { + if (user != null) { + if (user.status == null) { + onlineString = getResources().getString(R.string.Offline); + } else { + int currentTime = ConnectionsManager.Instance.getCurrentTime(); + if (user.id == UserConfig.clientUserId || user.status.expires > currentTime || user.status.was_online > currentTime) { + currentOnlinePaint = onlinePaint; + onlineString = getResources().getString(R.string.Online); + } else { + if (user.status.was_online <= 10000 && user.status.expires <= 10000) { + onlineString = getResources().getString(R.string.Invisible); + } else { + int value = user.status.was_online; + if (value == 0) { + value = user.status.expires; + } + onlineString = getResources().getString(R.string.LastSeen) + " " + Utilities.formatDateOnline(value); + } + } + } + } + } + + CharSequence onlineStringFinal = TextUtils.ellipsize(onlineString, currentOnlinePaint, nameWidth - Utilities.dp(12), TextUtils.TruncateAt.END); + onlineLayout = new StaticLayout(onlineStringFinal, currentOnlinePaint, nameWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); + nameTop = Utilities.dp(12); + } else { + onlineLayout = null; + nameTop = Utilities.dp(22); + } + + if (!Utilities.isRTL) { + avatarLeft = usePadding ? Utilities.dp(11) : 0; + } else { + avatarLeft = width - Utilities.dp(50 + (usePadding ? 11 : 0)); + } + avatarImage.imageX = avatarLeft; + avatarImage.imageY = avatarTop; + avatarImage.imageW = Utilities.dp(50); + avatarImage.imageH = Utilities.dp(50); + + double widthpx = 0; + float left = 0; + if (Utilities.isRTL) { + if (nameLayout.getLineCount() > 0) { + left = nameLayout.getLineLeft(0); + if (left == 0) { + widthpx = Math.ceil(nameLayout.getLineWidth(0)); + if (widthpx < nameWidth) { + nameLeft += (nameWidth - widthpx); + } + } + } + if (onlineLayout != null && onlineLayout.getLineCount() > 0) { + left = onlineLayout.getLineLeft(0); + if (left == 0) { + widthpx = Math.ceil(onlineLayout.getLineWidth(0)); + if (widthpx < onlineWidth) { + onlineLeft += (onlineWidth - widthpx); + } + } + } + } else { + if (nameLayout.getLineCount() > 0) { + left = nameLayout.getLineRight(0); + if (left == nameWidth) { + widthpx = Math.ceil(nameLayout.getLineWidth(0)); + if (widthpx < nameWidth) { + nameLeft -= (nameWidth - widthpx); + } + } + } + if (onlineLayout != null && onlineLayout.getLineCount() > 0) { + left = onlineLayout.getLineRight(0); + if (left == onlineWidth) { + widthpx = Math.ceil(onlineLayout.getLineWidth(0)); + if (widthpx < onlineWidth) { + onlineLeft -= (onlineWidth - widthpx); + } + } + } + } + } + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java new file mode 100644 index 000000000..6adea8808 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Cells/DialogCell.java @@ -0,0 +1,684 @@ +/* + * This is the source code of Telegram for Android v. 1.3.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. + */ + +package org.telegram.ui.Cells; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.drawable.Drawable; +import android.text.Html; +import android.text.Layout; +import android.text.StaticLayout; +import android.text.TextPaint; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.View; + +import org.telegram.PhoneFormat.PhoneFormat; +import org.telegram.TL.TLRPC; +import org.telegram.messenger.ContactsController; +import org.telegram.messenger.Emoji; +import org.telegram.messenger.MessagesController; +import org.telegram.messenger.R; +import org.telegram.messenger.UserConfig; +import org.telegram.messenger.Utilities; +import org.telegram.objects.MessageObject; +import org.telegram.ui.ApplicationLoader; +import org.telegram.ui.Views.ImageReceiver; + +import java.lang.ref.WeakReference; + +public class DialogCell extends BaseCell { + private static TextPaint namePaint; + private static TextPaint nameEncryptedPaint; + private static TextPaint nameUnknownPaint; + private static TextPaint messagePaint; + private static TextPaint messagePrintingPaint; + private static TextPaint timePaint; + private static TextPaint countPaint; + + private static Drawable checkDrawable; + private static Drawable halfCheckDrawable; + private static Drawable clockDrawable; + private static Drawable errorDrawable; + private static Drawable lockDrawable; + private static Drawable countDrawable; + + private TLRPC.TL_dialog currentDialog; + private ImageReceiver avatarImage; + + private DialogCellLayout cellLayout; + private TLRPC.User user = null; + private TLRPC.Chat chat = null; + private TLRPC.EncryptedChat encryptedChat = null; + private CharSequence lastPrintString = null; + + private void init() { + if (namePaint == null) { + namePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); + namePaint.setTextSize(Utilities.dp(19)); + namePaint.setColor(0xff222222); + namePaint.setTypeface(Utilities.getTypeface("fonts/rmedium.ttf")); + } + + if (nameEncryptedPaint == null) { + nameEncryptedPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); + nameEncryptedPaint.setTextSize(Utilities.dp(19)); + nameEncryptedPaint.setColor(0xff00a60e); + nameEncryptedPaint.setTypeface(Utilities.getTypeface("fonts/rmedium.ttf")); + } + + if (nameUnknownPaint == null) { + nameUnknownPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); + nameUnknownPaint.setTextSize(Utilities.dp(19)); + nameUnknownPaint.setColor(0xff316f9f); + nameUnknownPaint.setTypeface(Utilities.getTypeface("fonts/rmedium.ttf")); + } + + if (messagePaint == null) { + messagePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); + messagePaint.setTextSize(Utilities.dp(16)); + messagePaint.setColor(0xff808080); + } + + if (messagePrintingPaint == null) { + messagePrintingPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); + messagePrintingPaint.setTextSize(Utilities.dp(16)); + messagePrintingPaint.setColor(0xff316f9f); + } + + if (timePaint == null) { + timePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); + timePaint.setTextSize(Utilities.dp(14)); + timePaint.setColor(0xff9e9e9e); + } + + if (countPaint == null) { + countPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); + countPaint.setTextSize(Utilities.dp(13)); + countPaint.setColor(0xffffffff); + } + + if (lockDrawable == null) { + lockDrawable = getResources().getDrawable(R.drawable.ic_lock_green); + } + + if (checkDrawable == null) { + checkDrawable = getResources().getDrawable(R.drawable.dialogs_check); + } + + if (halfCheckDrawable == null) { + halfCheckDrawable = getResources().getDrawable(R.drawable.dialogs_halfcheck); + } + + if (clockDrawable == null) { + clockDrawable = getResources().getDrawable(R.drawable.msg_clock); + } + + if (errorDrawable == null) { + errorDrawable = getResources().getDrawable(R.drawable.dialogs_warning); + } + + if (countDrawable == null) { + countDrawable = getResources().getDrawable(R.drawable.dialogs_badge); + } + + if (avatarImage == null) { + avatarImage = new ImageReceiver(); + avatarImage.parentView = new WeakReference(this); + } + + if (cellLayout == null) { + cellLayout = new DialogCellLayout(); + } + } + + public DialogCell(Context context) { + super(context); + init(); + } + + public DialogCell(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public DialogCell(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(); + } + + public void setDialog(TLRPC.TL_dialog dialog) { + currentDialog = dialog; + update(0); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), Utilities.dp(70)); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + if (currentDialog == null) { + super.onLayout(changed, left, top, right, bottom); + return; + } + if (changed) { + buildLayout(); + } + } + + public void buildLayout() { + cellLayout.build(getMeasuredWidth(), getMeasuredHeight()); + } + + public void update(int mask) { + if (mask != 0) { + boolean continueUpdate = false; + if ((mask & MessagesController.UPDATE_MASK_USER_PRINT) != 0) { + CharSequence printString = MessagesController.Instance.printingStrings.get(currentDialog.id); + if (lastPrintString != null && printString == null || lastPrintString == null && printString != null || lastPrintString != null && printString != null && !lastPrintString.equals(printString)) { + continueUpdate = true; + } + } + if ((mask & MessagesController.UPDATE_MASK_AVATAR) != 0) { + if (chat == null) { + continueUpdate = true; + } + } + if ((mask & MessagesController.UPDATE_MASK_NAME) != 0) { + if (chat == null) { + continueUpdate = true; + } + } + if ((mask & MessagesController.UPDATE_MASK_CHAT_AVATAR) != 0) { + if (user == null) { + continueUpdate = true; + } + } + if ((mask & MessagesController.UPDATE_MASK_CHAT_NAME) != 0) { + if (user == null) { + continueUpdate = true; + } + } + + if (!continueUpdate) { + return; + } + } + user = null; + chat = null; + encryptedChat = null; + + int lower_id = (int)currentDialog.id; + if (lower_id != 0) { + if (lower_id < 0) { + chat = MessagesController.Instance.chats.get(-lower_id); + } else { + user = MessagesController.Instance.users.get(lower_id); + } + } else { + encryptedChat = MessagesController.Instance.encryptedChats.get((int)(currentDialog.id >> 32)); + if (encryptedChat != null) { + user = MessagesController.Instance.users.get(encryptedChat.user_id); + } + } + + int placeHolderId = 0; + TLRPC.FileLocation photo = null; + if (user != null) { + if (user.photo != null) { + photo = user.photo.photo_small; + } + placeHolderId = Utilities.getUserAvatarForId(user.id); + } else if (chat != null) { + if (chat.photo != null) { + photo = chat.photo.photo_small; + } + placeHolderId = Utilities.getGroupAvatarForId(chat.id); + } + avatarImage.setImage(photo, "50_50", placeHolderId == 0 ? null : getResources().getDrawable(placeHolderId)); + + if (getMeasuredWidth() != 0 || getMeasuredHeight() != 0) { + buildLayout(); + } else { + requestLayout(); + } + + invalidate(); + } + + @Override + protected void onDraw(Canvas canvas) { + if (currentDialog == null) { + return; + } + + if (cellLayout == null) { + requestLayout(); + return; + } + + if (cellLayout.drawNameLock) { + setDrawableBounds(lockDrawable, cellLayout.nameLockLeft, cellLayout.nameLockTop); + lockDrawable.draw(canvas); + } + + canvas.save(); + canvas.translate(cellLayout.nameLeft, cellLayout.nameTop); + cellLayout.nameLayout.draw(canvas); + canvas.restore(); + + canvas.save(); + canvas.translate(cellLayout.timeLeft, cellLayout.timeTop); + cellLayout.timeLayout.draw(canvas); + canvas.restore(); + + canvas.save(); + canvas.translate(cellLayout.messageLeft, cellLayout.messageTop); + cellLayout.messageLayout.draw(canvas); + canvas.restore(); + + if (cellLayout.drawClock) { + setDrawableBounds(clockDrawable, cellLayout.checkDrawLeft, cellLayout.checkDrawTop); + clockDrawable.draw(canvas); + } else if (cellLayout.drawCheck2) { + if (cellLayout.drawCheck1) { + setDrawableBounds(halfCheckDrawable, cellLayout.halfCheckDrawLeft, cellLayout.checkDrawTop); + halfCheckDrawable.draw(canvas); + setDrawableBounds(checkDrawable, cellLayout.checkDrawLeft, cellLayout.checkDrawTop); + checkDrawable.draw(canvas); + } else { + setDrawableBounds(checkDrawable, cellLayout.checkDrawLeft, cellLayout.checkDrawTop); + checkDrawable.draw(canvas); + } + } + + if (cellLayout.drawError) { + setDrawableBounds(errorDrawable, cellLayout.errorLeft, cellLayout.errorTop); + errorDrawable.draw(canvas); + } else if (cellLayout.drawCount) { + setDrawableBounds(countDrawable, cellLayout.countLeft - Utilities.dp(5), cellLayout.countTop, cellLayout.countWidth + Utilities.dp(10), countDrawable.getIntrinsicHeight()); + countDrawable.draw(canvas); + canvas.save(); + canvas.translate(cellLayout.countLeft, cellLayout.countTop + Utilities.dp(3)); + cellLayout.countLayout.draw(canvas); + canvas.restore(); + } + + avatarImage.draw(canvas, cellLayout.avatarLeft, cellLayout.avatarTop, Utilities.dp(54), Utilities.dp(54)); + } + + private class DialogCellLayout { + private int nameLeft; + private int nameTop = Utilities.dp(10); + private int nameWidth; + private StaticLayout nameLayout; + private boolean drawNameLock; + private int nameLockLeft; + private int nameLockTop = Utilities.dp(13); + + private int timeLeft; + private int timeTop = Utilities.dp(13); + private int timeWidth; + private StaticLayout timeLayout; + + private boolean drawCheck1; + private boolean drawCheck2; + private boolean drawClock; + private int checkDrawLeft; + private int checkDrawTop = Utilities.dp(15); + private int halfCheckDrawLeft; + + private int messageTop = Utilities.dp(40); + private int messageLeft; + private int messageWidth; + private StaticLayout messageLayout; + + private boolean drawError; + private int errorTop = Utilities.dp(37); + private int errorLeft; + + private boolean drawCount; + private int countTop = Utilities.dp(37); + private int countLeft; + private int countWidth; + private StaticLayout countLayout; + + private int avatarTop = Utilities.dp(8); + private int avatarLeft; + + public void build(int width, int height) { + MessageObject message = MessagesController.Instance.dialogMessage.get(currentDialog.top_message); + String nameString = ""; + String timeString = ""; + String countString = null; + CharSequence messageString = ""; + CharSequence printingString = MessagesController.Instance.printingStrings.get(currentDialog.id); + TextPaint currentNamePaint = namePaint; + TextPaint currentMessagePaint = messagePaint; + boolean checkMessage = true; + + if (encryptedChat != null) { + drawNameLock = true; + if (!Utilities.isRTL) { + nameLockLeft = Utilities.dp(77); + nameLeft = Utilities.dp(81) + lockDrawable.getIntrinsicWidth(); + } else { + nameLockLeft = width - Utilities.dp(77) - lockDrawable.getIntrinsicWidth(); + nameLeft = Utilities.dp(14); + } + } else { + drawNameLock = false; + if (!Utilities.isRTL) { + nameLeft = Utilities.dp(77); + } else { + nameLeft = Utilities.dp(14); + } + } + + if (message == null) { + if (printingString != null) { + lastPrintString = messageString = printingString; + currentMessagePaint = messagePrintingPaint; + } else { + lastPrintString = null; + if (encryptedChat != null) { + currentMessagePaint = messagePrintingPaint; + if (encryptedChat instanceof TLRPC.TL_encryptedChatRequested) { + messageString = ApplicationLoader.applicationContext.getString(R.string.EncryptionProcessing); + } else if (encryptedChat instanceof TLRPC.TL_encryptedChatWaiting) { + messageString = String.format(ApplicationLoader.applicationContext.getString(R.string.AwaitingEncryption), user.first_name); + } else if (encryptedChat instanceof TLRPC.TL_encryptedChatDiscarded) { + messageString = ApplicationLoader.applicationContext.getString(R.string.EncryptionRejected); + } else if (encryptedChat instanceof TLRPC.TL_encryptedChat) { + if (encryptedChat.admin_id == UserConfig.clientUserId) { + if (user != null) { + messageString = String.format(ApplicationLoader.applicationContext.getString(R.string.EncryptedChatStartedOutgoing), user.first_name); + } + } else { + if (user != null) { + messageString = String.format(ApplicationLoader.applicationContext.getString(R.string.EncryptedChatStartedIncoming), user.first_name); + } + } + } + } + } + if (currentDialog.last_message_date != 0) { + timeString = Utilities.stringForMessageListDate(currentDialog.last_message_date); + } + drawCheck1 = false; + drawCheck2 = false; + drawClock = false; + drawCount = false; + drawError = false; + } else { + TLRPC.User fromUser = MessagesController.Instance.users.get(message.messageOwner.from_id); + + if (currentDialog.last_message_date != 0) { + timeString = Utilities.stringForMessageListDate(currentDialog.last_message_date); + } else { + timeString = Utilities.stringForMessageListDate(message.messageOwner.date); + } + if (printingString != null) { + lastPrintString = messageString = printingString; + currentMessagePaint = messagePrintingPaint; + } else { + lastPrintString = null; + if (message.messageOwner instanceof TLRPC.TL_messageService) { + messageString = message.messageText; + currentMessagePaint = messagePrintingPaint; + } else { + if (chat != null) { + String name = ""; + if (message.messageOwner.from_id == UserConfig.clientUserId) { + name = ApplicationLoader.applicationContext.getString(R.string.FromYou); + } else { + if (fromUser != null) { + if (fromUser.first_name.length() > 0) { + name = fromUser.first_name; + } else { + name = fromUser.last_name; + } + } + } + if (message.messageOwner.media != null && !(message.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty)) { + messageString = message.messageText; + currentMessagePaint = messagePrintingPaint; + } else { + checkMessage = false; + if (message.messageOwner.message != null) { + messageString = Emoji.replaceEmoji(Html.fromHtml(String.format("%s: %s", name, message.messageOwner.message.replace("\n", " ")))); + } + } + } else { + messageString = message.messageText; + if (message.messageOwner.media != null && !(message.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty)) { + currentMessagePaint = messagePrintingPaint; + } + } + } + } + + if (currentDialog.unread_count != 0) { + drawCount = true; + countString = String.format("%d", currentDialog.unread_count); + } else { + drawCount = false; + } + + if (message.messageOwner.id < 0 && message.messageOwner.send_state != MessagesController.MESSAGE_SEND_STATE_SENT) { + if (MessagesController.Instance.sendingMessages.get(message.messageOwner.id) == null) { + message.messageOwner.send_state = MessagesController.MESSAGE_SEND_STATE_SEND_ERROR; + } + } + + if (message.messageOwner.from_id == UserConfig.clientUserId) { + if (message.messageOwner.send_state == MessagesController.MESSAGE_SEND_STATE_SENDING) { + drawCheck1 = false; + drawCheck2 = false; + drawClock = true; + drawError = false; + } else if (message.messageOwner.send_state == MessagesController.MESSAGE_SEND_STATE_SEND_ERROR) { + drawCheck1 = false; + drawCheck2 = false; + drawClock = false; + drawError = true; + drawCount = false; + } else if (message.messageOwner.send_state == MessagesController.MESSAGE_SEND_STATE_SENT) { + if (!message.messageOwner.unread) { + drawCheck1 = true; + drawCheck2 = true; + } else { + drawCheck1 = false; + drawCheck2 = true; + } + drawClock = false; + drawError = false; + } + } else { + drawCheck1 = false; + drawCheck2 = false; + drawClock = false; + drawError = false; + } + } + + timeWidth = (int)Math.ceil(timePaint.measureText(timeString)); + timeLayout = new StaticLayout(timeString, timePaint, timeWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); + if (!Utilities.isRTL) { + timeLeft = width - Utilities.dp(11) - timeWidth; + } else { + timeLeft = Utilities.dp(11); + } + + if (chat != null) { + nameString = chat.title; + } else if (user != null) { + if (user.id != 333000 && ContactsController.Instance.contactsDict.get(user.id) == null) { + if (ContactsController.Instance.contactsDict.size() == 0 && (!ContactsController.Instance.contactsLoaded || ContactsController.Instance.loadingContacts)) { + nameString = Utilities.formatName(user.first_name, user.last_name); + } else { + if (user.phone != null && user.phone.length() != 0) { + nameString = PhoneFormat.Instance.format("+" + user.phone); + } else { + currentNamePaint = nameUnknownPaint; + nameString = Utilities.formatName(user.first_name, user.last_name); + } + } + } else { + nameString = Utilities.formatName(user.first_name, user.last_name); + } + if (encryptedChat != null) { + currentNamePaint = nameEncryptedPaint; + } + } + if (nameString.length() == 0) { + nameString = ApplicationLoader.applicationContext.getString(R.string.HiddenName); + } + + if (!Utilities.isRTL) { + nameWidth = width - nameLeft - Utilities.dp(14) - timeWidth; + } else { + nameWidth = width - nameLeft - Utilities.dp(77) - timeWidth; + nameLeft += timeWidth; + } + if (drawNameLock) { + nameWidth -= Utilities.dp(4) + lockDrawable.getIntrinsicWidth(); + } + if (drawClock) { + int w = clockDrawable.getIntrinsicWidth() + Utilities.dp(2); + nameWidth -= w; + if (!Utilities.isRTL) { + checkDrawLeft = timeLeft - w; + } else { + checkDrawLeft = timeLeft + timeWidth + Utilities.dp(2); + nameLeft += w; + } + } else if (drawCheck2) { + int w = checkDrawable.getIntrinsicWidth() + Utilities.dp(2); + nameWidth -= w; + if (drawCheck1) { + nameWidth -= halfCheckDrawable.getIntrinsicWidth() - Utilities.dp(5); + if (!Utilities.isRTL) { + halfCheckDrawLeft = timeLeft - w; + checkDrawLeft = halfCheckDrawLeft - Utilities.dp(5); + } else { + checkDrawLeft = timeLeft + timeWidth + Utilities.dp(2); + halfCheckDrawLeft = checkDrawLeft + Utilities.dp(5); + nameLeft += w + halfCheckDrawable.getIntrinsicWidth() - Utilities.dp(5); + } + } else { + if (!Utilities.isRTL) { + checkDrawLeft = timeLeft - w; + } else { + checkDrawLeft = timeLeft + timeWidth + Utilities.dp(2); + nameLeft += w; + } + } + } + + CharSequence nameStringFinal = TextUtils.ellipsize(nameString.replace("\n", " "), currentNamePaint, nameWidth - Utilities.dp(12), TextUtils.TruncateAt.END); + nameLayout = new StaticLayout(nameStringFinal, currentNamePaint, nameWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); + + messageWidth = width - Utilities.dp(88); + if (!Utilities.isRTL) { + messageLeft = Utilities.dp(77); + avatarLeft = Utilities.dp(11); + } else { + messageLeft = Utilities.dp(11); + avatarLeft = width - Utilities.dp(65); + } + avatarImage.imageX = avatarLeft; + avatarImage.imageY = avatarTop; + avatarImage.imageW = Utilities.dp(54); + avatarImage.imageH = Utilities.dp(54); + if (drawError) { + int w = errorDrawable.getIntrinsicWidth() + Utilities.dp(8); + messageWidth -= w; + if (!Utilities.isRTL) { + errorLeft = width - errorDrawable.getIntrinsicWidth() - Utilities.dp(11); + } else { + errorLeft = Utilities.dp(11); + messageLeft += w; + } + } else if (countString != null) { + countWidth = Math.max(Utilities.dp(12), (int)Math.ceil(countPaint.measureText(countString))); + countLayout = new StaticLayout(countString, countPaint, countWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false); + int w = countWidth + Utilities.dp(18); + messageWidth -= w; + if (!Utilities.isRTL) { + countLeft = width - countWidth - Utilities.dp(16); + } else { + countLeft = Utilities.dp(16); + messageLeft += w; + } + drawCount = true; + } else { + drawCount = false; + } + + if (checkMessage) { + if (messageString == null) { + messageString = ""; + } + String mess = messageString.toString().replace("\n", " "); + if (mess.length() > 150) { + mess = mess.substring(0, 150); + } + messageString = Emoji.replaceEmoji(mess); + } + + CharSequence messageStringFinal = TextUtils.ellipsize(messageString, currentMessagePaint, messageWidth - Utilities.dp(12), TextUtils.TruncateAt.END); + messageLayout = new StaticLayout(messageStringFinal, currentMessagePaint, messageWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); + + double widthpx = 0; + float left = 0; + if (Utilities.isRTL) { + if (nameLayout.getLineCount() > 0) { + left = nameLayout.getLineLeft(0); + if (left == 0) { + widthpx = Math.ceil(nameLayout.getLineWidth(0)); + if (widthpx < nameWidth) { + nameLeft += (nameWidth - widthpx); + } + } + } + if (messageLayout.getLineCount() > 0) { + left = messageLayout.getLineLeft(0); + if (left == 0) { + widthpx = Math.ceil(messageLayout.getLineWidth(0)); + if (widthpx < messageWidth) { + messageLeft += (messageWidth - widthpx); + } + } + } + } else { + if (nameLayout.getLineCount() > 0) { + left = nameLayout.getLineRight(0); + if (left == nameWidth) { + widthpx = Math.ceil(nameLayout.getLineWidth(0)); + if (widthpx < nameWidth) { + nameLeft -= (nameWidth - widthpx); + } + } + } + if (messageLayout.getLineCount() > 0) { + left = messageLayout.getLineRight(0); + if (left == messageWidth) { + widthpx = Math.ceil(messageLayout.getLineWidth(0)); + if (widthpx < messageWidth) { + messageLeft -= (messageWidth - widthpx); + } + } + } + } + } + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java index 98af2ca08..515a1ad88 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatActivity.java @@ -16,7 +16,6 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; -import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.Point; import android.graphics.Rect; @@ -52,6 +51,7 @@ import android.view.ViewGroup; import android.view.ViewParent; import android.view.ViewTreeObserver; import android.view.WindowManager; +import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.webkit.MimeTypeMap; import android.widget.AbsListView; @@ -61,6 +61,7 @@ import android.widget.EditText; import android.widget.FrameLayout; import android.widget.ImageButton; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.ListView; import android.widget.PopupWindow; import android.widget.ProgressBar; @@ -69,6 +70,7 @@ import android.widget.TextView; import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.TL.TLRPC; +import org.telegram.messenger.ContactsController; import org.telegram.messenger.FileLog; import org.telegram.objects.MessageObject; import org.telegram.objects.PhotoObject; @@ -125,12 +127,14 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa private Point displaySize = new Point(); private boolean paused = true; private boolean readWhenResume = false; + private boolean sendByEnter = false; private int readWithDate = 0; private int readWithMid = 0; private boolean swipeOpening = false; public boolean scrollToTopOnResume = false; private boolean scrollToTopUnReadOnResume = false; private boolean isCustomTheme = false; + private boolean downloadPhotos = true; private ImageView topPlaneClose; private View pagedownButton; private TextView topPanelText; @@ -173,6 +177,8 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa private HashMap> loadingFile = new HashMap>(); private HashMap progressByTag = new HashMap(); + private CharSequence lastPrintString; + ActionMode mActionMode = null; private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() { @Override @@ -276,7 +282,6 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa NotificationCenter.Instance.addObserver(this, MessagesController.updateInterfaces); NotificationCenter.Instance.addObserver(this, MessagesController.didReceivedNewMessages); NotificationCenter.Instance.addObserver(this, MessagesController.closeChats); - NotificationCenter.Instance.addObserver(this, MessagesController.userPrintUpdate); NotificationCenter.Instance.addObserver(this, MessagesController.messagesReaded); NotificationCenter.Instance.addObserver(this, MessagesController.messagesDeleted); NotificationCenter.Instance.addObserver(this, MessagesController.messageReceivedByServer); @@ -293,11 +298,16 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa NotificationCenter.Instance.addObserver(this, 997); loading = true; MessagesController.Instance.loadMessages(dialog_id, 0, 30, 0, true, 0, classGuid, true, false); - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); fontSize = preferences.getInt("fons_size", 16); + sendByEnter = preferences.getBoolean("send_by_enter", false); + + if (currentChat != null) { + downloadPhotos = preferences.getBoolean("photo_download_chat", true); + } else { + downloadPhotos = preferences.getBoolean("photo_download_user", true); + } - keyboardHeight = ApplicationLoader.applicationContext.getSharedPreferences("emoji", 0).getInt("kbd_height", Emoji.scale(200.0f)); - keyboardHeightLand = ApplicationLoader.applicationContext.getSharedPreferences("emoji", 0).getInt("kbd_height_land3", Emoji.scale(200.0f)); return true; } @@ -309,7 +319,6 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa NotificationCenter.Instance.removeObserver(this, MessagesController.updateInterfaces); NotificationCenter.Instance.removeObserver(this, MessagesController.didReceivedNewMessages); NotificationCenter.Instance.removeObserver(this, MessagesController.closeChats); - NotificationCenter.Instance.removeObserver(this, MessagesController.userPrintUpdate); NotificationCenter.Instance.removeObserver(this, MessagesController.messagesReaded); NotificationCenter.Instance.removeObserver(this, MessagesController.messagesDeleted); NotificationCenter.Instance.removeObserver(this, MessagesController.messageReceivedByServer); @@ -377,7 +386,7 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa ImageView backgroundImage = (ImageView) fragmentView.findViewById(R.id.background_image); - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); int selectedBackground = preferences.getInt("selectedBackground", 1000001); int selectedColor = preferences.getInt("selectedColor", 0); if (selectedColor != 0) { @@ -475,13 +484,13 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa loading = true; } } - if (firstVisibleItem + visibleItemCount >= totalItemCount - 4) { + if (firstVisibleItem + visibleItemCount >= totalItemCount - 6) { if (!unread_end_reached && !loadingForward) { - MessagesController.Instance.loadMessages(dialog_id, 0, 20, minMessageId, true, minDate, classGuid, false, true); + MessagesController.Instance.loadMessages(dialog_id, 0, 20, minMessageId, true, maxDate, classGuid, false, true); loadingForward = true; } } - if (firstVisibleItem + visibleItemCount == totalItemCount) { + if (firstVisibleItem + visibleItemCount == totalItemCount && unread_end_reached) { showPagedownButton(false, true); } } else { @@ -528,6 +537,25 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa showEmojiPopup(false); } return true; + } else if (i == KeyEvent.KEYCODE_ENTER && sendByEnter && keyEvent.getAction() == KeyEvent.ACTION_DOWN) { + sendMessage(); + return true; + } + return false; + } + }); + + messsageEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @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) { + sendMessage(); + return true; + } } return false; } @@ -536,17 +564,7 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa sendButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - String message = messsageEditText.getText().toString().trim(); - if (processSendingText(message)) { - messsageEditText.setText(""); - lastTypingTimeSend = 0; - chatListView.post(new Runnable() { - @Override - public void run() { - chatListView.setSelectionFromTop(messages.size() - 1, -10000 - chatListView.getPaddingTop()); - } - }); - } + sendMessage(); } }); @@ -597,6 +615,9 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa @Override public void afterTextChanged(Editable editable) { + if (sendByEnter && editable.length() > 0 && editable.charAt(editable.length() - 1) == '\n') { + sendMessage(); + } int i = 0; ImageSpan[] arrayOfImageSpan = editable.getSpans(0, editable.length(), ImageSpan.class); int j = arrayOfImageSpan.length; @@ -701,6 +722,20 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa return fragmentView; } + private void sendMessage() { + String message = messsageEditText.getText().toString().trim(); + if (processSendingText(message)) { + messsageEditText.setText(""); + lastTypingTimeSend = 0; + chatListView.post(new Runnable() { + @Override + public void run() { + chatListView.setSelectionFromTop(messages.size() - 1, -10000 - chatListView.getPaddingTop()); + } + }); + } + } + private void showPagedownButton(boolean show, boolean animated) { if (pagedownButton == null) { return; @@ -937,7 +972,7 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa title.setCompoundDrawablePadding(0); } } else if (currentUser != null) { - if (currentUser.id != 333000 && MessagesController.Instance.contactsDict.get(currentUser.id) == null && (MessagesController.Instance.contactsDict.size() != 0 || !MessagesController.Instance.loadingContacts)) { + if (currentUser.id != 333000 && ContactsController.Instance.contactsDict.get(currentUser.id) == null && (ContactsController.Instance.contactsDict.size() != 0 || !ContactsController.Instance.loadingContacts)) { if (currentUser.phone != null && currentUser.phone.length() != 0) { actionBar.setTitle(PhoneFormat.Instance.format("+" + currentUser.phone)); } else { @@ -960,6 +995,7 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa CharSequence printString = MessagesController.Instance.printingStrings.get(dialog_id); if (printString == null || printString.length() == 0) { + lastPrintString = null; setTypingAnimation(false); if (currentChat != null) { if (currentChat instanceof TLRPC.TL_chatForbidden) { @@ -988,12 +1024,13 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa if (value == 0) { value = currentUser.status.expires; } - actionBar.setSubtitle(String.format("%s %s", getStringEntry(R.string.LastSeen), Utilities.formatDateOnline(value))); + actionBar.setSubtitle(Utilities.formatDateOnline(value)); } } } } } else { + lastPrintString = printString; actionBar.setSubtitle(printString); setTypingAnimation(true); } @@ -1053,7 +1090,7 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa @Override public void run() { contentView.setPadding(0, 0, 0, layoutParams.height); - contentView.forceLayout(); + contentView.requestLayout(); } }); } @@ -1077,8 +1114,11 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa processSendingPhoto(currentPicturePath); currentPicturePath = null; } else if (requestCode == 1) { + if (data == null) { + return; + } Uri imageUri = data.getData(); - if (imageUri == null) { + if (imageUri == null || imageUri.getScheme() == null) { return; } String imageFilePath = null; @@ -1093,14 +1133,7 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa return; } try { - Cursor cursor = inflaterActivity.getContentResolver().query(imageUri, new String[]{android.provider.MediaStore.Images.ImageColumns.DATA}, null, null, null); - if (cursor == null) { - return; - } - if (cursor.moveToFirst()) { - imageFilePath = cursor.getString(0); - } - cursor.close(); + imageFilePath = Utilities.getPath(inflaterActivity, imageUri); } catch (Exception e) { FileLog.e("tmessages", e); } @@ -1133,13 +1166,7 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa return; } try { - Cursor cursor = inflaterActivity.getContentResolver().query(uri, new String[]{android.provider.MediaStore.Images.ImageColumns.DATA}, null, null, null); - if (cursor == null) { - return; - } - cursor.moveToFirst(); - videoPath = cursor.getString(0); - cursor.close(); + videoPath = Utilities.getPath(inflaterActivity, uri); } catch (Exception e) { FileLog.e("tmessages", e); } @@ -1450,11 +1477,11 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa } } else if (id == MessagesController.updateInterfaces) { int updateMask = (Integer)args[0]; - if ((updateMask & MessagesController.UPDATE_MASK_NAME) != 0 || (updateMask & MessagesController.UPDATE_MASK_STATUS) != 0) { + if ((updateMask & MessagesController.UPDATE_MASK_NAME) != 0 || (updateMask & MessagesController.UPDATE_MASK_STATUS) != 0 || (updateMask & MessagesController.UPDATE_MASK_CHAT_NAME) != 0) { updateSubtitle(); updateOnlineCount(); } - if ((updateMask & MessagesController.UPDATE_MASK_AVATAR) != 0) { + if ((updateMask & MessagesController.UPDATE_MASK_AVATAR) != 0 || (updateMask & MessagesController.UPDATE_MASK_CHAT_AVATAR) != 0 || (updateMask & MessagesController.UPDATE_MASK_NAME) != 0) { checkAndUpdateAvatar(); if (animationInProgress) { invalidateAfterAnimation = true; @@ -1464,6 +1491,15 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa } } } + if ((updateMask & MessagesController.UPDATE_MASK_USER_PRINT) != 0) { + CharSequence printString = MessagesController.Instance.printingStrings.get(dialog_id); + if (lastPrintString != null && printString == null || lastPrintString == null && printString != null || lastPrintString != null && printString != null && !lastPrintString.equals(printString)) { + updateSubtitle(); + } + } + if ((updateMask & MessagesController.UPDATE_MASK_USER_PHONE) != 0) { + updateContactStatus(); + } } else if (id == MessagesController.didReceivedNewMessages) { long did = (Long)args[0]; if (did == dialog_id) { @@ -1505,7 +1541,9 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa readWithDate = currentMaxDate; readWithMid = currentMinMsgId; } else { - MessagesController.Instance.markDialogAsRead(dialog_id, messages.get(0).messageOwner.id, currentMinMsgId, 0, currentMaxDate, true); + if (messages.size() > 0) { + MessagesController.Instance.markDialogAsRead(dialog_id, messages.get(0).messageOwner.id, currentMinMsgId, 0, currentMaxDate, true); + } } } updateVisibleRows(); @@ -1613,11 +1651,6 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa Utilities.hideKeyboard(messsageEditText); } removeSelfFromStack(); - } else if (id == MessagesController.userPrintUpdate) { - long uid = (Long)args[0]; - if (uid == dialog_id) { - updateSubtitle(); - } } else if (id == MessagesController.messagesReaded) { ArrayList markAsReadMessages = (ArrayList)args[0]; boolean updated = false; @@ -1818,9 +1851,11 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa if (currentUser == null) { topPanel.setVisibility(View.GONE); } else { - if (!(currentEncryptedChat instanceof TLRPC.TL_encryptedChat) || currentUser.id == 333000 || (currentUser.phone != null && currentUser.phone.length() != 0 && - MessagesController.Instance.contactsDict.get(currentUser.id) != null && - (MessagesController.Instance.contactsDict.size() != 0 || !MessagesController.Instance.loadingContacts))) { + if (currentEncryptedChat != null && !(currentEncryptedChat instanceof TLRPC.TL_encryptedChat) + || currentUser.id == 333000 + || (currentUser.phone != null && currentUser.phone.length() != 0 && + ContactsController.Instance.contactsDict.get(currentUser.id) != null && + (ContactsController.Instance.contactsDict.size() != 0 || !ContactsController.Instance.loadingContacts))) { topPanel.setVisibility(View.GONE); } else { topPanel.setVisibility(View.VISIBLE); @@ -1848,6 +1883,9 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa topPanel.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { + if (parentActivity == null) { + return; + } ContactAddActivity fragment = new ContactAddActivity(); Bundle args = new Bundle(); args.putInt("user_id", currentUser.id); @@ -2013,7 +2051,7 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa ((ApplicationActivity)parentActivity).showActionBar(); ((ApplicationActivity)parentActivity).updateActionBar(); fixLayout(); - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); String lastMessageText = preferences.getString("dialog_" + dialog_id, null); if (lastMessageText != null) { SharedPreferences.Editor editor = preferences.edit(); @@ -2021,6 +2059,7 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa editor.commit(); ignoreTextChange = true; messsageEditText.setText(lastMessageText); + messsageEditText.setSelection(messsageEditText.getText().length()); ignoreTextChange = false; } if (messsageEditText != null) { @@ -2074,14 +2113,11 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa MessagesController.Instance.openned_dialog_id = 0; if (messsageEditText != null && messsageEditText.length() != 0) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); SharedPreferences.Editor editor = preferences.edit(); editor.putString("dialog_" + dialog_id, messsageEditText.getText().toString()); editor.commit(); } - if (messsageEditText != null) { - messsageEditText.clearFocus(); - } } private void fixLayout() { @@ -2386,6 +2422,9 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa } } else if (option == 2) { if (selectedObject != null) { + if (parentActivity == null) { + return; + } forwaringMessage = selectedObject; selectedObject = null; @@ -2447,6 +2486,10 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa if (did != dialog_id) { int lower_part = (int)did; if (lower_part != 0) { + ActionBarActivity inflaterActivity = parentActivity; + if (inflaterActivity == null) { + inflaterActivity = (ActionBarActivity)getActivity(); + } activity.removeSelfFromStack(); ChatActivity fragment = new ChatActivity(); Bundle bundle = new Bundle(); @@ -2455,22 +2498,30 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa fragment.setArguments(bundle); fragment.scrollToTopOnResume = true; ActionBarActivity act = (ActionBarActivity)getActivity(); - ((ApplicationActivity)parentActivity).presentFragment(fragment, "chat" + Math.random(), false); + if (inflaterActivity != null) { + ((ApplicationActivity)inflaterActivity).presentFragment(fragment, "chat" + Math.random(), false); + } } else if (lower_part < 0) { bundle.putInt("chat_id", -lower_part); fragment.setArguments(bundle); fragment.scrollToTopOnResume = true; - ((ApplicationActivity)parentActivity).presentFragment(fragment, "chat" + Math.random(), false); + if (inflaterActivity != null) { + ((ApplicationActivity)inflaterActivity).presentFragment(fragment, "chat" + Math.random(), false); + } } removeSelfFromStack(); if (forwaringMessage != null) { - MessagesController.Instance.sendMessage(forwaringMessage, did); + if (forwaringMessage.messageOwner.id > 0) { + MessagesController.Instance.sendMessage(forwaringMessage, did); + } forwaringMessage = null; } else { ArrayList ids = new ArrayList(selectedMessagesIds.keySet()); Collections.sort(ids); for (Integer id : ids) { - MessagesController.Instance.sendMessage(selectedMessagesIds.get(id), did); + if (id > 0) { + MessagesController.Instance.sendMessage(selectedMessagesIds.get(id), did); + } } selectedMessagesIds.clear(); } @@ -2547,14 +2598,14 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa Intent pickIntent = new Intent(); pickIntent.setType("video/*"); pickIntent.setAction(Intent.ACTION_GET_CONTENT); - pickIntent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 1024 * 1024 * 1000); + pickIntent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, (long)(1024 * 1024 * 1000)); Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); File video = Utilities.generateVideoPath(); if (video != null) { - if(android.os.Build.VERSION.SDK_INT > 10) { + if(android.os.Build.VERSION.SDK_INT > 16) { takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(video)); } - takeVideoIntent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 1024 * 1024 * 1000); + takeVideoIntent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, (long)(1024 * 1024 * 1000)); currentPicturePath = video.getAbsolutePath(); } Intent chooserIntent = Intent.createChooser(pickIntent, ""); @@ -2906,7 +2957,7 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa ChatListRowHolderEx holder = (ChatListRowHolderEx)view.getTag(); if (holder == null) { - holder = new ChatListRowHolderEx(view); + holder = new ChatListRowHolderEx(view, type); view.setTag(holder); } holder.message = message; @@ -3069,11 +3120,17 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa public ImageView addContactButton; public View addContactView; public View chatBubbleView; + public View photoProgressView; public ProgressBar actionProgress; public View actionView; public ImageView actionCancelButton; + private PhotoObject photoObjectToSet = null; + private File photoFile = null; + private String photoFileName = null; + private String photoFilter = null; + public void update() { TLRPC.User fromUser = MessagesController.Instance.users.get(message.messageOwner.from_id); @@ -3115,24 +3172,38 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa forwardedUserText.setText(Html.fromHtml(getStringEntry(R.string.From) + " " + Utilities.formatName(fwdUser.first_name, fwdUser.last_name) + "")); } } else if (type == 2 || type == 3 || type == 6 || type == 7) { - int width = (int)(Math.min(displaySize.x, displaySize.y) / 2.5f); - PhotoObject photo = PhotoObject.getClosestImageWithSize(message.photoThumbs, width, width + 100); + int width = (int)(Math.min(displaySize.x, displaySize.y) * 0.7f); + int height = width + Utilities.dp(100); + if (type == 6 || type == 7) { + width = (int)(Math.min(displaySize.x, displaySize.y) / 2.5f); + height = width + 100; + } + if (width > 800) { + width = 800; + } + if (height > 800) { + height = 800; + } + + PhotoObject photo = PhotoObject.getClosestImageWithSize(message.photoThumbs, width, height); + if (type == 3) { + if (photoProgressView != null) { + photoProgressView.setVisibility(View.GONE); + } + } if (photo != null) { float scale = (float)photo.photoOwner.w / (float)width; - if (scale < 1 && photo.photoOwner.w * scale < Utilities.dp(100)) { - scale = photo.photoOwner.w / Utilities.dp(100); - } int w = (int)(photo.photoOwner.w / scale); int h = (int)(photo.photoOwner.h / scale); - if (h > Utilities.dp(160)) { + if (h > height) { float scale2 = h; - h = Utilities.dp(160); + h = height; scale2 /= h; w = (int)(w / scale2); - } else if (h < Utilities.dp(90)) { - h = Utilities.dp(90); + } else if (h < Utilities.dp(120)) { + h = Utilities.dp(120); float hScale = (float)photo.photoOwner.h / h; if (photo.photoOwner.w / hScale < width) { w = (int)(photo.photoOwner.w / hScale); @@ -3144,13 +3215,46 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa params.height = h; photoImage.setLayoutParams(params); + LinearLayout.LayoutParams params2 = (LinearLayout.LayoutParams)chatBubbleView.getLayoutParams(); + params2.width = w + Utilities.dp(12); + params2.height = h + Utilities.dp(12); + chatBubbleView.setLayoutParams(params2); + if (photo.image != null) { photoImage.setImageBitmap(photo.image); } else { - if (message.imagePreview != null) { - photoImage.setImage(photo.photoOwner.location, String.format(Locale.US, "%d_%d", (int)(w / Utilities.density), (int)(h / Utilities.density)), message.imagePreview); + if (type == 2 || type == 3) { + String fileName = MessageObject.getAttachFileName(photo.photoOwner); + File cacheFile = new File(Utilities.getCacheDir(), fileName); + if (!cacheFile.exists()) { + photoFileName = fileName; + photoFile = cacheFile; + } else { + photoFileName = null; + photoFile = null; + } + } + if (photoFileName == null) { + if (message.imagePreview != null) { + photoImage.setImage(photo.photoOwner.location, String.format(Locale.US, "%d_%d", (int)(w / Utilities.density), (int)(h / Utilities.density)), message.imagePreview); + } else { + photoImage.setImage(photo.photoOwner.location, String.format(Locale.US, "%d_%d", (int)(w / Utilities.density), (int)(h / Utilities.density)), message.messageOwner.out ? R.drawable.photo_placeholder_out : R.drawable.photo_placeholder_in); + } } else { - photoImage.setImage(photo.photoOwner.location, String.format(Locale.US, "%d_%d", (int)(w / Utilities.density), (int)(h / Utilities.density)), message.messageOwner.out ? R.drawable.photo_placeholder_out : R.drawable.photo_placeholder_in); + if (downloadPhotos) { + addToLoadingFile(photoFileName, actionProgress); + if (message.imagePreview != null) { + photoImage.setImage(photo.photoOwner.location, String.format(Locale.US, "%d_%d", (int)(w / Utilities.density), (int)(h / Utilities.density)), message.imagePreview, photo.photoOwner.size); + } else { + photoImage.setImage(photo.photoOwner.location, String.format(Locale.US, "%d_%d", (int)(w / Utilities.density), (int)(h / Utilities.density)), message.messageOwner.out ? R.drawable.photo_placeholder_out : R.drawable.photo_placeholder_in, photo.photoOwner.size); + } + photoObjectToSet = null; + photoFilter = null; + } else { + photoFilter = String.format(Locale.US, "%d_%d", (int)(w / Utilities.density), (int)(h / Utilities.density)); + photoObjectToSet = photo; + photoImage.setImageBitmap(message.imagePreview); + } } } } @@ -3203,7 +3307,7 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa } int placeHolderId = Utilities.getUserAvatarForId(contactUser.id); contactAvatar.setImage(photo, "50_50", placeHolderId); - if (contactUser.id != UserConfig.clientUserId && MessagesController.Instance.contactsDict.get(contactUser.id) == null) { + if (contactUser.id != UserConfig.clientUserId && ContactsController.Instance.contactsDict.get(contactUser.id) == null) { addContactView.setVisibility(View.VISIBLE); } else { addContactView.setVisibility(View.GONE); @@ -3289,8 +3393,13 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa halfCheckImage.setImageResource(R.drawable.msg_clock); } halfCheckImage.setVisibility(View.VISIBLE); - if (actionView != null) { - actionView.setVisibility(View.VISIBLE); + if (actionView != null || photoProgressView != null) { + if (actionView != null) { + actionView.setVisibility(View.VISIBLE); + } + if (photoProgressView != null) { + photoProgressView.setVisibility(View.VISIBLE); + } Float progress = FileLoader.Instance.fileProgresses.get(message.messageOwner.attachPath); if (progress != null) { actionProgress.setProgress((int)(progress * 100)); @@ -3312,6 +3421,9 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa if (actionView != null) { actionView.setVisibility(View.GONE); } + if (photoProgressView != null) { + photoProgressView.setVisibility(View.GONE); + } if (actionAttachButton != null) { actionAttachButton.setVisibility(View.GONE); } @@ -3336,13 +3448,16 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa if (actionView != null) { actionView.setVisibility(View.GONE); } + if (photoProgressView != null) { + photoProgressView.setVisibility(View.GONE); + } if (actionAttachButton != null) { actionAttachButton.setVisibility(View.VISIBLE); } } } } - if (message.type == 6 || message.type == 7 || message.type == 16 || message.type == 17) { + if (message.type == 2 || message.type == 3 || message.type == 6 || message.type == 7 || message.type == 16 || message.type == 17) { Integer tag = (Integer)actionProgress.getTag(); String file = progressByTag.get(tag); if (file != null) { @@ -3352,30 +3467,49 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa if (file != null) { progressBarMap.remove(file); } - String fileName = message.getFileName(); + String fileName = null; + if (photoFileName != null) { + fileName = photoFileName; + } else { + fileName = message.getFileName(); + } boolean load = false; - if (message.messageOwner.attachPath != null && message.messageOwner.attachPath.length() != 0) { + if (message.type != 2 && message.type != 3 && message.messageOwner.attachPath != null && message.messageOwner.attachPath.length() != 0) { File f = new File(message.messageOwner.attachPath); if (f.exists()) { - actionAttachButton.setVisibility(View.VISIBLE); - actionView.setVisibility(View.GONE); - if (message.type == 6 || message.type == 7) { - actionAttachButton.setText(getStringEntry(R.string.ViewVideo)); - } else if (message.type == 16 || message.type == 17) { - actionAttachButton.setText(getStringEntry(R.string.Open)); + if (actionAttachButton != null) { + actionAttachButton.setVisibility(View.VISIBLE); + if (message.type == 6 || message.type == 7) { + actionAttachButton.setText(getStringEntry(R.string.ViewVideo)); + } else if (message.type == 16 || message.type == 17) { + actionAttachButton.setText(getStringEntry(R.string.Open)); + } + } + if (actionView != null) { + actionView.setVisibility(View.GONE); + } + if (photoProgressView != null) { + photoProgressView.setVisibility(View.GONE); } } else { load = true; } } else { - File cacheFile = new File(Utilities.getCacheDir(), fileName); - if (cacheFile.exists()) { - actionAttachButton.setVisibility(View.VISIBLE); - actionView.setVisibility(View.GONE); - if (message.type == 6 || message.type == 7) { - actionAttachButton.setText(getStringEntry(R.string.ViewVideo)); - } else if (message.type == 16 || message.type == 17) { - actionAttachButton.setText(getStringEntry(R.string.Open)); + File cacheFile = null; + if (((message.type == 2 || message.type == 3) && photoFileName == null) || (cacheFile = new File(Utilities.getCacheDir(), fileName)).exists()) { + if (actionAttachButton != null) { + actionAttachButton.setVisibility(View.VISIBLE); + if (message.type == 6 || message.type == 7) { + actionAttachButton.setText(getStringEntry(R.string.ViewVideo)); + } else if (message.type == 16 || message.type == 17) { + actionAttachButton.setText(getStringEntry(R.string.Open)); + } + } + if (actionView != null) { + actionView.setVisibility(View.GONE); + } + if (photoProgressView != null) { + photoProgressView.setVisibility(View.GONE); } } else { load = true; @@ -3391,41 +3525,67 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa } progressByTag.put((Integer)actionProgress.getTag(), fileName); addToLoadingFile(fileName, actionProgress); - actionView.setVisibility(View.VISIBLE); - actionAttachButton.setVisibility(View.GONE); + if (actionView != null) { + if ((message.type == 2 || message.type == 3) && downloadPhotos) { + actionView.setVisibility(View.GONE); + } else { + actionView.setVisibility(View.VISIBLE); + if (photoFileName != null) { + actionCancelButton.setImageResource(R.drawable.photo_download_cancel_states); + } + } + } + if (photoProgressView != null) { + photoProgressView.setVisibility(View.VISIBLE); + } + if (actionAttachButton != null) { + actionAttachButton.setVisibility(View.GONE); + } } else { - actionView.setVisibility(View.GONE); - actionAttachButton.setVisibility(View.VISIBLE); - if (message.type == 6 || message.type == 7) { - actionAttachButton.setText(String.format("%s %.1f MB", getStringEntry(R.string.DOWNLOAD), message.messageOwner.media.video.size / 1024.0f / 1024.0f)); - } else if (message.type == 16 || message.type == 17) { - actionAttachButton.setText(getStringEntry(R.string.DOWNLOAD)); + if (actionView != null) { + if ((message.type == 2 || message.type == 3) && !downloadPhotos) { + actionView.setVisibility(View.VISIBLE); + actionCancelButton.setImageResource(R.drawable.photo_download_states); + } else { + actionView.setVisibility(View.GONE); + } + } + if (photoProgressView != null) { + photoProgressView.setVisibility(View.GONE); + } + if (actionAttachButton != null) { + actionAttachButton.setVisibility(View.VISIBLE); + if (message.type == 6 || message.type == 7) { + actionAttachButton.setText(String.format("%s %.1f MB", getStringEntry(R.string.DOWNLOAD), message.messageOwner.media.video.size / 1024.0f / 1024.0f)); + } else if (message.type == 16 || message.type == 17) { + actionAttachButton.setText(getStringEntry(R.string.DOWNLOAD)); + } } } } } - } - if (message.type == 16 || message.type == 17) { - int width; - if (currentChat != null && type != 16) { - if (actionView.getVisibility() == View.VISIBLE) { - width = displaySize.x - Utilities.dp(290); + if (message.type == 16 || message.type == 17) { + int width; + if (currentChat != null && type != 16) { + if (actionView.getVisibility() == View.VISIBLE) { + width = displaySize.x - Utilities.dp(290); + } else { + width = displaySize.x - Utilities.dp(270); + } } else { - width = displaySize.x - Utilities.dp(270); - } - } else { - if (actionView.getVisibility() == View.VISIBLE) { - width = displaySize.x - Utilities.dp(240); - } else { - width = displaySize.x - Utilities.dp(220); + if (actionView.getVisibility() == View.VISIBLE) { + width = displaySize.x - Utilities.dp(240); + } else { + width = displaySize.x - Utilities.dp(220); + } } + nameTextView.setMaxWidth(width); + phoneTextView.setMaxWidth(width); } - nameTextView.setMaxWidth(width); - phoneTextView.setMaxWidth(width); } } - public ChatListRowHolderEx(View view) { + public ChatListRowHolderEx(View view, int type) { avatarImageView = (BackupImageView)view.findViewById(R.id.chat_group_avatar_image); nameTextView = (TextView)view.findViewById(R.id.chat_user_group_name); messageLayout = (MessageLayout)view.findViewById(R.id.message_layout); @@ -3448,6 +3608,7 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa addContactButton = (ImageView)view.findViewById(R.id.add_contact_button); addContactView = view.findViewById(R.id.add_contact_view); chatBubbleView = view.findViewById(R.id.chat_bubble_layout); + photoProgressView = view.findViewById(R.id.photo_progress); if (messageTextView != null) { messageTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, fontSize); } @@ -3457,11 +3618,13 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa progressTag++; } - if (actionView != null) { - if (isCustomTheme) { - actionView.setBackgroundResource(R.drawable.system_black); - } else { - actionView.setBackgroundResource(R.drawable.system_blue); + if (type != 2 && type != 3) { + if (actionView != null) { + if (isCustomTheme) { + actionView.setBackgroundResource(R.drawable.system_black); + } else { + actionView.setBackgroundResource(R.drawable.system_blue); + } } } @@ -3581,6 +3744,22 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa } updateVisibleRows(); } + } else if (message.type == 2 || message.type == 3) { + if (photoFile != null && !photoFile.exists() && photoObjectToSet != null) { + if (loadingFile.containsKey(photoFileName)) { + loadingFile.remove(photoFileName); + FileLoader.Instance.cancelLoadingForImageView(photoImage); + updateVisibleRows(); + } else { + addToLoadingFile(photoFileName, actionProgress); + if (message.imagePreview != null) { + photoImage.setImage(photoObjectToSet.photoOwner.location, photoFilter, message.imagePreview, photoObjectToSet.photoOwner.size); + } else { + photoImage.setImage(photoObjectToSet.photoOwner.location, photoFilter, message.messageOwner.out ? R.drawable.photo_placeholder_out : R.drawable.photo_placeholder_in, photoObjectToSet.photoOwner.size); + } + updateVisibleRows(); + } + } } } } @@ -3621,6 +3800,26 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa } } + private void alertUserOpenError() { + AlertDialog.Builder builder = new AlertDialog.Builder(parentActivity); + builder.setTitle(R.string.AppName); + builder.setPositiveButton(R.string.OK, null); + if (message.type == 6 || message.type == 7) { + builder.setMessage(R.string.NoPlayerInstalled); + } else { + builder.setMessage(String.format(getStringEntry(R.string.NoHandleAppInstalled), message.messageOwner.media.document.mime_type)); + } + visibleDialog = builder.show(); + visibleDialog.setCanceledOnTouchOutside(true); + + visibleDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + visibleDialog = null; + } + }); + } + private void processOnClick(View view) { if (mActionMode != null) { processRowSelect(view); @@ -3635,9 +3834,19 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa LocationActivity fragment = new LocationActivity(); ((ApplicationActivity)parentActivity).presentFragment(fragment, "location_view", false); } else if (message.type == 2 || message.type == 3) { - NotificationCenter.Instance.addToMemCache(51, message); - Intent intent = new Intent(parentActivity, GalleryImageViewer.class); - startActivity(intent); + if (photoFile == null || photoObjectToSet == null || photoFile != null && photoFile.exists()) { + NotificationCenter.Instance.addToMemCache(51, message); + Intent intent = new Intent(parentActivity, GalleryImageViewer.class); + startActivity(intent); + } else { + addToLoadingFile(photoFileName, actionProgress); + if (message.imagePreview != null) { + photoImage.setImage(photoObjectToSet.photoOwner.location, photoFilter, message.imagePreview, photoObjectToSet.photoOwner.size); + } else { + photoImage.setImage(photoObjectToSet.photoOwner.location, photoFilter, message.messageOwner.out ? R.drawable.photo_placeholder_out : R.drawable.photo_placeholder_in, photoObjectToSet.photoOwner.size); + } + updateVisibleRows(); + } } else if (message.type == 11) { NotificationCenter.Instance.addToMemCache(51, message); Intent intent = new Intent(parentActivity, GalleryImageViewer.class); @@ -3651,6 +3860,7 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa f = new File(Utilities.getCacheDir(), fileName); } if (f != null && f.exists()) { + String realMimeType = null; try { Intent intent = new Intent(Intent.ACTION_VIEW); if (message.type == 6 || message.type == 7) { @@ -3660,9 +3870,9 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa int idx = fileName.lastIndexOf("."); if (idx != -1) { String ext = fileName.substring(idx + 1); - String mimeType = myMime.getMimeTypeFromExtension(ext.toLowerCase()); - if (mimeType != null) { - intent.setDataAndType(Uri.fromFile(f), mimeType); + realMimeType = myMime.getMimeTypeFromExtension(ext.toLowerCase()); + if (realMimeType != null) { + intent.setDataAndType(Uri.fromFile(f), realMimeType); } else { intent.setDataAndType(Uri.fromFile(f), "text/plain"); } @@ -3670,25 +3880,18 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa intent.setDataAndType(Uri.fromFile(f), "text/plain"); } } - startActivity(intent); - } catch (Exception e) { - AlertDialog.Builder builder = new AlertDialog.Builder(parentActivity); - builder.setTitle(R.string.AppName); - builder.setPositiveButton(R.string.OK, null); - if (message.type == 6 || message.type == 7) { - builder.setMessage(R.string.NoPlayerInstalled); - } else { - builder.setMessage(String.format(getStringEntry(R.string.NoHandleAppInstalled), message.messageOwner.media.document.mime_type)); - } - visibleDialog = builder.show(); - visibleDialog.setCanceledOnTouchOutside(true); - - visibleDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { - @Override - public void onDismiss(DialogInterface dialog) { - visibleDialog = null; + if (realMimeType != null) { + try { + startActivity(intent); + } catch (Exception e) { + intent.setDataAndType(Uri.fromFile(f), "text/plain"); + startActivity(intent); } - }); + } else { + startActivity(intent); + } + } catch (Exception e) { + alertUserOpenError(); } } else { if (message.messageOwner.send_state != MessagesController.MESSAGE_SEND_STATE_SEND_ERROR && message.messageOwner.send_state != MessagesController.MESSAGE_SEND_STATE_SENDING || !message.messageOwner.out) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatProfileActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatProfileActivity.java index 69c4ffc78..7932cae35 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatProfileActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatProfileActivity.java @@ -44,6 +44,7 @@ import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.R; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; +import org.telegram.ui.Cells.ChatOrUserCell; import org.telegram.ui.Views.AvatarUpdater; import org.telegram.ui.Views.BackupImageView; import org.telegram.ui.Views.BaseFragment; @@ -239,8 +240,8 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen } @Override - public void didSelectContact(int user_id) { - MessagesController.Instance.addUserToChat(chat_id, user_id, info); + public void didSelectContact(TLRPC.User user) { + MessagesController.Instance.addUserToChat(chat_id, user, info); } @Override @@ -277,9 +278,12 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen public void didReceivedNotification(int id, Object... args) { if (id == MessagesController.updateInterfaces) { - updateOnlineCount(); - if (listView != null) { - listView.invalidateViews(); + int mask = (Integer)args[0]; + if ((mask & MessagesController.UPDATE_MASK_CHAT_AVATAR) != 0 || (mask & MessagesController.UPDATE_MASK_CHAT_NAME) != 0 || (mask & MessagesController.UPDATE_MASK_CHAT_MEMBERS) != 0) { + updateOnlineCount(); + } + if ((mask & MessagesController.UPDATE_MASK_AVATAR) != 0 || (mask & MessagesController.UPDATE_MASK_NAME) != 0 || (mask & MessagesController.UPDATE_MASK_STATUS) != 0) { + updateVisibleRows(mask); } } else if (id == MessagesController.chatInfoDidLoaded) { int chatId = (Integer)args[0]; @@ -355,6 +359,19 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen return true; } + private void updateVisibleRows(int mask) { + if (listView == null) { + return; + } + int count = listView.getChildCount(); + for (int a = 0; a < count; a++) { + View child = listView.getChildAt(a); + if (child instanceof ChatOrUserCell) { + ((ChatOrUserCell) child).update(mask); + } + } + } + private void updateOnlineCount() { if (info == null) { return; @@ -451,11 +468,11 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen private void kickUser(TLRPC.TL_chatParticipant user) { if (user != null) { - MessagesController.Instance.deleteUserFromChat(chat_id, user.user_id, info); + MessagesController.Instance.deleteUserFromChat(chat_id, MessagesController.Instance.users.get(user.user_id), info); } else { NotificationCenter.Instance.removeObserver(this, MessagesController.closeChats); NotificationCenter.Instance.postNotificationName(MessagesController.closeChats); - MessagesController.Instance.deleteUserFromChat(chat_id, UserConfig.clientUserId, info); + MessagesController.Instance.deleteUserFromChat(chat_id, MessagesController.Instance.users.get(UserConfig.clientUserId), info); MessagesController.Instance.deleteDialog(-chat_id, 0, false); finishFragment(); } @@ -674,60 +691,19 @@ public class ChatProfileActivity extends BaseFragment implements NotificationCen TLRPC.User user = MessagesController.Instance.users.get(part.user_id); if (view == null) { - LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - view = li.inflate(R.layout.messages_search_user_layout, viewGroup, false); - } - ContactsActivity.ContactListRowHolder holder = (ContactsActivity.ContactListRowHolder)view.getTag(); - if (holder == null) { - holder = new ContactsActivity.ContactListRowHolder(view); - view.setTag(holder); + view = new ChatOrUserCell(mContext); + ((ChatOrUserCell)view).useBoldFont = true; + ((ChatOrUserCell)view).usePadding = false; + ((ChatOrUserCell)view).useSeparator = true; } - View divider = view.findViewById(R.id.settings_row_divider); - divider.setVisibility(View.VISIBLE); - - if (user.first_name.length() != 0 && user.last_name.length() != 0) { - holder.nameTextView.setText(Html.fromHtml(user.first_name + " " + user.last_name + "")); - } else if (user.first_name.length() != 0) { - holder.nameTextView.setText(Html.fromHtml("" + user.first_name + "")); - } else { - holder.nameTextView.setText(Html.fromHtml("" + user.last_name + "")); - } + ((ChatOrUserCell)view).setData(user, null, null, null, null); // if (info.admin_id != UserConfig.clientUserId && part.inviter_id != UserConfig.clientUserId && part.user_id != UserConfig.clientUserId) { // // } else { // // } - - TLRPC.FileLocation photo = null; - if (user.photo != null) { - photo = user.photo.photo_small; - } - int placeHolderId = Utilities.getUserAvatarForId(user.id); - holder.avatarImage.setImage(photo, "50_50", placeHolderId); - - if (user.status == null) { - holder.messageTextView.setTextColor(0xff808080); - holder.messageTextView.setText(getStringEntry(R.string.Offline)); - } else { - int currentTime = ConnectionsManager.Instance.getCurrentTime(); - if ((user.status.expires > currentTime || user.status.was_online > currentTime || user.id == UserConfig.clientUserId) && user.status.expires != 0) { - holder.messageTextView.setTextColor(0xff357aa8); - holder.messageTextView.setText(getStringEntry(R.string.Online)); - } else { - if (user.status.was_online <= 10000 && user.status.expires <= 10000) { - holder.messageTextView.setText(getStringEntry(R.string.Invisible)); - } else { - int value = user.status.was_online; - if (value == 0) { - value = user.status.expires; - } - holder.messageTextView.setText(String.format("%s %s", getStringEntry(R.string.LastSeen), Utilities.formatDateOnline(value))); - } - holder.messageTextView.setTextColor(0xff808080); - } - } } else if (type == 5) { if (view == null) { LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ChatProfileChangeNameActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ChatProfileChangeNameActivity.java index 1c5318353..abc024dd5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ChatProfileChangeNameActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ChatProfileChangeNameActivity.java @@ -131,7 +131,7 @@ public class ChatProfileChangeNameActivity extends BaseFragment { } ((ApplicationActivity)parentActivity).updateActionBar(); - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); boolean animations = preferences.getBoolean("view_animations", true); if (!animations) { firstNameField.requestFocus(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ContactAddActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ContactAddActivity.java index fee48d293..64e628dc6 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ContactAddActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ContactAddActivity.java @@ -26,6 +26,7 @@ import android.widget.TextView; import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.TL.TLRPC; import org.telegram.messenger.ConnectionsManager; +import org.telegram.messenger.ContactsController; import org.telegram.messenger.MessagesController; import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.R; @@ -49,7 +50,8 @@ public class ContactAddActivity extends BaseFragment implements NotificationCent NotificationCenter.Instance.addObserver(this, MessagesController.updateInterfaces); user_id = getArguments().getInt("user_id", 0); phone = getArguments().getString("phone"); - return true; + TLRPC.User user = MessagesController.Instance.users.get(user_id); + return user != null; } @Override @@ -64,8 +66,10 @@ public class ContactAddActivity extends BaseFragment implements NotificationCent fragmentView = inflater.inflate(R.layout.contact_add_layout, container, false); TLRPC.User user = MessagesController.Instance.users.get(user_id); - if (phone != null) { - user.phone = PhoneFormat.stripExceptNumbers(phone); + if (user.phone == null) { + if (phone != null) { + user.phone = PhoneFormat.stripExceptNumbers(phone); + } } onlineText = (TextView)fragmentView.findViewById(R.id.settings_online); @@ -137,7 +141,7 @@ public class ContactAddActivity extends BaseFragment implements NotificationCent if (value == 0) { value = user.status.expires; } - onlineText.setText(String.format("%s %s", getStringEntry(R.string.LastSeen), Utilities.formatDateOnline(value))); + onlineText.setText(Utilities.formatDateOnline(value)); } } } @@ -151,7 +155,10 @@ public class ContactAddActivity extends BaseFragment implements NotificationCent public void didReceivedNotification(int id, Object... args) { if (id == MessagesController.updateInterfaces) { - updateAvatarLayout(); + int mask = (Integer)args[0]; + if ((mask & MessagesController.UPDATE_MASK_AVATAR) != 0 || (mask & MessagesController.UPDATE_MASK_STATUS) != 0) { + updateAvatarLayout(); + } } } @@ -197,8 +204,9 @@ public class ContactAddActivity extends BaseFragment implements NotificationCent TLRPC.User user = MessagesController.Instance.users.get(user_id); user.first_name = firstNameField.getText().toString(); user.last_name = lastNameField.getText().toString(); - MessagesController.Instance.addContact(user); + ContactsController.Instance.addContact(user); finishFragment(); + NotificationCenter.Instance.postNotificationName(MessagesController.updateInterfaces, MessagesController.UPDATE_MASK_NAME); } } }); @@ -212,7 +220,7 @@ public class ContactAddActivity extends BaseFragment implements NotificationCent } ((ApplicationActivity)parentActivity).updateActionBar(); - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); boolean animations = preferences.getBoolean("view_animations", true); if (!animations) { firstNameField.requestFocus(); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java index be815a202..7d9742281 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/ContactsActivity.java @@ -30,16 +30,15 @@ import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; -import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.TL.TLRPC; -import org.telegram.messenger.ConnectionsManager; +import org.telegram.messenger.ContactsController; import org.telegram.messenger.FileLog; import org.telegram.messenger.MessagesController; import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.R; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; -import org.telegram.ui.Views.BackupImageView; +import org.telegram.ui.Cells.ChatOrUserCell; import org.telegram.ui.Views.BaseFragment; import org.telegram.ui.Views.OnSwipeTouchListener; import org.telegram.ui.Views.PinnedHeaderListView; @@ -49,7 +48,6 @@ import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; -import java.util.Locale; import java.util.Timer; import java.util.TimerTask; @@ -70,7 +68,6 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter private TextView epmtyTextView; private HashMap ignoreUsers; private SupportMenuItem searchItem; - private boolean isRTL; private Timer searchDialogsTimer; public ArrayList searchResult; @@ -78,14 +75,13 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter public ContactsActivityDelegate delegate; public static interface ContactsActivityDelegate { - public abstract void didSelectContact(int user_id); + public abstract void didSelectContact(TLRPC.User user); } @SuppressWarnings("unchecked") @Override public boolean onFragmentCreate() { super.onFragmentCreate(); - NotificationCenter.Instance.addObserver(this, MessagesController.contactsBookDidLoaded); NotificationCenter.Instance.addObserver(this, MessagesController.contactsDidLoaded); NotificationCenter.Instance.addObserver(this, MessagesController.updateInterfaces); NotificationCenter.Instance.addObserver(this, MessagesController.encryptedChatCreated); @@ -105,7 +101,6 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter @Override public void onFragmentDestroy() { super.onFragmentDestroy(); - NotificationCenter.Instance.removeObserver(this, MessagesController.contactsBookDidLoaded); NotificationCenter.Instance.removeObserver(this, MessagesController.contactsDidLoaded); NotificationCenter.Instance.removeObserver(this, MessagesController.updateInterfaces); NotificationCenter.Instance.removeObserver(this, MessagesController.encryptedChatCreated); @@ -132,10 +127,6 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (fragmentView == null) { - Locale locale = Locale.getDefault(); - String lang = locale.getLanguage(); - isRTL = lang != null && lang.toLowerCase().equals("ar"); - fragmentView = inflater.inflate(R.layout.contacts_layout, container, false); epmtyTextView = (TextView)fragmentView.findViewById(R.id.searchEmptyView); @@ -150,23 +141,23 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter @Override public void onItemClick(AdapterView adapterView, View view, int i, long l) { if (searching && searchWas) { - int user_id = searchResult.get(i).id; - if (user_id == UserConfig.clientUserId) { + TLRPC.User user = searchResult.get(i); + if (user.id == UserConfig.clientUserId) { return; } if (returnAsResult) { - if (ignoreUsers != null && ignoreUsers.containsKey(user_id)) { + if (ignoreUsers != null && ignoreUsers.containsKey(user.id)) { return; } - didSelectResult(user_id, true); + didSelectResult(user, true); } else { if (createSecretChat) { creatingChat = true; - MessagesController.Instance.startSecretChat(parentActivity, user_id); + MessagesController.Instance.startSecretChat(parentActivity, user); } else { ChatActivity fragment = new ChatActivity(); Bundle bundle = new Bundle(); - bundle.putInt("user_id", user_id); + bundle.putInt("user_id", user.id); fragment.setArguments(bundle); ((ApplicationActivity)parentActivity).presentFragment(fragment, "chat" + Math.random(), destroyAfterSelect, false); } @@ -174,11 +165,14 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter } else { int section = listViewAdapter.getSectionForPosition(i); int row = listViewAdapter.getPositionInSectionForPosition(i); - int uid = 0; + TLRPC.User user = null; if (usersAsSections) { - if (section < MessagesController.Instance.sortedUsersSectionsArray.size()) { - ArrayList arr = MessagesController.Instance.usersSectionsDict.get(MessagesController.Instance.sortedUsersSectionsArray.get(section)); - uid = arr.get(row).user_id; + if (section < ContactsController.Instance.sortedUsersSectionsArray.size()) { + ArrayList arr = ContactsController.Instance.usersSectionsDict.get(ContactsController.Instance.sortedUsersSectionsArray.get(section)); + if (row >= arr.size()) { + return; + } + user = MessagesController.Instance.users.get(arr.get(row).user_id); } } else { if (section == 0) { @@ -193,8 +187,8 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter } return; } else { - if (row - 1 < MessagesController.Instance.contacts.size()) { - uid = MessagesController.Instance.contacts.get(row - 1).user_id; + if (row - 1 < ContactsController.Instance.contacts.size()) { + user = MessagesController.Instance.users.get(ContactsController.Instance.contacts.get(row - 1).user_id); } else { return; } @@ -202,53 +196,36 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter } } - if (uid != 0) { - if (uid == UserConfig.clientUserId) { + if (user != null) { + if (user.id == UserConfig.clientUserId) { return; } if (returnAsResult) { - if (ignoreUsers != null && ignoreUsers.containsKey(uid)) { + if (ignoreUsers != null && ignoreUsers.containsKey(user.id)) { return; } - didSelectResult(uid, true); + didSelectResult(user, true); } else { if (createSecretChat) { creatingChat = true; - MessagesController.Instance.startSecretChat(parentActivity, uid); + MessagesController.Instance.startSecretChat(parentActivity, user); } else { ChatActivity fragment = new ChatActivity(); Bundle bundle = new Bundle(); - bundle.putInt("user_id", uid); + bundle.putInt("user_id", user.id); fragment.setArguments(bundle); ((ApplicationActivity)parentActivity).presentFragment(fragment, "chat" + Math.random(), destroyAfterSelect, false); } } } else { - ArrayList arr = MessagesController.Instance.contactsSectionsDict.get(MessagesController.Instance.sortedContactsSectionsArray.get(section - 1)); - MessagesController.Contact contact = arr.get(row); + ArrayList arr = ContactsController.Instance.contactsSectionsDict.get(ContactsController.Instance.sortedContactsSectionsArray.get(section - 1)); + ContactsController.Contact contact = arr.get(row); String usePhone = null; - for (String phone : contact.phones) { - if (usePhone == null) { - usePhone = phone; - } - String cleanPhone = PhoneFormat.stripExceptNumbers(usePhone); - TLRPC.TL_contact cLocal = MessagesController.Instance.contactsByPhones.get(cleanPhone); - if (cLocal != null) { - if (cLocal.user_id == UserConfig.clientUserId) { - return; - } - if (createSecretChat) { - creatingChat = true; - MessagesController.Instance.startSecretChat(parentActivity, cLocal.user_id); - } else { - ChatActivity fragment = new ChatActivity(); - Bundle bundle = new Bundle(); - bundle.putInt("user_id", cLocal.user_id); - fragment.setArguments(bundle); - ((ApplicationActivity)parentActivity).presentFragment(fragment, "chat" + Math.random(), destroyAfterSelect, false); - } - return; - } + if (!contact.phones.isEmpty()) { + usePhone = contact.phones.get(0); + } + if (usePhone == null) { + return; } AlertDialog.Builder builder = new AlertDialog.Builder(parentActivity); builder.setMessage(getStringEntry(R.string.InviteUser)); @@ -302,23 +279,22 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter return fragmentView; } - private void didSelectResult(final int user_id, boolean useAlert) { + private void didSelectResult(final TLRPC.User user, boolean useAlert) { if (useAlert && selectAlertString != 0) { AlertDialog.Builder builder = new AlertDialog.Builder(parentActivity); builder.setTitle(R.string.AppName); - TLRPC.User user = MessagesController.Instance.users.get(user_id); builder.setMessage(String.format(getStringEntry(selectAlertString), Utilities.formatName(user.first_name, user.last_name))); builder.setPositiveButton(R.string.OK, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { - didSelectResult(user_id, false); + didSelectResult(user, false); } }); builder.setNegativeButton(R.string.Cancel, null); builder.show().setCanceledOnTouchOutside(true); } else { if (delegate != null) { - delegate.didSelectContact(user_id); + delegate.didSelectContact(user); delegate = null; } finishFragment(); @@ -422,7 +398,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter ArrayList resultArray = new ArrayList(); ArrayList resultArrayNames = new ArrayList(); - for (TLRPC.TL_contact contact : MessagesController.Instance.contacts) { + for (TLRPC.TL_contact contact : ContactsController.Instance.contacts) { TLRPC.User user = MessagesController.Instance.users.get(contact.user_id); if (user.first_name != null && user.first_name.toLowerCase().startsWith(q) || user.last_name != null && user.last_name.toLowerCase().startsWith(q)) { if (user.id == UserConfig.clientUserId) { @@ -537,7 +513,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter searchWas = false; ViewGroup group = (ViewGroup) listView.getParent(); listView.setAdapter(listViewAdapter); - if (!isRTL) { + if (!Utilities.isRTL) { listView.setPadding(Utilities.dp(16), listView.getPaddingTop(), Utilities.dp(30), listView.getPaddingBottom()); } else { listView.setPadding(Utilities.dp(30), listView.getPaddingTop(), Utilities.dp(16), listView.getPaddingBottom()); @@ -557,13 +533,14 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter @Override public void didReceivedNotification(int id, Object... args) { - if (id == MessagesController.contactsDidLoaded || id == MessagesController.contactsBookDidLoaded) { + if (id == MessagesController.contactsDidLoaded) { if (listViewAdapter != null) { listViewAdapter.notifyDataSetChanged(); } } else if (id == MessagesController.updateInterfaces) { - if (listView != null) { - listView.invalidateViews(); + int mask = (Integer)args[0]; + if ((mask & MessagesController.UPDATE_MASK_AVATAR) != 0 || (mask & MessagesController.UPDATE_MASK_NAME) != 0 || (mask & MessagesController.UPDATE_MASK_STATUS) != 0) { + updateVisibleRows(mask); } } else if (id == MessagesController.encryptedChatCreated) { if (createSecretChat && creatingChat) { @@ -577,6 +554,19 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter } } + private void updateVisibleRows(int mask) { + if (listView == null) { + return; + } + int count = listView.getChildCount(); + for (int a = 0; a < count; a++) { + View child = listView.getChildAt(a); + if (child instanceof ChatOrUserCell) { + ((ChatOrUserCell) child).update(mask); + } + } + } + private class SearchAdapter extends BaseAdapter { private Context mContext; @@ -619,76 +609,24 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter @Override public View getView(int i, View view, ViewGroup viewGroup) { - int type = getItemViewType(i); if (view == null) { - LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - if (type == 0) { - view = li.inflate(R.layout.messages_search_user_layout, viewGroup, false); - } else { - view = li.inflate(R.layout.messages_search_chat_layout, viewGroup, false); - } - } - ContactListRowHolder holder = (ContactListRowHolder)view.getTag(); - if (holder == null) { - holder = new ContactListRowHolder(view); - view.setTag(holder); - } - View divider = view.findViewById(R.id.settings_row_divider); - if (i == searchResult.size() - 1) { - divider.setVisibility(View.INVISIBLE); - } else { - divider.setVisibility(View.VISIBLE); + view = new ChatOrUserCell(mContext); + ((ChatOrUserCell)view).usePadding = false; } + ((ChatOrUserCell) view).useSeparator = i != searchResult.size() - 1; + Object obj = searchResult.get(i); - CharSequence name = searchResultNames.get(i); - TLRPC.User user = MessagesController.Instance.users.get(((TLRPC.User)obj).id); - holder.nameTextView.setText(name); - if (user != null) { + ((ChatOrUserCell)view).setData(user, null, null, searchResultNames.get(i), null); + if (ignoreUsers != null) { if (ignoreUsers.containsKey(user.id)) { - if(android.os.Build.VERSION.SDK_INT >= 11) { - holder.avatarImage.setAlpha(0.5f); - holder.messageTextView.setAlpha(0.5f); - holder.nameTextView.setAlpha(0.5f); - } + ((ChatOrUserCell)view).drawAlpha = 0.5f; } else { - if(android.os.Build.VERSION.SDK_INT >= 11) { - holder.avatarImage.setAlpha(1.0f); - holder.messageTextView.setAlpha(1.0f); - holder.nameTextView.setAlpha(1.0f); - } - } - } - TLRPC.FileLocation photo = null; - if (user.photo != null) { - photo = user.photo.photo_small; - } - int placeHolderId = Utilities.getUserAvatarForId(user.id); - holder.avatarImage.setImage(photo, "50_50", placeHolderId); - - if (user.status == null) { - holder.messageTextView.setTextColor(0xff808080); - holder.messageTextView.setText(getStringEntry(R.string.Offline)); - } else { - int currentTime = ConnectionsManager.Instance.getCurrentTime(); - if (user.status.expires > currentTime || user.status.was_online > currentTime) { - holder.messageTextView.setTextColor(0xff357aa8); - holder.messageTextView.setText(getStringEntry(R.string.Online)); - } else { - if (user.status.was_online <= 10000 && user.status.expires <= 10000) { - holder.messageTextView.setText(getStringEntry(R.string.Invisible)); - } else { - int value = user.status.was_online; - if (value == 0) { - value = user.status.expires; - } - holder.messageTextView.setText(getStringEntry(R.string.LastSeen) + " " + Utilities.formatDateOnline(value)); - } - holder.messageTextView.setTextColor(0xff808080); + ((ChatOrUserCell)view).drawAlpha = 1.0f; } } } @@ -697,17 +635,12 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter @Override public int getItemViewType(int i) { - Object obj = searchResult.get(i); - if (obj instanceof TLRPC.User) { - return 0; - } else { - return 1; - } + return 0; } @Override public int getViewTypeCount() { - return 2; + return 1; } @Override @@ -737,12 +670,12 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter public int getSectionCount() { int count = 0; if (usersAsSections) { - count += MessagesController.Instance.sortedUsersSectionsArray.size(); + count += ContactsController.Instance.sortedUsersSectionsArray.size(); } else { count++; } if (!onlyUsers) { - count += MessagesController.Instance.sortedContactsSectionsArray.size(); + count += ContactsController.Instance.sortedContactsSectionsArray.size(); } return count; } @@ -750,16 +683,16 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter @Override public int getCountForSection(int section) { if (usersAsSections) { - if (section < MessagesController.Instance.sortedUsersSectionsArray.size()) { - ArrayList arr = MessagesController.Instance.usersSectionsDict.get(MessagesController.Instance.sortedUsersSectionsArray.get(section)); + if (section < ContactsController.Instance.sortedUsersSectionsArray.size()) { + ArrayList arr = ContactsController.Instance.usersSectionsDict.get(ContactsController.Instance.sortedUsersSectionsArray.get(section)); return arr.size(); } } else { if (section == 0) { - return MessagesController.Instance.contacts.size() + 1; + return ContactsController.Instance.contacts.size() + 1; } } - ArrayList arr = MessagesController.Instance.contactsSectionsDict.get(MessagesController.Instance.sortedContactsSectionsArray.get(section - 1)); + ArrayList arr = ContactsController.Instance.contactsSectionsDict.get(ContactsController.Instance.sortedContactsSectionsArray.get(section - 1)); return arr.size(); } @@ -769,8 +702,8 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter TLRPC.User user = null; int count = 0; if (usersAsSections) { - if (section < MessagesController.Instance.sortedUsersSectionsArray.size()) { - ArrayList arr = MessagesController.Instance.usersSectionsDict.get(MessagesController.Instance.sortedUsersSectionsArray.get(section)); + if (section < ContactsController.Instance.sortedUsersSectionsArray.size()) { + ArrayList arr = ContactsController.Instance.usersSectionsDict.get(ContactsController.Instance.sortedUsersSectionsArray.get(section)); user = MessagesController.Instance.users.get(arr.get(position).user_id); count = arr.size(); } @@ -782,86 +715,36 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter convertView = li.inflate(R.layout.contacts_invite_row_layout, parent, false); } View divider = convertView.findViewById(R.id.settings_row_divider); - if (MessagesController.Instance.contacts.isEmpty()) { + if (ContactsController.Instance.contacts.isEmpty()) { divider.setVisibility(View.INVISIBLE); } else { divider.setVisibility(View.VISIBLE); } return convertView; } - user = MessagesController.Instance.users.get(MessagesController.Instance.contacts.get(position - 1).user_id); - count = MessagesController.Instance.contacts.size(); + user = MessagesController.Instance.users.get(ContactsController.Instance.contacts.get(position - 1).user_id); + count = ContactsController.Instance.contacts.size(); } } if (user != null) { if (convertView == null) { - LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - convertView = li.inflate(R.layout.messages_search_user_layout, parent, false); - } - ContactListRowHolder holder = (ContactListRowHolder)convertView.getTag(); - if (holder == null) { - holder = new ContactListRowHolder(convertView); - convertView.setTag(holder); + convertView = new ChatOrUserCell(mContext); + ((ChatOrUserCell)convertView).useBoldFont = true; + ((ChatOrUserCell)convertView).usePadding = false; } + ((ChatOrUserCell)convertView).setData(user, null, null, null, null); + if (ignoreUsers != null) { if (ignoreUsers.containsKey(user.id)) { - if(android.os.Build.VERSION.SDK_INT >= 11) { - holder.avatarImage.setAlpha(0.5f); - holder.messageTextView.setAlpha(0.5f); - holder.nameTextView.setAlpha(0.5f); - } + ((ChatOrUserCell)convertView).drawAlpha = 0.5f; } else { - if(android.os.Build.VERSION.SDK_INT >= 11) { - holder.avatarImage.setAlpha(1.0f); - holder.messageTextView.setAlpha(1.0f); - holder.nameTextView.setAlpha(1.0f); - } + ((ChatOrUserCell)convertView).drawAlpha = 1.0f; } } - View divider = convertView.findViewById(R.id.settings_row_divider); - if (position == count - 1) { - divider.setVisibility(View.INVISIBLE); - } else { - divider.setVisibility(View.VISIBLE); - } + ((ChatOrUserCell) convertView).useSeparator = position != count - 1; - TLRPC.FileLocation photo = null; - if (user.first_name.length() != 0 && user.last_name.length() != 0) { - holder.nameTextView.setText(Html.fromHtml(user.first_name + " " + user.last_name + "")); - } else if (user.first_name.length() != 0) { - holder.nameTextView.setText(Html.fromHtml("" + user.first_name + "")); - } else { - holder.nameTextView.setText(Html.fromHtml("" + user.last_name + "")); - } - if (user.photo != null) { - photo = user.photo.photo_small; - } - int placeHolderId = Utilities.getUserAvatarForId(user.id); - holder.avatarImage.setImage(photo, "50_50", placeHolderId); - - if (user.status == null) { - holder.messageTextView.setText(getStringEntry(R.string.Offline)); - holder.messageTextView.setTextColor(0xff808080); - } else { - int currentTime = ConnectionsManager.Instance.getCurrentTime(); - if (user.status.expires > currentTime || user.status.was_online > currentTime) { - holder.messageTextView.setTextColor(0xff357aa8); - holder.messageTextView.setText(getStringEntry(R.string.Online)); - } else { - if (user.status.was_online <= 10000 && user.status.expires <= 10000) { - holder.messageTextView.setText(getStringEntry(R.string.Invisible)); - } else { - int value = user.status.was_online; - if (value == 0) { - value = user.status.expires; - } - holder.messageTextView.setText(getStringEntry(R.string.LastSeen) + " " + Utilities.formatDateOnline(value)); - } - holder.messageTextView.setTextColor(0xff808080); - } - } return convertView; } @@ -873,13 +756,16 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter } else { textView = (TextView)convertView.findViewById(R.id.settings_row_text); } + View divider = convertView.findViewById(R.id.settings_row_divider); - ArrayList arr = MessagesController.Instance.contactsSectionsDict.get(MessagesController.Instance.sortedContactsSectionsArray.get(section - 1)); - MessagesController.Contact contact = arr.get(position); - if (position == arr.size() - 1) { - divider.setVisibility(View.INVISIBLE); - } else { - divider.setVisibility(View.VISIBLE); + ArrayList arr = ContactsController.Instance.contactsSectionsDict.get(ContactsController.Instance.sortedContactsSectionsArray.get(section - 1)); + ContactsController.Contact contact = arr.get(position); + if (divider != null) { + if (position == arr.size() - 1) { + divider.setVisibility(View.INVISIBLE); + } else { + divider.setVisibility(View.VISIBLE); + } } if (contact.first_name != null && contact.last_name != null) { textView.setText(Html.fromHtml(contact.first_name + " " + contact.last_name + "")); @@ -894,7 +780,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter @Override public int getItemViewType(int section, int position) { if (usersAsSections) { - if (section < MessagesController.Instance.sortedUsersSectionsArray.size()) { + if (section < ContactsController.Instance.sortedUsersSectionsArray.size()) { return 0; } } else if (section == 0) { @@ -914,7 +800,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter @Override public int getSectionHeaderViewType(int section) { if (usersAsSections) { - if (section < MessagesController.Instance.sortedUsersSectionsArray.size()) { + if (section < ContactsController.Instance.sortedUsersSectionsArray.size()) { return 1; } } else if (section == 0) { @@ -931,14 +817,14 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter @Override public View getSectionHeaderView(int section, View convertView, ViewGroup parent) { if (usersAsSections) { - if (section < MessagesController.Instance.sortedUsersSectionsArray.size()) { + if (section < ContactsController.Instance.sortedUsersSectionsArray.size()) { if (convertView == null) { LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = li.inflate(R.layout.settings_section_layout, parent, false); convertView.setBackgroundColor(0xffffffff); } TextView textView = (TextView)convertView.findViewById(R.id.settings_section_text); - textView.setText(MessagesController.Instance.sortedUsersSectionsArray.get(section)); + textView.setText(ContactsController.Instance.sortedUsersSectionsArray.get(section)); return convertView; } } else { @@ -957,20 +843,8 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter convertView.setBackgroundColor(0xffffffff); } TextView textView = (TextView)convertView.findViewById(R.id.settings_section_text); - textView.setText(MessagesController.Instance.sortedContactsSectionsArray.get(section - 1)); + textView.setText(ContactsController.Instance.sortedContactsSectionsArray.get(section - 1)); return convertView; } } - - public static class ContactListRowHolder { - public BackupImageView avatarImage; - public TextView messageTextView; - public TextView nameTextView; - - public ContactListRowHolder(View view) { - messageTextView = (TextView)view.findViewById(R.id.messages_list_row_message); - nameTextView = (TextView)view.findViewById(R.id.messages_list_row_name); - avatarImage = (BackupImageView)view.findViewById(R.id.messages_list_row_avatar); - } - } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java index 2229a75c3..9a8b78fdf 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/CountrySelectActivity.java @@ -41,7 +41,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; -import java.util.Locale; import java.util.Timer; import java.util.TimerTask; @@ -54,7 +53,6 @@ public class CountrySelectActivity extends ActionBarActivity { private boolean searching; private BaseAdapter searchListViewAdapter; private TextView epmtyTextView; - private boolean isRTL; private HashMap> countries = new HashMap>(); private ArrayList sortedCountries = new ArrayList(); @@ -71,10 +69,6 @@ public class CountrySelectActivity extends ActionBarActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - Locale locale = Locale.getDefault(); - String lang = locale.getLanguage(); - isRTL = lang != null && lang.toLowerCase().equals("ar"); - try { BufferedReader reader = new BufferedReader(new InputStreamReader(getResources().getAssets().open("countries.txt"))); String line; @@ -260,7 +254,7 @@ public class CountrySelectActivity extends ActionBarActivity { searchWas = false; ViewGroup group = (ViewGroup) listView.getParent(); listView.setAdapter(listViewAdapter); - if (!isRTL) { + if (!Utilities.isRTL) { listView.setPadding(Utilities.dp(16), listView.getPaddingTop(), Utilities.dp(30), listView.getPaddingBottom()); } else { listView.setPadding(Utilities.dp(30), listView.getPaddingTop(), Utilities.dp(16), listView.getPaddingBottom()); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/DocumentSelectActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/DocumentSelectActivity.java index 5d9937219..4877e3da1 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/DocumentSelectActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/DocumentSelectActivity.java @@ -102,8 +102,12 @@ public class DocumentSelectActivity extends BaseFragment { @Override public void onFragmentDestroy() { - if (receiverRegistered) { - parentActivity.unregisterReceiver(receiver); + try { + if (receiverRegistered) { + parentActivity.unregisterReceiver(receiver); + } + } catch (Exception e) { + FileLog.e("tmessages", e); } super.onFragmentDestroy(); } @@ -376,13 +380,17 @@ public class DocumentSelectActivity extends BaseFragment { if (extDevice != null) { result.removeAll(aliases.get(extDevice)); for (String path : result) { - boolean isSd = path.toLowerCase().contains("sd"); - ListItem item = new ListItem(); - item.title = getString(isSd ? R.string.SdCard : R.string.ExternalStorage); - item.icon = R.drawable.ic_external_storage; - item.subtitle = getRootSubtitle(path); - item.file = new File(path); - items.add(item); + try { + boolean isSd = path.toLowerCase().contains("sd"); + ListItem item = new ListItem(); + item.title = getString(isSd ? R.string.SdCard : R.string.ExternalStorage); + item.icon = R.drawable.ic_external_storage; + item.subtitle = getRootSubtitle(path); + item.file = new File(path); + items.add(item); + } catch (Exception e) { + FileLog.e("tmessages", e); + } } } } catch (Exception e) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/GalleryImageViewer.java b/TMessagesProj/src/main/java/org/telegram/ui/GalleryImageViewer.java index 06c55e940..14e1f65b0 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/GalleryImageViewer.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/GalleryImageViewer.java @@ -9,12 +9,14 @@ package org.telegram.ui; import android.content.Intent; +import android.graphics.Point; import android.net.Uri; import android.os.Bundle; import android.os.Parcelable; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.support.v7.app.ActionBar; +import android.view.Display; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@ -64,6 +66,7 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif private ProgressBar loadingProgress; private String currentFileName; private int user_id = 0; + private Point displaySize = new Point(); private ArrayList imagesArrTemp = new ArrayList(); private HashMap imagesByIdsTemp = new HashMap(); @@ -80,6 +83,14 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + + Display display = getWindowManager().getDefaultDisplay(); + if(android.os.Build.VERSION.SDK_INT < 13) { + displaySize.set(display.getWidth(), display.getHeight()); + } else { + display.getSize(displaySize); + } + classGuid = ConnectionsManager.Instance.generateClassGuid(); setContentView(R.layout.gallery_layout); @@ -112,6 +123,7 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif NotificationCenter.Instance.addObserver(this, MessagesController.mediaCountDidLoaded); NotificationCenter.Instance.addObserver(this, MessagesController.mediaDidLoaded); NotificationCenter.Instance.addObserver(this, MessagesController.userPhotosLoaded); + NotificationCenter.Instance.addObserver(this, 658); Integer index = null; if (localPagerAdapter == null) { @@ -212,6 +224,9 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif deleteButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { + if (mViewPager == null) { + return; + } int item = mViewPager.getCurrentItem(); MessageObject obj = localPagerAdapter.imagesArr.get(item); if (obj.messageOwner.send_state == MessagesController.MESSAGE_SEND_STATE_SENT) { @@ -241,6 +256,7 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif NotificationCenter.Instance.removeObserver(this, MessagesController.mediaCountDidLoaded); NotificationCenter.Instance.removeObserver(this, MessagesController.mediaDidLoaded); NotificationCenter.Instance.removeObserver(this, MessagesController.userPhotosLoaded); + NotificationCenter.Instance.removeObserver(this, 658); ConnectionsManager.Instance.cancelRpcsForClassGuid(classGuid); } @@ -354,7 +370,7 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif getSupportActionBar().setTitle(String.format("%d %s %d", pos, getString(R.string.Of), totalCount)); if (title != null) { fakeTitleView.setText(String.format("%d %s %d", pos, getString(R.string.Of), totalCount)); - fakeTitleView.measure(View.MeasureSpec.makeMeasureSpec(400, View.MeasureSpec.AT_MOST), 40); + fakeTitleView.measure(View.MeasureSpec.makeMeasureSpec(400, View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.AT_MOST)); title.setWidth(fakeTitleView.getMeasuredWidth() + Utilities.dp(8)); title.setMaxWidth(fakeTitleView.getMeasuredWidth() + Utilities.dp(8)); } @@ -450,10 +466,21 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif } } } + } else if (id == 658) { + try { + if (!isFinishing()) { + finish(); + } + } catch (Exception e) { + e.printStackTrace(); + } } } private TLRPC.FileLocation getCurrentFile() { + if (mViewPager == null) { + return null; + } int item = mViewPager.getCurrentItem(); if (withoutBottom) { return localPagerAdapter.imagesArrLocations.get(item); @@ -775,7 +802,7 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif getSupportActionBar().setTitle(String.format("%d %s %d", (totalCount - imagesArr.size()) + position + 1, getString(R.string.Of), totalCount)); if (title != null) { fakeTitleView.setText(String.format("%d %s %d", (totalCount - imagesArr.size()) + position + 1, getString(R.string.Of), totalCount)); - fakeTitleView.measure(View.MeasureSpec.makeMeasureSpec(400, View.MeasureSpec.AT_MOST), 40); + fakeTitleView.measure(View.MeasureSpec.makeMeasureSpec(400, View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.AT_MOST)); title.setWidth(fakeTitleView.getMeasuredWidth() + Utilities.dp(8)); title.setMaxWidth(fakeTitleView.getMeasuredWidth() + Utilities.dp(8)); } @@ -794,7 +821,7 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif getSupportActionBar().setTitle(String.format("%d %s %d", position + 1, getString(R.string.Of), imagesArrLocations.size())); if (title != null) { fakeTitleView.setText(String.format("%d %s %d", position + 1, getString(R.string.Of), imagesArrLocations.size())); - fakeTitleView.measure(View.MeasureSpec.makeMeasureSpec(400, View.MeasureSpec.AT_MOST), 40); + fakeTitleView.measure(View.MeasureSpec.makeMeasureSpec(400, View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.AT_MOST)); title.setWidth(fakeTitleView.getMeasuredWidth() + Utilities.dp(8)); title.setMaxWidth(fakeTitleView.getMeasuredWidth() + Utilities.dp(8)); } @@ -885,7 +912,16 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif ArrayList sizes = message.messageOwner.media.photo.sizes; iv.isVideo = false; if (sizes.size() > 0) { - TLRPC.PhotoSize sizeFull = PhotoObject.getClosestPhotoSizeWithSize(sizes, 800, 800); + int width = (int)(Math.min(displaySize.x, displaySize.y) * 0.7f); + int height = width + Utilities.dp(100); + if (width > 800) { + width = 800; + } + if (height > 800) { + height = 800; + } + + TLRPC.PhotoSize sizeFull = PhotoObject.getClosestPhotoSizeWithSize(sizes, width, height); if (message.imagePreview != null) { iv.setImage(sizeFull.location, null, message.imagePreview, sizeFull.size); } else { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java index 68210272e..afa191db7 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateActivity.java @@ -37,6 +37,7 @@ import android.widget.TextView; import org.telegram.TL.TLRPC; import org.telegram.messenger.ConnectionsManager; +import org.telegram.messenger.ContactsController; import org.telegram.messenger.Emoji; import org.telegram.messenger.FileLog; import org.telegram.messenger.MessagesController; @@ -44,6 +45,7 @@ import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.R; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; +import org.telegram.ui.Views.BackupImageView; import org.telegram.ui.Views.BaseFragment; import org.telegram.ui.Views.PinnedHeaderListView; import org.telegram.ui.Views.SectionedBaseAdapter; @@ -198,7 +200,7 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen if (searching && searchWas) { user = searchResult.get(row); } else { - ArrayList arr = MessagesController.Instance.usersSectionsDict.get(MessagesController.Instance.sortedUsersSectionsArray.get(section)); + ArrayList arr = ContactsController.Instance.usersSectionsDict.get(ContactsController.Instance.sortedUsersSectionsArray.get(section)); user = MessagesController.Instance.users.get(arr.get(row).user_id); listView.invalidateViews(); } @@ -367,7 +369,7 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen ArrayList resultArrayNames = new ArrayList(); String q = query.toLowerCase(); - for (TLRPC.TL_contact contact : MessagesController.Instance.contacts) { + for (TLRPC.TL_contact contact : ContactsController.Instance.contacts) { TLRPC.User user = MessagesController.Instance.users.get(contact.user_id); if (user.first_name.toLowerCase().startsWith(q) || user.last_name.toLowerCase().startsWith(q)) { if (user.id == UserConfig.clientUserId) { @@ -432,8 +434,11 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen listViewAdapter.notifyDataSetChanged(); } } else if (id == MessagesController.updateInterfaces) { - if (listView != null) { - listView.invalidateViews(); + int mask = (Integer)args[0]; + if ((mask & MessagesController.UPDATE_MASK_AVATAR) != 0 || (mask & MessagesController.UPDATE_MASK_NAME) != 0 || (mask & MessagesController.UPDATE_MASK_STATUS) != 0) { + if (listView != null) { + listView.invalidateViews(); + } } } else if (id == MessagesController.chatDidCreated) { Utilities.RunOnUIThread(new Runnable() { @@ -467,7 +472,7 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen if (searching && searchWas) { return searchResult == null || searchResult.isEmpty() ? 0 : 1; } - return MessagesController.Instance.sortedUsersSectionsArray.size(); + return ContactsController.Instance.sortedUsersSectionsArray.size(); } @Override @@ -475,7 +480,7 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen if (searching && searchWas) { return searchResult == null ? 0 : searchResult.size(); } - ArrayList arr = MessagesController.Instance.usersSectionsDict.get(MessagesController.Instance.sortedUsersSectionsArray.get(section)); + ArrayList arr = ContactsController.Instance.usersSectionsDict.get(ContactsController.Instance.sortedUsersSectionsArray.get(section)); return arr.size(); } @@ -488,7 +493,7 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen user = MessagesController.Instance.users.get(searchResult.get(position).id); size = searchResult.size(); } else { - ArrayList arr = MessagesController.Instance.usersSectionsDict.get(MessagesController.Instance.sortedUsersSectionsArray.get(section)); + ArrayList arr = ContactsController.Instance.usersSectionsDict.get(ContactsController.Instance.sortedUsersSectionsArray.get(section)); user = MessagesController.Instance.users.get(arr.get(position).user_id); size = arr.size(); } @@ -497,9 +502,9 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = li.inflate(R.layout.group_create_row_layout, parent, false); } - ContactsActivity.ContactListRowHolder holder = (ContactsActivity.ContactListRowHolder)convertView.getTag(); + ContactListRowHolder holder = (ContactListRowHolder)convertView.getTag(); if (holder == null) { - holder = new ContactsActivity.ContactListRowHolder(convertView); + holder = new ContactListRowHolder(convertView); convertView.setTag(holder); } @@ -552,7 +557,7 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen if (value == 0) { value = user.status.expires; } - holder.messageTextView.setText(getStringEntry(R.string.LastSeen) + " " + Utilities.formatDateOnline(value)); + holder.messageTextView.setText(Utilities.formatDateOnline(value)); } holder.messageTextView.setTextColor(0xff808080); } @@ -592,9 +597,21 @@ public class GroupCreateActivity extends BaseFragment implements NotificationCen if (searching && searchWas) { textView.setText(getStringEntry(R.string.AllContacts)); } else { - textView.setText(MessagesController.Instance.sortedUsersSectionsArray.get(section)); + textView.setText(ContactsController.Instance.sortedUsersSectionsArray.get(section)); } return convertView; } } + + public static class ContactListRowHolder { + public BackupImageView avatarImage; + public TextView messageTextView; + public TextView nameTextView; + + public ContactListRowHolder(View view) { + messageTextView = (TextView)view.findViewById(R.id.messages_list_row_message); + nameTextView = (TextView)view.findViewById(R.id.messages_list_row_name); + avatarImage = (BackupImageView)view.findViewById(R.id.messages_list_row_avatar); + } + } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java index f710efadb..24d72c46b 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/GroupCreateFinalActivity.java @@ -15,7 +15,6 @@ import android.content.Intent; import android.os.Bundle; import android.support.v4.internal.view.SupportMenuItem; import android.support.v7.app.ActionBar; -import android.text.Html; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -27,12 +26,12 @@ import android.widget.ImageButton; import android.widget.TextView; import org.telegram.TL.TLRPC; -import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLog; import org.telegram.messenger.MessagesController; import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.R; import org.telegram.messenger.Utilities; +import org.telegram.ui.Cells.ChatOrUserCell; import org.telegram.ui.Views.AvatarUpdater; import org.telegram.ui.Views.BackupImageView; import org.telegram.ui.Views.BaseFragment; @@ -228,8 +227,9 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati @Override public void didReceivedNotification(int id, final Object... args) { if (id == MessagesController.updateInterfaces) { - if (listView != null) { - listView.invalidateViews(); + int mask = (Integer)args[0]; + if ((mask & MessagesController.UPDATE_MASK_AVATAR) != 0 || (mask & MessagesController.UPDATE_MASK_NAME) != 0 || (mask & MessagesController.UPDATE_MASK_STATUS) != 0) { + updateVisibleRows(mask); } } else if (id == MessagesController.chatDidFailCreate) { Utilities.HideProgressDialog(parentActivity); @@ -250,6 +250,19 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati } } + private void updateVisibleRows(int mask) { + if (listView == null) { + return; + } + int count = listView.getChildCount(); + for (int a = 0; a < count; a++) { + View child = listView.getChildAt(a); + if (child instanceof ChatOrUserCell) { + ((ChatOrUserCell) child).update(mask); + } + } + } + private class ListAdapter extends SectionedBaseAdapter { private Context mContext; @@ -295,58 +308,13 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati TLRPC.User user = MessagesController.Instance.users.get(selectedContacts.get(position)); if (convertView == null) { - LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - convertView = li.inflate(R.layout.messages_search_user_layout, parent, false); - } - ContactsActivity.ContactListRowHolder holder = (ContactsActivity.ContactListRowHolder)convertView.getTag(); - if (holder == null) { - holder = new ContactsActivity.ContactListRowHolder(convertView); - convertView.setTag(holder); + convertView = new ChatOrUserCell(mContext); + ((ChatOrUserCell)convertView).useBoldFont = true; + ((ChatOrUserCell)convertView).usePadding = false; } - View divider = convertView.findViewById(R.id.settings_row_divider); - if (position == selectedContacts.size() - 1) { - divider.setVisibility(View.INVISIBLE); - } else { - divider.setVisibility(View.VISIBLE); - } - - if (user.first_name.length() != 0 && user.last_name.length() != 0) { - holder.nameTextView.setText(Html.fromHtml(user.first_name + " " + user.last_name + "")); - } else if (user.first_name.length() != 0) { - holder.nameTextView.setText(Html.fromHtml("" + user.first_name + "")); - } else { - holder.nameTextView.setText(Html.fromHtml("" + user.last_name + "")); - } - - TLRPC.FileLocation photo = null; - if (user.photo != null) { - photo = user.photo.photo_small; - } - int placeHolderId = Utilities.getUserAvatarForId(user.id); - holder.avatarImage.setImage(photo, "50_50", placeHolderId); - - if (user.status == null) { - holder.messageTextView.setTextColor(0xff808080); - holder.messageTextView.setText(getStringEntry(R.string.Offline)); - } else { - int currentTime = ConnectionsManager.Instance.getCurrentTime(); - if (user.status.expires > currentTime || user.status.was_online > currentTime) { - holder.messageTextView.setTextColor(0xff357aa8); - holder.messageTextView.setText(getStringEntry(R.string.Online)); - } else { - if (user.status.was_online <= 10000 && user.status.expires <= 10000) { - holder.messageTextView.setText(getStringEntry(R.string.Invisible)); - } else { - int value = user.status.was_online; - if (value == 0) { - value = user.status.expires; - } - holder.messageTextView.setText(getStringEntry(R.string.LastSeen) + " " + Utilities.formatDateOnline(value)); - } - holder.messageTextView.setTextColor(0xff808080); - } - } + ((ChatOrUserCell)convertView).setData(user, null, null, null, null); + ((ChatOrUserCell) convertView).useSeparator = position != selectedContacts.size() - 1; return convertView; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/IntroActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/IntroActivity.java index 8effb45cd..dc761ecd9 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/IntroActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/IntroActivity.java @@ -23,8 +23,7 @@ import android.widget.ImageView; import android.widget.TextView; import org.telegram.messenger.R; - -import java.util.Locale; +import org.telegram.messenger.Utilities; public class IntroActivity extends ActionBarActivity { private ViewPager viewPager; @@ -32,7 +31,6 @@ public class IntroActivity extends ActionBarActivity { private ImageView topImage2; private ViewGroup bottomPages; private int lastPage = 0; - private boolean isRTL = false; private boolean justCreated = false; private boolean startPressed = false; private int[] icons; @@ -45,10 +43,7 @@ public class IntroActivity extends ActionBarActivity { setContentView(R.layout.intro_layout); - Locale locale = Locale.getDefault(); - String lang = locale.getLanguage(); - if (lang != null && lang.toLowerCase().equals("ar")) { - isRTL = true; + if (Utilities.isRTL) { icons = new int[] { R.drawable.intro7, R.drawable.intro6, @@ -212,7 +207,7 @@ public class IntroActivity extends ActionBarActivity { protected void onResume() { super.onResume(); if (justCreated) { - if (isRTL) { + if (Utilities.isRTL) { viewPager.setCurrentItem(6); lastPage = 6; } else { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java index d9e56b540..c7acff8b4 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LaunchActivity.java @@ -14,6 +14,7 @@ import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; +import android.os.Parcelable; import org.telegram.TL.TLRPC; import org.telegram.messenger.FileLog; @@ -21,6 +22,7 @@ import org.telegram.messenger.MessagesController; import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.R; import org.telegram.messenger.UserConfig; +import org.telegram.messenger.Utilities; import org.telegram.ui.Views.PausableActivity; public class LaunchActivity extends PausableActivity { @@ -46,13 +48,22 @@ public class LaunchActivity extends PausableActivity { if (Intent.ACTION_SEND.equals(intent.getAction())) { if (intent.getType() != null) { if (intent.getType().startsWith("image/")) { - String path = intent.getParcelableExtra(Intent.EXTRA_STREAM).toString(); - if (path.startsWith("content:")) { - Cursor cursor = getContentResolver().query(Uri.parse(path), new String[]{android.provider.MediaStore.Images.ImageColumns.DATA}, null, null, null); - if (cursor != null) { - cursor.moveToFirst(); - path = cursor.getString(0); - cursor.close(); + Parcelable parcelable = intent.getParcelableExtra(Intent.EXTRA_STREAM); + if (parcelable == null) { + return; + } + String path = null; + if (parcelable instanceof Uri) { + path = Utilities.getPath(this, (Uri)parcelable); + } else { + path = intent.getParcelableExtra(Intent.EXTRA_STREAM).toString(); + if (path.startsWith("content:")) { + Cursor cursor = getContentResolver().query(Uri.parse(path), new String[]{android.provider.MediaStore.Images.ImageColumns.DATA}, null, null, null); + if (cursor != null) { + cursor.moveToFirst(); + path = cursor.getString(0); + cursor.close(); + } } } if (path != null) { @@ -62,13 +73,22 @@ public class LaunchActivity extends PausableActivity { NotificationCenter.Instance.addToMemCache(533, path); } } else if (intent.getType().startsWith("video/")) { - String path = intent.getParcelableExtra(Intent.EXTRA_STREAM).toString(); - if (path.startsWith("content:")) { - Cursor cursor = getContentResolver().query(Uri.parse(path), new String[]{android.provider.MediaStore.Images.ImageColumns.DATA}, null, null, null); - if (cursor != null) { - cursor.moveToFirst(); - path = cursor.getString(0); - cursor.close(); + Parcelable parcelable = intent.getParcelableExtra(Intent.EXTRA_STREAM); + if (parcelable == null) { + return; + } + String path = null; + if (parcelable instanceof Uri) { + path = Utilities.getPath(this, (Uri)parcelable); + } else { + path = parcelable.toString(); + if (path.startsWith("content:")) { + Cursor cursor = getContentResolver().query(Uri.parse(path), new String[]{android.provider.MediaStore.Images.ImageColumns.DATA}, null, null, null); + if (cursor != null) { + cursor.moveToFirst(); + path = cursor.getString(0); + cursor.close(); + } } } if (path != null) { @@ -79,17 +99,24 @@ public class LaunchActivity extends PausableActivity { } } else if (intent.getType().equals("text/plain")) { String text = intent.getStringExtra(Intent.EXTRA_TEXT); - if (text.length() != 0) { + if (text != null && text.length() != 0) { NotificationCenter.Instance.addToMemCache(535, text); } } } } else if (Intent.ACTION_VIEW.equals(intent.getAction())) { - Cursor cursor = getContentResolver().query(intent.getData(), null, null, null, null); - if (cursor.moveToFirst()) { - int userId = cursor.getInt(cursor.getColumnIndex("DATA4")); - NotificationCenter.Instance.postNotificationName(MessagesController.closeChats); - NotificationCenter.Instance.addToMemCache("push_user_id", userId); + try { + Cursor cursor = getContentResolver().query(intent.getData(), null, null, null, null); + if (cursor != null) { + if (cursor.moveToFirst()) { + int userId = cursor.getInt(cursor.getColumnIndex("DATA4")); + NotificationCenter.Instance.postNotificationName(MessagesController.closeChats); + NotificationCenter.Instance.addToMemCache("push_user_id", userId); + } + cursor.close(); + } + } catch (Exception e) { + FileLog.e("tmessages", e); } } else if (intent.getAction().equals("org.telegram.messenger.OPEN_ACCOUNT")) { NotificationCenter.Instance.addToMemCache("open_settings", 1); @@ -115,6 +142,7 @@ public class LaunchActivity extends PausableActivity { } int chatId = getIntent().getIntExtra("chatId", 0); int userId = getIntent().getIntExtra("userId", 0); + int encId = getIntent().getIntExtra("encId", 0); if (chatId != 0) { TLRPC.Chat chat = MessagesController.Instance.chats.get(chatId); if (chat != null) { @@ -127,6 +155,12 @@ public class LaunchActivity extends PausableActivity { NotificationCenter.Instance.postNotificationName(MessagesController.closeChats); NotificationCenter.Instance.addToMemCache("push_user_id", userId); } + } else if (encId != 0) { + TLRPC.EncryptedChat chat = MessagesController.Instance.encryptedChats.get(encId); + if (chat != null) { + NotificationCenter.Instance.postNotificationName(MessagesController.closeChats); + NotificationCenter.Instance.addToMemCache("push_enc_id", encId); + } } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java index 9bcf3fa41..b19633af8 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LocationActivity.java @@ -329,7 +329,10 @@ public class LocationActivity extends BaseFragment implements NotificationCenter @Override public void didReceivedNotification(int id, Object... args) { if (id == MessagesController.updateInterfaces) { - updateUserData(); + int mask = (Integer)args[0]; + if ((mask & MessagesController.UPDATE_MASK_AVATAR) != 0 || (mask & MessagesController.UPDATE_MASK_NAME) != 0) { + updateUserData(); + } } else if (id == MessagesController.closeChats) { removeSelfFromStack(); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java index e7266b45c..ea2ef46e1 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivity.java @@ -25,7 +25,6 @@ import android.view.animation.AccelerateDecelerateInterpolator; import android.widget.ImageView; import android.widget.TextView; -import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.R; import org.telegram.messenger.Utilities; import org.telegram.ui.Views.SlideView; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivityPhoneView.java b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivityPhoneView.java index f6d4ac4ac..5bde3e5a7 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivityPhoneView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivityPhoneView.java @@ -299,6 +299,10 @@ public class LoginActivityPhoneView extends SlideView implements AdapterView.OnI @Override public void onNextPressed() { + if (codeField.length() == 0 || phoneField.length() == 0) { + delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.InvalidPhoneNumber)); + return; + } TLRPC.TL_auth_sendCode req = new TLRPC.TL_auth_sendCode(); String phone = PhoneFormat.stripExceptNumbers("" + codeField.getText() + phoneField.getText()); req.api_hash = ConnectionsManager.APP_HASH; @@ -327,25 +331,31 @@ public class LoginActivityPhoneView extends SlideView implements AdapterView.OnI Utilities.RunOnUIThread(new Runnable() { @Override public void run() { - delegate.setPage(1, true, params, false); + if (delegate != null) { + delegate.setPage(1, true, params, false); + } } }); } else { - if (error.text != null) { - if (error.text.contains("PHONE_NUMBER_INVALID")) { - delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.InvalidPhoneNumber)); - } else if (error.text.contains("PHONE_CODE_EMPTY") || error.text.contains("PHONE_CODE_INVALID")) { - delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.InvalidCode)); - } else if (error.text.contains("PHONE_CODE_EXPIRED")) { - delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.CodeExpired)); - } else if (error.text.contains("FLOOD_WAIT")) { - delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.FloodWait)); - } else { - delegate.needShowAlert(error.text); + if (delegate != null) { + if (error.text != null) { + if (error.text.contains("PHONE_NUMBER_INVALID")) { + delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.InvalidPhoneNumber)); + } else if (error.text.contains("PHONE_CODE_EMPTY") || error.text.contains("PHONE_CODE_INVALID")) { + delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.InvalidCode)); + } else if (error.text.contains("PHONE_CODE_EXPIRED")) { + delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.CodeExpired)); + } else if (error.text.contains("FLOOD_WAIT")) { + delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.FloodWait)); + } else { + delegate.needShowAlert(error.text); + } } } } - delegate.needHideProgress(); + if (delegate != null) { + delegate.needHideProgress(); + } } }, null, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivityRegisterView.java b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivityRegisterView.java index 32f95aa38..3d5baf207 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivityRegisterView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivityRegisterView.java @@ -22,6 +22,7 @@ import android.widget.TextView; import org.telegram.TL.TLObject; import org.telegram.TL.TLRPC; import org.telegram.messenger.ConnectionsManager; +import org.telegram.messenger.ContactsController; import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesStorage; import org.telegram.messenger.R; @@ -191,7 +192,9 @@ public class LoginActivityRegisterView extends SlideView { ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() { @Override public void run(TLObject response, TLRPC.TL_error error) { - delegate.needHideProgress(); + if (delegate != null) { + delegate.needHideProgress(); + } if (error == null) { final TLRPC.TL_auth_authorization res = (TLRPC.TL_auth_authorization)response; Utilities.RunOnUIThread(new Runnable() { @@ -211,23 +214,27 @@ public class LoginActivityRegisterView extends SlideView { MessagesStorage.Instance.putUsersAndChats(users, null, true, true); //MessagesController.Instance.uploadAndApplyUserAvatar(avatarPhotoBig); MessagesController.Instance.users.put(res.user.id, res.user); - MessagesController.Instance.checkAppAccount(); - delegate.needFinishActivity(); + ContactsController.Instance.checkAppAccount(); + if (delegate != null) { + delegate.needFinishActivity(); + } } }); } else { - if (error.text.contains("PHONE_NUMBER_INVALID")) { - delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.InvalidPhoneNumber)); - } else if (error.text.contains("PHONE_CODE_EMPTY") || error.text.contains("PHONE_CODE_INVALID")) { - delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.InvalidCode)); - } else if (error.text.contains("PHONE_CODE_EXPIRED")) { - delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.CodeExpired)); - } else if (error.text.contains("FIRSTNAME_INVALID")) { - delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.InvalidFirstName)); - } else if (error.text.contains("LASTNAME_INVALID")) { - delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.InvalidLastName)); - } else { - delegate.needShowAlert(error.text); + if (delegate != null) { + if (error.text.contains("PHONE_NUMBER_INVALID")) { + delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.InvalidPhoneNumber)); + } else if (error.text.contains("PHONE_CODE_EMPTY") || error.text.contains("PHONE_CODE_INVALID")) { + delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.InvalidCode)); + } else if (error.text.contains("PHONE_CODE_EXPIRED")) { + delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.CodeExpired)); + } else if (error.text.contains("FIRSTNAME_INVALID")) { + delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.InvalidFirstName)); + } else if (error.text.contains("LASTNAME_INVALID")) { + delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.InvalidLastName)); + } else { + delegate.needShowAlert(error.text); + } } } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivitySmsView.java b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivitySmsView.java index 496db7052..b992b5298 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/LoginActivitySmsView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/LoginActivitySmsView.java @@ -24,6 +24,8 @@ import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.TL.TLObject; import org.telegram.TL.TLRPC; import org.telegram.messenger.ConnectionsManager; +import org.telegram.messenger.ContactsController; +import org.telegram.messenger.FileLog; import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesStorage; import org.telegram.messenger.NotificationCenter; @@ -47,6 +49,7 @@ public class LoginActivitySmsView extends SlideView implements NotificationCente private Bundle currentParams; private Timer timeTimer; + private final Integer timerSync = 1; private int time = 60000; private double lastCurrentTime; private boolean waitingForSms = false; @@ -102,6 +105,7 @@ public class LoginActivitySmsView extends SlideView implements NotificationCente @Override public void setParams(Bundle params) { codeField.setText(""); + Utilities.setWaitingForSms(true); NotificationCenter.Instance.addObserver(this, 998); currentParams = params; waitingForSms = true; @@ -117,9 +121,15 @@ public class LoginActivitySmsView extends SlideView implements NotificationCente codeField.requestFocus(); time = 60000; - if (timeTimer != null) { - timeTimer.cancel(); - timeTimer = null; + try { + synchronized(timerSync) { + if (timeTimer != null) { + timeTimer.cancel(); + timeTimer = null; + } + } + } catch (Exception e) { + FileLog.e("tmessages", e); } timeText.setText(String.format("%s 1:00", ApplicationLoader.applicationContext.getResources().getString(R.string.CallText))); lastCurrentTime = System.currentTimeMillis(); @@ -140,9 +150,11 @@ public class LoginActivitySmsView extends SlideView implements NotificationCente timeText.setText(String.format("%s %d:%02d", ApplicationLoader.applicationContext.getResources().getString(R.string.CallText), minutes, seconds)); } else { timeText.setText(ApplicationLoader.applicationContext.getResources().getString(R.string.Calling)); - if (timeTimer != null) { - timeTimer.cancel(); - timeTimer = null; + synchronized(timerSync) { + if (timeTimer != null) { + timeTimer.cancel(); + timeTimer = null; + } } TLRPC.TL_auth_sendCall req = new TLRPC.TL_auth_sendCall(); req.phone_number = requestPhone; @@ -162,12 +174,25 @@ public class LoginActivitySmsView extends SlideView implements NotificationCente @Override public void onNextPressed() { waitingForSms = false; + Utilities.setWaitingForSms(false); NotificationCenter.Instance.removeObserver(this, 998); final TLRPC.TL_auth_signIn req = new TLRPC.TL_auth_signIn(); req.phone_number = requestPhone; req.phone_code = codeField.getText().toString(); req.phone_code_hash = phoneHash; - delegate.needShowProgress(); + try { + synchronized(timerSync) { + if (timeTimer != null) { + timeTimer.cancel(); + timeTimer = null; + } + } + } catch (Exception e) { + FileLog.e("tmessages", e); + } + if (delegate != null) { + delegate.needShowProgress(); + } ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() { @Override public void run(TLObject response, TLRPC.TL_error error) { @@ -182,9 +207,15 @@ public class LoginActivitySmsView extends SlideView implements NotificationCente if (delegate == null) { return; } - if (timeTimer != null) { - timeTimer.cancel(); - timeTimer = null; + try { + synchronized(timerSync) { + if (timeTimer != null) { + timeTimer.cancel(); + timeTimer = null; + } + } + } catch (Exception e) { + FileLog.e("tmessages", e); } UserConfig.clearConfig(); MessagesStorage.Instance.cleanUp(); @@ -198,8 +229,10 @@ public class LoginActivitySmsView extends SlideView implements NotificationCente users.add(UserConfig.currentUser); MessagesStorage.Instance.putUsersAndChats(users, null, true, true); MessagesController.Instance.users.put(res.user.id, res.user); - MessagesController.Instance.checkAppAccount(); - delegate.needFinishActivity(); + ContactsController.Instance.checkAppAccount(); + if (delegate != null) { + delegate.needFinishActivity(); + } } }); } else { @@ -212,21 +245,67 @@ public class LoginActivitySmsView extends SlideView implements NotificationCente params.putString("phoneHash", phoneHash); params.putString("code", req.phone_code); delegate.setPage(2, true, params, false); - if (timeTimer != null) { - timeTimer.cancel(); - timeTimer = null; + try { + synchronized(timerSync) { + if (timeTimer != null) { + timeTimer.cancel(); + timeTimer = null; + } + } + } catch (Exception e) { + FileLog.e("tmessages", e); } } }); } else { - if (error.text.contains("PHONE_NUMBER_INVALID")) { - delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.InvalidPhoneNumber)); - } else if (error.text.contains("PHONE_CODE_EMPTY") || error.text.contains("PHONE_CODE_INVALID")) { - delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.InvalidCode)); - } else if (error.text.contains("PHONE_CODE_EXPIRED")) { - delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.CodeExpired)); - } else { - delegate.needShowAlert(error.text); + if (timeTimer == null) { + timeTimer = new Timer(); + timeTimer.schedule(new TimerTask() { + @Override + public void run() { + double currentTime = System.currentTimeMillis(); + double diff = currentTime - lastCurrentTime; + time -= diff; + lastCurrentTime = currentTime; + Utilities.RunOnUIThread(new Runnable() { + @Override + public void run() { + if (time >= 1000) { + int minutes = time / 1000 / 60; + int seconds = time / 1000 - minutes * 60; + timeText.setText(String.format("%s %d:%02d", ApplicationLoader.applicationContext.getResources().getString(R.string.CallText), minutes, seconds)); + } else { + timeText.setText(ApplicationLoader.applicationContext.getResources().getString(R.string.Calling)); + synchronized(timerSync) { + if (timeTimer != null) { + timeTimer.cancel(); + timeTimer = null; + } + } + TLRPC.TL_auth_sendCall req = new TLRPC.TL_auth_sendCall(); + req.phone_number = requestPhone; + req.phone_code_hash = phoneHash; + ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(TLObject response, TLRPC.TL_error error) { + } + }, null, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors); + } + } + }); + } + }, 0, 1000); + } + if (delegate != null) { + if (error.text.contains("PHONE_NUMBER_INVALID")) { + delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.InvalidPhoneNumber)); + } else if (error.text.contains("PHONE_CODE_EMPTY") || error.text.contains("PHONE_CODE_INVALID")) { + delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.InvalidCode)); + } else if (error.text.contains("PHONE_CODE_EXPIRED")) { + delegate.needShowAlert(ApplicationLoader.applicationContext.getString(R.string.CodeExpired)); + } else { + delegate.needShowAlert(error.text); + } } } } @@ -236,11 +315,18 @@ public class LoginActivitySmsView extends SlideView implements NotificationCente @Override public void onBackPressed() { - if (timeTimer != null) { - timeTimer.cancel(); - timeTimer = null; + try { + synchronized(timerSync) { + if (timeTimer != null) { + timeTimer.cancel(); + timeTimer = null; + } + } + } catch (Exception e) { + FileLog.e("tmessages", e); } currentParams = null; + Utilities.setWaitingForSms(false); NotificationCenter.Instance.removeObserver(this, 998); waitingForSms = false; } @@ -248,10 +334,17 @@ public class LoginActivitySmsView extends SlideView implements NotificationCente @Override public void onDestroyActivity() { super.onDestroyActivity(); + Utilities.setWaitingForSms(false); NotificationCenter.Instance.removeObserver(this, 998); - if (timeTimer != null) { - timeTimer.cancel(); - timeTimer = null; + try { + synchronized(timerSync) { + if (timeTimer != null) { + timeTimer.cancel(); + timeTimer = null; + } + } + } catch (Exception e) { + FileLog.e("tmessages", e); } waitingForSms = false; } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java index 8a49103be..60a6c34a5 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/MessagesActivity.java @@ -11,15 +11,12 @@ package org.telegram.ui; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; -import android.graphics.Typeface; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.internal.view.SupportMenuItem; import android.support.v4.view.MenuItemCompat; import android.support.v7.app.ActionBar; import android.support.v7.widget.SearchView; -import android.text.Html; -import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -33,25 +30,22 @@ import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; -import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.TL.TLObject; import org.telegram.TL.TLRPC; -import org.telegram.messenger.Emoji; +import org.telegram.messenger.ContactsController; import org.telegram.messenger.FileLog; -import org.telegram.objects.MessageObject; -import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesStorage; import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.R; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; -import org.telegram.ui.Views.BackupImageView; +import org.telegram.ui.Cells.ChatOrUserCell; +import org.telegram.ui.Cells.DialogCell; import org.telegram.ui.Views.BaseFragment; import java.lang.reflect.Field; import java.util.ArrayList; -import java.util.Locale; import java.util.Timer; import java.util.TimerTask; @@ -65,7 +59,6 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter private SearchView searchView; public int selectAlertString = 0; private boolean serverOnly = false; - private boolean isRTL; private static boolean dialogsLoaded = false; private boolean searching = false; @@ -91,7 +84,6 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter NotificationCenter.Instance.addObserver(this, 999); NotificationCenter.Instance.addObserver(this, MessagesController.updateInterfaces); NotificationCenter.Instance.addObserver(this, MessagesController.reloadSearchResults); - NotificationCenter.Instance.addObserver(this, MessagesController.userPrintUpdateAll); NotificationCenter.Instance.addObserver(this, MessagesController.encryptedChatUpdated); NotificationCenter.Instance.addObserver(this, MessagesController.contactsDidLoaded); NotificationCenter.Instance.addObserver(this, 1234); @@ -100,8 +92,8 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter serverOnly = getArguments().getBoolean("serverOnly", false); } if (!dialogsLoaded) { - MessagesController.Instance.readContacts(); MessagesController.Instance.loadDialogs(0, 0, 100, true); + ContactsController.Instance.checkAppAccount(); dialogsLoaded = true; } return true; @@ -114,7 +106,6 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter NotificationCenter.Instance.removeObserver(this, 999); NotificationCenter.Instance.removeObserver(this, MessagesController.updateInterfaces); NotificationCenter.Instance.removeObserver(this, MessagesController.reloadSearchResults); - NotificationCenter.Instance.removeObserver(this, MessagesController.userPrintUpdateAll); NotificationCenter.Instance.removeObserver(this, MessagesController.encryptedChatUpdated); NotificationCenter.Instance.removeObserver(this, MessagesController.contactsDidLoaded); NotificationCenter.Instance.removeObserver(this, 1234); @@ -133,9 +124,6 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter fragmentView = inflater.inflate(R.layout.messages_list, container, false); messagesListViewAdapter = new MessagesAdapter(parentActivity); - Locale locale = Locale.getDefault(); - String lang = locale.getLanguage(); - isRTL = lang != null && lang.toLowerCase().equals("ar"); messagesListView = (ListView)fragmentView.findViewById(R.id.messages_list_view); messagesListView.setAdapter(messagesListViewAdapter); @@ -248,7 +236,7 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter if (which == 0) { MessagesController.Instance.deleteDialog(selectedDialog, 0, true); } else if (which == 1) { - MessagesController.Instance.deleteUserFromChat((int) -selectedDialog, UserConfig.clientUserId, null); + MessagesController.Instance.deleteUserFromChat((int) -selectedDialog, MessagesController.Instance.users.get(UserConfig.clientUserId), null); MessagesController.Instance.deleteDialog(selectedDialog, 0, false); } } @@ -314,7 +302,7 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter actionBar.setDisplayShowCustomEnabled(false); actionBar.setSubtitle(null); actionBar.setCustomView(null); - actionBar.setTitle(getStringEntry(R.string.AppName)); + actionBar.setTitle(getStringEntry(R.string.SelectChat)); ((ApplicationActivity)parentActivity).fixBackButton(); } else { ImageView view = (ImageView)parentActivity.findViewById(16908332); @@ -392,12 +380,10 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter } } else if (id == 999) { if (messagesListView != null) { - updateVisibleRows(); + updateVisibleRows(0); } } else if (id == MessagesController.updateInterfaces) { - if (messagesListViewAdapter != null) { - messagesListViewAdapter.notifyDataSetChanged(); - } + updateVisibleRows((Integer)args[0]); } else if (id == MessagesController.reloadSearchResults) { int token = (Integer)args[0]; if (token == activityToken) { @@ -405,32 +391,24 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter } } else if (id == 1234) { dialogsLoaded = false; - } else if (id == MessagesController.userPrintUpdateAll) { - if (messagesListView != null) { - updateVisibleRows(); - } } else if (id == MessagesController.encryptedChatUpdated) { - if (messagesListView != null) { - updateVisibleRows(); - } + updateVisibleRows(0); } else if (id == MessagesController.contactsDidLoaded) { - if (messagesListView != null) { - updateVisibleRows(); - } + updateVisibleRows(0); } } - private void updateVisibleRows() { - if (searching && searchWas) { - messagesListView.invalidate(); - } else { - int count = messagesListView.getChildCount(); - for (int a = 0; a < count; a++) { - View child = messagesListView.getChildAt(a); - Object tag = child.getTag(); - if (tag instanceof MessagesListRowHolder) { - ((MessagesListRowHolder) tag).update(); - } + private void updateVisibleRows(int mask) { + if (messagesListView == null) { + return; + } + int count = messagesListView.getChildCount(); + for (int a = 0; a < count; a++) { + View child = messagesListView.getChildAt(a); + if (child instanceof DialogCell) { + ((DialogCell) child).update(mask); + } else if (child instanceof ChatOrUserCell) { + ((ChatOrUserCell) child).update(mask); } } } @@ -452,15 +430,24 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter if (lower_part != 0) { if (lower_part > 0) { TLRPC.User user = MessagesController.Instance.users.get(lower_part); + if (user == null) { + return; + } builder.setMessage(String.format(getStringEntry(selectAlertString), Utilities.formatName(user.first_name, user.last_name))); } else if (lower_part < 0) { TLRPC.Chat chat = MessagesController.Instance.chats.get(-lower_part); + if (chat == null) { + return; + } builder.setMessage(String.format(getStringEntry(selectAlertString), chat.title)); } } else { int chat_id = (int)(dialog_id >> 32); TLRPC.EncryptedChat chat = MessagesController.Instance.encryptedChats.get(chat_id); TLRPC.User user = MessagesController.Instance.users.get(chat.user_id); + if (user == null) { + return; + } builder.setMessage(String.format(getStringEntry(selectAlertString), Utilities.formatName(user.first_name, user.last_name))); } builder.setPositiveButton(R.string.OK, new DialogInterface.OnClickListener() { @@ -740,29 +727,14 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter @Override public View getView(int i, View view, ViewGroup viewGroup) { if (searching && searchWas) { - int type = getItemViewType(i); if (view == null) { - LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - if (type == 2) { - view = li.inflate(R.layout.messages_search_user_layout, viewGroup, false); - } else { - view = li.inflate(R.layout.messages_search_chat_layout, viewGroup, false); - } - View v = view.findViewById(R.id.settings_row_divider); - v.setVisibility(View.VISIBLE); - view.setPadding(Utilities.dp(11), 0, Utilities.dp(11), 0); - } - MessagesListSearchRowHolder holder = (MessagesListSearchRowHolder)view.getTag(); - if (holder == null) { - holder = new MessagesListSearchRowHolder(view); - view.setTag(holder); + view = new ChatOrUserCell(mContext); } TLRPC.User user = null; TLRPC.Chat chat = null; TLRPC.EncryptedChat encryptedChat = null; TLObject obj = searchResult.get(i); - CharSequence name = searchResultNames.get(i); if (obj instanceof TLRPC.User) { user = MessagesController.Instance.users.get(((TLRPC.User)obj).id); } else if (obj instanceof TLRPC.Chat) { @@ -772,57 +744,7 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter user = MessagesController.Instance.users.get(encryptedChat.user_id); } - holder.nameTextView.setText(name); - if (encryptedChat != null) { - if (!isRTL) { - holder.nameTextView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_green, 0, 0, 0); - } else { - holder.nameTextView.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_lock_green, 0); - } - holder.nameTextView.setCompoundDrawablePadding(Utilities.dp(4)); - } else { - holder.nameTextView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); - holder.nameTextView.setCompoundDrawablePadding(0); - } - - TLRPC.FileLocation photo = null; - int placeHolderId = 0; - if (user != null) { - if (user.photo != null) { - photo = user.photo.photo_small; - } - placeHolderId = Utilities.getUserAvatarForId(user.id); - } else if (chat != null) { - if (chat.photo != null) { - photo = chat.photo.photo_small; - } - placeHolderId = Utilities.getGroupAvatarForId(chat.id); - } - holder.avatarImage.setImage(photo, "50_50", placeHolderId); - - if (user != null) { - if (user.status == null) { - holder.messageTextView.setTextColor(0xff808080); - holder.messageTextView.setText(getStringEntry(R.string.Offline)); - } else { - int currentTime = ConnectionsManager.Instance.getCurrentTime(); - if (user.status.expires > currentTime || user.status.was_online > currentTime) { - holder.messageTextView.setTextColor(0xff316f9f); - holder.messageTextView.setText(getStringEntry(R.string.Online)); - } else { - if (user.status.was_online <= 10000 && user.status.expires <= 10000) { - holder.messageTextView.setText(getStringEntry(R.string.Invisible)); - } else { - int value = user.status.was_online; - if (value == 0) { - value = user.status.expires; - } - holder.messageTextView.setText(getStringEntry(R.string.LastSeen) + " " + Utilities.formatDateOnline(value)); - } - holder.messageTextView.setTextColor(0xff808080); - } - } - } + ((ChatOrUserCell)view).setData(user, chat, encryptedChat, searchResultNames.get(i), null); return view; } @@ -836,21 +758,13 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter } if (view == null) { - LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - view = li.inflate(R.layout.messages_list_row, viewGroup, false); - } - - MessagesListRowHolder holder = (MessagesListRowHolder)view.getTag(); - if (holder == null) { - holder = new MessagesListRowHolder(view); - view.setTag(holder); + view = new DialogCell(mContext); } if (serverOnly) { - holder.dialog = MessagesController.Instance.dialogsServerOnly.get(i); + ((DialogCell)view).setDialog(MessagesController.Instance.dialogsServerOnly.get(i)); } else { - holder.dialog = MessagesController.Instance.dialogs.get(i); + ((DialogCell)view).setDialog(MessagesController.Instance.dialogs.get(i)); } - holder.update(); return view; } @@ -865,14 +779,8 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter return 3; } } - if (serverOnly) { - if (i == MessagesController.Instance.dialogsServerOnly.size()) { - return 1; - } - } else { - if (i == MessagesController.Instance.dialogs.size()) { - return 1; - } + if (serverOnly && i == MessagesController.Instance.dialogsServerOnly.size() || !serverOnly && i == MessagesController.Instance.dialogs.size()) { + return 1; } return 0; } @@ -905,250 +813,4 @@ public class MessagesActivity extends BaseFragment implements NotificationCenter return count == 0; } } - - private class MessagesListSearchRowHolder { - public BackupImageView avatarImage; - public TextView messageTextView; - public TextView nameTextView; - - public MessagesListSearchRowHolder(View view) { - messageTextView = (TextView)view.findViewById(R.id.messages_list_row_message); - nameTextView = (TextView)view.findViewById(R.id.messages_list_row_name); - avatarImage = (BackupImageView)view.findViewById(R.id.messages_list_row_avatar); - } - } - - private class MessagesListRowHolder { - public ImageView errorImage; - public TextView messagesCountImage; - public BackupImageView avatarImage; - public TextView timeTextView; - public TextView messageTextView; - public TextView nameTextView; - public ImageView check1Image; - public ImageView check2Image; - public ImageView clockImage; - public TLRPC.TL_dialog dialog; - - public MessagesListRowHolder(View view) { - messageTextView = (TextView)view.findViewById(R.id.messages_list_row_message); - nameTextView = (TextView)view.findViewById(R.id.messages_list_row_name); - if (nameTextView != null) { - Typeface typeface = Utilities.getTypeface("fonts/rmedium.ttf"); - nameTextView.setTypeface(typeface); - } - timeTextView = (TextView)view.findViewById(R.id.messages_list_row_time); - avatarImage = (BackupImageView)view.findViewById(R.id.messages_list_row_avatar); - messagesCountImage = (TextView)view.findViewById(R.id.messages_list_row_badge); - errorImage = (ImageView)view.findViewById(R.id.messages_list_row_error); - check1Image = (ImageView)view.findViewById(R.id.messages_list_row_check_half); - check2Image = (ImageView)view.findViewById(R.id.messages_list_row_check); - clockImage = (ImageView)view.findViewById(R.id.messages_list_row_clock); - } - - public void update() { - MessageObject message = MessagesController.Instance.dialogMessage.get(dialog.top_message); - TLRPC.User user = null; - TLRPC.Chat chat = null; - TLRPC.EncryptedChat encryptedChat = null; - - int lower_id = (int)dialog.id; - if (lower_id != 0) { - if (lower_id < 0) { - chat = MessagesController.Instance.chats.get(-lower_id); - } else { - user = MessagesController.Instance.users.get(lower_id); - } - nameTextView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); - nameTextView.setCompoundDrawablePadding(0); - } else { - encryptedChat = MessagesController.Instance.encryptedChats.get((int)(dialog.id >> 32)); - if (encryptedChat != null) { - user = MessagesController.Instance.users.get(encryptedChat.user_id); - if (!isRTL) { - nameTextView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_green, 0, 0, 0); - } else { - nameTextView.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_lock_green, 0); - } - nameTextView.setCompoundDrawablePadding(Utilities.dp(4)); - } else { - Log.e("test", "tda"); - } - } - - if (chat != null) { - nameTextView.setText(chat.title); - nameTextView.setTextColor(0xff000000); - } else if (user != null) { - if (user.id != 333000 && MessagesController.Instance.contactsDict.get(user.id) == null) { - if (MessagesController.Instance.contactsDict.size() == 0 && MessagesController.Instance.loadingContacts) { - nameTextView.setTextColor(0xff000000); - nameTextView.setText(Utilities.formatName(user.first_name, user.last_name)); - } else { - if (user.phone != null && user.phone.length() != 0) { - nameTextView.setTextColor(0xff000000); - nameTextView.setText(PhoneFormat.Instance.format("+" + user.phone)); - } else { - nameTextView.setTextColor(0xff316f9f); - nameTextView.setText(Utilities.formatName(user.first_name, user.last_name)); - } - } - if (encryptedChat != null) { - nameTextView.setTextColor(0xff00a60e); - } - } else { - if (encryptedChat != null) { - nameTextView.setTextColor(0xff00a60e); - } else { - nameTextView.setTextColor(0xff000000); - } - nameTextView.setText(Utilities.formatName(user.first_name, user.last_name)); - } - } - TLRPC.FileLocation photo = null; - int placeHolderId = 0; - if (user != null) { - if (user.photo != null) { - photo = user.photo.photo_small; - } - placeHolderId = Utilities.getUserAvatarForId(user.id); - } else if (chat != null) { - if (chat.photo != null) { - photo = chat.photo.photo_small; - } - placeHolderId = Utilities.getGroupAvatarForId(chat.id); - } - CharSequence printingString = MessagesController.Instance.printingStrings.get(dialog.id); - - avatarImage.setImage(photo, "50_50", placeHolderId); - - if (message == null) { - if (printingString != null) { - messageTextView.setText(printingString); - messageTextView.setTextColor(0xff316f9f); - } else { - if (encryptedChat != null) { - messageTextView.setTextColor(0xff316f9f); - if (encryptedChat instanceof TLRPC.TL_encryptedChatRequested) { - messageTextView.setText(getStringEntry(R.string.EncryptionProcessing)); - } else if (encryptedChat instanceof TLRPC.TL_encryptedChatWaiting) { - messageTextView.setText(String.format(getStringEntry(R.string.AwaitingEncryption), user.first_name)); - } else if (encryptedChat instanceof TLRPC.TL_encryptedChatDiscarded) { - messageTextView.setText(getStringEntry(R.string.EncryptionRejected)); - } else if (encryptedChat instanceof TLRPC.TL_encryptedChat) { - if (encryptedChat.admin_id == UserConfig.clientUserId) { - if (user != null) { - messageTextView.setText(String.format(getStringEntry(R.string.EncryptedChatStartedOutgoing), user.first_name)); - } - } else { - if (user != null) { - messageTextView.setText(String.format(getStringEntry(R.string.EncryptedChatStartedIncoming), user.first_name)); - } - } - } - } else { - messageTextView.setText(""); - } - } - if (dialog.last_message_date != 0) { - timeTextView.setText(Utilities.stringForMessageListDate(dialog.last_message_date)); - } else { - timeTextView.setText(""); - } - messagesCountImage.setVisibility(View.GONE); - check1Image.setVisibility(View.GONE); - check2Image.setVisibility(View.GONE); - errorImage.setVisibility(View.GONE); - clockImage.setVisibility(View.GONE); - } else { - TLRPC.User fromUser = MessagesController.Instance.users.get(message.messageOwner.from_id); - - if (dialog.last_message_date != 0) { - timeTextView.setText(Utilities.stringForMessageListDate(dialog.last_message_date)); - } else { - timeTextView.setText(Utilities.stringForMessageListDate(message.messageOwner.date)); - } - if (printingString != null) { - messageTextView.setTextColor(0xff316f9f); - messageTextView.setText(printingString); - } else { - if (message.messageOwner instanceof TLRPC.TL_messageService) { - messageTextView.setText(message.messageText); - messageTextView.setTextColor(0xff316f9f); - } else { - if (chat != null) { - String name = ""; - if (message.messageOwner.from_id == UserConfig.clientUserId) { - name = getStringEntry(R.string.FromYou); - } else { - if (fromUser != null) { - if (fromUser.first_name.length() > 0) { - name = fromUser.first_name; - } else { - name = fromUser.last_name; - } - } - } - if (message.messageOwner.media != null && !(message.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty)) { - messageTextView.setTextColor(0xff316f9f); - messageTextView.setText(message.messageText); - } else { - messageTextView.setText(Emoji.replaceEmoji(Html.fromHtml(String.format("%s: %s", name, message.messageOwner.message)))); - } - } else { - messageTextView.setText(message.messageText); - if (message.messageOwner.media != null && !(message.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty)) { - messageTextView.setTextColor(0xff316f9f); - } else { - messageTextView.setTextColor(0xff808080); - } - } - } - } - - if (dialog.unread_count != 0) { - messagesCountImage.setVisibility(View.VISIBLE); - messagesCountImage.setText(String.format("%d", dialog.unread_count)); - } else { - messagesCountImage.setVisibility(View.GONE); - } - - if (message.messageOwner.id < 0 && message.messageOwner.send_state != MessagesController.MESSAGE_SEND_STATE_SENT) { - if (MessagesController.Instance.sendingMessages.get(message.messageOwner.id) == null) { - message.messageOwner.send_state = MessagesController.MESSAGE_SEND_STATE_SEND_ERROR; - } - } - - if (message.messageOwner.from_id == UserConfig.clientUserId) { - if (message.messageOwner.send_state == MessagesController.MESSAGE_SEND_STATE_SENDING) { - check1Image.setVisibility(View.GONE); - check2Image.setVisibility(View.GONE); - clockImage.setVisibility(View.VISIBLE); - errorImage.setVisibility(View.GONE); - } else if (message.messageOwner.send_state == MessagesController.MESSAGE_SEND_STATE_SEND_ERROR) { - check1Image.setVisibility(View.GONE); - check2Image.setVisibility(View.GONE); - clockImage.setVisibility(View.GONE); - errorImage.setVisibility(View.VISIBLE); - messagesCountImage.setVisibility(View.GONE); - } else if (message.messageOwner.send_state == MessagesController.MESSAGE_SEND_STATE_SENT) { - if (!message.messageOwner.unread) { - check1Image.setVisibility(View.VISIBLE); - check2Image.setVisibility(View.VISIBLE); - } else { - check1Image.setVisibility(View.GONE); - check2Image.setVisibility(View.VISIBLE); - } - clockImage.setVisibility(View.GONE); - errorImage.setVisibility(View.GONE); - } - } else { - check1Image.setVisibility(View.GONE); - check2Image.setVisibility(View.GONE); - errorImage.setVisibility(View.GONE); - clockImage.setVisibility(View.GONE); - } - } - } - } } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java index de8a6c29e..5365378bb 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/SettingsActivity.java @@ -18,6 +18,7 @@ import android.graphics.Typeface; import android.net.Uri; import android.os.Bundle; import android.support.v7.app.ActionBar; +import android.support.v7.app.ActionBarActivity; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; @@ -28,6 +29,7 @@ import android.widget.ImageButton; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; +import android.widget.Toast; import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.TL.TLObject; @@ -35,11 +37,13 @@ import org.telegram.TL.TLRPC; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLog; import org.telegram.messenger.MessagesController; +import org.telegram.messenger.MessagesStorage; import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.R; import org.telegram.messenger.RPCRequest; import org.telegram.messenger.UserConfig; import org.telegram.messenger.Utilities; +import org.telegram.objects.PhotoObject; import org.telegram.ui.Views.AvatarUpdater; import org.telegram.ui.Views.BackupImageView; import org.telegram.ui.Views.BaseFragment; @@ -67,6 +71,12 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter int logoutRow; int sendLogsRow; int rowCount; + int messagesSectionRow; + int sendByEnterRow; + int terminateSessionsRow; + int photoDownloadSection; + int photoDownloadChatRow; + int photoDownloadPrivateRow; @Override public boolean onFragmentCreate() { @@ -83,7 +93,46 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() { @Override public void run(TLObject response, TLRPC.TL_error error) { - + if (error == null) { + TLRPC.User user = MessagesController.Instance.users.get(UserConfig.clientUserId); + if (user == null) { + user = UserConfig.currentUser; + if (user == null) { + return; + } + MessagesController.Instance.users.put(user.id, user); + } else { + UserConfig.currentUser = user; + } + if (user == null) { + return; + } + TLRPC.TL_photos_photo photo = (TLRPC.TL_photos_photo)response; + ArrayList sizes = photo.photo.sizes; + TLRPC.PhotoSize smallSize = PhotoObject.getClosestPhotoSizeWithSize(sizes, 100, 100); + TLRPC.PhotoSize bigSize = PhotoObject.getClosestPhotoSizeWithSize(sizes, 1000, 1000); + user.photo = new TLRPC.TL_userProfilePhoto(); + user.photo.photo_id = photo.photo.id; + if (smallSize != null) { + user.photo.photo_small = smallSize.location; + } + if (bigSize != null) { + user.photo.photo_big = bigSize.location; + } else if (smallSize != null) { + user.photo.photo_small = smallSize.location; + } + MessagesStorage.Instance.clearUserPhotos(user.id); + ArrayList users = new ArrayList(); + users.add(user); + MessagesStorage.Instance.putUsersAndChats(users, null, false, true); + Utilities.RunOnUIThread(new Runnable() { + @Override + public void run() { + NotificationCenter.Instance.postNotificationName(MessagesController.updateInterfaces, MessagesController.UPDATE_MASK_ALL); + UserConfig.saveConfig(true); + } + }); + } } }, null, true, RPCRequest.RPCRequestClassGeneric); } @@ -96,11 +145,17 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter numberSectionRow = rowCount++; numberRow = rowCount++; settingsSectionRow = rowCount++; - textSizeRow = rowCount++; enableAnimationsRow = rowCount++; notificationRow = rowCount++; blockedRow = rowCount++; backgroundRow = rowCount++; + terminateSessionsRow = rowCount++; + photoDownloadSection = rowCount++; + photoDownloadChatRow = rowCount++; + photoDownloadPrivateRow = rowCount++; + messagesSectionRow = rowCount++; + textSizeRow = rowCount++; + sendByEnterRow = rowCount++; supportSectionRow = rowCount++; if (ConnectionsManager.DEBUG_VERSION) { sendLogsRow = rowCount++; @@ -140,7 +195,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter builder.setItems(new CharSequence[]{String.format("%d", 12), String.format("%d", 13), String.format("%d", 14), String.format("%d", 15), String.format("%d", 16), String.format("%d", 17), String.format("%d", 18), String.format("%d", 19), String.format("%d", 20)}, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); SharedPreferences.Editor editor = preferences.edit(); editor.putInt("fons_size", 12 + which); editor.commit(); @@ -152,7 +207,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter builder.setNegativeButton(getStringEntry(R.string.Cancel), null); builder.show().setCanceledOnTouchOutside(true); } else if (i == enableAnimationsRow) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); boolean animations = preferences.getBoolean("view_animations", true); SharedPreferences.Editor editor = preferences.edit(); editor.putBoolean("view_animations", !animations); @@ -174,6 +229,66 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter ((ApplicationActivity)parentActivity).presentFragment(fragment, "chat" + Math.random(), false); } else if (i == sendLogsRow) { sendLogs(); + } else if (i == sendByEnterRow) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + boolean send = preferences.getBoolean("send_by_enter", false); + SharedPreferences.Editor editor = preferences.edit(); + editor.putBoolean("send_by_enter", !send); + editor.commit(); + if (listView != null) { + listView.invalidateViews(); + } + } else if (i == terminateSessionsRow) { + AlertDialog.Builder builder = new AlertDialog.Builder(parentActivity); + builder.setMessage(getStringEntry(R.string.AreYouSure)); + builder.setTitle(getStringEntry(R.string.AppName)); + builder.setPositiveButton(getStringEntry(R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + TLRPC.TL_auth_resetAuthorizations req = new TLRPC.TL_auth_resetAuthorizations(); + ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(TLObject response, TLRPC.TL_error error) { + ActionBarActivity inflaterActivity = parentActivity; + if (inflaterActivity == null) { + inflaterActivity = (ActionBarActivity)getActivity(); + } + if (inflaterActivity == null) { + return; + } + if (error == null && response instanceof TLRPC.TL_boolTrue) { + Toast toast = Toast.makeText(inflaterActivity, R.string.TerminateAllSessions, Toast.LENGTH_SHORT); + toast.show(); + } else { + Toast toast = Toast.makeText(inflaterActivity, R.string.UnknownError, Toast.LENGTH_SHORT); + toast.show(); + } + UserConfig.registeredForPush = false; + MessagesController.Instance.registerForPush(UserConfig.pushString); + } + }, null, true, RPCRequest.RPCRequestClassGeneric); + } + }); + builder.setNegativeButton(getStringEntry(R.string.Cancel), null); + builder.show().setCanceledOnTouchOutside(true); + } else if (i == photoDownloadChatRow) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + boolean value = preferences.getBoolean("photo_download_chat", true); + SharedPreferences.Editor editor = preferences.edit(); + editor.putBoolean("photo_download_chat", !value); + editor.commit(); + if (listView != null) { + listView.invalidateViews(); + } + } else if (i == photoDownloadPrivateRow) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); + boolean value = preferences.getBoolean("photo_download_user", true); + SharedPreferences.Editor editor = preferences.edit(); + editor.putBoolean("photo_download_user", !value); + editor.commit(); + if (listView != null) { + listView.invalidateViews(); + } } // else if (i == 6) { // UserConfig.saveIncomingPhotos = !UserConfig.saveIncomingPhotos; @@ -209,8 +324,11 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter @Override public void didReceivedNotification(int id, Object... args) { if (id == MessagesController.updateInterfaces) { - if (listView != null) { - listView.invalidateViews(); + int mask = (Integer)args[0]; + if ((mask & MessagesController.UPDATE_MASK_AVATAR) != 0 || (mask & MessagesController.UPDATE_MASK_NAME) != 0) { + if (listView != null) { + listView.invalidateViews(); + } } } } @@ -307,7 +425,9 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter @Override public boolean isEnabled(int i) { - return i == textSizeRow || i == enableAnimationsRow || i == blockedRow || i == notificationRow || i == backgroundRow || i == askQuestionRow || i == sendLogsRow; + return i == textSizeRow || i == enableAnimationsRow || i == blockedRow || i == notificationRow || i == backgroundRow || + i == askQuestionRow || i == sendLogsRow || i == sendByEnterRow || i == terminateSessionsRow || i == photoDownloadPrivateRow || + i == photoDownloadChatRow; } @Override @@ -405,7 +525,30 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() { @Override public void run(TLObject response, TLRPC.TL_error error) { - + if (error == null) { + TLRPC.User user = MessagesController.Instance.users.get(UserConfig.clientUserId); + if (user == null) { + user = UserConfig.currentUser; + MessagesController.Instance.users.put(user.id, user); + } else { + UserConfig.currentUser = user; + } + if (user == null) { + return; + } + MessagesStorage.Instance.clearUserPhotos(user.id); + ArrayList users = new ArrayList(); + users.add(user); + MessagesStorage.Instance.putUsersAndChats(users, null, false, true); + user.photo = (TLRPC.UserProfilePhoto)response; + Utilities.RunOnUIThread(new Runnable() { + @Override + public void run() { + NotificationCenter.Instance.postNotificationName(MessagesController.updateInterfaces, MessagesController.UPDATE_MASK_ALL); + UserConfig.saveConfig(true); + } + }); + } } }, null, true, RPCRequest.RPCRequestClassGeneric); } @@ -444,6 +587,10 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter textView.setText(getStringEntry(R.string.SETTINGS)); } else if (i == supportSectionRow) { textView.setText(getStringEntry(R.string.Support)); + } else if (i == messagesSectionRow) { + textView.setText(getStringEntry(R.string.MessagesSettings)); + } else if (i == photoDownloadSection) { + textView.setText(getStringEntry(R.string.AutomaticPhotoDownload)); } } else if (type == 2) { if (view == null) { @@ -468,13 +615,16 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter divider.setVisibility(backgroundRow != 0 ? View.VISIBLE : View.INVISIBLE); } else if (i == backgroundRow) { textView.setText(getStringEntry(R.string.ChatBackground)); - divider.setVisibility(View.INVISIBLE); + divider.setVisibility(View.VISIBLE); } else if (i == sendLogsRow) { textView.setText("Send Logs"); divider.setVisibility(View.VISIBLE); } else if (i == askQuestionRow) { textView.setText(getStringEntry(R.string.AskAQuestion)); divider.setVisibility(View.INVISIBLE); + } else if (i == terminateSessionsRow) { + textView.setText(getStringEntry(R.string.TerminateAllSessions)); + divider.setVisibility(View.INVISIBLE); } } else if (type == 3) { if (view == null) { @@ -483,14 +633,40 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter } TextView textView = (TextView)view.findViewById(R.id.settings_row_text); View divider = view.findViewById(R.id.settings_row_divider); + ImageView checkButton = (ImageView)view.findViewById(R.id.settings_row_check_button); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); if (i == enableAnimationsRow) { textView.setText(getStringEntry(R.string.EnableAnimations)); divider.setVisibility(View.VISIBLE); - - ImageView checkButton = (ImageView)view.findViewById(R.id.settings_row_check_button); - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); - boolean animations = preferences.getBoolean("view_animations", true); - if (animations) { + boolean enabled = preferences.getBoolean("view_animations", true); + if (enabled) { + checkButton.setImageResource(R.drawable.btn_check_on); + } else { + checkButton.setImageResource(R.drawable.btn_check_off); + } + } else if (i == sendByEnterRow) { + textView.setText(getStringEntry(R.string.SendByEnter)); + divider.setVisibility(View.INVISIBLE); + boolean enabled = preferences.getBoolean("send_by_enter", false); + if (enabled) { + checkButton.setImageResource(R.drawable.btn_check_on); + } else { + checkButton.setImageResource(R.drawable.btn_check_off); + } + } else if (i == photoDownloadChatRow) { + textView.setText(getStringEntry(R.string.AutomaticPhotoDownloadGroups)); + divider.setVisibility(View.VISIBLE); + boolean enabled = preferences.getBoolean("photo_download_chat", true); + if (enabled) { + checkButton.setImageResource(R.drawable.btn_check_on); + } else { + checkButton.setImageResource(R.drawable.btn_check_off); + } + } else if (i == photoDownloadPrivateRow) { + textView.setText(getStringEntry(R.string.AutomaticPhotoDownloadPrivateChats)); + divider.setVisibility(View.INVISIBLE); + boolean enabled = preferences.getBoolean("photo_download_user", true); + if (enabled) { checkButton.setImageResource(R.drawable.btn_check_on); } else { checkButton.setImageResource(R.drawable.btn_check_off); @@ -541,7 +717,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter TextView detailTextView = (TextView)view.findViewById(R.id.settings_row_text_detail); View divider = view.findViewById(R.id.settings_row_divider); if (i == textSizeRow) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); int size = preferences.getInt("fons_size", 16); detailTextView.setText(String.format("%d", size)); textView.setText(ApplicationLoader.applicationContext.getString(R.string.TextSize)); @@ -556,13 +732,13 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter public int getItemViewType(int i) { if (i == profileRow) { return 0; - } else if (i == numberSectionRow || i == settingsSectionRow || i == supportSectionRow) { + } else if (i == numberSectionRow || i == settingsSectionRow || i == supportSectionRow || i == messagesSectionRow || i == photoDownloadSection) { return 1; } else if (i == textSizeRow) { return 5; - } else if (i == enableAnimationsRow) { + } else if (i == enableAnimationsRow || i == sendByEnterRow || i == photoDownloadChatRow || i == photoDownloadPrivateRow) { return 3; - } else if (i == numberRow || i == notificationRow || i == blockedRow || i == backgroundRow || i == askQuestionRow || i == sendLogsRow) { + } else if (i == numberRow || i == notificationRow || i == blockedRow || i == backgroundRow || i == askQuestionRow || i == sendLogsRow || i == terminateSessionsRow) { return 2; } else if (i == logoutRow) { return 4; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/SettingsBlockedUsers.java b/TMessagesProj/src/main/java/org/telegram/ui/SettingsBlockedUsers.java index 8d0898f9a..5febab5b8 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/SettingsBlockedUsers.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/SettingsBlockedUsers.java @@ -13,7 +13,6 @@ import android.content.Context; import android.content.DialogInterface; import android.os.Bundle; import android.support.v7.app.ActionBar; -import android.text.Html; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -34,6 +33,7 @@ import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.R; import org.telegram.messenger.RPCRequest; import org.telegram.messenger.Utilities; +import org.telegram.ui.Cells.ChatOrUserCell; import org.telegram.ui.Views.BaseFragment; import org.telegram.ui.Views.OnSwipeTouchListener; @@ -118,14 +118,10 @@ public class SettingsBlockedUsers extends BaseFragment implements NotificationCe if (i == 0) { TLRPC.TL_contacts_unblock req = new TLRPC.TL_contacts_unblock(); TLRPC.User user = MessagesController.Instance.users.get(selectedUserId); - if (user instanceof TLRPC.TL_userForeign || user instanceof TLRPC.TL_userRequest) { - req.id = new TLRPC.TL_inputUserForeign(); - req.id.user_id = selectedUserId; - req.id.access_hash = user.access_hash; - } else { - req.id = new TLRPC.TL_inputUserContact(); - req.id.user_id = selectedUserId; + if (user == null) { + return; } + req.id = MessagesController.getInputUser(user); TLRPC.TL_contactBlocked blocked = blockedContactsDict.get(selectedUserId); blockedContactsDict.remove(selectedUserId); blockedContacts.remove(blocked); @@ -229,8 +225,22 @@ public class SettingsBlockedUsers extends BaseFragment implements NotificationCe @Override public void didReceivedNotification(int id, Object... args) { if (id == MessagesController.updateInterfaces) { - if (listView != null) { - listView.invalidateViews(); + int mask = (Integer)args[0]; + if ((mask & MessagesController.UPDATE_MASK_AVATAR) != 0 || (mask & MessagesController.UPDATE_MASK_NAME) != 0) { + updateVisibleRows(mask); + } + } + } + + private void updateVisibleRows(int mask) { + if (listView == null) { + return; + } + int count = listView.getChildCount(); + for (int a = 0; a < count; a++) { + View child = listView.getChildAt(a); + if (child instanceof ChatOrUserCell) { + ((ChatOrUserCell) child).update(mask); } } } @@ -307,22 +317,14 @@ public class SettingsBlockedUsers extends BaseFragment implements NotificationCe } @Override - public void didSelectContact(int user_id) { - if (blockedContactsDict.containsKey(user_id)) { + public void didSelectContact(TLRPC.User user) { + if (user == null || blockedContactsDict.containsKey(user.id)) { return; } TLRPC.TL_contacts_block req = new TLRPC.TL_contacts_block(); - TLRPC.User user = MessagesController.Instance.users.get(selectedUserId); - if (user instanceof TLRPC.TL_userForeign || user instanceof TLRPC.TL_userRequest) { - req.id = new TLRPC.TL_inputUserForeign(); - req.id.access_hash = user.access_hash; - req.id.user_id = user_id; - } else { - req.id = new TLRPC.TL_inputUserContact(); - req.id.user_id = user_id; - } + req.id = MessagesController.getInputUser(user); TLRPC.TL_contactBlocked blocked = new TLRPC.TL_contactBlocked(); - blocked.user_id = user_id; + blocked.user_id = user.id; blocked.date = (int)(System.currentTimeMillis() / 1000); blockedContactsDict.put(blocked.user_id, blocked); blockedContacts.add(blocked); @@ -380,41 +382,13 @@ public class SettingsBlockedUsers extends BaseFragment implements NotificationCe int type = getItemViewType(i); if (type == 0) { if (view == null) { - LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - view = li.inflate(R.layout.messages_search_user_layout, viewGroup, false); + view = new ChatOrUserCell(mContext); + ((ChatOrUserCell)view).useBoldFont = true; + ((ChatOrUserCell)view).usePadding = false; + ((ChatOrUserCell)view).useSeparator = true; } - ContactsActivity.ContactListRowHolder holder = (ContactsActivity.ContactListRowHolder)view.getTag(); - if (holder == null) { - holder = new ContactsActivity.ContactListRowHolder(view); - view.setTag(holder); - } - - View divider = view.findViewById(R.id.settings_row_divider); - divider.setVisibility(View.VISIBLE); - TLRPC.User user = MessagesController.Instance.users.get(blockedContacts.get(i).user_id); - - TLRPC.FileLocation photo = null; - if (user.first_name.length() != 0 && user.last_name.length() != 0) { - holder.nameTextView.setText(Html.fromHtml(user.first_name + " " + user.last_name + "")); - } else if (user.first_name.length() != 0) { - holder.nameTextView.setText(Html.fromHtml("" + user.first_name + "")); - } else { - holder.nameTextView.setText(Html.fromHtml("" + user.last_name + "")); - } - if (user.photo != null) { - photo = user.photo.photo_small; - } - int placeHolderId = Utilities.getUserAvatarForId(user.id); - holder.avatarImage.setImage(photo, "50_50", placeHolderId); - - holder.messageTextView.setTextColor(0xff808080); - - if (user.phone != null && user.phone.length() != 0) { - holder.messageTextView.setText(PhoneFormat.Instance.format("+" + user.phone)); - } else { - holder.messageTextView.setText("Unknown"); - } + ((ChatOrUserCell)view).setData(user, null, null, null, user.phone != null && user.phone.length() != 0 ? PhoneFormat.Instance.format("+" + user.phone) : "Unknown"); } else if (type == 1) { if (view == null) { LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/SettingsChangeNameActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/SettingsChangeNameActivity.java index 590cdfeef..07d736a47 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/SettingsChangeNameActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/SettingsChangeNameActivity.java @@ -82,7 +82,7 @@ public class SettingsChangeNameActivity extends BaseFragment { } }); - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); boolean animations = preferences.getBoolean("view_animations", true); if (!animations) { firstNameField.requestFocus(); @@ -171,6 +171,9 @@ public class SettingsChangeNameActivity extends BaseFragment { private void saveName() { TLRPC.TL_account_updateProfile req = new TLRPC.TL_account_updateProfile(); + if (UserConfig.currentUser == null || lastNameField.getText() == null || firstNameField.getText() == null) { + return; + } UserConfig.currentUser.first_name = req.first_name = firstNameField.getText().toString(); UserConfig.currentUser.last_name = req.last_name = lastNameField.getText().toString(); TLRPC.User user = MessagesController.Instance.users.get(UserConfig.clientUserId); @@ -179,7 +182,7 @@ public class SettingsChangeNameActivity extends BaseFragment { user.last_name = req.last_name; } UserConfig.saveConfig(true); - NotificationCenter.Instance.postNotificationName(MessagesController.updateInterfaces, MessagesController.UPDATE_MASK_ALL); + NotificationCenter.Instance.postNotificationName(MessagesController.updateInterfaces, MessagesController.UPDATE_MASK_NAME); ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() { @Override public void run(TLObject response, TLRPC.TL_error error) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/SettingsNotificationsActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/SettingsNotificationsActivity.java index d14174b20..18d1dba47 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/SettingsNotificationsActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/SettingsNotificationsActivity.java @@ -34,6 +34,7 @@ import org.telegram.TL.TLObject; import org.telegram.TL.TLRPC; import org.telegram.messenger.ConnectionsManager; import org.telegram.messenger.FileLog; +import org.telegram.messenger.MessagesController; import org.telegram.messenger.R; import org.telegram.messenger.RPCRequest; import org.telegram.messenger.Utilities; @@ -138,7 +139,7 @@ public class SettingsNotificationsActivity extends BaseFragment { } catch (Exception e) { FileLog.e("tmessages", e); } - } else if (i == 15) { + } else if (i == 17) { if (reseting) { return; } @@ -150,6 +151,7 @@ public class SettingsNotificationsActivity extends BaseFragment { Utilities.RunOnUIThread(new Runnable() { @Override public void run() { + MessagesController.Instance.enableJoined = true; ActionBarActivity inflaterActivity = parentActivity; if (inflaterActivity == null) { inflaterActivity = (ActionBarActivity)getActivity(); @@ -190,6 +192,14 @@ public class SettingsNotificationsActivity extends BaseFragment { editor.putBoolean("EnableInAppPreview", !enabled); editor.commit(); listView.invalidateViews(); + } else if (i == 15) { + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences.Editor editor = preferences.edit(); + boolean enabled = preferences.getBoolean("EnableContactJoined", true); + MessagesController.Instance.enableJoined = !enabled; + editor.putBoolean("EnableContactJoined", !enabled); + editor.commit(); + listView.invalidateViews(); } } }); @@ -318,12 +328,15 @@ public class SettingsNotificationsActivity extends BaseFragment { public boolean isEnabled(int i) { SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); boolean enabledAll = preferences.getBoolean("EnableAll", true); - return !(i != 1 && !enabledAll && i != 13) && (i > 0 && i < 5 || i > 5 && i < 10 || i > 10 && i < 14 || i == 15); + if (i == 17 || i == 15) { + return true; + } + return !(i != 1 && !enabledAll && i != 13) && (i > 0 && i < 5 || i > 5 && i < 10 || i > 10 && i < 14); } @Override public int getCount() { - return 16; + return 18; } @Override @@ -357,6 +370,8 @@ public class SettingsNotificationsActivity extends BaseFragment { } else if (i == 10) { textView.setText(getStringEntry(R.string.InAppNotifications)); } else if (i == 14) { + textView.setText(getStringEntry(R.string.Events)); + } else if (i == 16) { textView.setText(getStringEntry(R.string.Reset)); } } if (type == 1) { @@ -408,13 +423,17 @@ public class SettingsNotificationsActivity extends BaseFragment { enabled = preferences.getBoolean("EnableInAppPreview", true); textView.setText(getStringEntry(R.string.InAppPreview)); divider.setVisibility(View.INVISIBLE); + } else if (i == 15) { + enabled = preferences.getBoolean("EnableContactJoined", true); + textView.setText(getStringEntry(R.string.ContactJoined)); + divider.setVisibility(View.INVISIBLE); } if (enabled) { checkButton.setImageResource(R.drawable.btn_check_on); } else { checkButton.setImageResource(R.drawable.btn_check_off); } - if (i != 1 && !enabledAll) { + if (i != 1 && !enabledAll && i != 15) { view.setEnabled(false); if(android.os.Build.VERSION.SDK_INT >= 11) { checkButton.setAlpha(0.3f); @@ -455,12 +474,12 @@ public class SettingsNotificationsActivity extends BaseFragment { } textView.setText(getStringEntry(R.string.Sound)); divider.setVisibility(View.INVISIBLE); - } else if (i == 15) { + } else if (i == 17) { textView.setText(getStringEntry(R.string.ResetAllNotifications)); textViewDetail.setText(getStringEntry(R.string.UndoAllCustom)); divider.setVisibility(View.INVISIBLE); } - if (i != 15 && !enabledAll) { + if (i != 17 && !enabledAll) { view.setEnabled(false); if(android.os.Build.VERSION.SDK_INT >= 11) { textView.setAlpha(0.3f); @@ -482,9 +501,9 @@ public class SettingsNotificationsActivity extends BaseFragment { @Override public int getItemViewType(int i) { - if (i == 0 || i == 5 || i == 10 || i == 14) { + if (i == 0 || i == 5 || i == 10 || i == 14 || i == 16) { return 0; - } else if (i > 0 && i < 4 || i > 5 && i < 9 || i > 10 && i < 14) { + } else if (i > 0 && i < 4 || i > 5 && i < 9 || i > 10 && i < 14 || i == 15) { return 1; } else { return 2; diff --git a/TMessagesProj/src/main/java/org/telegram/ui/SettingsWallpapersActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/SettingsWallpapersActivity.java index 9e34e3a53..f793dd5ef 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/SettingsWallpapersActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/SettingsWallpapersActivity.java @@ -73,7 +73,7 @@ public class SettingsWallpapersActivity extends BaseFragment implements Notifica NotificationCenter.Instance.addObserver(this, FileLoader.FileLoadProgressChanged); NotificationCenter.Instance.addObserver(this, MessagesStorage.wallpapersDidLoaded); - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); selectedBackground = preferences.getInt("selectedBackground", 1000001); selectedColor = preferences.getInt("selectedColor", 0); MessagesStorage.Instance.getWallpapers(); @@ -165,7 +165,7 @@ public class SettingsWallpapersActivity extends BaseFragment implements Notifica } if (done) { - SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE); + SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); SharedPreferences.Editor editor = preferences.edit(); editor.putInt("selectedBackground", selectedBackground); editor.putInt("selectedColor", selectedColor); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/UserProfileActivity.java b/TMessagesProj/src/main/java/org/telegram/ui/UserProfileActivity.java index 84ad77958..279b95569 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/UserProfileActivity.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/UserProfileActivity.java @@ -21,6 +21,7 @@ import android.net.Uri; import android.os.Bundle; import android.provider.Settings; import android.support.v7.app.ActionBar; +import android.support.v7.app.ActionBarActivity; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -39,6 +40,7 @@ import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.TL.TLObject; import org.telegram.TL.TLRPC; import org.telegram.messenger.ConnectionsManager; +import org.telegram.messenger.ContactsController; import org.telegram.messenger.FileLog; import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesStorage; @@ -51,6 +53,8 @@ import org.telegram.ui.Views.BaseFragment; import org.telegram.ui.Views.IdenticonView; import org.telegram.ui.Views.OnSwipeTouchListener; +import java.util.ArrayList; + public class UserProfileActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate, MessagesActivity.MessagesActivityDelegate { private ListView listView; private ListAdapter listAdapter; @@ -104,7 +108,7 @@ public class UserProfileActivity extends BaseFragment implements NotificationCen @Override public void onClick(View view) { creatingChat = true; - MessagesController.Instance.startSecretChat(parentActivity, user_id); + MessagesController.Instance.startSecretChat(parentActivity, MessagesController.Instance.users.get(user_id)); } }); if (dialog_id == 0) { @@ -282,8 +286,11 @@ public class UserProfileActivity extends BaseFragment implements NotificationCen public void didReceivedNotification(int id, Object... args) { if (id == MessagesController.updateInterfaces) { - if (listView != null) { - listView.invalidateViews(); + int mask = (Integer)args[0]; + if ((mask & MessagesController.UPDATE_MASK_AVATAR) != 0 || (mask & MessagesController.UPDATE_MASK_NAME) != 0) { + if (listView != null) { + listView.invalidateViews(); + } } } else if (id == MessagesController.contactsDidLoaded) { if (parentActivity != null) { @@ -409,16 +416,12 @@ public class UserProfileActivity extends BaseFragment implements NotificationCen finishFragment(); break; case R.id.block_contact: { - TLRPC.TL_contacts_block req = new TLRPC.TL_contacts_block(); TLRPC.User user = MessagesController.Instance.users.get(user_id); - if (user instanceof TLRPC.TL_userForeign || user instanceof TLRPC.TL_userRequest) { - req.id = new TLRPC.TL_inputUserForeign(); - req.id.access_hash = user.access_hash; - req.id.user_id = user_id; - } else { - req.id = new TLRPC.TL_inputUserContact(); - req.id.user_id = user_id; + if (user == null) { + break; } + TLRPC.TL_contacts_block req = new TLRPC.TL_contacts_block(); + req.id = MessagesController.getInputUser(user); TLRPC.TL_contactBlocked blocked = new TLRPC.TL_contactBlocked(); blocked.user_id = user_id; blocked.date = (int)(System.currentTimeMillis() / 1000); @@ -449,14 +452,51 @@ public class UserProfileActivity extends BaseFragment implements NotificationCen ((ApplicationActivity)parentActivity).presentFragment(fragment, "chat_select", false); break; } + case R.id.edit_contact: { + ContactAddActivity fragment = new ContactAddActivity(); + Bundle args = new Bundle(); + args.putInt("user_id", user_id); + fragment.setArguments(args); + ((ApplicationActivity)parentActivity).presentFragment(fragment, "add_contact_" + user_id, false); + break; + } + case R.id.delete_contact: { + final TLRPC.User user = MessagesController.Instance.users.get(user_id); + if (user == null) { + break; + } + AlertDialog.Builder builder = new AlertDialog.Builder(parentActivity); + builder.setMessage(getStringEntry(R.string.AreYouSure)); + builder.setTitle(getStringEntry(R.string.AppName)); + builder.setPositiveButton(getStringEntry(R.string.OK), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + TLRPC.TL_auth_resetAuthorizations req = new TLRPC.TL_auth_resetAuthorizations(); + ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() { + @Override + public void run(TLObject response, TLRPC.TL_error error) { + ArrayList arrayList = new ArrayList(); + arrayList.add(user); + ContactsController.Instance.deleteContact(arrayList); + } + }, null, true, RPCRequest.RPCRequestClassGeneric); + } + }); + builder.setNegativeButton(getStringEntry(R.string.Cancel), null); + builder.show().setCanceledOnTouchOutside(true); + break; + } } return true; } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - if (MessagesController.Instance.contactsDict.get(user_id) == null) { + if (ContactsController.Instance.contactsDict.get(user_id) == null) { TLRPC.User user = MessagesController.Instance.users.get(user_id); + if (user == null) { + return; + } if (user.phone != null && user.phone.length() != 0) { inflater.inflate(R.menu.user_profile_menu, menu); } else { @@ -608,7 +648,7 @@ public class UserProfileActivity extends BaseFragment implements NotificationCen if (value == 0) { value = user.status.expires; } - onlineText.setText(String.format("%s %s", getStringEntry(R.string.LastSeen), Utilities.formatDateOnline(value))); + onlineText.setText(Utilities.formatDateOnline(value)); } } } @@ -661,12 +701,19 @@ public class UserProfileActivity extends BaseFragment implements NotificationCen FileLog.e("tmessages", e); } } else if (i == 0) { + ActionBarActivity inflaterActivity = parentActivity; + if (inflaterActivity == null) { + inflaterActivity = (ActionBarActivity)getActivity(); + } + if (inflaterActivity == null) { + return; + } int sdk = android.os.Build.VERSION.SDK_INT; if(sdk < android.os.Build.VERSION_CODES.HONEYCOMB) { - android.text.ClipboardManager clipboard = (android.text.ClipboardManager)parentActivity.getSystemService(Context.CLIPBOARD_SERVICE); + android.text.ClipboardManager clipboard = (android.text.ClipboardManager)inflaterActivity.getSystemService(Context.CLIPBOARD_SERVICE); clipboard.setText(selectedPhone); } else { - android.content.ClipboardManager clipboard = (android.content.ClipboardManager)parentActivity.getSystemService(Context.CLIPBOARD_SERVICE); + android.content.ClipboardManager clipboard = (android.content.ClipboardManager)inflaterActivity.getSystemService(Context.CLIPBOARD_SERVICE); android.content.ClipData clip = android.content.ClipData.newPlainText("label", selectedPhone); clipboard.setPrimaryClip(clip); } diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/ImageReceiver.java b/TMessagesProj/src/main/java/org/telegram/ui/Views/ImageReceiver.java new file mode 100644 index 000000000..65759ac27 --- /dev/null +++ b/TMessagesProj/src/main/java/org/telegram/ui/Views/ImageReceiver.java @@ -0,0 +1,169 @@ +/* + * This is the source code of Telegram for Android v. 1.3.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. + */ + +package org.telegram.ui.Views; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.view.View; + +import org.telegram.TL.TLRPC; +import org.telegram.messenger.FileLoader; +import org.telegram.messenger.FileLog; +import org.telegram.messenger.Utilities; + +import java.lang.ref.WeakReference; + +public class ImageReceiver { + private TLRPC.FileLocation last_path = null; + private String last_httpUrl = null; + private String last_filter = null; + private Drawable last_placeholder = null; + private int last_size = 0; + private String currentPath = null; + private boolean isPlaceholder = false; + private Drawable currentImage = null; + public Integer TAG = null; + public WeakReference parentView = null; + public int imageX = 0, imageY = 0, imageW = 0, imageH = 0; + + public void setImage(TLRPC.FileLocation path, String filter, Drawable placeholder) { + setImage(path, null, filter, placeholder, 0); + } + + public void setImage(TLRPC.FileLocation path, String filter, Drawable placeholder, int size) { + setImage(path, null, filter, placeholder, size); + } + + public void setImage(String path, String filter, Drawable placeholder) { + setImage(null, path, filter, placeholder, 0); + } + + public void setImage(TLRPC.FileLocation path, String httpUrl, String filter, Drawable placeholder, int size) { + if ((path == null && httpUrl == null) || (path != null && !(path instanceof TLRPC.TL_fileLocation) && !(path instanceof TLRPC.TL_fileEncryptedLocation))) { + recycleBitmap(null); + currentPath = null; + isPlaceholder = true; + last_path = null; + last_httpUrl = null; + last_filter = null; + last_placeholder = placeholder; + last_size = 0; + currentImage = null; + FileLoader.Instance.cancelLoadingForImageView(this); + return; + } + String key; + if (path != null) { + key = path.volume_id + "_" + path.local_id; + } else { + key = Utilities.MD5(httpUrl); + } + if (filter != null) { + key += "@" + filter; + } + Bitmap img; + if (currentPath != null) { + if (currentPath.equals(key)) { + return; + } else { + img = FileLoader.Instance.getImageFromMemory(path, httpUrl, this, filter, true); + recycleBitmap(img); + } + } else { + img = FileLoader.Instance.getImageFromMemory(path, httpUrl, this, filter, true); + } + currentPath = key; + last_path = path; + last_httpUrl = httpUrl; + last_filter = filter; + last_placeholder = placeholder; + last_size = size; + if (img == null) { + isPlaceholder = true; + FileLoader.Instance.loadImage(path, httpUrl, this, filter, true, size); + } else { + setImageBitmap(img, currentPath); + } + } + + public void setImageBitmap(Bitmap bitmap, String imgKey) { + if (currentPath == null || !imgKey.equals(currentPath)) { + return; + } + isPlaceholder = false; + FileLoader.Instance.incrementUseCount(currentPath); + currentImage = new BitmapDrawable(null, bitmap); + if (parentView.get() != null) { + if (imageW != 0) { + parentView.get().invalidate(imageX, imageY, imageX + imageW, imageY + imageH); + } else { + parentView.get().invalidate(); + } + } + } + + public void clearImage() { + recycleBitmap(null); + } + + private void recycleBitmap(Bitmap newBitmap) { + if (currentImage == null || isPlaceholder) { + return; + } + if (currentImage instanceof BitmapDrawable) { + Bitmap bitmap = ((BitmapDrawable)currentImage).getBitmap(); + if (bitmap != null && bitmap != newBitmap) { + if (currentPath != null) { + boolean canDelete = FileLoader.Instance.decrementUseCount(currentPath); + if (!FileLoader.Instance.isInCache(currentPath)) { + if (FileLoader.Instance.runtimeHack != null) { + FileLoader.Instance.runtimeHack.trackAlloc(bitmap.getRowBytes() * bitmap.getHeight()); + } + if (canDelete) { + currentImage = null; + if (Build.VERSION.SDK_INT < 11) { + bitmap.recycle(); + } + } + } else { + currentImage = null; + } + } + } + } + } + + public void draw(Canvas canvas, int x, int y, int w, int h) { + try { + if (currentImage != null) { + currentImage.setBounds(x, y, x + w, y + h); + currentImage.draw(canvas); + } else if (last_placeholder != null) { + last_placeholder.setBounds(x, y, x + w, y + h); + last_placeholder.draw(canvas); + } + } catch (Exception e) { + if (currentPath != null) { + FileLoader.Instance.removeImage(currentPath); + currentPath = null; + } + setImage(last_path, last_httpUrl, last_filter, last_placeholder, last_size); + FileLog.e("tmessages", e); + } + } + + @Override + protected void finalize() throws Throwable { + recycleBitmap(null); + super.finalize(); + } +} diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/NotificationView.java b/TMessagesProj/src/main/java/org/telegram/ui/Views/NotificationView.java index a73eb234a..17c64028a 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/NotificationView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Views/NotificationView.java @@ -32,7 +32,6 @@ import org.telegram.messenger.Utilities; import org.telegram.objects.MessageObject; import org.telegram.ui.ApplicationLoader; -import java.util.Locale; import java.util.Timer; import java.util.TimerTask; @@ -52,7 +51,7 @@ public class NotificationView extends LinearLayout { private int currentUserId = 0; private int currentEncId = 0; private boolean isVisible; - private boolean isRTL = false; + private final Integer timerSync = 1; public NotificationView(Context context) { super(context); @@ -78,9 +77,11 @@ public class NotificationView extends LinearLayout { @Override public void onClick(View v) { try { - if (hideTimer != null) { - hideTimer.cancel(); - hideTimer = null; + synchronized (timerSync) { + if (hideTimer != null) { + hideTimer.cancel(); + hideTimer = null; + } } } catch (Exception e) { FileLog.e("tmessages", e); @@ -89,19 +90,15 @@ public class NotificationView extends LinearLayout { } }); - Locale locale = Locale.getDefault(); - String lang = locale.getLanguage(); - if (lang != null && lang.toLowerCase().equals("ar")) { - isRTL = true; - } - this.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { try { - if (hideTimer != null) { - hideTimer.cancel(); - hideTimer = null; + synchronized (timerSync) { + if (hideTimer != null) { + hideTimer.cancel(); + hideTimer = null; + } } } catch (Exception e) { FileLog.e("tmessages", e); @@ -211,9 +208,11 @@ public class NotificationView extends LinearLayout { avatarImage.setImage(photo, "50_50", Utilities.getUserAvatarForId(user.id)); try { - if (hideTimer != null) { - hideTimer.cancel(); - hideTimer = null; + synchronized (timerSync) { + if (hideTimer != null) { + hideTimer.cancel(); + hideTimer = null; + } } hideTimer = new Timer(); hideTimer.schedule(new TimerTask() { @@ -226,8 +225,12 @@ public class NotificationView extends LinearLayout { } }); try { - hideTimer.cancel(); - hideTimer = null; + synchronized (timerSync) { + if (hideTimer != null) { + hideTimer.cancel(); + hideTimer = null; + } + } } catch (Exception e) { FileLog.e("tmessages", e); } @@ -251,9 +254,11 @@ public class NotificationView extends LinearLayout { startAnimation(animHide); } else { try { - if (hideTimer != null) { - hideTimer.cancel(); - hideTimer = null; + synchronized (timerSync) { + if (hideTimer != null) { + hideTimer.cancel(); + hideTimer = null; + } } } catch (Exception e) { FileLog.e("tmessages", e); @@ -300,7 +305,7 @@ public class NotificationView extends LinearLayout { messageTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14); nameTextView.setPadding(0, Utilities.dp(2), 0, 0); messageTextView.setPadding(0, Utilities.dp(18), 0, 0); - if (isRTL) { + if (Utilities.isRTL) { params1.setMargins(Utilities.dp(40), 0, height + Utilities.dp(6), 0); } else { params1.setMargins(height + Utilities.dp(6), 0, Utilities.dp(40), 0); @@ -310,7 +315,7 @@ public class NotificationView extends LinearLayout { messageTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15); nameTextView.setPadding(0, Utilities.dp(4), 0, 0); messageTextView.setPadding(0, Utilities.dp(24), 0, 0); - if (isRTL) { + if (Utilities.isRTL) { params1.setMargins(Utilities.dp(40), 0, height + Utilities.dp(8), 0); } else { params1.setMargins(height + Utilities.dp(8), 0, Utilities.dp(40), 0); diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/PagerSlidingTabStrip.java b/TMessagesProj/src/main/java/org/telegram/ui/Views/PagerSlidingTabStrip.java index 18c9be2a0..bf7cb0858 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/PagerSlidingTabStrip.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Views/PagerSlidingTabStrip.java @@ -256,7 +256,7 @@ public class PagerSlidingTabStrip extends HorizontalScrollView { }); tabsContainer.addView(tab); - + tab.setSelected(position == currentPosition); } private void updateExpanded() { @@ -309,21 +309,6 @@ public class PagerSlidingTabStrip extends HorizontalScrollView { int myWidth = getMeasuredWidth(); tabsContainer.measure(MeasureSpec.EXACTLY | myWidth, heightMeasureSpec); - /*int childWidth = 0; - for (int i = 0; i < tabCount; i++) { - childWidth += tabsContainer.getChildAt(i).getMeasuredWidth(); - } - - if (!checkedTabWidths && childWidth > 0 && myWidth > 0) { - - if (childWidth <= myWidth) { - for (int i = 0; i < tabCount; i++) { - tabsContainer.getChildAt(i).setLayoutParams(expandedTabLayoutParams); - } - } - - checkedTabWidths = true; - }*/ } private void scrollToChild(int position, int offset) { diff --git a/TMessagesProj/src/main/java/org/telegram/ui/Views/TightTextView.java b/TMessagesProj/src/main/java/org/telegram/ui/Views/TightTextView.java index f4ed8c2df..2aa782a37 100644 --- a/TMessagesProj/src/main/java/org/telegram/ui/Views/TightTextView.java +++ b/TMessagesProj/src/main/java/org/telegram/ui/Views/TightTextView.java @@ -94,6 +94,12 @@ public class TightTextView extends TextView { } } catch (Exception e) { FileLog.e("tmessages", e); + try { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } catch (Exception e2) { + setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec)); + FileLog.e("tmessages", e2); + } } } diff --git a/TMessagesProj/src/main/res/drawable-hdpi/photocancel.png b/TMessagesProj/src/main/res/drawable-hdpi/photocancel.png new file mode 100755 index 0000000000000000000000000000000000000000..24328d56822e1073f6d86ae5bb29cb2077b6492c GIT binary patch literal 1154 zcmV-|1bzF7P)0i2OCXEyS7 zB$bF%029QVF zMFDl{!eE35gUF-p%T(D+A}UNW5kPvSx3~9+0pt$}5N28t9*^g)*=)`;fc!x-S1-EO zqlkuvhV7b~nwvRbi9}+rv$OO0@bK`m;727)G@lV_81r7Q_t8PWVltU~dU`r|EB0}- zB^2;eGtB2D8m;>6n*$>gg7XRni^WC?U96ACC(ey#f@kRna`jA~0O$D91B>0HWt` zB6ED>rMmIgXDlKDij8T}Z66t-t5B@8_0Oeg3 U&J%DrumAu607*qoM6N<$f;fQ(lK=n! literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/res/drawable-hdpi/photocancel_pressed.png b/TMessagesProj/src/main/res/drawable-hdpi/photocancel_pressed.png new file mode 100755 index 0000000000000000000000000000000000000000..39d9fbfe7a3f2644b791a4d233d6f01ba40dd00d GIT binary patch literal 1165 zcmV;81akX{P)q&Kic57X{G|k?7is{sk|*7fBGW?IJ>R7a3_6 z{jflg3?!1$nbj~QQ8$0roc6x-PUiSFzjMCx&H2EC!|mJmJUi#S?|a_!r7$^210Dw! z0&{^Dpbeo8v%T?iX}hX zz)Up*SRR=7fq`_=y2C&w#e6PUEEdIPv*|KjP*5NeEGoi5CTyUL_t!`99*^fTu+DC` z3q>rq+imUd@4wyJ+FC9!3MG*SN=0t&a5(IFd3n~ZuCA-RCh+?9_V#NT85sxQb+N#Y zP!^6tIDKk)4UCPAtt>1o%(`5z!knC(%-Y&odtYDQ|Bo~ zK>Q!4(|I%n5DJAh8yg#+4-O9cCEsepMEx1L)fUY8`uh5c?UGkfOwG;BRiYU?UT?`n z<*8Khkqfr1t?dntfM~|n5`~KNhS7MTvZtqKS~O#8X}_R>Bfxwk#D^EGNXFKPFAC*= z5~IZHDLXXaJsQ9pRf@Jxc#@Q46Pv&nXkdeO{Mkl|H^9Vq;0GmQXI9K}H3-P<=;){u z$*^iBdV6~(R#sMc&I_;!JQLo~eCEvuUaxo6@Aof@X4uZoPG3_~Q$L1SpU*cB;AyL` zQ;%rJysx3Qie_L;w_2@fdddTwh64iwbHQM6i}Tli9c=)cSr7I>XJQTbkpAwdLU9TO zX+bA5UIKr_YAxas&r}kN{|Ow9{D(;;wsteY1GfZBou{O68%m57jz^-W*xsHE?AW*f zA2XGMj#xV}?867BW04H-0Kcle5pOGrZgB(R*u#+sk@!!sKCs(fc!m}=nn>M)IsXJJ z&UhcvvYDT!Or1~NutY_hN5E+<-7OyA(dR{G+>tAu3%`mtW%L?A;G+h(-*qv0=V)tG z8Vobe2SD^JP85$1d4wPKNEZ<8rJ`&?w7DQFx|qnsG1^~e(@yVD#5!81sD{&IlKp?= fW>fEt{|PVv`Qbd_Vu2Z300000NkvXXu0mjf`SlMV literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/res/drawable-hdpi/photoload.png b/TMessagesProj/src/main/res/drawable-hdpi/photoload.png new file mode 100755 index 0000000000000000000000000000000000000000..c3c96feddd27004e691d9894fbe2eda49408399d GIT binary patch literal 952 zcmV;p14sOcP);4 zMPiBgleosL*!^Ocjc4}|j}!eYe5lLk%WPtm_=Wg)PzE6MJn;h2ttf&J|DO1PqtzD! zxc4;iGSMUYgH7T);*x3u$m<)#17a{(C(aXpb&?KNm>}LH?h}KGG1`ZKpyDYvwjSFnV(!gHgErlggRU}RjKM}Xg z7i8Uyl1JVnoCi#t*Xy&QJ_4AWri61b%FB`O%_4x*xhR~EE44sBA3L$+CYG_~_rB(7~L`Psg z7?-?k&=uPT#xyoC1_NG=4R|Hbz`A1lB_7t;z_1jW0|v?(>o3E=Z;cK7k)5yqPvo^&;^Eb)6d|Od~iRtO-$DNqS<#J09pH8PYZKh8S+KqW&*={l# zCQ_-?t9IgJvDl0P@j%ABrCd=lAHYN?6naDgUpFLcKEJF`JlgTAW&`-gqKdKr6Tx8c zq1gn)N2AdPio^qHW5CT#A~dt^s9GDLIwcZ``#zuVh+^@0XP@!khTi8n;#E~e8YcXH zzek~X;Eg$3TuruVw;jAo%M+iQ%f4(nApWgR9O5@*AljS!4-W*ZPkw8t!!>rV*$IQuFJu9EBiaCs>oBqphNG{@EV3fPz!BscG6KU@l}%){7&whw z<>8};HjpRCyH0PgcDeZk;@6m|L}bZHOv9iC$^*`TXsFp1aq3PvFN>@JFd;k`#-U*)$~&AsRmW zO=y57vs2>Dh#5t(dnGO#%&LX~kBJRj3+rwdKo20`|OQc35FuBM;&BXE7 zBrZ?Qsx>lDF|mPFGEg?Lfims-skeE(?|q)#Zi&TW(>|YXLd|`-TyEL#_s>--mAVE4 z59tX|gLR|dPpH@Hn=>;r3yDNxQBClnQ0SS);3?(;8CZj6D-X1oh(@C?w_>7DC^UjE zl}cK(-xqlj19a(psWp*ICNtfF4+euGf+xLKZYe*CSP#fVBodiVrBd0}YsF&mhrr;e zHIrv zPta^{PYWDYG+gG96sY_Gh?dDo!H>b;AA30Z2s*<>*;2p7q^Rs7H;E5Hv(raI%*k^H pc;8*+thU07Wmd~ZO4c6%1^|1;@hpGEdJ_Nu002ovPDHLkV1fY4yjK7K literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/res/drawable-ldpi/photocancel.png b/TMessagesProj/src/main/res/drawable-ldpi/photocancel.png new file mode 100755 index 0000000000000000000000000000000000000000..0edd56984caf0f35d0fefb71552c426b9a52e344 GIT binary patch literal 709 zcmV;$0y_PPP)g=i+9*8kOpFNB7y`TV1&lk zTOj_zfaFq6sLLra9N7|UXrh2ypaaCL4AcXx&_n{ZfD4*hFo1)DgV2Kq56VF_Hu-bs z&ZSJ8IMEb`B_K1|K;F>;Vts5X&YnG+WMpLI^6As3m;V0#%?Az~fJfe?OP4Zqb#?7N zfByVhPEM})!-o%luo!U$#%L8(bFu z`^S$TUjoL7==$~RtF5f81PEyT39{f5A;V!23JmimJw3gi+qZ9@1O}Vr)~#D>30U$G zWWftuvd51fk3ljV9HF4#GBY!qifjoej&K<99Av>GXpxHnCQO*H7no}9qNf&QOEz!b zyb(t-{RhMkVPy{}H>xmD7u<$rG!VD~N*q)){5P}$f*02yFMb4KIVzN>px{0X3Q6?( z;4?JIN>X46$new9c*R%IRt0kFLIzr$ rg4n!B!3nB+p91j{Y^@0x00=MudzkX31DX|c00000NkvXXu0mjfYWXb^ literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/res/drawable-ldpi/photocancel_pressed.png b/TMessagesProj/src/main/res/drawable-ldpi/photocancel_pressed.png new file mode 100755 index 0000000000000000000000000000000000000000..b616d1799d2d2ea3b3daa9cc2793d467f839ea5f GIT binary patch literal 715 zcmV;+0yO=JP)L{K6~-33c1(m_%Ep%2$lReB)CkI2*kv%88)JA<4}yB#QRsi-Rjk89rK{9a z>uHC{>cN65-JnSKL$RZpWOJ_Do(JB*i_2@?wLb7c^CtOzljnJOpG*nkV-}DBHy{Gn z$@&+-0QP|<&|?WqG1g~*6<`s#VDk{afn8u5(0B|a;016|_`moGyaEpB#p#iYRN$G# zI#1v|Uh)>7tqc}`Cu7pa6L{|(;0QPtsQh9vpK|1zCs5-#;Ghj20GEWx1!^su26Loa z{s~!@9hFMu5&l}8&*gH#WHNb^VWI$+(cm5{HJMCi(c|&V=kxi{s7awvSPlk*o^(3x z7e#TJRdf`-&3eyND)pw(XdF77&RN<7#r=N2yVvU(iA17o7{)0>Lc*%QBt^Cie7a(> z_|WV1-sp5XC#_bit0>AX6pzQ_8?{>PWK1o-p~0$M-_s^|tZAANjYjRnF@A8hC8j{v z^?`Xj7z|FqUI}l&V4?gyWj5{&1UlmYH|fS=&>Y8qRp+}(V%N5ZWc5ai*1C% z;jMbT{?X-f&B3{ljY%5~KCsSavsu*?Hw%jCibNvYvIV+vR1jSzid#s7}i3|(*3{wq9<{B+NZs^ xIoEl=D(J6^1p@xRM%ItX?0rwrSOR|q7yuRu-1GDwdC&j=002ovPDHLkV1hZkO>zJL literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/res/drawable-ldpi/photoload.png b/TMessagesProj/src/main/res/drawable-ldpi/photoload.png new file mode 100755 index 0000000000000000000000000000000000000000..c41e23978367d83761096e18cd1b70cc0bdee5a5 GIT binary patch literal 464 zcmV;>0WbcEP)KpigzJQOQH;$e;h#+1>2_{-4)_=^@Oi0;o zq5CIaL$+o9?e27DwX&-U_Q4(qzz&bUf(Sf;NAR&MfL=1b2~NO~<(Wh==!1Lk>0%Iq z3s6@1GzWKJEC)*q4|Tv9Fe<<3KL`94lQe@SICWSOn>6p&3wT#zrd6K#I>DvMIVZ)x z!7-?);#A=z`7@|-wqz=f<7>jvgko-x!C^s5le+12*;W1&l0n_0!L~_u+miyLJj-y= z@}-Efrwbak)UrvbhSCpeBjdb z1JU%2L$)MMKXN@)$kRoO+bR9t63a=wcLauMr-?+r0t^7GhDNC!?lxoq00002xFHv#_;D@f}f zR6GanKq!;Rw9Op&AWV~Unz@sE3(BquPz8%%9L&o4Gx!8|;1+zO85C01%U~0%f*|8h z{DCWQ4%#jO5!eNzsz3dLQ_xH$m}@W}FWgKuy@s6mD~)nvepwA{Wz9L&4mngQ?9 z&y{P4gE@7nYoMFmL5}_C8yxZg>301CUcu6k?OIQ`6Y$bI58h)5Q51guWK5fs>355aupmitp@EAaYB5mc!bQ9O0sn#)E(2{FZQ4p3R}zT37^zK? zxX7LjGS&#`Ob#UFjOLrh&XM!t^3eD0yXt)KEySzmyZ3zO-g7JxKPXpBiBWcoTRT=-?Eq0KWl00sn{!umOX>>p;6ChC^T-DANgX3&3690j^1l zK^OQQIGnaiEikY5fTyIz!A&XL(Wb;UW#{*SC#1y#{d0-D@pqa4EATFGRazcU#Ay;S z)(TLazHGSZ1iI?35iWB3aRIB#$qKk(RBC>|e}(toIo8_g#3usq!&SZ2u~^JotJR+8 z^Z9k7;JCJ0tv)Lji;oPJUO@|3$(c62m9i}N+wJyNJRX0dCjx^P3Wb!%xaYP zQ8t^cBoc{>5cEMf9NurWT6==QCr<&s1&^6(;FIn3+RNo~G7t#d9t;M*91e$5Ao%3f zw2BllrX!h5zE%`v=yJJM!Sx#g!T(>sirF7w&U3lkQwtm*REHdiMAmsqbk+&{HXEGH zc`z7E>s5yV`Y50$8XS)u(-8`VUI>clp@1Kv!P)8%6wyHe-`V%sZ16cmp!as|)VFN` zugzN7Y&H+N-EJ$B$-L5YyDFkmsf_CNddEOO6E|*Qp5upeG@qv34}1e0srSGD_~jV; z0ql}TlI8~dOoPR;vCD3jeTK(mNWX~z#4Pa6*&yFd?TWD)I@BX9T0|fC4!CbL7hvDM zO+$%$LBa8^c?&$?8BElXYMaKXHM6g!#_cuWNA}pw4yR6PApL45%K>!wR|-CwcRFUF qj^{oSbCNOFh{kkvJmk7RCwCF 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 Hu0mjf3yYOh literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/photocancel_pressed.png b/TMessagesProj/src/main/res/drawable-xhdpi/photocancel_pressed.png new file mode 100755 index 0000000000000000000000000000000000000000..890a61b2b1f100cb45f535aa45b29185bfb4b331 GIT binary patch literal 1466 zcmV;r1x5OaP)4`eA!FK989w*Y{u%WmidB?sEZh1@Eh=f?}YG)K>R@bz#qV0VPZ_s z_!2O4B#?#15;k$!lu6dbiFGTu)WSdSMO@O_V%88?#nOvh2GMhp68c)&hv7g z;}h1ShFDMBLwtz;0{e-6e!WS&!LM%;{~#ub*NAIYPR?i1xCe;Gh(~n>SBl?>3&e{$ zksK+&{lpW@M=TN+0$d=TCvG@JfbGPS#4xd1r~#Hmlo%tf+bKYZ_@+X`^RYtwhL?v@ z0kE09PkdB3199T##FPpFnuzc5ns*Y`ScG{aUkVufk++C%RPa3&s3JZ^ypMQQwgC9t z2gGND^Kpo{llU_+D?Tcwz;WL2+z#X+3F300fBK7j38C!U!aIQ5-ep99cR0lL3aZ(Ql_fx!U5VFlh~tEN z3IL@}3Gd?d{0KH*fQXHWjS3(@dcK$dQ04{UeKhOu0)O7xm$LD-wzgVQ5Ro))4X5${ ziv!*z?l3$0$jHcvfq{WjRaI51)6>(-vW)NV?|))=c=&WfLxXR8d^{mRgju}+b;Os= zPI72ysHwBFGvXtJ!{K^aBEa~bo}O3ye!s7=vGG7{ZSC6Ri;dUzffxihB62l+;S>=R7!P3V>ky!kcv!Z} zs#F9;#%ov#u>ap{h2J(Rf@0%=6$tPWy9HsV2sRkMz)|2~JB-&h zJlR>K0bJ6u!DDtAZ&fN?CZZ4k?&zejpkvHvgr``93~>wspt8~=qaY$9u~8_(uf!Rx zBD7mbd>UjnwpS#=95Jp5aGUs?6O30V!k7A@=n5A`Of7@n-rmRi`ubj#mDm&$VRLgc z6^q4gnTg1W=d@5*!v(XFPE1VPph>UFOl-8=0pqbKt5Z``H%(6Uy!Jx>U<89cYbG^L zCX*X9xp*iP+S%3Bbw*ZVqumLSNMtuHud{P=b7?bGAdzdQ%ZdW755W10PNMx39hlV$Z})SY*qC~>C;R9u>IoqWy~S@LSGYl7^S6uvtvWotkHhH4MD8H9 z8C(~+BQHO2crFz_1-EN8yH51^;>2l?->(t>o#ME~$yb&)vL)VZuL+BvUjHM&04uZ8 U;4`)Ts{jB107*qoM6N<$f{y#h?*IS* literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/photoload.png b/TMessagesProj/src/main/res/drawable-xhdpi/photoload.png new file mode 100755 index 0000000000000000000000000000000000000000..e302e1f9ec5da8fc38c92827bbb754d95c0ce8f3 GIT binary patch literal 1270 zcmV_D5CfPRD7^70fVU~L`V!9egW=C*b>7IA`6m2O41NlY*-VwEbs?l zGz1NhAn}0@XpvXJLV>10Tde2Exo|C9TFRZvZRbnAv;o?3zMeUcnKLHF9~r=lz--`I z;5qtv4$wr;{{VgT93TC_Rp25p$n&2waeCie;B{aD8GanB0Ox^jg-C`Jzzn zwFU|>3H%8R8%2P0;5}do(8BZqE{m_gZ@|z=3UC8hrlaA}*aVK!^3YWP3}!aq1!fF* zfJ4B59s*n=iW*nc&{A%mA$|u&u}|2F%huYY>xT) zdDU-qYinz*v9YnEySsae@x`RF7m$JDr&~Nf)#Y++mY0`1W@cvgt?P}A4PQe;gT1Gx z$IaRJO*H|qDf-4c@h&VZ1S={koNl*!H?ju;f#v%8dV6ng?=0hwFKlNz{U4%pKW>iH zG97k_pgu5~sQAHCqQ`oaVJJdrX=xUwOPwme zcPwgjPObWT%2IDi1Z$l)2W^NPgdxWHriRYI;Qs!gU#N}A1u0La!l7w|T;F#T0T}HQ zq@}=8_y|<3D`HKGV!e!a1CsUh2&>6M8>x6^g=a~CWIIE|g6c!8KZkENZ_@4q`J3<1w1VTkh8-y#Ra3BEaSz>fkayR zmioc1bbEY_Uwe zJaSu$H{^AB+Dc_Kj-urr^Sypk@O3c`XBZ|O+|@#<^Be_DS&&S&cZ%RgF06`-kqiy;yhyVZp07*qoM6N<$g4+i=(EtDd literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/res/drawable-xhdpi/photoload_pressed.png b/TMessagesProj/src/main/res/drawable-xhdpi/photoload_pressed.png new file mode 100755 index 0000000000000000000000000000000000000000..30bbf25a176a30b887be5c591c898899e54063e5 GIT binary patch literal 1304 zcmV+z1?T#SP)sFgR21O%u0cIL>;gI z+kwA$2yg~iLg&1i;G!aY59Olx5Fc_McqfeOc;EoA0GI&$8EpaZd*#53MEx)U4+F=5 zThR~zzw;27Pqc$vU>4B4mk7ZKP^K~Cy}$(Q&|W@aF9Gh+#73*grRlaM90ATzho^O5 z9Wn!4@OM%d;37{-}$@Gll z<57SCQ?2#v^PP0lmNa7>n^W zK0dx$QBfhy%*=%BXVw7?4Go>Gt*tgj!{0&_!~P4aNoKWL<+8G}&Z()XpnZ)j%kKL6 z`mXl&_F0DWe?%z&KFH4MNj95JE-fwX05KeU24?aDe1IWECGL2r_(9d*4B3R_V%)lOoPf=KzY!~H0Ulat``>+)e+T?XB3#;w_SV@;#M6YxDq2j_7dM#LM5TscwRt+5rqNhb86&(GzBj-Z zm?MP28b%z4;i{*h6PvNH9VeF_PgPW$OSJgfqK<5yI$JAYyn6jtfB^s~tud2~0-^Z; O0000RCwC# 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 literal 12857 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 xC=c#@kG`YsNzJzzOt`-os8 zF#|RM<^gkq`B?xVoL~pQ3W$6wfntn-{SCI9ZUVdpb`UHt#Er-Ty06DzqhRByEC3#> z2|lj-Zf?~Cz~K4;js8>z z#*acRZL>Z0|*h;eji@E<~3b2nxzC)xRG?z35wkSgYJox)5>hJaNhi#NO zsvRs701x_}P^+0I3z&RhKWkR3bY4vtAdf~qlfOEh&!_BY$xH!uksc0or&xGa!emT}EPf1MC&O0^syH z#@rd^ijL_O;Lt{@F?1t`+7&SgfQlVq&J4%fu?kQm(yO;`6|yO%-%tP?{fC(=>t;c? z0NCl=$vl|`OzBrG!3-}FUQdRz2nK_f!(UroUS4uKogXE^*GG=sk!HXav2ux#VJ`Bi z!>~qx1A;HISOFWk`ZWUVXKpM*LAU@oC3Z6}mLXT;UK3z9yC2Kl(5_Gc_A)0@X2DAV za+wdyu~!qoE|PcsezF&3n=-ial?LQ~8~(#99pqsL3b2EDkShSs0C{-fg0?abas_ZQ z57OX70X8!aas|j>9^|E>S|P@e0|$?O1*$PW(;yAYC_sRDkcI#X@RWIwhG!_iGv-0A z0E^6nG%TP1KITEL0CUWPGfdFDYHe3}aiG8dKucWYdJS!_J z?wi0fGBWHfEiE6$`uDA^twU{XZIcpDc^U`4)(4u9Ex_>bu)Ds#{$sn{o*B>kZ8n?p z+_`fxEzTVr9K3b?`t=UUGhpJy_YP@E6w3TIU0q$%OG``lPo6ya4v=Zub_o6b{Wpt? zi@)^y{j%NeAlQ;7z!R}@W3klLaoyeBGl0R$%1RW$@C!w~y}j)vB_&OY`2XI}8G!vD zTqq>{@?=j>kJs&X51cx6subLjVHb<;+_`hDtgNhAkpPVM4UdHip#7Yu!nf<|>zi}A zT>Ym{pDuMc9GQuJUT0_LwQQ4ERPyMt-TPsyYrL zY>D@CZrr%hT2WE)jbiENJ@PuM1n^TPq|7>@p`oD#$XI%6YHE%1Dh^?GC4Hu%bwD_@;Gd$wIc@^KJNZ6tseAe2K#N5>3|==#~&*?-pin_w^) zXl`!)qPDj7rlReKHQYuL0G}qIWP=V;NiU?Q_0!YSW0A;jY;0_(tE;=EDEZnmY@!N) z72*R$PXddnd8n2zdOV&{?X^H4;BRPX`276&^FIl7F%;>=^_HdJ$<3;ICXg8|l$V!Z zoSd9|h~$3;xNzaZU4_Z_kY`zgjdFgxrM^PplM;o6g_+>*3oc!{^rymK6FtiJ>ka5= zMHg;QTp$>U0H40myWTIOt&GDr^0Jlqf!&2)H~NEU0^pLByUb(UuIFbFW#wTk8@J*m zOYFtG%AD%LAK_JRyaEWyU-L)^Ms&Do^hZUktD~`Vcbnru%znR1#JJEw&+h5?3@z-% z6bjzHem&p-{Xyt>hJaooabNstN=zrzBmcID&}cJL0K^>4gnW^{H~RT$-Dg#CHkekEP*x}TtcoAA9AHUp>PD8++4DNH=(_PC<$9{GNuiU1nW7fw;toN6xV z3Hf`MksoSS27_xmOGN5C0Ag6IJkZ(jTYAk-A<-S-6PS|qSp*nh`w|VbG6m3pl`}5> zO_sgs@B%ts!+mV_fvhf~@<|9)9}MIn;>WEzpsXquAL&sqxpQGf;XE0(N*08|x8nXUzyMzoux#-a!R7z}002ovPDHLkV1lgH BtY-iK literal 0 HcmV?d00001 diff --git a/TMessagesProj/src/main/res/drawable-xxhdpi/photoload_pressed.png b/TMessagesProj/src/main/res/drawable-xxhdpi/photoload_pressed.png new file mode 100755 index 0000000000000000000000000000000000000000..ed7a374b9d9a1b59153afdabd97a001a681d2277 GIT binary patch literal 1981 zcmV;u2SWIXP)7FD^^ph0>XN$R@0_0wY(Tov}p>IL=D8Ynlv%I;fskczWAasF)=Z* z547opw5ds{sF74LfQVLF!Ip3-2&Ev%WfkNm1nB?Cf6Riwo?Xt_ncbZ)`2u@C=l{;k zf0;Qm3xv8@NL)dDow$tXBrf-OeI?Ps|Bn*8JYK{9Ze|bh5phh#lU$(Cu|yNs5!VtE z*uYleA@KpRh1g6S(EFK?m!9v<|u0k(tcE>6F*DZliRo3%cY@(8T3TAZoc`SK@bHMs<@zQF4j(pd zo~Z@ACMJg%HSEPkt}whLz-FNbSposv_u!gM0FA(4%X9(IBy`Oua6pyR;VHlx-Tef- z8(QrtK)kkzlveOUfH-ZBfMdNOK$HmH`TN11lto17%vT!VgqK2q7;Ot_SOEd_R1;LK^h{AL`*{t7U=?<>?R--SvMz4@eBft zX*)>6I0P8dc94c4Er0?7Jl1xQh9?lft?eKUZV1q&?H~=0v;cC^V{}2|+7<)8R9uOo zQ&Uq{oj!ef_dHeQ(9VDvw#2olJRlrz3vTkLB@$be))N!&d6^@R&qQT0_%9fOr6o@cypHNUxaPRQp!@nyO0TpxLGi5?g($poX_`MxNzZac6Rn%#lp`znrq`Sa&Xj~_q&w}QsU?j8TlC4k`|lmq1n1AF)GE$Hm*oV9#T zvHir^vuBG>oH$XVX!+qK+s-5ac9ZB<@#q^G8U`~mG78$;+k0j*{+TmpZk#%Gs!mbk zV+s65GXfwIx~b?%i00(M%dM@gFD{a?v9a-!Cr@4{0UCt5D4pra*`}pn!MP4q z&!nxbZ8$A0?GlO63FA|jbM4%@a}N|YehY{BFJZ3ILoD%gg-=R2oz8_xNlDA|^Yc3t zK1}o|U(I$wd#n9?DkK-_LI6ktFVFU(x0!J$7!7C}`VEB5zs>aqZvtS-%0+EQzq_7% z;brEbnYuedzE{QMYOosSam!3)!R){X;@3nLLc>I~%vZnH5jV55qcL9allBLu`~9DV z$;z@XLx0b>B_Jx&%h%5gT%cbQ`^#w+X=z=({%4Z0;fzw&<+lbc10KnWnYsi7ro6ybZLA7cDGe~m9JFkBD+ zI9fuu-Ry^G=UeuPLY4pkh6*wIgymP3go*JH4Sp{yxVOTpt^*-z6+7j1Azogf`?YzLj5UR~U({uCVb>sB8d%NnO{34Y%~#9mmHKQ$+CY zMF0nTWxkG9rT_+zIb%4UbH=L|D9Sxk>^Uz?L4{ z#pH6yvbRPY;xM|>&aOr^0SsW~b0UkeK7bkZC?}AA^3^VFxdxSrX%Hih^9Zz%H5SM3 zt=z>lbGWR;8X2lrGqI+rlNrO0J;x$evT;3cwH@IS37&H^yH!2G{{ + + + + + + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/drawable/photo_download_cancel_states.xml b/TMessagesProj/src/main/res/drawable/photo_download_cancel_states.xml new file mode 100644 index 000000000..df64a4b09 --- /dev/null +++ b/TMessagesProj/src/main/res/drawable/photo_download_cancel_states.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/drawable/photo_download_states.xml b/TMessagesProj/src/main/res/drawable/photo_download_states.xml new file mode 100644 index 000000000..122ca213c --- /dev/null +++ b/TMessagesProj/src/main/res/drawable/photo_download_states.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout-ar/contact_add_layout.xml b/TMessagesProj/src/main/res/layout-ar/contact_add_layout.xml index 02934ef38..b952a5b2d 100644 --- a/TMessagesProj/src/main/res/layout-ar/contact_add_layout.xml +++ b/TMessagesProj/src/main/res/layout-ar/contact_add_layout.xml @@ -2,13 +2,13 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" - android:paddingLeft="16dp" - android:paddingRight="16dp" android:layout_gravity="top"> + android:textColor="#000000" + android:layout_marginBottom="16dp"/> diff --git a/TMessagesProj/src/main/res/layout-ar/messages_list.xml b/TMessagesProj/src/main/res/layout-ar/messages_list.xml index aff49284c..8e219ecd9 100644 --- a/TMessagesProj/src/main/res/layout-ar/messages_list.xml +++ b/TMessagesProj/src/main/res/layout-ar/messages_list.xml @@ -11,6 +11,8 @@ android:layout_alignParentBottom="true" android:clipToPadding="false" android:fadingEdge="none" + android:divider="@drawable/messages_list_divider" + android:dividerHeight="1px" android:fadingEdgeLength="0dp" android:verticalScrollbarPosition="left"/> @@ -37,6 +39,7 @@ android:textColor="#959595" android:text="@string/NoChats" android:textSize="24dp" + android:gravity="center" android:id="@+id/list_empty_view_text1"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout-ar/messages_search_chat_layout.xml b/TMessagesProj/src/main/res/layout-ar/messages_search_chat_layout.xml deleted file mode 100644 index 5d6826034..000000000 --- a/TMessagesProj/src/main/res/layout-ar/messages_search_chat_layout.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout-ar/messages_search_user_layout.xml b/TMessagesProj/src/main/res/layout-ar/messages_search_user_layout.xml deleted file mode 100644 index dd5e99d7e..000000000 --- a/TMessagesProj/src/main/res/layout-ar/messages_search_user_layout.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout-ar/settings_row_check_layout.xml b/TMessagesProj/src/main/res/layout-ar/settings_row_check_layout.xml index 2be028654..6c4e623c2 100644 --- a/TMessagesProj/src/main/res/layout-ar/settings_row_check_layout.xml +++ b/TMessagesProj/src/main/res/layout-ar/settings_row_check_layout.xml @@ -18,7 +18,7 @@ android:id="@+id/settings_row_text" android:layout_width="wrap_content" android:layout_height="fill_parent" - android:layout_marginLeft="8dp" + android:layout_marginLeft="104dp" android:layout_marginRight="8dp" android:gravity="center_vertical|right" android:layout_gravity="top|right"/> diff --git a/TMessagesProj/src/main/res/layout-ar/settings_row_check_notify_layout.xml b/TMessagesProj/src/main/res/layout-ar/settings_row_check_notify_layout.xml index 84b26c5e9..2ce84a1cb 100644 --- a/TMessagesProj/src/main/res/layout-ar/settings_row_check_notify_layout.xml +++ b/TMessagesProj/src/main/res/layout-ar/settings_row_check_notify_layout.xml @@ -18,7 +18,7 @@ android:id="@+id/settings_row_text" android:layout_width="wrap_content" android:layout_height="fill_parent" - android:layout_marginLeft="8dp" + android:layout_marginLeft="104dp" android:layout_marginRight="8dp" android:gravity="center_vertical|right" android:layout_gravity="top|right"/> diff --git a/TMessagesProj/src/main/res/layout/chat_group_incoming_location_layout.xml b/TMessagesProj/src/main/res/layout/chat_group_incoming_location_layout.xml index 1b1988942..88bf1a054 100644 --- a/TMessagesProj/src/main/res/layout/chat_group_incoming_location_layout.xml +++ b/TMessagesProj/src/main/res/layout/chat_group_incoming_location_layout.xml @@ -40,8 +40,6 @@ android:id="@+id/chat_time_layout" android:paddingLeft="3dp" android:paddingRight="3dp" - android:paddingBottom="1dp" - android:paddingTop="1dp" android:layout_marginRight="8dp" android:layout_marginBottom="8dp" android:layout_gravity="right|bottom" diff --git a/TMessagesProj/src/main/res/layout/chat_group_incoming_photo_layout.xml b/TMessagesProj/src/main/res/layout/chat_group_incoming_photo_layout.xml index 20a8122e1..d08382573 100644 --- a/TMessagesProj/src/main/res/layout/chat_group_incoming_photo_layout.xml +++ b/TMessagesProj/src/main/res/layout/chat_group_incoming_photo_layout.xml @@ -36,47 +36,78 @@ android:minWidth="100dp" android:id="@+id/chat_photo_image"/> - + - + + + + + + + + + + + + + android:layout_height="16dp" + android:id="@+id/chat_time_layout" + android:paddingLeft="3dp" + android:paddingRight="3dp" + android:background="@drawable/phototime"> + + + + - - \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/chat_group_incoming_video_layout.xml b/TMessagesProj/src/main/res/layout/chat_group_incoming_video_layout.xml index ac594232d..417f0d089 100644 --- a/TMessagesProj/src/main/res/layout/chat_group_incoming_video_layout.xml +++ b/TMessagesProj/src/main/res/layout/chat_group_incoming_video_layout.xml @@ -72,8 +72,6 @@ android:id="@+id/chat_time_layout" android:paddingLeft="3dp" android:paddingRight="3dp" - android:paddingBottom="1dp" - android:paddingTop="1dp" android:layout_marginRight="8dp" android:layout_marginBottom="8dp" android:layout_gravity="right|bottom" diff --git a/TMessagesProj/src/main/res/layout/chat_incoming_location_layout.xml b/TMessagesProj/src/main/res/layout/chat_incoming_location_layout.xml index e571dd78f..4a1ff03f7 100644 --- a/TMessagesProj/src/main/res/layout/chat_incoming_location_layout.xml +++ b/TMessagesProj/src/main/res/layout/chat_incoming_location_layout.xml @@ -33,8 +33,6 @@ android:id="@+id/chat_time_layout" android:paddingLeft="3dp" android:paddingRight="3dp" - android:paddingBottom="1dp" - android:paddingTop="1dp" android:layout_marginRight="8dp" android:layout_marginBottom="8dp" android:layout_gravity="right|bottom" diff --git a/TMessagesProj/src/main/res/layout/chat_incoming_photo_layout.xml b/TMessagesProj/src/main/res/layout/chat_incoming_photo_layout.xml index d064735c1..a9771383f 100644 --- a/TMessagesProj/src/main/res/layout/chat_incoming_photo_layout.xml +++ b/TMessagesProj/src/main/res/layout/chat_incoming_photo_layout.xml @@ -26,47 +26,78 @@ android:minWidth="100dp" android:id="@+id/chat_photo_image"/> - + - + + + + + + + + + + + + + android:layout_height="16dp" + android:id="@+id/chat_time_layout" + android:paddingLeft="3dp" + android:paddingRight="3dp" + android:background="@drawable/phototime"> + + + + - - \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/chat_incoming_video_layout.xml b/TMessagesProj/src/main/res/layout/chat_incoming_video_layout.xml index caf2f8635..4f8802627 100644 --- a/TMessagesProj/src/main/res/layout/chat_incoming_video_layout.xml +++ b/TMessagesProj/src/main/res/layout/chat_incoming_video_layout.xml @@ -63,8 +63,6 @@ android:id="@+id/chat_time_layout" android:paddingLeft="3dp" android:paddingRight="3dp" - android:paddingBottom="1dp" - android:paddingTop="1dp" android:layout_marginRight="8dp" android:layout_marginBottom="8dp" android:layout_gravity="right|bottom" diff --git a/TMessagesProj/src/main/res/layout/chat_outgoing_location_layout.xml b/TMessagesProj/src/main/res/layout/chat_outgoing_location_layout.xml index 4da0f2f20..612e641ed 100644 --- a/TMessagesProj/src/main/res/layout/chat_outgoing_location_layout.xml +++ b/TMessagesProj/src/main/res/layout/chat_outgoing_location_layout.xml @@ -51,8 +51,6 @@ android:id="@+id/chat_time_layout" android:paddingLeft="3dp" android:paddingRight="3dp" - android:paddingBottom="1dp" - android:paddingTop="1dp" android:layout_marginRight="8dp" android:layout_marginBottom="8dp" android:layout_gravity="right|bottom" diff --git a/TMessagesProj/src/main/res/layout/chat_outgoing_photo_layout.xml b/TMessagesProj/src/main/res/layout/chat_outgoing_photo_layout.xml index cb6b899b7..ea34e11db 100644 --- a/TMessagesProj/src/main/res/layout/chat_outgoing_photo_layout.xml +++ b/TMessagesProj/src/main/res/layout/chat_outgoing_photo_layout.xml @@ -9,56 +9,6 @@ android:paddingBottom="1dp" android:paddingTop="1dp"> - - - - - - - - - - + + + + + + + android:gravity="right"> - + - + - + + + android:layout_height="16dp" + android:id="@+id/chat_time_layout" + android:paddingLeft="3dp" + android:paddingRight="3dp" + android:background="@drawable/phototime"> + + + + + + + + diff --git a/TMessagesProj/src/main/res/layout/chat_outgoing_video_layout.xml b/TMessagesProj/src/main/res/layout/chat_outgoing_video_layout.xml index 3c6b1f8a2..44a8c978b 100644 --- a/TMessagesProj/src/main/res/layout/chat_outgoing_video_layout.xml +++ b/TMessagesProj/src/main/res/layout/chat_outgoing_video_layout.xml @@ -113,8 +113,6 @@ android:id="@+id/chat_time_layout" android:paddingLeft="3dp" android:paddingRight="3dp" - android:paddingBottom="1dp" - android:paddingTop="1dp" android:layout_marginRight="8dp" android:layout_marginBottom="8dp" android:layout_gravity="right|bottom" diff --git a/TMessagesProj/src/main/res/layout/contact_add_layout.xml b/TMessagesProj/src/main/res/layout/contact_add_layout.xml index 32faaaaad..862f36f56 100644 --- a/TMessagesProj/src/main/res/layout/contact_add_layout.xml +++ b/TMessagesProj/src/main/res/layout/contact_add_layout.xml @@ -2,14 +2,14 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" - android:paddingLeft="16dp" - android:paddingRight="16dp" android:layout_gravity="top"> + android:orientation="vertical" + android:paddingLeft="16dp" + android:paddingRight="16dp"> + android:textColor="#000000" + android:layout_marginBottom="16dp"/> diff --git a/TMessagesProj/src/main/res/layout/messages_list.xml b/TMessagesProj/src/main/res/layout/messages_list.xml index dabee8f19..9c789a72b 100644 --- a/TMessagesProj/src/main/res/layout/messages_list.xml +++ b/TMessagesProj/src/main/res/layout/messages_list.xml @@ -12,8 +12,8 @@ android:clipToPadding="false" android:fadingEdge="none" android:fadingEdgeLength="0dp" - android:divider="@null" - android:dividerHeight="0dp" + android:divider="@drawable/messages_list_divider" + android:dividerHeight="1px" android:animationCache="false"/> - diff --git a/TMessagesProj/src/main/res/layout/messages_list_row.xml b/TMessagesProj/src/main/res/layout/messages_list_row.xml deleted file mode 100644 index e9794be94..000000000 --- a/TMessagesProj/src/main/res/layout/messages_list_row.xml +++ /dev/null @@ -1,139 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/messages_search_chat_layout.xml b/TMessagesProj/src/main/res/layout/messages_search_chat_layout.xml deleted file mode 100644 index b750c11fd..000000000 --- a/TMessagesProj/src/main/res/layout/messages_search_chat_layout.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/messages_search_user_layout.xml b/TMessagesProj/src/main/res/layout/messages_search_user_layout.xml deleted file mode 100644 index 046fc8287..000000000 --- a/TMessagesProj/src/main/res/layout/messages_search_user_layout.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/TMessagesProj/src/main/res/layout/settings_row_check_layout.xml b/TMessagesProj/src/main/res/layout/settings_row_check_layout.xml index f14a48913..de29a61f2 100644 --- a/TMessagesProj/src/main/res/layout/settings_row_check_layout.xml +++ b/TMessagesProj/src/main/res/layout/settings_row_check_layout.xml @@ -11,7 +11,7 @@ android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_marginLeft="8dp" - android:layout_marginRight="8dp" + android:layout_marginRight="104dp" android:gravity="center_vertical" android:layout_gravity="top"/> diff --git a/TMessagesProj/src/main/res/layout/settings_row_check_notify_layout.xml b/TMessagesProj/src/main/res/layout/settings_row_check_notify_layout.xml index 96bfcd77b..c9ee80459 100644 --- a/TMessagesProj/src/main/res/layout/settings_row_check_notify_layout.xml +++ b/TMessagesProj/src/main/res/layout/settings_row_check_notify_layout.xml @@ -11,7 +11,7 @@ android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_marginLeft="8dp" - android:layout_marginRight="8dp" + android:layout_marginRight="104dp" android:gravity="center_vertical" android:layout_gravity="top"/> diff --git a/TMessagesProj/src/main/res/menu/messages_list_menu.xml b/TMessagesProj/src/main/res/menu/messages_list_menu.xml index de6dfaaa8..b00ff8bd2 100644 --- a/TMessagesProj/src/main/res/menu/messages_list_menu.xml +++ b/TMessagesProj/src/main/res/menu/messages_list_menu.xml @@ -16,28 +16,23 @@ sabd:showAsAction="always"/> + android:id="@+id/messages_list_menu_new_chat" + android:title="@string/NewGroup" + sabd:showAsAction="never"/> - - + - + - - - - - - + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/menu/user_profile_contact_menu.xml b/TMessagesProj/src/main/res/menu/user_profile_contact_menu.xml index 1104be328..7b4b570f3 100644 --- a/TMessagesProj/src/main/res/menu/user_profile_contact_menu.xml +++ b/TMessagesProj/src/main/res/menu/user_profile_contact_menu.xml @@ -1,7 +1,5 @@ - - + + + + \ No newline at end of file diff --git a/TMessagesProj/src/main/res/values-ar/strings.xml b/TMessagesProj/src/main/res/values-ar/strings.xml index 828a1b5ac..6163a6968 100644 --- a/TMessagesProj/src/main/res/values-ar/strings.xml +++ b/TMessagesProj/src/main/res/values-ar/strings.xml @@ -1,13 +1,16 @@ + + + Telegram - + رقم هاتفك المحمول يرجى التحقق من صحة رمز بلدك وإدخال رقم هاتفك المحمول اختر دولة رمز البلد خاطئ - + رمز التفعيل تم إرسال رسالة قصيرة تحتوي على رمز التفعيل الخاص بك @@ -15,7 +18,7 @@ جاري الاتصال بك ... رمز التفعيل الرقم خاطئ؟ - + اسمك اختر الاسم الأول واسم العائلة @@ -23,7 +26,7 @@ الاسم الأول اسم العائلة إلغاء التسجيل - + الدردشات بحث @@ -46,6 +49,8 @@ لقد قمت بالدخول للمحادثة السرية. مسح سجل التاريخ حذف وخروج + الاسم مخفي + اختر محادثة اختر ملف @@ -60,7 +65,7 @@ الذاكرة الخارجية جذر النظام بطاقة الذاكرة - + مخفي جاري الكتابة… @@ -100,13 +105,14 @@ لقد تم إخراجك من هذه المجموعة لقد قمت بمغادرة المجموعة حذف المجموعة - + تم طلب محادثة سرية تم بدء المحادثة السرية %1$s قام بتعيين عداد التدمير الذاتي إلى to %2$s لقد قمت بتعيين التدمير الذاتي إلى %1$s %1$s قام بإيقاف عداد التدمير الذاتي + لقد قمت بتعطيل عداد التدمير الذاتي ثانيتان ٥ ثوانٍ دقيقة @@ -138,9 +144,9 @@ %1$s قام بإخراجك من المجموعة %2$s %1$s قام بمغادرة المجموعة %2$s %1$s قام بالتسجيل في تيليجرام! - لقد تم تسجيل الدخول لحسابك من جهاز غير معروف من نوع %1$s, الموقع: %2$s + %1$s,\nتم تسجيل الدخول لحسابك من جهاز جديد يوم %2$s\n\nالجهاز: %3$s\nالموقع: %4$s\n\nإذا لم يكن أنت من سجل الدخول، يمكنك الذهاب للإعدادات ثم تسجيل الخروج من كافة الأجهزة الأخرى.\n\nشكرًا,\nفريق عمل تيليجرام %1$s قام بتغيير صورته الشخصية - + اختر جهة اتصال لا توجد جهات اتصال بعد @@ -151,8 +157,9 @@ متصل غير متصل آخر ظهور + آخر ظهور قم بدعوة صديق - + إرسال الرسالة إلى... أدخل اسم للمجموعة @@ -160,7 +167,7 @@ اسم المجموعة أعضاء جميع جهات الاتصال - + أدخل سم للمجموعة عدد الوسائط المشتركة @@ -171,11 +178,13 @@ مغادرة المجموعة وحذفها الإشعارات إخراج من المجموعة - + - أرسل جهة الاتصال - إضافة جهة الاتصال - حظر جهة الاتصال + مشاركة + إضافة + حظر + تعديل + حذف الهاتف المنزلي الهاتف المحمول هاتف العمل @@ -197,7 +206,7 @@ يوم أسبوع هذه الصورة هي تصور لمفتاح التشفير لهذه المحادثة السرية مع ]]>%1$s]]>.
]]>إذا كانت مطابقة للصورة التي في جهاز ]]>%2$s]]>, فمحادثتكم آمنة ٢٠٠٪.
]]>للمزيد نرجو الذهاب إلى telegram.org
- + تم تعيين كافة الإشعارات افتراضيا حجم نص الرسائل @@ -229,11 +238,19 @@ افتراضي الدعم خلفية الدردشة - + الرسائل + أرسل بزر الإدخال + سجل الخروج من كافة الأجهزة الأخرى + تنزيل الصور تلقائيًا + المجموعات + المحادثات + الأحداث + عندما يشترك صديق في تيليجرام + لا توجد وسائط بعد إلغاء التنزيل - + موقعي الخريطة @@ -243,13 +260,13 @@ كيلومتر يبعد أرسل موقعك مشاركة الموقع - + عرض كافة الوسائط حفظ في الجهاز من الألبوم - + التالي رجوع @@ -270,7 +287,7 @@ فتح الصورة تعيين موافق - + un1 قام بإخراج un2 غادر المجموعة العضو un1 @@ -279,6 +296,15 @@ تم تغيير صورة المجموعة من قِبَل un1 un1 قام بتغيير اسم المجموعة إلى un2 تم إنشاء مجموعة جديدة من قِبَل un1 + لقد قمت بإخراج un2 + لقد قمت بمغادرة المجموعة + لقد قمت بإضافة un2 + لقد قمت بإزالة صورة المجموعة + لقد قمت بتغيير صورة المجموعة + لقد قمت بتغيير اسم المجموعة إلى un2 + لقد قمت بإنشاء المجموعة + un1 قام بإخراجك + un1 قام بإضافتك نسخة تيليجرام التي تستخدمها لا تدعم هذه الرسالة صورة مقطع مرئي @@ -287,7 +313,7 @@ مستند مقطع صوتي أنت - + رقم الهاتف غير صحيح انتهت صلاحية الرمز الخاص بك، يرجى تسجيل الدخول مرة أخرى @@ -297,14 +323,14 @@ اسم العائلة غير صحيح جاري التحميل ... ليس لديك أي مشغل مقاطع مرئية، يرجى تنزيل أية مشغل - لا يوجد لديك تطبيق يمكنه فته هذا المستند، يرجى تنزيل تطبيق يمكنه للإستمرار + لا يوجد لديك تطبيق يمكنه فتح \'%1$s\'، يرجى تنزيل تطبيق مناسب للإستمرار هذا المستخدم ليس لديه تيليجرام بعد ، هل ترغب في دعوته الآن؟ هل أنت متأكد؟ هل تريد حذف هذه الدردشة؟ هل تريد إضافة جهة اتصال؟ إلى المجموعة؟ %1$s هل تريد إضافة ؟%1$s هل تريد إعادة توجيه الرسائل إلى - + تيليجرام سريع @@ -321,7 +347,7 @@ تيليجرام]]> يمكنك الوصول إلى الرسائل الخاصة بك من أجهزة متعددة. تيليجرام]]> الرسائل مشفرة بشكل قوي وتستطيع تدمير ذاتها إبدأ المراسلة - + CACHE_TAG
\ 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 new file mode 100644 index 000000000..32dbcbfde --- /dev/null +++ b/TMessagesProj/src/main/res/values-es/strings.xml @@ -0,0 +1,353 @@ + + + + + + Telegram + + + Tu teléfono + Por favor, confirma tu código de país\ne introduce tu número. + Elige un país + Código de país incorrecto + + + Tu código + Hemos enviado un SMS con un código de activación a tu teléfono + Te llamaremos en + Llamándote... + Código + ¿Número incorrecto? + + + Tu nombre + Ingresa tu nombre y apellidos + + Nombre (requerido) + Apellido/s (opcional) + Cancelar registro + + + Chats + Buscar + Mensajes nuevos + Ajustes + Contactos + Nuevo grupo + ayer + Sin resultados + No tienes conversaciones todavía... + Empieza a chatear presionando el\nbotón de componer en la esquina superior\nderecha o ve a la sección de Contactos. + Esperando red... + Conectando... + Actualizando... + Nuevo chat secreto + Esperando que %s se conecte... + Chat secreto cancelado + Intercambiando claves de cifrado... + %s se unió a tu chat secreto. + Te has unido al chat secreto. + Limpiar historial + Eliminar y salir + Nombre oculto + Selecciona el chat + + + Seleccionar archivo + %1$s de %2$s libres + Error desconocido + Error de acceso + No hay archivos aún... + El tamaño del archivo no debe superar los %1$s + Almacenamiento no montado + Transferencia USB activa + Almacenamiento Interno + Almacenamiento Externo + Raíz del Sistema + Tarjeta SD + + + invisible + escribiendo... + Adjuntar + está escribiendo... + están escribiendo... + y %d personas más + ¿Tienes una pregunta\nsobre Telegram? + Hacer foto + Galería + Ubicación + Vídeo + Archivo + No hay mensajes aún... + Ver foto + Ver ubicación + Reproducir vídeo + Mensaje reenviado + De + No hay recientes + miembros + Mensaje + Escribe un mensaje + Descargar + Elegidos: + COMPARTIR MI INFORMACIÓN DE CONTACTO + AÑADIR A CONTACTOS + %s te ha invitado a un chat secreto. + Has invitado a %s a un chat secreto. + Los Chats Secretos: + Usan cifrado de móvil-a-móvil + No dejan rastro en nuestros servidores + Tienen autodestrucción de mensajes + No permiten reenvíos de mensajes + %1$d nuevo mensaje + %1$d nuevos mensajes + Has sido expulsado de este grupo + Has abandonado este grupo + Eliminar este grupo + + + Chat secreto solicitado + Chat secreto iniciado + %1$s activó la autodestrucción en %2$s + Activaste la autodestrucción en %1$s + %1$s desactivó la autodestrucción + Desactivaste la autodestrucción + 2 segundos + 5 segundos + 1 minuto + 1 hora + 1 día + 1 semana + Tienes un nuevo mensaje + %1$s: %2$s + %1$s te envió un mensaje + %1$s te envió una foto + %1$s te envió un vídeo + %1$s compartió un contacto contigo + %1$s te envió un mapa + %1$s te envió un archivo + %1$s te envió un audio + %1$s @ %2$s: %3$s + %1$s envió un mensaje al grupo %2$s + %1$s envió una foto al grupo %2$s + %1$s envió un vídeo al grupo %2$s + %1$s compartió un contacto en el grupo %2$s + %1$s envió un mapa al grupo %2$s + %1$s envió un archivo al grupo %2$s + %1$s envió un audio al grupo %2$s + %1$s te ha invitado al grupo %2$s + %1$s cambió el nombre del grupo %2$s + %1$s cambió la foto del grupo %2$s + %1$s invitó a %3$s al grupo %2$s + %1$s expulsó a %3$s del grupo %2$s + %1$s te ha expulsado del grupo %2$s + %1$s abandonó el grupo %2$s + ¡%1$s se unió a Telegram! + %1$s,\nHemos detectado una conexión a tu cuenta desde un nuevo dispositivo el %2$s\n\nDispositivo: %3$s\nUbicación: %4$s\n\nSi no eras tú, puedes ir a Ajustes - Cerrar todas las otras sesiones.\n\nGracias,\nEl equipo de Telegram + %1$s actualizó su foto de perfil + + + Seleccionar contacto + No hay contactos aún + Hey, cambiémonos a Telegram: http://telegram.org/dl2 + hoy a las + ayer a las + a las + en línea + desconectado + últ. vez + últ. vez el + Invitar a amigos + + + Enviar mensaje a... + El nombre del grupo + MIEMBRO + Nombre del grupo + MIEMBROS + TODOS LOS CONTACTOS + + + INGRESA EL NOMBRE DEL GRUPO + Multimedia compartida + Información del grupo + MULTIMEDIA COMPARTIDA + AJUSTES + Añadir miembro + Eliminar y salir del grupo + Notificaciones + Expulsar del grupo + + + Compartir + Añadir + Bloquear + Editar + Eliminar + CASA + MÓVIL + TRABAJO + OTRO + PRINCIPAL + Información del contacto + TELÉFONO + Iniciar chat secreto + Ocurrió un error. + No podemos crear un chat secreto con %1$s.\n\n%2$s está usando una versión antigua de Telegram y debe actualizarla primero. + Chat secreto + Clave de cifrado + Autodestrucción + Apagado + 2s + 5s + 1m + 1h + 1d + 1sem + Esta imagen es una visualización de la clave de cifrado para el chat secreto con ]]>%1$s]]>.
]]>Si esta imagen se visualiza de la misma manera en el teléfono de ]]>%2$s]]>, tu chat es seguro en un 200%%.
]]>Aprende más en telegram.org
+ + + Restablecer todas las notificaciones + Tamaño del texto + Haz una pregunta + Activar animaciones + Desbloquear + Mantén pulsado un usuario para desbloquearlo + No hay usuarios bloqueados aún + TU NÚMERO DE TELÉFONO + NOTIFICACIONES DE MENSAJES + Alerta + Vista previa del mensaje + NOTIFICACIONES DE GRUPO + Sonido + NOTIFICACIONES EN LA APP + Sonidos en la app + Vibración en la app + Vibración + Vista previa en la app + RESTABLECER + Restablecer todas las notificaciones + Deshacer todas las notificaciones personalizadas para todos tus usuarios y grupos + Notificaciones y sonidos + Usuarios bloqueados + Guardar fotos entrantes + Cerrar sesión + TU NOMBRE Y APELLIDOS + Sin sonido + Por defecto + SOPORTE + Fondo de chat + MENSAJES + Enviar con enter + Cerrar todas las otras sesiones + DESCARGA AUTOMÁTICA DE FOTOS + Grupos + Chats + EVENTOS + Un contacto se unió a Telegram + + + No hay fotos ni vídeos compartidos aún + Cancelar descarga + + + Mi ubicación + Mapa + Satélite + Híbrido + m de distancia + km de distancia + Enviar ubicación + Compartir ubicación + + + Mostrar todas las fotos y vídeos + Guardar en galería + de + Galería + + + Siguiente + Atrás + Hecho + Abrir + Cancelar + Añadir + Editar + Enviar + Llamar + Copiar + Eliminar + Reenviar + Reintentar + Desde la cámara + Desde la galería + Eliminar foto + Abrir foto + Establecer + OK + + + un1 expulsó a un2 + un1 dejó el grupo + un1 agregó a un2 + un1 eliminó la foto del grupo + un1 cambió la foto del grupo + un1 cambió el nombre del grupo a un2 + un1 creó el grupo + Expulsaste a un2 + Abandonaste el grupo + Añadiste a un2 + Quitaste la foto de grupo + Cambiaste la foto de grupo + Cambiaste el nombre de grupo a un2 + Creaste el grupo + un1 te expulsó + un1 te añadió + Este mensaje no está soportado en tu versión de Telegram. + Foto + Vídeo + Ubicación + Contacto + Archivo + Audio + + + + Número de teléfono inválido + Código expirado. Por favor, vuelve a iniciar sesión. + Demasiados intentos. Por favor, prueba de nuevo más tarde. + Código inválido + Nombre inválido + Apellido/s inválido/s + Cargando... + No tienes reproductor de vídeo. Por favor, instala uno para continuar. + No tienes una aplicación que pueda manejar el tipo mime \'%1$s\'. Por favor, instala una para continuar + Este usuario no tiene Telegram aún. ¿Enviarle una invitación? + ¿Estás seguro? + ¿Añadir contacto? + ¿Añadir a %1$s al grupo? + ¿Reenviar mensajes a %1$s? + ¿Eliminar este chat? + + + Telegram + Rápida + Gratis + Segura + Poderosa + Basada en la nube + Privada + Bienvenidos a la era de la mensajería rápida y segura. + Telegram]]> entrega mensajes más rápido que]]>cualquier otra aplicación. + Telegram]]> es gratis para siempre. Sin publicidad.]]>Sin cuotas de suscripción. + Telegram]]> mantiene tus mensajes]]>a salvo del ataque de hackers. + Telegram]]> no tiene límites en el tamaño de tus]]>chats y archivos. + Telegram]]> te permite acceder a tus mensajes]]>desde múltiples dispositivos. + Los mensajes de Telegram]]> están fuertemente]]>cifrados y se pueden autodestruir. + Empieza a conversar + + + CACHE_TAG +
\ 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 c271755d9..3b850b794 100644 --- a/TMessagesProj/src/main/res/values/strings.xml +++ b/TMessagesProj/src/main/res/values/strings.xml @@ -1,4 +1,7 @@ + + + Telegram @@ -46,6 +49,8 @@ You joined the secret chat. Clear History Delete and Exit + Hidden Name + Select Chat Select File @@ -69,7 +74,7 @@ are typing... and %d more people Got a question\nabout Telegram? - Take a photo + Take photo Gallery Location Video @@ -107,6 +112,7 @@ %1$s set the self-destruct timer to %2$s You set the self-destruct timer to %1$s %1$s disabled the self-destruct timer + You disabled the self-destruct timer 2 seconds 5 seconds 1 minute @@ -137,8 +143,8 @@ %1$s kicked %3$s from the group %2$s %1$s kicked you from the group %2$s %1$s has left the group %2$s - %1$s joined the Telegram! - New login from unrecognized device %1$s, location: %2$s + %1$s joined Telegram! + %1$s,\nWe detected a login into your account from a new device on %2$s\n\nDevice: %3$s\nLocation: %4$s\n\nIf this wasn’t you, you can go to Settings – Terminate all sessions.\n\nThanks,\nThe Telegram Team %1$s updated profile photo @@ -151,6 +157,7 @@ online offline last seen + last seen Invite Friends @@ -173,9 +180,11 @@ Kick from group - Share Contact - Add Contact - Block Contact + Share + Add + Block + Edit + Delete HOME MOBILE WORK @@ -229,6 +238,14 @@ Default SUPPORT Chat Background + MESSAGES + Send by Enter + Terminate All Other Sessions + AUTOMATIC PHOTO DOWNLOAD + Groups + Private Chats + EVENTS + Contact joined Telegram No shared media yet @@ -279,6 +296,15 @@ un1 changed group photo un1 changed group name to un2 un1 created the group + You kicked un2 + You left group + You added un2 + You removed group photo + You changed group photo + You changed group name to un2 + You created the group + un1 kicked you + un1 added you This message is not supported on your version of Telegram. Photo Video diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c21f71319..13bb3e047 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,6 @@ -# -#Thu Jul 18 15:19:16 MSK 2013 +#Fri Jan 24 13:44:30 MSK 2014 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=http\://services.gradle.org/distributions/gradle-1.9-all.zip +distributionUrl=http\://services.gradle.org/distributions/gradle-1.10-all.zip