update to 1.3.21

Ability to delete add rename contacts, proper handling of new contacts
in phone book
New photo crop
Ability to disable automatic photo download
Ability to disable notifications about new registered contacts
Updated Spanish localization
Bug fixes
This commit is contained in:
DrKLO 2014-02-11 18:32:09 +04:00
parent 9814a6e927
commit 507d05aaf1
147 changed files with 4500 additions and 619 deletions

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.telegram.messenger"
android:versionCode="148"
android:versionName="1.3.19">
android:versionCode="160"
android:versionName="1.3.21">
<supports-screens android:anyDensity="true"
android:smallScreens="true"
@ -25,6 +25,7 @@
<uses-feature android:name="android.hardware.screen.PORTRAIT" android:required="false" />
<uses-permission android:name="android.permission.INTERNET" />
<!--<uses-permission android:name="android.permission.RECORD_AUDIO" />-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
@ -164,6 +165,9 @@
<meta-data android:name="android.provider.CONTACTS_STRUCTURE"
android:resource="@xml/contacts" />
</service>
<service android:name="org.telegram.messenger.GcmService" android:enabled="true" android:exported="true"/>
<service android:name=".BackgroundService" android:enabled="true" android:stopWithTask="false"/>
<uses-library android:name="com.google.android.maps" android:required="false"/>
</application>

View File

@ -414,6 +414,7 @@ public class TLClassStore {
classStore.put(TLRPC.TL_messageActionTTLChange.constructor, TLRPC.TL_messageActionTTLChange.class);
classStore.put(TLRPC.TL_videoEncrypted.constructor, TLRPC.TL_videoEncrypted.class);
classStore.put(TLRPC.TL_documentEncrypted.constructor, TLRPC.TL_documentEncrypted.class);
classStore.put(TLRPC.TL_audioEncrypted.constructor, TLRPC.TL_audioEncrypted.class);
classStore.put(TLRPC.TL_gzip_packed.constructor, TLRPC.TL_gzip_packed.class);
classStore.put(TLRPC.Vector.constructor, TLRPC.Vector.class);
classStore.put(TLRPC.TL_userProfilePhotoOld.constructor, TLRPC.TL_userProfilePhotoOld.class);

View File

@ -1227,16 +1227,6 @@ public class TLRPC {
}
}
public static class Audio extends TLObject {
public long id;
public long access_hash;
public int user_id;
public int date;
public int duration;
public int size;
public int dc_id;
}
public static class TL_audioEmpty extends Audio {
public static int constructor = 0x586988d8;
@ -8776,6 +8766,19 @@ public class TLRPC {
public byte[] iv;
}
public static class Audio extends TLObject {
public long id;
public long access_hash;
public int user_id;
public int date;
public int duration;
public int size;
public int dc_id;
public String path;
public byte[] key;
public byte[] iv;
}
public static class MessageAction extends TLObject {
public Photo photo;
public UserProfilePhoto newUserPhoto;
@ -8871,6 +8874,36 @@ public class TLRPC {
}
}
public static class TL_audioEncrypted extends Audio {
public static int constructor = 0x555555F6;
public void readParams(SerializedData stream) {
id = stream.readInt64();
access_hash = stream.readInt64();
user_id = stream.readInt32();
date = stream.readInt32();
duration = stream.readInt32();
size = stream.readInt32();
dc_id = stream.readInt32();
key = stream.readByteArray();
iv = stream.readByteArray();
}
public void serializeToStream(SerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt64(id);
stream.writeInt64(access_hash);
stream.writeInt32(user_id);
stream.writeInt32(date);
stream.writeInt32(duration);
stream.writeInt32(size);
stream.writeInt32(dc_id);
stream.writeByteArray(key);
stream.writeByteArray(iv);
}
}
public static class TL_messageActionUserUpdatedPhoto extends MessageAction {
public static int constructor = 0x55555551;

View File

@ -0,0 +1,61 @@
/*
* 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.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
public class BackgroundService extends Service {
private Handler handler = new Handler(Looper.getMainLooper());
private Runnable checkRunnable = new Runnable() {
@Override
public void run() {
check();
}
};
public BackgroundService() {
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
check();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Log.e("tmessages", "onStartCommand");
return START_STICKY;
}
private void check() {
handler.removeCallbacks(checkRunnable);
handler.postDelayed(checkRunnable, 1500);
ConnectionsManager connectionsManager = ConnectionsManager.Instance;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e("tmessages", "onDestroy");
}
}

View File

@ -15,7 +15,6 @@ 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;
@ -38,6 +37,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
public static int APP_ID = 2458;
public static String APP_HASH = "5bce48dc7d331e62c955669eb7233217";
public static String HOCKEY_APP_HASH = "your-hockeyapp-api-key-here";
public static boolean disableContactsImport = false;
private HashMap<Integer, Datacenter> datacenters = new HashMap<Integer, Datacenter>();
private HashMap<Long, ArrayList<Long>> processedMessageIdsSet = new HashMap<Long, ArrayList<Long>>();
@ -160,7 +160,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
if (datacenters != null) {
MessagesController.Instance.updateTimerProc();
if (datacenterWithId(currentDatacenterId).authKey != null) {
if (lastPingTime < System.currentTimeMillis() - 30000) {
if (lastPingTime < System.currentTimeMillis() - 19000) {
lastPingTime = System.currentTimeMillis();
generatePing();
}
@ -947,6 +947,10 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
}
Datacenter requestDatacenter = datacenterWithId(datacenterId);
if (!request.initRequest && requestDatacenter.lastInitVersion != currentAppVersion) {
request.rpcRequest = wrapInLayer(request.rawRequest, requestDatacenter.datacenterId, request);
}
if (requestDatacenter == null) {
if (!unknownDatacenterIds.contains(datacenterId)) {
unknownDatacenterIds.add(datacenterId);
@ -1145,6 +1149,10 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
}
Datacenter requestDatacenter = datacenterWithId(datacenterId);
if (!request.initRequest && requestDatacenter.lastInitVersion != currentAppVersion) {
request.rpcRequest = wrapInLayer(request.rawRequest, requestDatacenter.datacenterId, request);
}
if (requestDatacenter == null) {
unknownDatacenterIds.add(datacenterId);
continue;
@ -1209,7 +1217,9 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
long messageId = generateMessageId();
SerializedData os = new SerializedData();
boolean canCompress = (request.flags & RPCRequest.RPCRequestClassCanCompress) != 0;
SerializedData os = new SerializedData(!canCompress);
request.rpcRequest.serializeToStream(os);
int requestLength = os.length();
@ -1223,13 +1233,16 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
sessionId = requestDatacenter.authUploadSessionId;
}
if ((request.flags & RPCRequest.RPCRequestClassCanCompress) != 0) {
if (canCompress) {
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;
os = new SerializedData(true);
packed.serializeToStream(os);
requestLength = os.length();
}
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -1431,7 +1444,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
}
TLRPC.TL_protoMessage wrapMessage(TLObject message, long sessionId, boolean meaningful) {
SerializedData os = new SerializedData();
SerializedData os = new SerializedData(true);
message.serializeToStream(os);
if (os.length() != 0) {
@ -1463,7 +1476,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
msgAck.msg_ids = new ArrayList<Long>();
msgAck.msg_ids.addAll(arr);
SerializedData os = new SerializedData();
SerializedData os = new SerializedData(true);
msgAck.serializeToStream(os);
if (os.length() != 0) {
@ -1559,7 +1572,20 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
NetworkMessage networkMessage = messages.get(0);
TLRPC.TL_protoMessage message = networkMessage.protoMessage;
FileLog.d("tmessages", sessionId + ":Send message " + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + message.body);
if (DEBUG_VERSION) {
if (message.body instanceof TLRPC.invokeWithLayer11) {
FileLog.d("tmessages", sessionId + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer11)message.body).query);
} else if (message.body instanceof TLRPC.initConnection) {
TLRPC.initConnection r = (TLRPC.initConnection)message.body;
if (r.query instanceof TLRPC.invokeWithLayer11) {
FileLog.d("tmessages", sessionId + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer11)r.query).query);
} else {
FileLog.d("tmessages", sessionId + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + r.query);
}
} else {
FileLog.d("tmessages", sessionId + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + message.body);
}
}
long msg_time = getTimeFromMsgId(message.msg_id);
long currentTime = System.currentTimeMillis() + ((long)timeDifference) * 1000;
@ -1586,7 +1612,20 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
for (NetworkMessage networkMessage : messages) {
TLRPC.TL_protoMessage message = networkMessage.protoMessage;
containerMessages.add(message);
FileLog.d("tmessages", sessionId + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + message.body);
if (DEBUG_VERSION) {
if (message.body instanceof TLRPC.invokeWithLayer11) {
FileLog.d("tmessages", sessionId + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer11)message.body).query);
} else if (message.body instanceof TLRPC.initConnection) {
TLRPC.initConnection r = (TLRPC.initConnection)message.body;
if (r.query instanceof TLRPC.invokeWithLayer11) {
FileLog.d("tmessages", sessionId + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer11)r.query).query);
} else {
FileLog.d("tmessages", sessionId + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + r.query);
}
} else {
FileLog.d("tmessages", sessionId + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + message.body);
}
}
}
messageContainer.messages = containerMessages;
@ -2339,7 +2378,11 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
try {
ConnectivityManager cm = (ConnectivityManager)ApplicationLoader.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo[] networkInfos = cm.getAllNetworkInfo();
for (NetworkInfo info : networkInfos) {
for (int a = 0; a < 2; a++) {
if (a >= networkInfos.length) {
break;
}
NetworkInfo info = networkInfos[a];
FileLog.e("tmessages", "Network: " + info.getTypeName() + " status: " + info.getState() + " info: " + info.getExtraInfo() + " object: " + info.getDetailedState() + " other: " + info);
}
if (networkInfos.length == 0) {
@ -2438,6 +2481,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
} else {
if (datacenter.authKeyId == null || !Arrays.equals(keyId, datacenter.authKeyId)) {
FileLog.e("tmessages", "Error: invalid auth key id " + connection);
connection.suspendConnection(true);
connection.connect();
return;
}
@ -2449,6 +2494,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
messageData = Utilities.aesIgeEncryption(messageData, keyData.aesKey, keyData.aesIv, false, false);
if (messageData == null) {
FileLog.e("tmessages", "Error: can't decrypt message data " + connection);
connection.suspendConnection(true);
connection.connect();
return;
}
@ -2490,6 +2537,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
if (!Arrays.equals(messageKey, realMessageKey)) {
FileLog.e("tmessages", "***** Error: invalid message key");
connection.suspendConnection(true);
connection.connect();
return;
}
@ -2551,7 +2600,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
public void run() {
moveToDatacenter(datacenterId);
}
}, 1000, false);
}, 1000);
}
}
}, null, true, RPCRequest.RPCRequestClassGeneric, currentDatacenterId);

File diff suppressed because it is too large Load Diff

View File

@ -183,105 +183,110 @@ public class ContactsController {
private HashMap<Integer, Contact> readContactsFromPhoneBook() {
HashMap<Integer, Contact> contactsMap = new HashMap<Integer, Contact>();
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) {
try {
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()) {
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);
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 = 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);
if (contact != null) {
contact.first_name = fname;
contact.last_name = sname;
if (contact.first_name == null) {
contact.first_name = "";
}
} else {
if (contact.shortPhones.contains(number)) {
addNumber = false;
} else {
contact.shortPhones.add(number);
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;
}
}
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.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();
} catch (Exception e) {
FileLog.e("tmessages", e);
contactsMap.clear();
}
return contactsMap;
}
@ -303,18 +308,42 @@ public class ContactsController {
return ret;
}
public void performSyncPhoneBook(final HashMap<Integer, Contact> contactHashMap, final boolean request, final boolean first) {
public void performSyncPhoneBook(final HashMap<Integer, Contact> contactHashMap, final boolean requ, final boolean first) {
Utilities.globalQueue.postRunnable(new Runnable() {
@Override
public void run() {
boolean request = requ;
if (request && first) {
if (UserConfig.contactsHash != null && UserConfig.contactsHash.length() != 0) {
UserConfig.contactsHash = "";
UserConfig.saveConfig(false);
request = false;
}
}
FileLog.e("tmessages", "start read contacts from phone");
final HashMap<Integer, Contact> contactsMap = readContactsFromPhoneBook();
final HashMap<String, Contact> contactsBookShort = new HashMap<String, Contact>();
int oldCount = contactHashMap.size();
if (ConnectionsManager.disableContactsImport) {
if (requ && first) {
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
contactsBookSPhones = contactsBookShort;
contactsBook = contactsMap;
contactsSyncInProgress = false;
contactsBookLoaded = true;
loadContacts(true);
}
});
}
return;
}
ArrayList<TLRPC.TL_inputPhoneContact> toImport = new ArrayList<TLRPC.TL_inputPhoneContact>();
if (!contactHashMap.isEmpty()) {
HashMap<Integer, Contact> contactsMapCopy = new HashMap<Integer, Contact>(contactsMap);
for (HashMap.Entry<Integer, Contact> pair : contactsMap.entrySet()) {
Integer id = pair.getKey();
Contact value = pair.getValue();
@ -413,7 +442,7 @@ public class ContactsController {
}
});
FileLog.e("tmessages", "done procrssing contacts");
FileLog.e("tmessages", "done processing contacts");
if (request) {
if (!toImport.isEmpty()) {
@ -426,7 +455,9 @@ public class ContactsController {
public void run(TLObject response, TLRPC.TL_error error) {
if (error == null) {
FileLog.e("tmessages", "contacts imported");
MessagesStorage.Instance.putCachedPhoneBook(contactsMap);
if (!contactsMap.isEmpty()) {
MessagesStorage.Instance.putCachedPhoneBook(contactsMap);
}
TLRPC.TL_contacts_importedContacts res = (TLRPC.TL_contacts_importedContacts)response;
MessagesStorage.Instance.putUsersAndChats(res.users, null, true, true);
ArrayList<TLRPC.TL_contact> cArr = new ArrayList<TLRPC.TL_contact>();
@ -462,7 +493,17 @@ public class ContactsController {
});
}
} else {
MessagesStorage.Instance.putCachedPhoneBook(contactsMap);
if (!contactsMap.isEmpty()) {
MessagesStorage.Instance.putCachedPhoneBook(contactsMap);
}
if (first) {
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
loadContacts(true);
}
});
}
}
}
});
@ -890,6 +931,9 @@ public class ContactsController {
@Override
public void run() {
try {
if (ConnectionsManager.disableContactsImport) {
return;
}
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<Integer, Long> bookContacts = new HashMap<Integer, Long>();
@ -922,20 +966,8 @@ public class ContactsController {
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);
}
}
}
}
}
@ -952,8 +984,10 @@ public class ContactsController {
}
if (user == null) {
user = MessagesController.Instance.users.get(newContact.user_id);
} else {
MessagesController.Instance.users.putIfAbsent(user.id, user);
}
if (user == null || user.phone == null && user.phone.length() == 0) {
if (user == null || user.phone == null || user.phone.length() == 0) {
reloadContacts = true;
continue;
}
@ -989,6 +1023,8 @@ public class ContactsController {
}
if (user == null) {
user = MessagesController.Instance.users.get(uid);
} else {
MessagesController.Instance.users.putIfAbsent(user.id, user);
}
if (user == null) {
reloadContacts = true;
@ -1095,7 +1131,7 @@ public class ContactsController {
}
public long addContactToPhoneBook(TLRPC.User user) {
if (currentAccount == null || user == null || user.phone == null || user.phone.length() == 0) {
if (currentAccount == null || user == null || user.phone == null || user.phone.length() == 0 || ConnectionsManager.disableContactsImport) {
return -1;
}
long res = -1;
@ -1146,6 +1182,9 @@ public class ContactsController {
}
private void deleteContactFromPhoneBook(int uid) {
if (ConnectionsManager.disableContactsImport) {
return;
}
ContentResolver contentResolver = ApplicationLoader.applicationContext.getContentResolver();
synchronized (observerLock) {
ignoreChanges = true;

View File

@ -42,14 +42,10 @@ public class DispatchQueue extends Thread {
}
public void postRunnable(Runnable runnable) {
postRunnable(runnable, 0, false);
postRunnable(runnable, 0);
}
public void postRunnable(Runnable runnable, boolean inFront) {
postRunnable(runnable, 0, true);
}
public void postRunnable(Runnable runnable, int delay, boolean inFront) {
public void postRunnable(Runnable runnable, int delay) {
if (handler == null) {
try {
synchronized (handlerSyncObject) {
@ -62,11 +58,7 @@ public class DispatchQueue extends Thread {
if (handler != null) {
if (delay <= 0) {
if (inFront) {
handler.postAtFrontOfQueue(runnable);
} else {
handler.post(runnable);
}
handler.post(runnable);
} else {
handler.postDelayed(runnable, delay);
}

View File

@ -53,7 +53,7 @@ public class ExportAuthorizationAction extends Action {
public void run() {
beginExport();
}
}, retryCount * 1500, false);
}, retryCount * 1500);
}
}
}
@ -84,7 +84,7 @@ public class ExportAuthorizationAction extends Action {
public void run() {
beginExport();
}
}, retryCount * 1500, false);
}, retryCount * 1500);
}
}
}

View File

@ -94,6 +94,24 @@ public class FileLoadOperation {
ext = ".mp4";
}
public FileLoadOperation(TLRPC.Audio audioLocation) {
if (audioLocation instanceof TLRPC.TL_audio) {
location = new TLRPC.TL_inputAudioFileLocation();
datacenter_id = audioLocation.dc_id;
location.id = audioLocation.id;
location.access_hash = audioLocation.access_hash;
} else if (audioLocation instanceof TLRPC.TL_audioEncrypted) {
location = new TLRPC.TL_inputEncryptedFileLocation();
location.id = audioLocation.id;
location.access_hash = audioLocation.access_hash;
datacenter_id = audioLocation.dc_id;
iv = new byte[32];
System.arraycopy(audioLocation.iv, 0, iv, 0, iv.length);
key = audioLocation.key;
}
ext = ".m4a";
}
public FileLoadOperation(TLRPC.Document documentLocation) {
if (documentLocation instanceof TLRPC.TL_document) {
location = new TLRPC.TL_inputDocumentFileLocation();
@ -220,14 +238,14 @@ public class FileLoadOperation {
opts.inSampleSize = (int)scaleFactor;
}
opts.inPreferredConfig = Bitmap.Config.RGB_565;
opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
opts.inDither = false;
image = BitmapFactory.decodeStream(is, null, opts);
is.close();
if (image == null) {
if (!dontDelete) {
cacheFileFinal.delete();
}
//if (!dontDelete) {
// cacheFileFinal.delete();
//}
} else {
if (filter != null && image != null) {
float bitmapW = image.getWidth();
@ -252,13 +270,17 @@ public class FileLoadOperation {
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
delegate.didFinishLoadingFile(FileLoadOperation.this);
if (image == null) {
delegate.didFailedLoadingFile(FileLoadOperation.this);
} else {
delegate.didFinishLoadingFile(FileLoadOperation.this);
}
}
});
} catch (Exception e) {
if (!dontDelete) {
cacheFileFinal.delete();
}
//if (!dontDelete) {
// cacheFileFinal.delete();
//}
FileLog.e("tmessages", e);
}
}
@ -414,7 +436,7 @@ public class FileLoadOperation {
opts.inSampleSize = (int) scaleFactor;
}
opts.inPreferredConfig = Bitmap.Config.RGB_565;
opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
opts.inDither = false;
try {
if (renamed) {
@ -442,10 +464,14 @@ public class FileLoadOperation {
}
}
if (FileLoader.Instance.runtimeHack != null) {
if (image != null && FileLoader.Instance.runtimeHack != null) {
FileLoader.Instance.runtimeHack.trackFree(image.getRowBytes() * image.getHeight());
}
delegate.didFinishLoadingFile(FileLoadOperation.this);
if (image != null) {
delegate.didFinishLoadingFile(FileLoadOperation.this);
} else {
delegate.didFailedLoadingFile(FileLoadOperation.this);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
delegate.didFailedLoadingFile(FileLoadOperation.this);

View File

@ -391,8 +391,8 @@ public class FileLoader {
});
}
public void cancelLoadFile(final TLRPC.Video video, final TLRPC.PhotoSize photo, final TLRPC.Document document) {
if (video == null && photo == null && document == null) {
public void cancelLoadFile(final TLRPC.Video video, final TLRPC.PhotoSize photo, final TLRPC.Document document, final TLRPC.Audio audio) {
if (video == null && photo == null && document == null && audio == null) {
return;
}
Utilities.fileUploadQueue.postRunnable(new Runnable() {
@ -405,6 +405,8 @@ public class FileLoader {
fileName = MessageObject.getAttachFileName(photo);
} else if (document != null) {
fileName = MessageObject.getAttachFileName(document);
} else if (audio != null) {
fileName = MessageObject.getAttachFileName(audio);
}
if (fileName == null) {
return;
@ -422,7 +424,7 @@ public class FileLoader {
return loadOperationPaths.containsKey(fileName);
}
public void loadFile(final TLRPC.Video video, final TLRPC.PhotoSize photo, final TLRPC.Document document) {
public void loadFile(final TLRPC.Video video, final TLRPC.PhotoSize photo, final TLRPC.Document document, final TLRPC.Audio audio) {
Utilities.fileUploadQueue.postRunnable(new Runnable() {
@Override
public void run() {
@ -433,6 +435,8 @@ public class FileLoader {
fileName = MessageObject.getAttachFileName(photo);
} else if (document != null) {
fileName = MessageObject.getAttachFileName(document);
} else if (audio != null) {
fileName = MessageObject.getAttachFileName(audio);
}
if (fileName == null) {
return;
@ -451,6 +455,9 @@ public class FileLoader {
} else if (document != null) {
operation = new FileLoadOperation(document);
operation.totalBytesCount = document.size;
} else if (audio != null) {
operation = new FileLoadOperation(audio);
operation.totalBytesCount = audio.size;
}
final String arg1 = fileName;
@ -888,7 +895,7 @@ public class FileLoader {
}
void enqueueImageProcessingOperationWithImage(final Bitmap image, final String filter, final String key, final CacheImage img) {
if (image == null || key == null) {
if (key == null) {
return;
}
@ -907,7 +914,7 @@ public class FileLoader {
@Override
public void run() {
img.callAndClear(image);
if (memCache.get(key) == null) {
if (image != null && memCache.get(key) == null) {
memCache.put(key, image);
}
}

View File

@ -9,55 +9,20 @@
package org.telegram.messenger;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.PowerManager;
import android.support.v4.content.WakefulBroadcastReceiver;
import com.google.android.gms.gcm.GoogleCloudMessaging;
public class GcmBroadcastReceiver extends BroadcastReceiver {
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
public static final int NOTIFICATION_ID = 1;
@Override
public void onReceive(final Context context, final Intent intent) {
FileLog.d("tmessages", "GCM received intent: " + intent);
ComponentName comp = new ComponentName(context.getPackageName(), GcmService.class.getName());
startWakefulService(context, (intent.setComponent(comp)));
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) {
FileLog.d("tmessages", "GCM disabled");
return;
}
Thread thread = new Thread(new Runnable() {
public void run() {
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
String messageType = gcm.getMessageType(intent);
ConnectionsManager.Instance.resumeNetworkMaybe();
wl.release();
}
});
thread.setPriority(Thread.MAX_PRIORITY);
thread.start();
} 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.");
} else if (intent.getStringExtra("unregistered") != null) {
FileLog.e("tmessages", "unregistration done, new messages from the authorized sender will be rejected");
} else if (registration != null) {
FileLog.e("tmessages", "registration id = " + registration);
}
}
}
}

View File

@ -0,0 +1,42 @@
/*
* 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.app.IntentService;
import android.content.Intent;
public class GcmService extends IntentService {
public GcmService() {
super("GcmService");
}
@Override
protected void onHandleIntent(Intent intent) {
if (intent.getAction().equals("com.google.android.c2dm.intent.RECEIVE")) {
// SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Context.MODE_PRIVATE);
// boolean globalEnabled = preferences.getBoolean("EnableAll", true);
// if (!globalEnabled) {
// FileLog.d("tmessages", "GCM disabled");
// return;
// }
ConnectionsManager.Instance.resumeNetworkMaybe();
} 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.");
} else if (intent.getStringExtra("unregistered") != null) {
FileLog.e("tmessages", "unregistration done, new messages from the authorized sender will be rejected");
} else if (registration != null) {
FileLog.e("tmessages", "registration id = " + registration);
}
}
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
}

View File

@ -53,12 +53,12 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Semaphore;
public class MessagesController implements NotificationCenter.NotificationCenterDelegate {
public ConcurrentHashMap<Integer, TLRPC.Chat> chats = new ConcurrentHashMap<Integer, TLRPC.Chat>(100, 1.0f, 1);
public ConcurrentHashMap<Integer, TLRPC.EncryptedChat> encryptedChats = new ConcurrentHashMap<Integer, TLRPC.EncryptedChat>(10, 1.0f, 1);
public ConcurrentHashMap<Integer, TLRPC.User> users = new ConcurrentHashMap<Integer, TLRPC.User>(100, 1.0f, 1);
public ConcurrentHashMap<Integer, TLRPC.Chat> chats = new ConcurrentHashMap<Integer, TLRPC.Chat>(100, 1.0f, 2);
public ConcurrentHashMap<Integer, TLRPC.EncryptedChat> encryptedChats = new ConcurrentHashMap<Integer, TLRPC.EncryptedChat>(10, 1.0f, 2);
public ConcurrentHashMap<Integer, TLRPC.User> users = new ConcurrentHashMap<Integer, TLRPC.User>(100, 1.0f, 2);
public ArrayList<TLRPC.TL_dialog> dialogs = new ArrayList<TLRPC.TL_dialog>();
public ArrayList<TLRPC.TL_dialog> dialogsServerOnly = new ArrayList<TLRPC.TL_dialog>();
public ConcurrentHashMap<Long, TLRPC.TL_dialog> dialogs_dict = new ConcurrentHashMap<Long, TLRPC.TL_dialog>(100, 1.0f, 1);
public ConcurrentHashMap<Long, TLRPC.TL_dialog> dialogs_dict = new ConcurrentHashMap<Long, TLRPC.TL_dialog>(100, 1.0f, 2);
public SparseArray<MessageObject> dialogMessage = new SparseArray<MessageObject>();
public ConcurrentHashMap<Long, ArrayList<PrintingUser>> printingUsers = new ConcurrentHashMap<Long, ArrayList<PrintingUser>>(100, 1.0f, 2);
public HashMap<Long, CharSequence> printingStrings = new HashMap<Long, CharSequence>();
@ -137,6 +137,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
public int type;
public TLRPC.FileLocation location;
public TLRPC.TL_video videoLocation;
public TLRPC.TL_audio audioLocation;
public TLRPC.TL_document documentLocation;
public MessageObject obj;
public TLRPC.EncryptedChat encryptedChat;
@ -1476,35 +1477,39 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
public void sendMessage(TLRPC.User user, long peer) {
sendMessage(null, 0, 0, null, null, null, null, user, null, peer);
sendMessage(null, 0, 0, null, null, null, null, user, null, null, peer);
}
public void sendMessage(MessageObject message, long peer) {
sendMessage(null, 0, 0, null, null, message, null, null, null, peer);
sendMessage(null, 0, 0, null, null, message, null, null, null, null, peer);
}
public void sendMessage(TLRPC.TL_document document, long peer) {
sendMessage(null, 0, 0, null, null, null, null, null, document, peer);
sendMessage(null, 0, 0, null, null, null, null, null, document, null, peer);
}
public void sendMessage(String message, long peer) {
sendMessage(message, 0, 0, null, null, null, null, null, null, peer);
sendMessage(message, 0, 0, null, null, null, null, null, null, null, peer);
}
public void sendMessage(TLRPC.FileLocation location, long peer) {
sendMessage(null, 0, 0, null, null, null, location, null, null, peer);
sendMessage(null, 0, 0, null, null, null, location, null, null, null, peer);
}
public void sendMessage(double lat, double lon, long peer) {
sendMessage(null, lat, lon, null, null, null, null, null, null, peer);
sendMessage(null, lat, lon, null, null, null, null, null, null, null, peer);
}
public void sendMessage(TLRPC.TL_photo photo, long peer) {
sendMessage(null, 0, 0, photo, null, null, null, null, null, peer);
sendMessage(null, 0, 0, photo, null, null, null, null, null, null, peer);
}
public void sendMessage(TLRPC.TL_video video, long peer) {
sendMessage(null, 0, 0, null, video, null, null, null, null, peer);
sendMessage(null, 0, 0, null, video, null, null, null, null, null, peer);
}
public void sendMessage(TLRPC.TL_audio audio, long peer) {
sendMessage(null, 0, 0, null, null, null, null, null, null, audio, peer);
}
public void sendTTLMessage(TLRPC.EncryptedChat encryptedChat) {
@ -1548,7 +1553,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
performSendEncryptedRequest(reqSend, newMsgObj, encryptedChat, null);
}
private void sendMessage(String message, double lat, double lon, TLRPC.TL_photo photo, TLRPC.TL_video video, MessageObject msgObj, TLRPC.FileLocation location, TLRPC.User user, TLRPC.TL_document document, long peer) {
private void sendMessage(String message, double lat, double lon, TLRPC.TL_photo photo, TLRPC.TL_video video, MessageObject msgObj, TLRPC.FileLocation location, TLRPC.User user, TLRPC.TL_document document, TLRPC.TL_audio audio, long peer) {
TLRPC.Message newMsg = null;
int type = -1;
if (message != null) {
@ -1622,6 +1627,13 @@ public class MessagesController implements NotificationCenter.NotificationCenter
type = 7;
newMsg.message = "-1";
newMsg.attachPath = document.path;
} else if (audio != null) {
newMsg = new TLRPC.TL_message();
newMsg.media = new TLRPC.TL_messageMediaAudio();
newMsg.media.audio = audio;
type = 8;
newMsg.message = "-1";
newMsg.attachPath = audio.path;
}
if (newMsg == null) {
return;
@ -1699,7 +1711,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
reqSend.media = new TLRPC.TL_decryptedMessageMediaEmpty();
performSendEncryptedRequest(reqSend, newMsgObj, encryptedChat, null);
}
} else if (type == 1 || type == 2 || type == 3 || type == 5 || type == 6 || type == 7) {
} else if (type >= 1 && type <= 3 || type >= 5 && type <= 8) {
if (encryptedChat == null) {
TLRPC.TL_messages_sendMedia reqSend = new TLRPC.TL_messages_sendMedia();
reqSend.peer = sendToPeer;
@ -1753,6 +1765,15 @@ public class MessagesController implements NotificationCenter.NotificationCenter
delayedMessage.obj = newMsgObj;
delayedMessage.documentLocation = document;
performSendDelayedMessage(delayedMessage);
} else if (type == 8) {
reqSend.media = new TLRPC.TL_inputMediaUploadedAudio();
reqSend.media.duration = audio.duration;
DelayedMessage delayedMessage = new DelayedMessage();
delayedMessage.sendRequest = reqSend;
delayedMessage.type = 3;
delayedMessage.obj = newMsgObj;
delayedMessage.audioLocation = audio;
performSendDelayedMessage(delayedMessage);
}
} else {
TLRPC.TL_decryptedMessage reqSend = new TLRPC.TL_decryptedMessage();
@ -1837,6 +1858,22 @@ public class MessagesController implements NotificationCenter.NotificationCenter
delayedMessage.encryptedChat = encryptedChat;
delayedMessage.documentLocation = document;
performSendDelayedMessage(delayedMessage);
} else if (type == 8) {
reqSend.media = new TLRPC.TL_decryptedMessageMediaAudio();
reqSend.media.iv = new byte[32];
reqSend.media.key = new byte[32];
random.nextBytes(reqSend.media.iv);
random.nextBytes(reqSend.media.key);
reqSend.media.duration = audio.duration;
reqSend.media.size = audio.size;
DelayedMessage delayedMessage = new DelayedMessage();
delayedMessage.sendEncryptedRequest = reqSend;
delayedMessage.type = 3;
delayedMessage.obj = newMsgObj;
delayedMessage.encryptedChat = encryptedChat;
delayedMessage.audioLocation = audio;
performSendDelayedMessage(delayedMessage);
}
}
} else if (type == 4) {
@ -1852,10 +1889,10 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
}
private void processSendedMessage(TLRPC.Message newMsg, TLRPC.Message sendedMessage, TLRPC.EncryptedFile file, TLRPC.DecryptedMessage decryptedMessage) {
if (sendedMessage != null) {
if (sendedMessage.media instanceof TLRPC.TL_messageMediaPhoto && sendedMessage.media.photo != null && newMsg.media instanceof TLRPC.TL_messageMediaPhoto && newMsg.media.photo != null) {
for (TLRPC.PhotoSize size : sendedMessage.media.photo.sizes) {
private void processSendedMessage(TLRPC.Message newMsg, TLRPC.Message sentMessage, TLRPC.EncryptedFile file, TLRPC.DecryptedMessage decryptedMessage) {
if (sentMessage != null) {
if (sentMessage.media instanceof TLRPC.TL_messageMediaPhoto && sentMessage.media.photo != null && newMsg.media instanceof TLRPC.TL_messageMediaPhoto && newMsg.media.photo != null) {
for (TLRPC.PhotoSize size : sentMessage.media.photo.sizes) {
if (size instanceof TLRPC.TL_photoSizeEmpty) {
continue;
}
@ -1875,11 +1912,11 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
}
}
sendedMessage.message = newMsg.message;
sendedMessage.attachPath = newMsg.attachPath;
} else if (sendedMessage.media instanceof TLRPC.TL_messageMediaVideo && sendedMessage.media.video != null && newMsg.media instanceof TLRPC.TL_messageMediaVideo && newMsg.media.video != null) {
sentMessage.message = newMsg.message;
sentMessage.attachPath = newMsg.attachPath;
} else if (sentMessage.media instanceof TLRPC.TL_messageMediaVideo && sentMessage.media.video != null && newMsg.media instanceof TLRPC.TL_messageMediaVideo && newMsg.media.video != null) {
TLRPC.PhotoSize size2 = newMsg.media.video.thumb;
TLRPC.PhotoSize size = sendedMessage.media.video.thumb;
TLRPC.PhotoSize size = sentMessage.media.video.thumb;
if (size2.location != null && size.location != null && !(size instanceof TLRPC.TL_photoSizeEmpty) && !(size2 instanceof TLRPC.TL_photoSizeEmpty)) {
String fileName = size2.location.volume_id + "_" + size2.location.local_id;
String fileName2 = size.location.volume_id + "_" + size.location.local_id;
@ -1891,12 +1928,26 @@ public class MessagesController implements NotificationCenter.NotificationCenter
boolean result = cacheFile.renameTo(cacheFile2);
FileLoader.Instance.replaceImageInCache(fileName, fileName2);
size2.location = size.location;
sendedMessage.message = newMsg.message;
sendedMessage.attachPath = newMsg.attachPath;
sentMessage.message = newMsg.message;
sentMessage.attachPath = newMsg.attachPath;
}
} else if (sendedMessage.media instanceof TLRPC.TL_messageMediaDocument && sendedMessage.media.document != null && newMsg.media instanceof TLRPC.TL_messageMediaDocument && newMsg.media.document != null) {
sendedMessage.message = newMsg.message;
sendedMessage.attachPath = newMsg.attachPath;
} else if (sentMessage.media instanceof TLRPC.TL_messageMediaDocument && sentMessage.media.document != null && newMsg.media instanceof TLRPC.TL_messageMediaDocument && newMsg.media.document != null) {
sentMessage.message = newMsg.message;
sentMessage.attachPath = newMsg.attachPath;
} else if (sentMessage.media instanceof TLRPC.TL_messageMediaAudio && sentMessage.media.audio != null && newMsg.media instanceof TLRPC.TL_messageMediaAudio && newMsg.media.audio != null) {
sentMessage.message = newMsg.message;
sentMessage.attachPath = newMsg.attachPath;
String fileName = newMsg.media.audio.dc_id + "_" + newMsg.media.audio.id + ".m4a";
String fileName2 = sentMessage.media.audio.dc_id + "_" + sentMessage.media.audio.id + ".m4a";
if (fileName.equals(fileName2)) {
return;
}
File cacheFile = new File(Utilities.getCacheDir(), fileName);
File cacheFile2 = new File(Utilities.getCacheDir(), fileName2);
cacheFile.renameTo(cacheFile2);
sentMessage.media.audio.dc_id = newMsg.media.audio.dc_id;
sentMessage.media.audio.id = newMsg.media.audio.id;
}
} else if (file != null) {
if (newMsg.media instanceof TLRPC.TL_messageMediaPhoto && newMsg.media.photo != null) {
@ -1953,6 +2004,32 @@ public class MessagesController implements NotificationCenter.NotificationCenter
newMsg.media.document.path = document.path;
newMsg.media.document.thumb = document.thumb;
newMsg.media.document.dc_id = file.dc_id;
ArrayList<TLRPC.Message> arr = new ArrayList<TLRPC.Message>();
arr.add(newMsg);
MessagesStorage.Instance.putMessages(arr, false, true);
} else if (newMsg.media instanceof TLRPC.TL_messageMediaAudio && newMsg.media.audio != null) {
TLRPC.Audio audio = newMsg.media.audio;
newMsg.media.audio = new TLRPC.TL_audioEncrypted();
newMsg.media.audio.id = file.id;
newMsg.media.audio.access_hash = file.access_hash;
newMsg.media.audio.user_id = audio.user_id;
newMsg.media.audio.date = audio.date;
newMsg.media.audio.duration = audio.duration;
newMsg.media.audio.size = file.size;
newMsg.media.audio.dc_id = file.dc_id;
newMsg.media.audio.key = decryptedMessage.media.key;
newMsg.media.audio.iv = decryptedMessage.media.iv;
newMsg.media.audio.path = audio.path;
String fileName = audio.dc_id + "_" + audio.id + ".m4a";
String fileName2 = newMsg.media.audio.dc_id + "_" + newMsg.media.audio.id + ".m4a";
if (fileName.equals(fileName2)) {
return;
}
File cacheFile = new File(Utilities.getCacheDir(), fileName);
File cacheFile2 = new File(Utilities.getCacheDir(), fileName2);
cacheFile.renameTo(cacheFile2);
ArrayList<TLRPC.Message> arr = new ArrayList<TLRPC.Message>();
arr.add(newMsg);
MessagesStorage.Instance.putMessages(arr, false, true);
@ -2210,6 +2287,14 @@ public class MessagesController implements NotificationCenter.NotificationCenter
} else {
FileLoader.Instance.uploadFile(location, message.sendEncryptedRequest.media.key, message.sendEncryptedRequest.media.iv);
}
} else if (message.type == 3) {
String location = message.audioLocation.path;
delayedMessages.put(location, message);
if (message.sendRequest != null) {
FileLoader.Instance.uploadFile(location, null, null);
} else {
FileLoader.Instance.uploadFile(location, message.sendEncryptedRequest.media.key, message.sendEncryptedRequest.media.iv);
}
}
}
});
@ -2304,15 +2389,12 @@ public class MessagesController implements NotificationCenter.NotificationCenter
} else if (message.type == 2) {
message.sendRequest.media.file = file;
performSendMessageRequest(message.sendRequest, message.obj);
} else if (message.type == 3) {
message.sendRequest.media.file = file;
performSendMessageRequest(message.sendRequest, message.obj);
}
} else if (encryptedFile != null) {
if (message.type == 0) {
performSendEncryptedRequest(message.sendEncryptedRequest, message.obj, message.encryptedChat, encryptedFile);
} else if (message.type == 1) {
performSendEncryptedRequest(message.sendEncryptedRequest, message.obj, message.encryptedChat, encryptedFile);
} else if (message.type == 2) {
performSendEncryptedRequest(message.sendEncryptedRequest, message.obj, message.encryptedChat, encryptedFile);
}
performSendEncryptedRequest(message.sendEncryptedRequest, message.obj, message.encryptedChat, encryptedFile);
}
delayedMessages.remove(location);
}
@ -2933,6 +3015,21 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
}
Utilities.RunOnUIThread(new Runnable() {
@Override
public void run() {
for (TLRPC.User user : res.users) {
users.put(user.id, user);
if (user.id == UserConfig.clientUserId) {
UserConfig.currentUser = user;
}
}
for (TLRPC.Chat chat : res.chats) {
chats.put(chat.id, chat);
}
}
});
MessagesStorage.Instance.storageQueue.postRunnable(new Runnable() {
@Override
public void run() {
@ -3015,15 +3112,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
Utilities.RunOnUIThread(new Runnable() {
@Override
public void run() {
for (TLRPC.User user : res.users) {
users.put(user.id, user);
if (user.id == UserConfig.clientUserId) {
UserConfig.currentUser = user;
}
}
for (TLRPC.Chat chat : res.chats) {
chats.put(chat.id, chat);
}
for (HashMap.Entry<Long, ArrayList<MessageObject>> pair : messages.entrySet()) {
Long key = pair.getKey();
ArrayList<MessageObject> value = pair.getValue();
@ -3315,7 +3403,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
final ArrayList<TLRPC.TL_updateEncryptedMessagesRead> tasks = new ArrayList<TLRPC.TL_updateEncryptedMessagesRead>();
final ArrayList<Integer> contactsIds = new ArrayList<Integer>();
MessageObject lastMessage = null;
boolean usersAdded = false;
boolean checkForUsers = true;
ConcurrentHashMap<Integer, TLRPC.User> usersDict;
@ -3339,6 +3426,27 @@ public class MessagesController implements NotificationCenter.NotificationCenter
chatsDict = chats;
}
if (usersArr != null || chatsArr != null) {
Utilities.RunOnUIThread(new Runnable() {
@Override
public void run() {
if (usersArr != null) {
for (TLRPC.User user : usersArr) {
users.put(user.id, user);
if (user.id == UserConfig.clientUserId) {
UserConfig.currentUser = user;
}
}
}
if (chatsArr != null) {
for (TLRPC.Chat chat : chatsArr) {
chats.put(chat.id, chat);
}
}
}
});
}
int interfaceUpdateMask = 0;
for (TLRPC.Update update : updates) {
@ -3629,25 +3737,10 @@ public class MessagesController implements NotificationCenter.NotificationCenter
dialog.unread_count = 0;
dialog.top_message = 0;
dialog.last_message_date = update.date;
usersAdded = true;
Utilities.RunOnUIThread(new Runnable() {
@Override
public void run() {
if (usersArr != null) {
for (TLRPC.User user : usersArr) {
users.put(user.id, user);
if (user.id == UserConfig.clientUserId) {
UserConfig.currentUser = user;
}
}
}
if (chatsArr != null) {
for (TLRPC.Chat chat : chatsArr) {
chats.put(chat.id, chat);
}
}
dialogs_dict.put(dialog.id, dialog);
dialogs.add(dialog);
dialogsServerOnly.clear();
@ -3723,27 +3816,11 @@ public class MessagesController implements NotificationCenter.NotificationCenter
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() || !contactsIds.isEmpty()) {
Utilities.RunOnUIThread(new Runnable() {
@Override
public void run() {
int updateMask = interfaceUpdateMaskFinal;
if (!usersAddedConst) {
if (usersArr != null) {
for (TLRPC.User user : usersArr) {
users.put(user.id, user);
if (user.id == UserConfig.clientUserId) {
UserConfig.currentUser = user;
}
}
}
if (chatsArr != null) {
for (TLRPC.Chat chat : chatsArr) {
chats.put(chat.id, chat);
}
}
}
boolean avatarsUpdate = false;
if (!updatesOnMainThread.isEmpty()) {

View File

@ -334,7 +334,7 @@ public class MessagesStorage {
FileLog.e("tmessages", e);
}
}
}, true);
});
}
public void clearUserPhotos(final int uid) {
@ -967,7 +967,7 @@ public class MessagesStorage {
FileLog.e("tmessages", e);
}
}
}, true);
});
}
public void putContacts(final ArrayList<TLRPC.TL_contact> contacts, final boolean deleteAll) {
@ -1102,21 +1102,21 @@ public class MessagesStorage {
}
cursor.dispose();
} catch (Exception e) {
contactHashMap.clear();
FileLog.e("tmessages", e);
} finally {
ContactsController.Instance.performSyncPhoneBook(contactHashMap, true, true);
}
ContactsController.Instance.performSyncPhoneBook(contactHashMap, true, true);
}
}, true);
});
}
public void getContacts() {
storageQueue.postRunnable(new Runnable() {
@Override
public void run() {
ArrayList<TLRPC.TL_contact> contacts = new ArrayList<TLRPC.TL_contact>();
ArrayList<TLRPC.User> users = new ArrayList<TLRPC.User>();
try {
ArrayList<TLRPC.TL_contact> contacts = new ArrayList<TLRPC.TL_contact>();
ArrayList<TLRPC.User> users = new ArrayList<TLRPC.User>();
SQLiteCursor cursor = database.queryFinalized("SELECT * FROM contacts WHERE 1");
String uids = "";
while (cursor.next()) {
@ -1150,12 +1150,14 @@ public class MessagesStorage {
}
cursor.dispose();
}
ContactsController.Instance.processLoadedContacts(contacts, users, 1);
} catch (Exception e) {
contacts.clear();
users.clear();
FileLog.e("tmessages", e);
}
ContactsController.Instance.processLoadedContacts(contacts, users, 1);
}
}, true);
});
}
public void putMediaCount(final long uid, final int count) {
@ -1203,7 +1205,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) {
@ -1279,7 +1281,7 @@ public class MessagesStorage {
MessagesController.Instance.processLoadedMedia(res, uid, offset, count, max_id, true, classGuid);
}
}
}, true);
});
}
public void putMedia(final long uid, final ArrayList<TLRPC.Message> messages) {
@ -1469,7 +1471,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) {
@ -2691,7 +2693,7 @@ public class MessagesStorage {
MessagesController.Instance.processLoadedDialogs(dialogs, encryptedChats, 0, 0, 100, true, true);
}
}
}, true);
});
}
public void putDialogs(final TLRPC.messages_Dialogs dialogs) {

View File

@ -22,12 +22,23 @@ public class SerializedData {
private DataOutputStream out;
private ByteArrayInputStream inbuf;
private DataInputStream in;
private boolean justCalc = false;
private int len;
public SerializedData() {
outbuf = new ByteArrayOutputStream();
out = new DataOutputStream(outbuf);
}
public SerializedData(boolean calculate) {
if (!calculate) {
outbuf = new ByteArrayOutputStream();
out = new DataOutputStream(outbuf);
}
justCalc = calculate;
len = 0;
}
public SerializedData(int size) {
outbuf = new ByteArrayOutputStream(size);
out = new DataOutputStream(outbuf);
@ -50,13 +61,17 @@ public class SerializedData {
in = new DataInputStream(inbuf);
}
public void writeInt32(int x){
writeInt32(x, out);
public void writeInt32(int x) {
if (!justCalc) {
writeInt32(x, out);
} else {
len += 4;
}
}
protected void writeInt32(int x, DataOutputStream out){
private void writeInt32(int x, DataOutputStream out) {
try {
for(int i = 0; i < 4; i++){
for(int i = 0; i < 4; i++) {
out.write(x >> (i * 8));
}
} catch(IOException gfdsgd) {
@ -65,10 +80,14 @@ public class SerializedData {
}
public void writeInt64(long i) {
writeInt64(i, out);
if (!justCalc) {
writeInt64(i, out);
} else {
len += 8;
}
}
protected void writeInt64(long x, DataOutputStream out){
private void writeInt64(long x, DataOutputStream out) {
try {
for(int i = 0; i < 8; i++){
out.write((int)(x >> (i * 8)));
@ -90,10 +109,14 @@ public class SerializedData {
}
public void writeBool(boolean value) {
if (value) {
writeInt32(0x997275b5);
if (!justCalc) {
if (value) {
writeInt32(0x997275b5);
} else {
writeInt32(0xbc799737);
}
} else {
writeInt32(0xbc799737);
len += 4;
}
}
@ -143,9 +166,13 @@ public class SerializedData {
return 0;
}
public void writeRaw(byte[] b){
public void writeRaw(byte[] b) {
try {
out.write(b);
if (!justCalc) {
out.write(b);
} else {
len += b.length;
}
} catch(Exception x) {
FileLog.e("tmessages", "write raw error");
}
@ -153,7 +180,11 @@ public class SerializedData {
public void writeRaw(byte[] b, int offset, int count) {
try {
out.write(b, offset, count);
if (!justCalc) {
out.write(b, offset, count);
} else {
len += count;
}
} catch(Exception x) {
FileLog.e("tmessages", "write raw error");
}
@ -161,7 +192,11 @@ public class SerializedData {
public void writeByte(int i) {
try {
out.writeByte((byte)i);
if (!justCalc) {
out.writeByte((byte)i);
} else {
len += 1;
}
} catch (Exception e) {
FileLog.e("tmessages", "write byte error");
}
@ -169,13 +204,17 @@ public class SerializedData {
public void writeByte(byte b) {
try {
out.writeByte(b);
if (!justCalc) {
out.writeByte(b);
} else {
len += 1;
}
} catch (Exception e) {
FileLog.e("tmessages", "write byte error");
}
}
public void readRaw(byte[] b){
public void readRaw(byte[] b) {
try {
in.read(b);
} catch(Exception x) {
@ -189,7 +228,7 @@ public class SerializedData {
return arr;
}
public String readString(){
public String readString() {
try {
int sl = 1;
int l = in.read();
@ -233,20 +272,36 @@ public class SerializedData {
return null;
}
public void writeByteArray(byte[] b){
public void writeByteArray(byte[] b) {
try {
if (b.length <= 253){
out.write(b.length);
if (!justCalc) {
out.write(b.length);
} else {
len += 1;
}
} else {
out.write(254);
out.write(b.length);
out.write(b.length >> 8);
out.write(b.length >> 16);
if (!justCalc) {
out.write(254);
out.write(b.length);
out.write(b.length >> 8);
out.write(b.length >> 16);
} else {
len += 4;
}
}
if (!justCalc) {
out.write(b);
} else {
len += b.length;
}
out.write(b);
int i = b.length <= 253 ? 1 : 4;
while((b.length + i) % 4 != 0){
out.write(0);
if (!justCalc) {
out.write(0);
} else {
len += 1;
}
i++;
}
} catch(Exception x) {
@ -265,17 +320,33 @@ public class SerializedData {
public void writeByteArray(byte[] b, int offset, int count) {
try {
if(count <= 253){
out.write(count);
if (!justCalc) {
out.write(count);
} else {
len += 1;
}
} else {
out.write(254);
out.write(count);
out.write(count >> 8);
out.write(count >> 16);
if (!justCalc) {
out.write(254);
out.write(count);
out.write(count >> 8);
out.write(count >> 16);
} else {
len += 4;
}
}
if (!justCalc) {
out.write(b, offset, count);
} else {
len += count;
}
out.write(b, offset, count);
int i = count <= 253 ? 1 : 4;
while ((count + i) % 4 != 0){
out.write(0);
if (!justCalc) {
out.write(0);
} else {
len += 1;
}
i++;
}
} catch(Exception x) {
@ -292,7 +363,7 @@ public class SerializedData {
return 0;
}
public void writeDouble(double d){
public void writeDouble(double d) {
try {
writeInt64(Double.doubleToRawLongBits(d));
} catch(Exception x) {
@ -301,7 +372,10 @@ public class SerializedData {
}
public int length() {
return isOut ? outbuf.size() : inbuf.available();
if (!justCalc) {
return isOut ? outbuf.size() : inbuf.available();
}
return len;
}
protected void set(byte[] newData) {

View File

@ -10,6 +10,7 @@ package org.telegram.messenger;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Timer;
@ -51,6 +52,7 @@ public class TcpConnection extends PyroClientAdapter {
private int willRetryConnectCount = 5;
private boolean isNextPort = false;
private final Integer timerSync = 1;
private boolean wasConnected;
public int transportRequestClass;
@ -102,6 +104,7 @@ public class TcpConnection extends PyroClientAdapter {
FileLog.d("tmessages", String.format(TcpConnection.this + " Connecting (%s:%d)", hostAddress, hostPort));
firstPacket = true;
restOfTheData = null;
wasConnected = false;
hasSomeDataSinceLastConnect = false;
if (client != null) {
client.removeListener(TcpConnection.this);
@ -113,7 +116,7 @@ public class TcpConnection extends PyroClientAdapter {
if (isNextPort) {
client.setTimeout(8000);
} else {
client.setTimeout(35000);
client.setTimeout(15000);
}
selector.wakeup();
} catch (Exception e) {
@ -141,7 +144,7 @@ public class TcpConnection extends PyroClientAdapter {
failedConnectionCount++;
if (failedConnectionCount == 1) {
if (hasSomeDataSinceLastConnect) {
willRetryConnectCount = 5;
willRetryConnectCount = 3;
} else {
willRetryConnectCount = 1;
}
@ -217,6 +220,7 @@ public class TcpConnection extends PyroClientAdapter {
firstPacket = true;
restOfTheData = null;
channelToken = 0;
wasConnected = false;
}
public void suspendConnection(boolean task) {
@ -306,7 +310,7 @@ public class TcpConnection extends PyroClientAdapter {
Datacenter datacenter = ConnectionsManager.Instance.datacenterWithId(datacenterId);
datacenter.storeCurrentAddressAndPortNum();
isNextPort = false;
client.setTimeout(35000);
client.setTimeout(20000);
}
hasSomeDataSinceLastConnect = true;
@ -407,7 +411,7 @@ public class TcpConnection extends PyroClientAdapter {
}
}
public void handleDisconnect(PyroClient client, Exception e) {
public void handleDisconnect(PyroClient client, Exception e, boolean timedout) {
synchronized (timerSync) {
if (reconnectTimer != null) {
reconnectTimer.cancel();
@ -419,9 +423,11 @@ public class TcpConnection extends PyroClientAdapter {
} else {
FileLog.d("tmessages", "Disconnected " + TcpConnection.this);
}
boolean swirchToNextPort = wasConnected && hasSomeDataSinceLastConnect;
firstPacket = true;
restOfTheData = null;
channelToken = 0;
wasConnected = false;
if (connectionState != TcpConnectionState.TcpConnectionStageSuspended && connectionState != TcpConnectionState.TcpConnectionStageIdle) {
connectionState = TcpConnectionState.TcpConnectionStageIdle;
}
@ -446,7 +452,7 @@ public class TcpConnection extends PyroClientAdapter {
}
if (ConnectionsManager.isNetworkOnline()) {
isNextPort = true;
if (failedConnectionCount > willRetryConnectCount) {
if (failedConnectionCount > willRetryConnectCount || swirchToNextPort) {
Datacenter datacenter = ConnectionsManager.Instance.datacenterWithId(datacenterId);
datacenter.nextAddressOrPort();
failedConnectionCount = 0;
@ -486,6 +492,7 @@ public class TcpConnection extends PyroClientAdapter {
public void connectedClient(PyroClient client) {
connectionState = TcpConnectionState.TcpConnectionStageConnected;
channelToken = generateChannelToken();
wasConnected = true;
FileLog.d("tmessages", String.format(TcpConnection.this + " Connected (%s:%d)", hostAddress, hostPort));
if (delegate != null) {
final TcpConnectionDelegate finalDelegate = delegate;
@ -500,18 +507,18 @@ public class TcpConnection extends PyroClientAdapter {
@Override
public void unconnectableClient(PyroClient client, Exception cause) {
handleDisconnect(client, cause);
handleDisconnect(client, cause, false);
}
@Override
public void droppedClient(PyroClient client, IOException cause) {
super.droppedClient(client, cause);
handleDisconnect(client, cause);
handleDisconnect(client, cause, (cause instanceof SocketTimeoutException));
}
@Override
public void disconnectedClient(PyroClient client) {
handleDisconnect(client, null);
handleDisconnect(client, null, false);
}
@Override
@ -527,7 +534,5 @@ public class TcpConnection extends PyroClientAdapter {
@Override
public void sentData(PyroClient client, int bytes) {
failedConnectionCount = 0;
FileLog.d("tmessages", TcpConnection.this + " bytes sent " + bytes);
}
}

View File

@ -27,6 +27,7 @@ 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;
@ -54,6 +55,7 @@ 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();
@ -69,6 +71,7 @@ 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");
}
@ -102,7 +105,7 @@ public class UserConfig {
lastSendMessageId = data.readInt32();
lastLocalId = data.readInt32();
contactsHash = data.readString();
data.readString();
importHash = data.readString();
saveIncomingPhotos = data.readBool();
if (currentUser.status != null) {
if (currentUser.status.expires != 0) {
@ -136,6 +139,7 @@ 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) {
@ -160,6 +164,7 @@ 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) {
@ -185,6 +190,7 @@ public class UserConfig {
currentUser = null;
registeredForPush = false;
contactsHash = "";
importHash = "";
lastLocalId = -210000;
lastSendMessageId = -210000;
saveIncomingPhotos = false;

View File

@ -749,9 +749,9 @@ public class Utilities {
return storageDir;
}
public static String getPath(final Context context, final Uri uri) {
public static String getPath(final Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
if (isKitKat && DocumentsContract.isDocumentUri(ApplicationLoader.applicationContext, uri)) {
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
@ -762,7 +762,7 @@ public class Utilities {
} 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);
return getDataColumn(ApplicationLoader.applicationContext, contentUri, null, null);
} else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
@ -782,10 +782,10 @@ public class Utilities {
split[1]
};
return getDataColumn(context, contentUri, selection, selectionArgs);
return getDataColumn(ApplicationLoader.applicationContext, contentUri, selection, selectionArgs);
}
} else if ("content".equalsIgnoreCase(uri.getScheme())) {
return getDataColumn(context, uri, null, null);
return getDataColumn(ApplicationLoader.applicationContext, uri, null, null);
} else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}

View File

@ -22,7 +22,6 @@ 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 {
@ -303,6 +302,8 @@ public class MessageObject {
return getAttachFileName(messageOwner.media.video);
} else if (messageOwner.media instanceof TLRPC.TL_messageMediaDocument) {
return getAttachFileName(messageOwner.media.document);
} else if (messageOwner.media instanceof TLRPC.TL_messageMediaAudio) {
return getAttachFileName(messageOwner.media.audio);
}
return "";
}
@ -328,6 +329,9 @@ public class MessageObject {
} else if (attach instanceof TLRPC.PhotoSize) {
TLRPC.PhotoSize photo = (TLRPC.PhotoSize)attach;
return photo.location.volume_id + "_" + photo.location.local_id + ".jpg";
} else if (attach instanceof TLRPC.Audio) {
TLRPC.Audio audio = (TLRPC.Audio)attach;
return audio.dc_id + "_" + audio.id + ".m4a";
}
return "";
}

View File

@ -11,6 +11,7 @@ package org.telegram.ui;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@ -25,6 +26,7 @@ import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.gcm.GoogleCloudMessaging;
import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.messenger.BackgroundService;
import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.MessagesController;
@ -60,6 +62,7 @@ public class ApplicationLoader extends Application {
@Override
public void onCreate() {
super.onCreate();
currentLocale = Locale.getDefault();
Instance = this;
@ -130,6 +133,8 @@ public class ApplicationLoader extends Application {
lastPauseTime = System.currentTimeMillis();
FileLog.e("tmessages", "start application with time " + lastPauseTime);
startService(new Intent(this, BackgroundService.class));
}
@Override

View File

@ -0,0 +1,26 @@
/*
* 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.util.AttributeSet;
public class ChatMessageCell extends BaseCell {
public ChatMessageCell(Context context) {
super(context);
}
public ChatMessageCell(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ChatMessageCell(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}

View File

@ -393,7 +393,7 @@ public class ChatOrUserCell extends BaseCell {
if (value == 0) {
value = user.status.expires;
}
onlineString = getResources().getString(R.string.LastSeen) + " " + Utilities.formatDateOnline(value);
onlineString = Utilities.formatDateOnline(value);
}
}
}

View File

@ -394,18 +394,22 @@ public class DialogCell extends BaseCell {
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);
if (user != null && user.first_name != null) {
messageString = String.format(ApplicationLoader.applicationContext.getString(R.string.AwaitingEncryption), user.first_name);
} else {
messageString = String.format(ApplicationLoader.applicationContext.getString(R.string.AwaitingEncryption), "");
}
} 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) {
if (user != null && user.first_name != null) {
messageString = String.format(ApplicationLoader.applicationContext.getString(R.string.EncryptedChatStartedOutgoing), user.first_name);
} else {
messageString = String.format(ApplicationLoader.applicationContext.getString(R.string.EncryptedChatStartedOutgoing), "");
}
} else {
if (user != null) {
messageString = String.format(ApplicationLoader.applicationContext.getString(R.string.EncryptedChatStartedIncoming), user.first_name);
}
messageString = ApplicationLoader.applicationContext.getString(R.string.EncryptedChatStartedIncoming);
}
}
}

View File

@ -22,6 +22,7 @@ import android.graphics.Rect;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.Bundle;
@ -37,6 +38,7 @@ import android.text.SpannableStringBuilder;
import android.text.TextWatcher;
import android.text.style.ClickableSpan;
import android.text.style.ImageSpan;
import android.util.Log;
import android.util.TypedValue;
import android.view.Display;
import android.view.KeyEvent;
@ -121,6 +123,7 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa
private TextView emptyView;
private View bottomOverlay;
private TextView bottomOverlayText;
private ImageButton audioSendButton;
private MessageObject selectedObject;
private MessageObject forwaringMessage;
private TextView secretViewStatusTextView;
@ -179,6 +182,10 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa
private CharSequence lastPrintString;
private MediaRecorder audioRecorder = null;
private TLRPC.TL_audio recordingAudio = null;
private File recordingAudioFile = null;
ActionMode mActionMode = null;
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
@Override
@ -380,6 +387,7 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa
View bottomOverlayChat = fragmentView.findViewById(R.id.bottom_overlay_chat);
progressView = fragmentView.findViewById(R.id.progressLayout);
pagedownButton = fragmentView.findViewById(R.id.pagedown_button);
audioSendButton = (ImageButton)fragmentView.findViewById(R.id.chat_audio_send_button);
View progressViewInner = progressView.findViewById(R.id.progressLayoutInner);
updateContactStatus();
@ -460,7 +468,9 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa
chatListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> adapter, View view, int position, long id) {
createMenu(view, false);
if (mActionMode == null) {
createMenu(view, false);
}
return true;
}
});
@ -502,8 +512,8 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa
messsageEditText = (EditText)fragmentView.findViewById(R.id.chat_text_edit);
sendButton = (ImageButton)fragmentView.findViewById(R.id.chat_send_button);
sendButton.setImageResource(R.drawable.send_button_states);
sendButton.setEnabled(false);
sendButton.setVisibility(View.INVISIBLE);
emojiButton = (ImageView)fragmentView.findViewById(R.id.chat_smile_button);
if (loading && messages.isEmpty()) {
@ -568,6 +578,18 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa
}
});
audioSendButton.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
startRecording();
} else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
stopRecording();
}
return false;
}
});
pagedownButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
@ -590,6 +612,8 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa
}
});
checkSendButton();
messsageEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
@ -602,6 +626,7 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa
message = message.replaceAll("\n\n+", "\n\n");
message = message.replaceAll(" +", " ");
sendButton.setEnabled(message.length() != 0);
checkSendButton();
if (message.length() != 0 && lastTypingTimeSend < System.currentTimeMillis() - 5000 && !ignoreTextChange) {
int currentTime = ConnectionsManager.Instance.getCurrentTime();
@ -722,6 +747,18 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa
return fragmentView;
}
private void checkSendButton() {
sendButton.setVisibility(View.VISIBLE);
audioSendButton.setVisibility(View.INVISIBLE);
// if (messsageEditText.length() > 0) {
// sendButton.setVisibility(View.VISIBLE);
// audioSendButton.setVisibility(View.INVISIBLE);
// } else {
// sendButton.setVisibility(View.INVISIBLE);
// audioSendButton.setVisibility(View.VISIBLE);
// }
}
private void sendMessage() {
String message = messsageEditText.getText().toString().trim();
if (processSendingText(message)) {
@ -782,6 +819,84 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa
paused = true;
}
private void startRecording() {
if (audioRecorder != null) {
return;
}
recordingAudio = new TLRPC.TL_audio();
recordingAudio.dc_id = Integer.MIN_VALUE;
recordingAudio.id = UserConfig.lastLocalId;
recordingAudio.user_id = UserConfig.clientUserId;
UserConfig.lastLocalId--;
UserConfig.saveConfig(false);
recordingAudioFile = new File(Utilities.getCacheDir(), MessageObject.getAttachFileName(recordingAudio));
audioRecorder = new MediaRecorder();
audioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
audioRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
audioRecorder.setOutputFile(recordingAudioFile.getAbsolutePath());
if(android.os.Build.VERSION.SDK_INT >= 10) {
audioRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
} else {
audioRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
}
audioRecorder.setAudioSamplingRate(24000);
audioRecorder.setAudioChannels(1);
audioRecorder.setAudioEncodingBitRate(16000);
try {
audioRecorder.prepare();
audioRecorder.start();
} catch (Exception e) {
Log.e("tmessages", "prepare() failed");
}
}
private void stopRecording() {
try {
audioRecorder.stop();
audioRecorder.release();
audioRecorder = null;
recordingAudio.date = ConnectionsManager.Instance.getCurrentTime();
recordingAudio.size = (int)recordingAudioFile.length();
recordingAudio.path = recordingAudioFile.getAbsolutePath();
int duration = 0;
MediaPlayer player = new MediaPlayer();
try {
player.setDataSource(recordingAudio.path);
player.prepare();
duration = player.getDuration();
recordingAudio.duration = duration / 1000;
} catch (Exception e) {
FileLog.e("tmessages", e);
} finally {
try {
player.release();
player = null;
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
if (duration > 500) {
MessagesController.Instance.sendMessage(recordingAudio, dialog_id);
} else {
recordingAudio = null;
recordingAudioFile.delete();
recordingAudioFile = null;
}
} catch (Exception e) {
FileLog.e("tmessages", e);
recordingAudio = null;
recordingAudioFile.delete();
recordingAudioFile = null;
}
}
private void updateSecretStatus() {
if (bottomOverlay == null) {
return;
@ -1125,15 +1240,8 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa
if (imageUri.getScheme().contains("file")) {
imageFilePath = imageUri.getPath();
} else {
ActionBarActivity inflaterActivity = parentActivity;
if (inflaterActivity == null) {
inflaterActivity = (ActionBarActivity)getActivity();
}
if (inflaterActivity == null) {
return;
}
try {
imageFilePath = Utilities.getPath(inflaterActivity, imageUri);
imageFilePath = Utilities.getPath(imageUri);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
@ -1158,15 +1266,8 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa
Utilities.addMediaToGallery(currentPicturePath);
currentPicturePath = null;
} else {
ActionBarActivity inflaterActivity = parentActivity;
if (inflaterActivity == null) {
inflaterActivity = (ActionBarActivity)getActivity();
}
if (inflaterActivity == null) {
return;
}
try {
videoPath = Utilities.getPath(inflaterActivity, uri);
videoPath = Utilities.getPath(uri);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
@ -1477,7 +1578,7 @@ 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 || (updateMask & MessagesController.UPDATE_MASK_CHAT_NAME) != 0) {
if ((updateMask & MessagesController.UPDATE_MASK_NAME) != 0 || (updateMask & MessagesController.UPDATE_MASK_STATUS) != 0 || (updateMask & MessagesController.UPDATE_MASK_CHAT_NAME) != 0 || (updateMask & MessagesController.UPDATE_MASK_CHAT_MEMBERS) != 0) {
updateSubtitle();
updateOnlineCount();
}
@ -2406,6 +2507,10 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa
TLRPC.TL_document document = (TLRPC.TL_document)selectedObject.messageOwner.media.document;
document.path = selectedObject.messageOwner.attachPath;
MessagesController.Instance.sendMessage(document, dialog_id);
} else if (selectedObject.type == 18 || selectedObject.type == 19) {
TLRPC.TL_audio audio = (TLRPC.TL_audio)selectedObject.messageOwner.media.audio;
audio.path = selectedObject.messageOwner.attachPath;
MessagesController.Instance.sendMessage(audio, dialog_id);
}
ArrayList<Integer> arr = new ArrayList<Integer>();
arr.add(selectedObject.messageOwner.id);
@ -2732,88 +2837,102 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa
} else {
view.setBackgroundColor(0);
}
int messageType = holder.message.type;
if (!disableSelection) {
if (messageType == 2 || messageType == 4 || messageType == 6) {
holder.chatBubbleView.setBackgroundResource(R.drawable.chat_outgoing_photo_states);
} else if (messageType == 3 || messageType == 5 || messageType == 7) {
holder.chatBubbleView.setBackgroundResource(R.drawable.chat_incoming_photo_states);
} else if (messageType == 0 || messageType == 8) {
holder.messageLayout.setBackgroundResource(R.drawable.chat_outgoing_text_states);
holder.messageLayout.setPadding(Utilities.dp(11), Utilities.dp(7), Utilities.dp(18), 0);
} else if (messageType == 1 || messageType == 9) {
holder.messageLayout.setBackgroundResource(R.drawable.chat_incoming_text_states);
holder.messageLayout.setPadding(Utilities.dp(19), Utilities.dp(7), Utilities.dp(9), 0);
} else if (messageType == 12) {
holder.chatBubbleView.setBackgroundResource(R.drawable.chat_outgoing_text_states);
holder.chatBubbleView.setPadding(Utilities.dp(6), Utilities.dp(6), Utilities.dp(18), 0);
} else if (messageType == 13) {
holder.chatBubbleView.setBackgroundResource(R.drawable.chat_incoming_text_states);
holder.chatBubbleView.setPadding(Utilities.dp(15), Utilities.dp(6), Utilities.dp(9), 0);
} else if (messageType == 16) {
holder.chatBubbleView.setBackgroundResource(R.drawable.chat_outgoing_text_states);
holder.chatBubbleView.setPadding(Utilities.dp(9), Utilities.dp(9), Utilities.dp(18), 0);
} else if (messageType == 17) {
holder.chatBubbleView.setBackgroundResource(R.drawable.chat_incoming_text_states);
holder.chatBubbleView.setPadding(Utilities.dp(18), Utilities.dp(9), Utilities.dp(9), 0);
}
updateRowBackground(holder, disableSelection, selected);
}
}
}
private void updateRowBackground(ChatListRowHolderEx holder, boolean disableSelection, boolean selected) {
int messageType = holder.message.type;
if (!disableSelection) {
if (messageType == 2 || messageType == 4 || messageType == 6) {
holder.chatBubbleView.setBackgroundResource(R.drawable.chat_outgoing_photo_states);
} else if (messageType == 3 || messageType == 5 || messageType == 7) {
holder.chatBubbleView.setBackgroundResource(R.drawable.chat_incoming_photo_states);
} else if (messageType == 0 || messageType == 8) {
holder.messageLayout.setBackgroundResource(R.drawable.chat_outgoing_text_states);
holder.messageLayout.setPadding(Utilities.dp(11), Utilities.dp(7), Utilities.dp(18), 0);
} else if (messageType == 1 || messageType == 9) {
holder.messageLayout.setBackgroundResource(R.drawable.chat_incoming_text_states);
holder.messageLayout.setPadding(Utilities.dp(19), Utilities.dp(7), Utilities.dp(9), 0);
} else if (messageType == 12) {
holder.chatBubbleView.setBackgroundResource(R.drawable.chat_outgoing_text_states);
holder.chatBubbleView.setPadding(Utilities.dp(6), Utilities.dp(6), Utilities.dp(18), 0);
} else if (messageType == 13) {
holder.chatBubbleView.setBackgroundResource(R.drawable.chat_incoming_text_states);
holder.chatBubbleView.setPadding(Utilities.dp(15), Utilities.dp(6), Utilities.dp(9), 0);
} else if (messageType == 16) {
holder.chatBubbleView.setBackgroundResource(R.drawable.chat_outgoing_text_states);
holder.chatBubbleView.setPadding(Utilities.dp(9), Utilities.dp(9), Utilities.dp(18), 0);
} else if (messageType == 17) {
holder.chatBubbleView.setBackgroundResource(R.drawable.chat_incoming_text_states);
holder.chatBubbleView.setPadding(Utilities.dp(18), Utilities.dp(9), Utilities.dp(9), 0);
} else if (messageType == 18) {
holder.chatBubbleView.setBackgroundResource(R.drawable.chat_outgoing_text_states);
holder.chatBubbleView.setPadding(Utilities.dp(9), Utilities.dp(9), Utilities.dp(18), Utilities.dp(6));
}
} else {
if (messageType == 2 || messageType == 4 || messageType == 6) {
if (selected) {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_out_photo_selected);
} else {
if (messageType == 2 || messageType == 4 || messageType == 6) {
if (selected) {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_out_photo_selected);
} else {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_out_photo);
}
} else if (messageType == 3 || messageType == 5 || messageType == 7) {
if (selected) {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_in_photo_selected);
} else {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_in_photo);
}
} else if (messageType == 0 || messageType == 8) {
if (selected) {
holder.messageLayout.setBackgroundResource(R.drawable.msg_out_selected);
} else {
holder.messageLayout.setBackgroundResource(R.drawable.msg_out);
}
holder.messageLayout.setPadding(Utilities.dp(11), Utilities.dp(7), Utilities.dp(18), 0);
} else if (messageType == 1 || messageType == 9) {
if (selected) {
holder.messageLayout.setBackgroundResource(R.drawable.msg_in_selected);
} else {
holder.messageLayout.setBackgroundResource(R.drawable.msg_in);
}
holder.messageLayout.setPadding(Utilities.dp(19), Utilities.dp(7), Utilities.dp(9), 0);
} else if (messageType == 12) {
if (selected) {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_out_selected);
} else {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_out);
}
holder.chatBubbleView.setPadding(Utilities.dp(6), Utilities.dp(6), Utilities.dp(18), 0);
} else if (messageType == 13) {
if (selected) {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_in_selected);
} else {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_in);
}
holder.chatBubbleView.setPadding(Utilities.dp(15), Utilities.dp(6), Utilities.dp(9), 0);
} else if (messageType == 16) {
if (selected) {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_out_selected);
} else {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_out);
}
holder.chatBubbleView.setPadding(Utilities.dp(9), Utilities.dp(9), Utilities.dp(18), 0);
} else if (messageType == 17) {
if (selected) {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_in_selected);
} else {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_in);
}
holder.chatBubbleView.setPadding(Utilities.dp(18), Utilities.dp(9), Utilities.dp(9), 0);
}
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_out_photo);
}
} else if (messageType == 3 || messageType == 5 || messageType == 7) {
if (selected) {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_in_photo_selected);
} else {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_in_photo);
}
} else if (messageType == 0 || messageType == 8) {
if (selected) {
holder.messageLayout.setBackgroundResource(R.drawable.msg_out_selected);
} else {
holder.messageLayout.setBackgroundResource(R.drawable.msg_out);
}
holder.messageLayout.setPadding(Utilities.dp(11), Utilities.dp(7), Utilities.dp(18), 0);
} else if (messageType == 1 || messageType == 9) {
if (selected) {
holder.messageLayout.setBackgroundResource(R.drawable.msg_in_selected);
} else {
holder.messageLayout.setBackgroundResource(R.drawable.msg_in);
}
holder.messageLayout.setPadding(Utilities.dp(19), Utilities.dp(7), Utilities.dp(9), 0);
} else if (messageType == 12) {
if (selected) {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_out_selected);
} else {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_out);
}
holder.chatBubbleView.setPadding(Utilities.dp(6), Utilities.dp(6), Utilities.dp(18), 0);
} else if (messageType == 13) {
if (selected) {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_in_selected);
} else {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_in);
}
holder.chatBubbleView.setPadding(Utilities.dp(15), Utilities.dp(6), Utilities.dp(9), 0);
} else if (messageType == 16) {
if (selected) {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_out_selected);
} else {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_out);
}
holder.chatBubbleView.setPadding(Utilities.dp(9), Utilities.dp(9), Utilities.dp(18), 0);
} else if (messageType == 17) {
if (selected) {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_in_selected);
} else {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_in);
}
holder.chatBubbleView.setPadding(Utilities.dp(18), Utilities.dp(9), Utilities.dp(9), 0);
} else if (messageType == 18) {
if (selected) {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_out_selected);
} else {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_out);
}
holder.chatBubbleView.setPadding(Utilities.dp(9), Utilities.dp(9), Utilities.dp(18), Utilities.dp(6));
}
}
}
@ -2952,6 +3071,14 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa
} else {
view = li.inflate(R.layout.chat_incoming_document_layout, viewGroup, false);
}
} else if (type == 18) {
view = li.inflate(R.layout.chat_outgoing_audio_layout, viewGroup, false);
} else if (type == 19) {
if (currentChat != null) {
view = li.inflate(R.layout.chat_group_incoming_document_layout, viewGroup, false);
} else {
view = li.inflate(R.layout.chat_incoming_document_layout, viewGroup, false);
}
}
}
@ -2975,89 +3102,7 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa
} else {
view.setBackgroundColor(0);
}
int messageType = holder.message.type;
if (!disableSelection) {
if (messageType == 2 || messageType == 4 || messageType == 6) {
holder.chatBubbleView.setBackgroundResource(R.drawable.chat_outgoing_photo_states);
} else if (messageType == 3 || messageType == 5 || messageType == 7) {
holder.chatBubbleView.setBackgroundResource(R.drawable.chat_incoming_photo_states);
} else if (messageType == 0 || messageType == 8) {
holder.messageLayout.setBackgroundResource(R.drawable.chat_outgoing_text_states);
holder.messageLayout.setPadding(Utilities.dp(11), Utilities.dp(7), Utilities.dp(18), 0);
} else if (messageType == 1 || messageType == 9) {
holder.messageLayout.setBackgroundResource(R.drawable.chat_incoming_text_states);
holder.messageLayout.setPadding(Utilities.dp(19), Utilities.dp(7), Utilities.dp(9), 0);
} else if (messageType == 12) {
holder.chatBubbleView.setBackgroundResource(R.drawable.chat_outgoing_text_states);
holder.chatBubbleView.setPadding(Utilities.dp(6), Utilities.dp(6), Utilities.dp(18), 0);
} else if (messageType == 13) {
holder.chatBubbleView.setBackgroundResource(R.drawable.chat_incoming_text_states);
holder.chatBubbleView.setPadding(Utilities.dp(15), Utilities.dp(6), Utilities.dp(9), 0);
} else if (messageType == 16) {
holder.chatBubbleView.setBackgroundResource(R.drawable.chat_outgoing_text_states);
holder.chatBubbleView.setPadding(Utilities.dp(9), Utilities.dp(9), Utilities.dp(18), 0);
} else if (messageType == 17) {
holder.chatBubbleView.setBackgroundResource(R.drawable.chat_incoming_text_states);
holder.chatBubbleView.setPadding(Utilities.dp(18), Utilities.dp(9), Utilities.dp(9), 0);
}
} else {
if (messageType == 2 || messageType == 4 || messageType == 6) {
if (selected) {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_out_photo_selected);
} else {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_out_photo);
}
} else if (messageType == 3 || messageType == 5 || messageType == 7) {
if (selected) {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_in_photo_selected);
} else {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_in_photo);
}
} else if (messageType == 0 || messageType == 8) {
if (selected) {
holder.messageLayout.setBackgroundResource(R.drawable.msg_out_selected);
} else {
holder.messageLayout.setBackgroundResource(R.drawable.msg_out);
}
holder.messageLayout.setPadding(Utilities.dp(11), Utilities.dp(7), Utilities.dp(18), 0);
} else if (messageType == 1 || messageType == 9) {
if (selected) {
holder.messageLayout.setBackgroundResource(R.drawable.msg_in_selected);
} else {
holder.messageLayout.setBackgroundResource(R.drawable.msg_in);
}
holder.messageLayout.setPadding(Utilities.dp(19), Utilities.dp(7), Utilities.dp(9), 0);
} else if (messageType == 12) {
if (selected) {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_out_selected);
} else {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_out);
}
holder.chatBubbleView.setPadding(Utilities.dp(6), Utilities.dp(6), Utilities.dp(18), 0);
} else if (messageType == 13) {
if (selected) {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_in_selected);
} else {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_in);
}
holder.chatBubbleView.setPadding(Utilities.dp(15), Utilities.dp(6), Utilities.dp(9), 0);
} else if (messageType == 16) {
if (selected) {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_out_selected);
} else {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_out);
}
holder.chatBubbleView.setPadding(Utilities.dp(9), Utilities.dp(9), Utilities.dp(18), 0);
} else if (messageType == 17) {
if (selected) {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_in_selected);
} else {
holder.chatBubbleView.setBackgroundResource(R.drawable.msg_in);
}
holder.chatBubbleView.setPadding(Utilities.dp(18), Utilities.dp(9), Utilities.dp(9), 0);
}
}
updateRowBackground(holder, disableSelection, selected);
holder.update();
return view;
@ -3081,7 +3126,7 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa
@Override
public int getViewTypeCount() {
return 18;
return 20;
}
@Override
@ -3673,7 +3718,7 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa
processRowSelect(view);
return;
}
if (message.messageOwner.media.user_id != UserConfig.clientUserId) {
if (message.messageOwner.media.user_id != UserConfig.clientUserId && message.messageOwner.media.user_id != 0) {
UserProfileActivity fragment = new UserProfileActivity();
Bundle args = new Bundle();
args.putInt("user_id", message.messageOwner.media.user_id);
@ -3738,9 +3783,9 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa
if (file != null) {
loadingFile.remove(file);
if (message.type == 6 || message.type == 7) {
FileLoader.Instance.cancelLoadFile(message.messageOwner.media.video, null, null);
FileLoader.Instance.cancelLoadFile(message.messageOwner.media.video, null, null, null);
} else if (message.type == 16 || message.type == 17) {
FileLoader.Instance.cancelLoadFile(null, null, message.messageOwner.media.document);
FileLoader.Instance.cancelLoadFile(null, null, message.messageOwner.media.document, null);
}
updateVisibleRows();
}
@ -3899,9 +3944,9 @@ public class ChatActivity extends BaseFragment implements SizeNotifierRelativeLa
progressByTag.put((Integer)actionProgress.getTag(), fileName);
addToLoadingFile(fileName, actionProgress);
if (message.type == 6 || message.type == 7) {
FileLoader.Instance.loadFile(message.messageOwner.media.video, null, null);
FileLoader.Instance.loadFile(message.messageOwner.media.video, null, null, null);
} else if (message.type == 16 || message.type == 17) {
FileLoader.Instance.loadFile(null, null, message.messageOwner.media.document);
FileLoader.Instance.loadFile(null, null, message.messageOwner.media.document, null);
}
updateVisibleRows();
}

View File

@ -8,10 +8,12 @@
package org.telegram.ui;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.internal.view.SupportMenuItem;
@ -30,12 +32,15 @@ import android.widget.BaseAdapter;
import android.widget.ImageView;
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.FileLog;
import org.telegram.messenger.MessagesController;
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.ui.Cells.ChatOrUserCell;
@ -48,6 +53,7 @@ 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,6 +76,8 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
private SupportMenuItem searchItem;
private Timer searchDialogsTimer;
private String inviteText;
private boolean updatingInviteText = false;
public ArrayList<TLRPC.User> searchResult;
public ArrayList<CharSequence> searchResultNames;
public ContactsActivityDelegate delegate;
@ -95,6 +103,15 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
ignoreUsers = (HashMap<Integer, TLRPC.User>)NotificationCenter.Instance.getFromMemCache(7);
}
}
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
inviteText = preferences.getString("invitetext", null);
int time = preferences.getInt("invitetexttime", 0);
if (inviteText == null || time + 86400 < (int)(System.currentTimeMillis() / 1000)) {
updateInviteText();
}
return true;
}
@ -165,14 +182,20 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
} else {
int section = listViewAdapter.getSectionForPosition(i);
int row = listViewAdapter.getPositionInSectionForPosition(i);
if (row < 0 || section < 0) {
return;
}
TLRPC.User user = null;
if (usersAsSections) {
if (section < ContactsController.Instance.sortedUsersSectionsArray.size()) {
ArrayList<TLRPC.TL_contact> arr = ContactsController.Instance.usersSectionsDict.get(ContactsController.Instance.sortedUsersSectionsArray.get(section));
if (row >= arr.size()) {
if (row < arr.size()) {
TLRPC.TL_contact contact = arr.get(row);
user = MessagesController.Instance.users.get(contact.user_id);
} else {
return;
}
user = MessagesController.Instance.users.get(arr.get(row).user_id);
}
} else {
if (section == 0) {
@ -180,7 +203,7 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
try {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, getStringEntry(R.string.InviteText));
intent.putExtra(Intent.EXTRA_TEXT, inviteText != null ? inviteText : getStringEntry(R.string.InviteText));
startActivity(intent);
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -554,6 +577,41 @@ public class ContactsActivity extends BaseFragment implements NotificationCenter
}
}
private void updateInviteText() {
if (updatingInviteText) {
return;
}
updatingInviteText = true;
TLRPC.TL_help_getInviteText req = new TLRPC.TL_help_getInviteText();
req.lang_code = Locale.getDefault().getCountry();
if (req.lang_code == null || req.lang_code.length() == 0) {
req.lang_code = "en";
}
ConnectionsManager.Instance.performRpc(req, new RPCRequest.RPCRequestDelegate() {
@Override
public void run(TLObject response, TLRPC.TL_error error) {
if (error != null) {
return;
}
final TLRPC.TL_help_inviteText res = (TLRPC.TL_help_inviteText)response;
if (res.message.length() == 0) {
return;
}
Utilities.RunOnUIThread(new Runnable() {
@Override
public void run() {
updatingInviteText = false;
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("invitetext", res.message);
editor.putInt("invitetexttime", (int) (System.currentTimeMillis() / 1000));
editor.commit();
}
});
}
}, null, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors);
}
private void updateVisibleRows(int mask) {
if (listView == null) {
return;

View File

@ -67,6 +67,7 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
private String currentFileName;
private int user_id = 0;
private Point displaySize = new Point();
private boolean cancelRunning = false;
private ArrayList<MessageObject> imagesArrTemp = new ArrayList<MessageObject>();
private HashMap<Integer, MessageObject> imagesByIdsTemp = new HashMap<Integer, MessageObject>();
@ -224,7 +225,7 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
deleteButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mViewPager == null) {
if (mViewPager == null || localPagerAdapter == null || localPagerAdapter.imagesArr == null) {
return;
}
int item = mViewPager.getCurrentItem();
@ -645,9 +646,20 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
}
}
@Override
public void onBackPressed() {
super.onBackPressed();
cancelRunning = true;
mViewPager.setAdapter(null);
localPagerAdapter = null;
finish();
System.gc();
}
private void processSelectedMenu(int itemId) {
switch (itemId) {
case android.R.id.home:
cancelRunning = true;
mViewPager.setAdapter(null);
localPagerAdapter = null;
finish();
@ -958,9 +970,9 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
}
if (loadFile) {
if (!FileLoader.Instance.isLoadingFile(fileName)) {
FileLoader.Instance.loadFile(message.messageOwner.media.video, null, null);
FileLoader.Instance.loadFile(message.messageOwner.media.video, null, null, null);
} else {
FileLoader.Instance.cancelLoadFile(message.messageOwner.media.video, null, null);
FileLoader.Instance.cancelLoadFile(message.messageOwner.media.video, null, null, null);
}
checkCurrentFile();
processViews(playButton, message);
@ -988,7 +1000,9 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
public void destroyItem(View collection, int position, Object view) {
((ViewPager)collection).removeView((View)view);
PZSImageView iv = (PZSImageView)((View)view).findViewById(R.id.page_image);
FileLoader.Instance.cancelLoadingForImageView(iv);
if (cancelRunning) {
FileLoader.Instance.cancelLoadingForImageView(iv);
}
iv.clearImage();
}

View File

@ -54,7 +54,7 @@ public class LaunchActivity extends PausableActivity {
}
String path = null;
if (parcelable instanceof Uri) {
path = Utilities.getPath(this, (Uri)parcelable);
path = Utilities.getPath((Uri)parcelable);
} else {
path = intent.getParcelableExtra(Intent.EXTRA_STREAM).toString();
if (path.startsWith("content:")) {
@ -79,7 +79,7 @@ public class LaunchActivity extends PausableActivity {
}
String path = null;
if (parcelable instanceof Uri) {
path = Utilities.getPath(this, (Uri)parcelable);
path = Utilities.getPath((Uri)parcelable);
} else {
path = parcelable.toString();
if (path.startsWith("content:")) {

View File

@ -253,7 +253,9 @@ public class LoginActivityPhoneView extends SlideView implements AdapterView.OnI
public void selectCountry(String name) {
int index = countriesArray.indexOf(name);
if (index != -1) {
ignoreOnTextChange = true;
codeField.setText(countriesMap.get(name));
countryButton.setText(name);
}
}

View File

@ -0,0 +1,381 @@
/*
* 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;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.util.AttributeSet;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.messenger.Utilities;
import org.telegram.ui.Views.BaseFragment;
import java.io.File;
public class PhotoCropActivity extends BaseFragment {
public interface PhotoCropActivityDelegate {
public abstract void didFinishCrop(Bitmap bitmap);
}
private class PhotoCropView extends FrameLayout {
Paint rectPaint = null;
Paint circlePaint = null;
Paint halfPaint = null;
float rectSize = 600;
float rectX = -1, rectY = -1;
int draggingState = 0;
float oldX = 0, oldY = 0;
int bitmapWidth, bitmapHeight, bitmapX, bitmapY;
int viewWidth, viewHeight;
public PhotoCropView(Context context) {
super(context);
init();
}
public PhotoCropView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public PhotoCropView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
rectPaint = new Paint();
rectPaint.setColor(0xfffafafa);
rectPaint.setStrokeWidth(Utilities.dp(2));
rectPaint.setStyle(Paint.Style.STROKE);
circlePaint = new Paint();
circlePaint.setColor(0x7fffffff);
halfPaint = new Paint();
halfPaint.setColor(0x3f000000);
setBackgroundColor(0xff000000);
setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
float x = motionEvent.getX();
float y = motionEvent.getY();
int cornerSide = Utilities.dp(14);
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
if (rectX - cornerSide < x && rectX + cornerSide > x && rectY - cornerSide < y && rectY + cornerSide > y) {
draggingState = 1;
} else if (rectX - cornerSide + rectSize < x && rectX + cornerSide + rectSize > x && rectY - cornerSide < y && rectY + cornerSide > y) {
draggingState = 2;
} else if (rectX - cornerSide < x && rectX + cornerSide > x && rectY - cornerSide + rectSize < y && rectY + cornerSide + rectSize > y) {
draggingState = 3;
} else if (rectX - cornerSide + rectSize < x && rectX + cornerSide + rectSize > x && rectY - cornerSide + rectSize < y && rectY + cornerSide + rectSize > y) {
draggingState = 4;
} else if (rectX < x && rectX + rectSize > x && rectY < y && rectY + rectSize > y) {
draggingState = 5;
} else {
draggingState = 0;
}
oldX = x;
oldY = y;
} else if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
draggingState = 0;
} else if (motionEvent.getAction() == MotionEvent.ACTION_MOVE && draggingState != 0) {
float diffX = x - oldX;
float diffY = y - oldY;
if (draggingState == 5) {
rectX += diffX;
rectY += diffY;
if (rectX < bitmapX) {
rectX = bitmapX;
} else if (rectX + rectSize > bitmapX + bitmapWidth) {
rectX = bitmapX + bitmapWidth - rectSize;
}
if (rectY < bitmapY) {
rectY = bitmapY;
} else if (rectY + rectSize > bitmapY + bitmapHeight) {
rectY = bitmapY + bitmapHeight - rectSize;
}
} else if (draggingState == 1) {
if (rectSize - diffX < 160) {
diffX = rectSize - 160;
}
if (rectX + diffX < bitmapX) {
diffX = bitmapX - rectX;
}
if (rectY + diffX < bitmapY) {
diffX = bitmapY - rectY;
}
rectX += diffX;
rectY += diffX;
rectSize -= diffX;
} else if (draggingState == 2) {
if (rectSize + diffX < 160) {
diffX = -(rectSize - 160);
}
if (rectX + rectSize + diffX > bitmapX + bitmapWidth) {
diffX = bitmapX + bitmapWidth - rectX - rectSize;
}
if (rectY - diffX < bitmapY) {
diffX = rectY - bitmapY;
}
rectY -= diffX;
rectSize += diffX;
} else if (draggingState == 3) {
if (rectSize - diffX < 160) {
diffX = rectSize - 160;
}
if (rectX + diffX < bitmapX) {
diffX = bitmapX - rectX;
}
if (rectY + rectSize - diffX > bitmapY + bitmapHeight) {
diffX = rectY + rectSize - bitmapY - bitmapHeight;
}
rectX += diffX;
rectSize -= diffX;
} else if (draggingState == 4) {
if (rectX + rectSize + diffX > bitmapX + bitmapWidth) {
diffX = bitmapX + bitmapWidth - rectX - rectSize;
}
if (rectY + rectSize + diffX > bitmapY + bitmapHeight) {
diffX = bitmapY + bitmapHeight - rectY - rectSize;
}
rectSize += diffX;
if (rectSize < 160) {
rectSize = 160;
}
}
oldX = x;
oldY = y;
invalidate();
}
return true;
}
});
}
private void updateBitmapSize() {
if (viewWidth == 0 || viewHeight == 0) {
return;
}
float percX = (rectX - bitmapX) / bitmapWidth;
float percY = (rectY - bitmapY) / bitmapHeight;
float percSize = rectSize / bitmapWidth;
float w = imageToCrop.getWidth();
float h = imageToCrop.getHeight();
float scaleX = viewWidth / w;
float scaleY = viewHeight / h;
if (scaleX > scaleY) {
bitmapHeight = viewHeight;
bitmapWidth = (int)Math.ceil(w * scaleY);
} else {
bitmapWidth = viewWidth;
bitmapHeight = (int)Math.ceil(h * scaleX);
}
bitmapX = (viewWidth - bitmapWidth) / 2;
bitmapY = (viewHeight - bitmapHeight) / 2;
if (rectX == -1 && rectY == -1) {
if (bitmapWidth > bitmapHeight) {
rectY = bitmapY;
rectX = (viewWidth - bitmapHeight) / 2;
rectSize = bitmapHeight;
} else {
rectX = bitmapX;
rectY = (viewHeight - bitmapWidth) / 2;
rectSize = bitmapWidth;
}
} else {
rectX = percX * bitmapWidth + bitmapX;
rectY = percY * bitmapHeight + bitmapY;
rectSize = percSize * bitmapWidth;
}
invalidate();
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
viewWidth = right - left;
viewHeight = bottom - top;
updateBitmapSize();
}
public Bitmap getBitmap() {
float percX = (rectX - bitmapX) / bitmapWidth;
float percY = (rectY - bitmapY) / bitmapHeight;
float percSize = rectSize / bitmapWidth;
int x = (int)(percX * imageToCrop.getWidth());
int y = (int)(percY * imageToCrop.getHeight());
int size = (int)(percSize * imageToCrop.getWidth());
try {
return Bitmap.createBitmap(imageToCrop, x, y, size, size);
} catch (Exception e) {
FileLog.e("tmessags", e);
System.gc();
try {
return Bitmap.createBitmap(imageToCrop, x, y, size, size);
} catch (Exception e2) {
FileLog.e("tmessages", e2);
}
}
return null;
}
@Override
protected void onDraw(Canvas canvas) {
if (drawable != null) {
drawable.setBounds(bitmapX, bitmapY, bitmapX + bitmapWidth, bitmapY + bitmapHeight);
drawable.draw(canvas);
}
canvas.drawRect(bitmapX, bitmapY, bitmapX + bitmapWidth, rectY, halfPaint);
canvas.drawRect(bitmapX, rectY, rectX, rectY + rectSize, halfPaint);
canvas.drawRect(rectX + rectSize, rectY, bitmapX + bitmapWidth, rectY + rectSize, halfPaint);
canvas.drawRect(bitmapX, rectY + rectSize, bitmapX + bitmapWidth, bitmapY + bitmapHeight, halfPaint);
canvas.drawRect(rectX, rectY, rectX + rectSize, rectY + rectSize, rectPaint);
int side = Utilities.dp(7);
canvas.drawRect(rectX - side, rectY - side, rectX + side, rectY + side, circlePaint);
canvas.drawRect(rectX + rectSize - side, rectY - side, rectX + rectSize + side, rectY + side, circlePaint);
canvas.drawRect(rectX - side, rectY + rectSize - side, rectX + side, rectY + rectSize + side, circlePaint);
canvas.drawRect(rectX + rectSize - side, rectY + rectSize - side, rectX + rectSize + side, rectY + rectSize + side, circlePaint);
}
}
private Bitmap imageToCrop;
private BitmapDrawable drawable;
public PhotoCropActivityDelegate delegate = null;
private PhotoCropView view;
private boolean sameBitmap = false;
private boolean doneButtonPressed = false;
@Override
public boolean onFragmentCreate() {
super.onFragmentCreate();
String photoPath = getArguments().getString("photoPath");
if (photoPath == null) {
return false;
}
File f = new File(photoPath);
if (!f.exists()) {
return false;
}
Point displaySize = new Point();
Display display = ((WindowManager)ApplicationLoader.applicationContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
if(android.os.Build.VERSION.SDK_INT < 13) {
displaySize.set(display.getWidth(), display.getHeight());
} else {
display.getSize(displaySize);
}
int size = Math.max(displaySize.x, displaySize.y);
imageToCrop = FileLoader.loadBitmap(photoPath, size, size);
if (imageToCrop == null) {
return false;
}
drawable = new BitmapDrawable(imageToCrop);
return true;
}
@Override
public void onFragmentDestroy() {
super.onFragmentDestroy();
drawable = null;
if (imageToCrop != null && !sameBitmap) {
imageToCrop.recycle();
imageToCrop = null;
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (fragmentView == null) {
fragmentView = view = new PhotoCropView(this.getActivity());
fragmentView.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
} else {
ViewGroup parent = (ViewGroup)fragmentView.getParent();
if (parent != null) {
parent.removeView(fragmentView);
}
}
return fragmentView;
}
@Override
public boolean canApplyUpdateStatus() {
return false;
}
@Override
public void applySelfActionBar() {
if (parentActivity == null) {
return;
}
ActionBar actionBar = parentActivity.getSupportActionBar();
actionBar.setDisplayShowCustomEnabled(true);
actionBar.setDisplayShowHomeEnabled(false);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(false);
actionBar.setCustomView(R.layout.settings_do_action_layout);
View cancelButton = actionBar.getCustomView().findViewById(R.id.cancel_button);
cancelButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finishFragment();
}
});
View doneButton = actionBar.getCustomView().findViewById(R.id.done_button);
doneButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (delegate != null && !doneButtonPressed) {
Bitmap bitmap = view.getBitmap();
if (bitmap == imageToCrop) {
sameBitmap = true;
}
delegate.didFinishCrop(bitmap);
doneButtonPressed = true;
}
finishFragment();
}
});
}
@Override
public void onResume() {
super.onResume();
if (getActivity() == null) {
return;
}
((ApplicationActivity)parentActivity).updateActionBar();
}
}

View File

@ -246,11 +246,11 @@ public class SettingsWallpapersActivity extends BaseFragment implements Notifica
progressBar.setVisibility(View.VISIBLE);
loadingSize = size;
selectedColor = 0;
FileLoader.Instance.loadFile(null, size, null);
FileLoader.Instance.loadFile(null, size, null, null);
backgroundImage.setBackgroundColor(0);
} else {
if (loadingFile != null) {
FileLoader.Instance.cancelLoadFile(null, loadingSize, null);
FileLoader.Instance.cancelLoadFile(null, loadingSize, null, null);
}
loadingFileObject = null;
loadingFile = null;
@ -263,7 +263,7 @@ public class SettingsWallpapersActivity extends BaseFragment implements Notifica
}
} else {
if (loadingFile != null) {
FileLoader.Instance.cancelLoadFile(null, loadingSize, null);
FileLoader.Instance.cancelLoadFile(null, loadingSize, null, null);
}
if (selectedBackground == 1000001) {
backgroundImage.setImageResource(R.drawable.background_hd);

View File

@ -78,7 +78,7 @@ public class UserProfileActivity extends BaseFragment implements NotificationCen
if (dialog_id != 0) {
currentEncryptedChat = MessagesController.Instance.encryptedChats.get((int)(dialog_id >> 32));
}
return true;
return MessagesController.Instance.users.get(user_id) != null;
}
@Override
@ -471,15 +471,9 @@ public class UserProfileActivity extends BaseFragment implements NotificationCen
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<TLRPC.User> arrayList = new ArrayList<TLRPC.User>();
arrayList.add(user);
ContactsController.Instance.deleteContact(arrayList);
}
}, null, true, RPCRequest.RPCRequestClassGeneric);
ArrayList<TLRPC.User> arrayList = new ArrayList<TLRPC.User>();
arrayList.add(user);
ContactsController.Instance.deleteContact(arrayList);
}
});
builder.setNegativeButton(getStringEntry(R.string.Cancel), null);

View File

@ -10,11 +10,10 @@ package org.telegram.ui.Views;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import org.telegram.TL.TLRPC;
import org.telegram.messenger.FileLoader;
@ -22,17 +21,19 @@ import org.telegram.messenger.FileLog;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities;
import org.telegram.ui.ApplicationActivity;
import org.telegram.ui.PhotoCropActivity;
import java.io.File;
public class AvatarUpdater implements NotificationCenter.NotificationCenterDelegate {
public class AvatarUpdater implements NotificationCenter.NotificationCenterDelegate, PhotoCropActivity.PhotoCropActivityDelegate {
public String currentPicturePath;
private TLRPC.PhotoSize smallPhoto;
private TLRPC.PhotoSize bigPhoto;
public String uploadingAvatar = null;
File picturePath = null;
public Activity parentActivity = null;
public Fragment parentFragment = null;
public BaseFragment parentFragment = null;
public AvatarUpdaterDelegate delegate;
private boolean clearAfterUpdate = false;
public boolean returnOnly = false;
@ -85,22 +86,38 @@ public class AvatarUpdater implements NotificationCenter.NotificationCenterDeleg
private void startCrop(String path) {
try {
Intent cropIntent = new Intent("com.android.camera.action.CROP");
cropIntent.setDataAndType(Uri.fromFile(new File(path)), "image/*");
cropIntent.putExtra("crop", "true");
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
cropIntent.putExtra("outputX", 800);
cropIntent.putExtra("outputY", 800);
cropIntent.putExtra("scale", true);
cropIntent.putExtra("return-data", false);
picturePath = Utilities.generatePicturePath();
cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(picturePath));
cropIntent.putExtra("output", Uri.fromFile(picturePath));
if (parentFragment != null) {
parentFragment.startActivityForResult(cropIntent, 2);
} else if (parentActivity != null) {
parentActivity.startActivityForResult(cropIntent, 2);
ApplicationActivity activity = (ApplicationActivity)parentFragment.parentActivity;
if (activity == null) {
activity = (ApplicationActivity)parentFragment.getActivity();
}
if (activity == null) {
return;
}
Bundle params = new Bundle();
params.putString("photoPath", path);
PhotoCropActivity photoCropActivity = new PhotoCropActivity();
photoCropActivity.delegate = this;
photoCropActivity.setArguments(params);
activity.presentFragment(photoCropActivity, "crop", false);
} else {
Intent cropIntent = new Intent("com.android.camera.action.CROP");
cropIntent.setDataAndType(Uri.fromFile(new File(path)), "image/*");
cropIntent.putExtra("crop", "true");
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
cropIntent.putExtra("outputX", 800);
cropIntent.putExtra("outputY", 800);
cropIntent.putExtra("scale", true);
cropIntent.putExtra("return-data", false);
picturePath = Utilities.generatePicturePath();
cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(picturePath));
cropIntent.putExtra("output", Uri.fromFile(picturePath));
if (parentFragment != null) {
parentFragment.startActivityForResult(cropIntent, 2);
} else if (parentActivity != null) {
parentActivity.startActivityForResult(cropIntent, 2);
}
}
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -120,26 +137,15 @@ public class AvatarUpdater implements NotificationCenter.NotificationCenterDeleg
if (data == null) {
return;
}
Uri imageUri = data.getData();
Cursor cursor = null;
try {
if (parentFragment != null) {
cursor = parentFragment.getActivity().getContentResolver().query(imageUri, new String[]{android.provider.MediaStore.Images.ImageColumns.DATA}, null, null, null);
} else if (parentActivity != null) {
cursor = parentActivity.getContentResolver().query(imageUri, new String[]{android.provider.MediaStore.Images.ImageColumns.DATA}, null, null, null);
Uri imageUri = data.getData();
if (imageUri != null) {
String imageFilePath = Utilities.getPath(imageUri);
startCrop(imageFilePath);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
return;
}
if (cursor == null) {
return;
}
if (cursor.moveToFirst()) {
String imageFilePath = cursor.getString(0);
startCrop(imageFilePath);
}
cursor.close();
} else if (requestCode == 2) {
Bitmap bitmap = FileLoader.loadBitmap(picturePath.getAbsolutePath(), 800, 800);
processBitmap(bitmap);
@ -168,6 +174,11 @@ public class AvatarUpdater implements NotificationCenter.NotificationCenterDeleg
}
}
@Override
public void didFinishCrop(Bitmap bitmap) {
processBitmap(bitmap);
}
@Override
public void didReceivedNotification(int id, final Object... args) {
if (id == FileLoader.FileDidUpload) {

View File

@ -40,11 +40,19 @@ public class LayoutListView extends ListView {
post(new Runnable() {
@Override
public void run() {
setSelectionFromTop(scrollTo, offset - getPaddingTop());
try {
setSelectionFromTop(scrollTo, offset - getPaddingTop());
} catch (Exception e) {
e.printStackTrace();
}
}
});
} else {
super.onLayout(changed, left, top, right, bottom);
try {
super.onLayout(changed, left, top, right, bottom);
} catch (Exception e) {
e.printStackTrace();
}
}
height = (bottom - top);
}

View File

@ -0,0 +1,135 @@
/*
* 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.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import org.telegram.messenger.R;
import org.telegram.messenger.Utilities;
public class SeekBar extends View {
Drawable thumbDrawable1;
Drawable thumbDrawablePressed1;
Drawable thumbDrawable2;
Drawable thumbDrawablePressed2;
static Paint innerPaint1 = new Paint();
static Paint outerPaint1 = new Paint();
static Paint innerPaint2 = new Paint();
static Paint outerPaint2 = new Paint();
public int type;
public int thumbX = 0;
public int thumbDX = 0;
private boolean pressed = false;
private boolean dragging = false;
private int thumbWidth;
private int thumbHeight;
public SeekBar(Context context) {
super(context);
init();
}
public SeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public SeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
if (thumbDrawable1 == null) {
thumbDrawable1 = getResources().getDrawable(R.drawable.player1);
thumbDrawablePressed1 = getResources().getDrawable(R.drawable.player1_pressed);
thumbDrawable2 = getResources().getDrawable(R.drawable.player2);
thumbDrawablePressed2 = getResources().getDrawable(R.drawable.player2_pressed);
innerPaint1.setColor(0xffb4e396);
outerPaint1.setColor(0xff6ac453);
innerPaint2.setColor(0xffd9e2eb);
outerPaint2.setColor(0xff86c5f8);
thumbWidth = thumbDrawable1.getIntrinsicWidth();
thumbHeight = thumbDrawable1.getIntrinsicHeight();
}
setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
float x = motionEvent.getX();
float y = motionEvent.getY();
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
int additionWidth = (getMeasuredHeight() - thumbWidth) / 2;
if (thumbX - additionWidth <= x && x <= thumbX + thumbWidth + additionWidth && y >= 0 && y <= getMeasuredHeight()) {
pressed = true;
thumbDX = (int)(x - thumbX);
invalidate();
getParent().requestDisallowInterceptTouchEvent(true);
return true;
}
} else if (motionEvent.getAction() == MotionEvent.ACTION_UP || motionEvent.getAction() == MotionEvent.ACTION_CANCEL) {
if (pressed) {
pressed = false;
invalidate();
return true;
}
} else if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {
if (pressed) {
thumbX = (int)(x - thumbDX);
if (thumbX < 0) {
thumbX = 0;
} else if (thumbX > getMeasuredWidth() - thumbWidth) {
thumbX = getMeasuredWidth() - thumbWidth;
}
invalidate();
return true;
}
}
return false;
}
});
}
@Override
protected void onDraw(Canvas canvas) {
Drawable thumb = null;
Paint inner = null;
Paint outer = null;
if (type == 0) {
if (!pressed) {
thumb = thumbDrawable1;
} else {
thumb = thumbDrawablePressed1;
}
inner = innerPaint1;
outer = outerPaint1;
} else if (type == 1) {
if (!pressed) {
thumb = thumbDrawable2;
} else {
thumb = thumbDrawablePressed2;
}
inner = innerPaint2;
outer = outerPaint2;
}
int height = getMeasuredHeight();
int width = getMeasuredWidth();
int y = (height - thumbHeight) / 2;
canvas.drawRect(thumbWidth / 2, height / 2 - Utilities.dp(1), width - thumbWidth / 2, height / 2 + Utilities.dp(1), inner);
canvas.drawRect(thumbWidth / 2, height / 2 - Utilities.dp(1), thumbWidth / 2 + thumbX, height / 2 + Utilities.dp(1), outer);
thumb.setBounds(thumbX, y, thumbX + thumbWidth, y + thumbHeight);
thumb.draw(canvas);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 703 B

After

Width:  |  Height:  |  Size: 591 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 725 B

After

Width:  |  Height:  |  Size: 599 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 602 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 581 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 441 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 687 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 676 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 418 B

After

Width:  |  Height:  |  Size: 343 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 420 B

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 532 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 524 B

After

Width:  |  Height:  |  Size: 309 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 531 B

After

Width:  |  Height:  |  Size: 381 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 516 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 828 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 503 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 845 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 844 B

After

Width:  |  Height:  |  Size: 748 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 842 B

After

Width:  |  Height:  |  Size: 744 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 722 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 666 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

Some files were not shown because too many files have changed in this diff Show More