UI improvements

This commit is contained in:
DrKLO 2014-10-17 00:02:44 +04:00
parent 288fceeb9f
commit 5bbfba2092
26 changed files with 777 additions and 925 deletions

View file

@ -80,7 +80,7 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 8 minSdkVersion 8
targetSdkVersion 19 targetSdkVersion 19
versionCode 357 versionCode 358
versionName "1.9.5" versionName "1.9.5"
} }
} }

View file

@ -3551,7 +3551,15 @@ public class MessagesController implements NotificationCenter.NotificationCenter
} }
if (object instanceof TLRPC.TL_decryptedMessageLayer) { if (object instanceof TLRPC.TL_decryptedMessageLayer) {
object = ((TLRPC.TL_decryptedMessageLayer) object).message; final TLRPC.TL_decryptedMessageLayer layer = (TLRPC.TL_decryptedMessageLayer)object;
AndroidUtilities.RunOnUIThread(new Runnable() {
@Override
public void run() {
chat.seq_in = layer.out_seq_no;
MessagesStorage.getInstance().updateEncryptedChatSeq(chat);
}
});
object = layer.message;
} }
if (object instanceof TLRPC.TL_decryptedMessage) { if (object instanceof TLRPC.TL_decryptedMessage) {
@ -3890,6 +3898,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter
salt[a] = (byte) ((byte) (Utilities.random.nextDouble() * 256) ^ res.random[a]); salt[a] = (byte) ((byte) (Utilities.random.nextDouble() * 256) ^ res.random[a]);
} }
encryptedChat.a_or_b = salt; encryptedChat.a_or_b = salt;
encryptedChat.seq_in = 1;
encryptedChat.seq_out = 0;
BigInteger p = new BigInteger(1, MessagesStorage.secretPBytes); BigInteger p = new BigInteger(1, MessagesStorage.secretPBytes);
BigInteger g_b = BigInteger.valueOf(MessagesStorage.secretG); BigInteger g_b = BigInteger.valueOf(MessagesStorage.secretG);
g_b = g_b.modPow(new BigInteger(1, salt), p); g_b = g_b.modPow(new BigInteger(1, salt), p);
@ -4033,8 +4043,10 @@ public class MessagesController implements NotificationCenter.NotificationCenter
} }
TLRPC.EncryptedChat chat = (TLRPC.EncryptedChat) response; TLRPC.EncryptedChat chat = (TLRPC.EncryptedChat) response;
chat.user_id = chat.participant_id; chat.user_id = chat.participant_id;
putEncryptedChat(chat, false); chat.seq_in = 0;
chat.seq_out = 1;
chat.a_or_b = salt; chat.a_or_b = salt;
putEncryptedChat(chat, false);
TLRPC.TL_dialog dialog = new TLRPC.TL_dialog(); TLRPC.TL_dialog dialog = new TLRPC.TL_dialog();
dialog.id = ((long) chat.id) << 32; dialog.id = ((long) chat.id) << 32;
dialog.unread_count = 0; dialog.unread_count = 0;

View file

@ -93,7 +93,7 @@ public class MessagesStorage {
database.executeFast("CREATE TABLE users(uid INTEGER PRIMARY KEY, name TEXT, status INTEGER, data BLOB)").stepThis().dispose(); database.executeFast("CREATE TABLE users(uid INTEGER PRIMARY KEY, name TEXT, status INTEGER, data BLOB)").stepThis().dispose();
database.executeFast("CREATE TABLE messages(mid INTEGER PRIMARY KEY, uid INTEGER, read_state INTEGER, send_state INTEGER, date INTEGER, data BLOB, out INTEGER, ttl INTEGER, media INTEGER)").stepThis().dispose(); database.executeFast("CREATE TABLE messages(mid INTEGER PRIMARY KEY, uid INTEGER, read_state INTEGER, send_state INTEGER, date INTEGER, data BLOB, out INTEGER, ttl INTEGER, media INTEGER)").stepThis().dispose();
database.executeFast("CREATE TABLE chats(uid INTEGER PRIMARY KEY, name TEXT, data BLOB)").stepThis().dispose(); database.executeFast("CREATE TABLE chats(uid INTEGER PRIMARY KEY, name TEXT, data BLOB)").stepThis().dispose();
database.executeFast("CREATE TABLE enc_chats(uid INTEGER PRIMARY KEY, user INTEGER, name TEXT, data BLOB, g BLOB, authkey BLOB, ttl INTEGER, layer INTEGER)").stepThis().dispose(); database.executeFast("CREATE TABLE enc_chats(uid INTEGER PRIMARY KEY, user INTEGER, name TEXT, data BLOB, g BLOB, authkey BLOB, ttl INTEGER, layer INTEGER, seq_in INTEGER, seq_out INTEGER)").stepThis().dispose();
database.executeFast("CREATE TABLE dialogs(did INTEGER PRIMARY KEY, date INTEGER, unread_count INTEGER, last_mid INTEGER)").stepThis().dispose(); database.executeFast("CREATE TABLE dialogs(did INTEGER PRIMARY KEY, date INTEGER, unread_count INTEGER, last_mid INTEGER)").stepThis().dispose();
database.executeFast("CREATE TABLE chat_settings(uid INTEGER PRIMARY KEY, participants BLOB)").stepThis().dispose(); database.executeFast("CREATE TABLE chat_settings(uid INTEGER PRIMARY KEY, participants BLOB)").stepThis().dispose();
database.executeFast("CREATE TABLE contacts(uid INTEGER PRIMARY KEY, mutual INTEGER)").stepThis().dispose(); database.executeFast("CREATE TABLE contacts(uid INTEGER PRIMARY KEY, mutual INTEGER)").stepThis().dispose();
@ -291,6 +291,8 @@ public class MessagesStorage {
} }
if (version == 6 && version < 7) { if (version == 6 && version < 7) {
database.executeFast("ALTER TABLE enc_chats ADD COLUMN layer INTEGER default 0").stepThis().dispose(); database.executeFast("ALTER TABLE enc_chats ADD COLUMN layer INTEGER default 0").stepThis().dispose();
database.executeFast("ALTER TABLE enc_chats ADD COLUMN seq_in INTEGER default 0").stepThis().dispose();
database.executeFast("ALTER TABLE enc_chats ADD COLUMN seq_out INTEGER default 0").stepThis().dispose();
database.executeFast("PRAGMA user_version = 7").stepThis().dispose(); database.executeFast("PRAGMA user_version = 7").stepThis().dispose();
version = 7; version = 7;
} }
@ -491,7 +493,7 @@ public class MessagesStorage {
if (!encryptedChatIds.isEmpty()) { if (!encryptedChatIds.isEmpty()) {
String stringToLoad = TextUtils.join(",", encryptedChatIds); String stringToLoad = TextUtils.join(",", encryptedChatIds);
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, user, g, authkey, ttl, layer FROM enc_chats WHERE uid IN(%s)", stringToLoad)); cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, user, g, authkey, ttl, layer, seq_in, seq_out FROM enc_chats WHERE uid IN(%s)", stringToLoad));
while (cursor.next()) { while (cursor.next()) {
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0)); ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) { if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
@ -505,6 +507,8 @@ public class MessagesStorage {
chat.auth_key = cursor.byteArrayValue(3); chat.auth_key = cursor.byteArrayValue(3);
chat.ttl = cursor.intValue(4); chat.ttl = cursor.intValue(4);
chat.layer = cursor.intValue(5); chat.layer = cursor.intValue(5);
chat.seq_in = cursor.intValue(6);
chat.seq_out = cursor.intValue(7);
} }
buffersStorage.reuseFreeBuffer(data); buffersStorage.reuseFreeBuffer(data);
} }
@ -1232,7 +1236,7 @@ public class MessagesStorage {
cursor.dispose(); cursor.dispose();
if (needEncrypted) { if (needEncrypted) {
cursor = database.queryFinalized("SELECT q.data, u.name, q.user, q.g, q.authkey, q.ttl, u.data, u.status, q.layer FROM enc_chats as q INNER JOIN dialogs as d ON (q.uid << 32) = d.did INNER JOIN users as u ON q.user = u.uid"); cursor = database.queryFinalized("SELECT q.data, u.name, q.user, q.g, q.authkey, q.ttl, u.data, u.status, q.layer, q.seq_in, q.seq_out FROM enc_chats as q INNER JOIN dialogs as d ON (q.uid << 32) = d.did INNER JOIN users as u ON q.user = u.uid");
while (cursor.next()) { while (cursor.next()) {
String name = cursor.stringValue(1); String name = cursor.stringValue(1);
if (name.startsWith(q) || name.contains(" " + q)) { if (name.startsWith(q) || name.contains(" " + q)) {
@ -1245,6 +1249,8 @@ public class MessagesStorage {
chat.auth_key = cursor.byteArrayValue(4); chat.auth_key = cursor.byteArrayValue(4);
chat.ttl = cursor.intValue(5); chat.ttl = cursor.intValue(5);
chat.layer = cursor.intValue(8); chat.layer = cursor.intValue(8);
chat.seq_in = cursor.intValue(9);
chat.seq_out = cursor.intValue(10);
TLRPC.User user = (TLRPC.User)TLClassStore.Instance().TLdeserialize(data2, data2.readInt32()); TLRPC.User user = (TLRPC.User)TLClassStore.Instance().TLdeserialize(data2, data2.readInt32());
if (user.status != null) { if (user.status != null) {
@ -1720,7 +1726,7 @@ public class MessagesStorage {
if (!encryptedChatIds.isEmpty()) { if (!encryptedChatIds.isEmpty()) {
String stringToLoad = TextUtils.join(",", encryptedChatIds); String stringToLoad = TextUtils.join(",", encryptedChatIds);
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, user, g, authkey, ttl, layer FROM enc_chats WHERE uid IN(%s)", stringToLoad)); cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, user, g, authkey, ttl, layer, seq_in, seq_out FROM enc_chats WHERE uid IN(%s)", stringToLoad));
while (cursor.next()) { while (cursor.next()) {
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0)); ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) { if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
@ -1734,6 +1740,8 @@ public class MessagesStorage {
chat.auth_key = cursor.byteArrayValue(3); chat.auth_key = cursor.byteArrayValue(3);
chat.ttl = cursor.intValue(4); chat.ttl = cursor.intValue(4);
chat.layer = cursor.intValue(5); chat.layer = cursor.intValue(5);
chat.seq_in = cursor.intValue(6);
chat.seq_out = cursor.intValue(7);
} }
buffersStorage.reuseFreeBuffer(data); buffersStorage.reuseFreeBuffer(data);
} }
@ -2126,6 +2134,31 @@ public class MessagesStorage {
}); });
} }
public void updateEncryptedChatSeq(final TLRPC.EncryptedChat chat) {
if (chat == null) {
return;
}
storageQueue.postRunnable(new Runnable() {
@Override
public void run() {
SQLitePreparedStatement state = null;
try {
state = database.executeFast("UPDATE enc_chats SET seq_in = ?, seq_out = ? WHERE uid = ?");
state.bindInteger(1, chat.seq_in);
state.bindInteger(2, chat.seq_out);
state.bindInteger(3, chat.id);
state.step();
} catch (Exception e) {
FileLog.e("tmessages", e);
} finally {
if (state != null) {
state.dispose();
}
}
}
});
}
public void updateEncryptedChatTTL(final TLRPC.EncryptedChat chat) { public void updateEncryptedChatTTL(final TLRPC.EncryptedChat chat) {
if (chat == null) { if (chat == null) {
return; return;
@ -2183,7 +2216,7 @@ public class MessagesStorage {
public void run() { public void run() {
SQLitePreparedStatement state = null; SQLitePreparedStatement state = null;
try { try {
state = database.executeFast("UPDATE enc_chats SET data = ?, g = ?, authkey = ?, ttl = ?, layer = ? WHERE uid = ?"); state = database.executeFast("UPDATE enc_chats SET data = ?, g = ?, authkey = ?, ttl = ?, layer = ?, seq_in = ?, seq_out = ? WHERE uid = ?");
ByteBufferDesc data = buffersStorage.getFreeBuffer(chat.getObjectSize()); ByteBufferDesc data = buffersStorage.getFreeBuffer(chat.getObjectSize());
ByteBufferDesc data2 = buffersStorage.getFreeBuffer(chat.a_or_b != null ? chat.a_or_b.length : 1); ByteBufferDesc data2 = buffersStorage.getFreeBuffer(chat.a_or_b != null ? chat.a_or_b.length : 1);
ByteBufferDesc data3 = buffersStorage.getFreeBuffer(chat.auth_key != null ? chat.auth_key.length : 1); ByteBufferDesc data3 = buffersStorage.getFreeBuffer(chat.auth_key != null ? chat.auth_key.length : 1);
@ -2199,7 +2232,9 @@ public class MessagesStorage {
state.bindByteBuffer(3, data3.buffer); state.bindByteBuffer(3, data3.buffer);
state.bindInteger(4, chat.ttl); state.bindInteger(4, chat.ttl);
state.bindInteger(5, chat.layer); state.bindInteger(5, chat.layer);
state.bindInteger(6, chat.id); state.bindInteger(6, chat.seq_in);
state.bindInteger(7, chat.seq_out);
state.bindInteger(8, chat.id);
state.step(); state.step();
buffersStorage.reuseFreeBuffer(data); buffersStorage.reuseFreeBuffer(data);
buffersStorage.reuseFreeBuffer(data2); buffersStorage.reuseFreeBuffer(data2);
@ -2224,7 +2259,7 @@ public class MessagesStorage {
public void run() { public void run() {
try { try {
int userToLoad = 0; int userToLoad = 0;
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, user, g, authkey, ttl, layer FROM enc_chats WHERE uid = %d", chat_id)); SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, user, g, authkey, ttl, layer, seq_in, seq_out FROM enc_chats WHERE uid = %d", chat_id));
if (cursor.next()) { if (cursor.next()) {
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0)); ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) { if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
@ -2236,6 +2271,8 @@ public class MessagesStorage {
chat.auth_key = cursor.byteArrayValue(3); chat.auth_key = cursor.byteArrayValue(3);
chat.ttl = cursor.intValue(4); chat.ttl = cursor.intValue(4);
chat.layer = cursor.intValue(5); chat.layer = cursor.intValue(5);
chat.seq_in = cursor.intValue(6);
chat.seq_out = cursor.intValue(7);
} }
buffersStorage.reuseFreeBuffer(data); buffersStorage.reuseFreeBuffer(data);
} }
@ -2276,7 +2313,7 @@ public class MessagesStorage {
@Override @Override
public void run() { public void run() {
try { try {
SQLitePreparedStatement state = database.executeFast("REPLACE INTO enc_chats VALUES(?, ?, ?, ?, ?, ?, ?, ?)"); SQLitePreparedStatement state = database.executeFast("REPLACE INTO enc_chats VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
ByteBufferDesc data = buffersStorage.getFreeBuffer(chat.getObjectSize()); ByteBufferDesc data = buffersStorage.getFreeBuffer(chat.getObjectSize());
ByteBufferDesc data2 = buffersStorage.getFreeBuffer(chat.a_or_b != null ? chat.a_or_b.length : 1); ByteBufferDesc data2 = buffersStorage.getFreeBuffer(chat.a_or_b != null ? chat.a_or_b.length : 1);
ByteBufferDesc data3 = buffersStorage.getFreeBuffer(chat.auth_key != null ? chat.auth_key.length : 1); ByteBufferDesc data3 = buffersStorage.getFreeBuffer(chat.auth_key != null ? chat.auth_key.length : 1);
@ -2301,6 +2338,8 @@ public class MessagesStorage {
state.bindByteBuffer(6, data3.buffer); state.bindByteBuffer(6, data3.buffer);
state.bindInteger(7, chat.ttl); state.bindInteger(7, chat.ttl);
state.bindInteger(8, chat.layer); state.bindInteger(8, chat.layer);
state.bindInteger(9, chat.seq_in);
state.bindInteger(10, chat.seq_out);
state.step(); state.step();
state.dispose(); state.dispose();
buffersStorage.reuseFreeBuffer(data); buffersStorage.reuseFreeBuffer(data);
@ -3160,7 +3199,7 @@ public class MessagesStorage {
if (!encryptedToLoad.isEmpty()) { if (!encryptedToLoad.isEmpty()) {
String toLoad = TextUtils.join(",", encryptedToLoad); String toLoad = TextUtils.join(",", encryptedToLoad);
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, user, g, authkey, ttl, layer FROM enc_chats WHERE uid IN(%s)", toLoad)); cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, user, g, authkey, ttl, layer, seq_in, seq_out FROM enc_chats WHERE uid IN(%s)", toLoad));
while (cursor.next()) { while (cursor.next()) {
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0)); ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) { if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
@ -3174,6 +3213,8 @@ public class MessagesStorage {
chat.auth_key = cursor.byteArrayValue(3); chat.auth_key = cursor.byteArrayValue(3);
chat.ttl = cursor.intValue(4); chat.ttl = cursor.intValue(4);
chat.layer = cursor.intValue(5); chat.layer = cursor.intValue(5);
chat.seq_in = cursor.intValue(6);
chat.seq_out = cursor.intValue(7);
} }
buffersStorage.reuseFreeBuffer(data); buffersStorage.reuseFreeBuffer(data);
} }
@ -3417,7 +3458,7 @@ public class MessagesStorage {
if (!encryptedToLoad.isEmpty()) { if (!encryptedToLoad.isEmpty()) {
String toLoad = TextUtils.join(",", encryptedToLoad); String toLoad = TextUtils.join(",", encryptedToLoad);
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, user, g, authkey, ttl, layer FROM enc_chats WHERE uid IN(%s)", toLoad)); cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, user, g, authkey, ttl, layer, seq_in, seq_out FROM enc_chats WHERE uid IN(%s)", toLoad));
while (cursor.next()) { while (cursor.next()) {
try { try {
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0)); ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
@ -3433,6 +3474,8 @@ public class MessagesStorage {
chat.auth_key = cursor.byteArrayValue(3); chat.auth_key = cursor.byteArrayValue(3);
chat.ttl = cursor.intValue(4); chat.ttl = cursor.intValue(4);
chat.layer = cursor.intValue(5); chat.layer = cursor.intValue(5);
chat.seq_in = cursor.intValue(6);
chat.seq_out = cursor.intValue(7);
} }
} }
buffersStorage.reuseFreeBuffer(data); buffersStorage.reuseFreeBuffer(data);
@ -3706,7 +3749,7 @@ public class MessagesStorage {
public TLRPC.EncryptedChat getEncryptedChat(final int chat_id) { public TLRPC.EncryptedChat getEncryptedChat(final int chat_id) {
TLRPC.EncryptedChat chat = null; TLRPC.EncryptedChat chat = null;
try { try {
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, user, g, authkey, ttl, layer FROM enc_chats WHERE uid = %d", chat_id)); SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, user, g, authkey, ttl, layer, seq_in, seq_out FROM enc_chats WHERE uid = %d", chat_id));
if (cursor.next()) { if (cursor.next()) {
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0)); ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) { if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
@ -3717,6 +3760,8 @@ public class MessagesStorage {
chat.auth_key = cursor.byteArrayValue(3); chat.auth_key = cursor.byteArrayValue(3);
chat.ttl = cursor.intValue(4); chat.ttl = cursor.intValue(4);
chat.layer = cursor.intValue(5); chat.layer = cursor.intValue(5);
chat.seq_in = cursor.intValue(6);
chat.seq_out = cursor.intValue(7);
} }
} }
buffersStorage.reuseFreeBuffer(data); buffersStorage.reuseFreeBuffer(data);

View file

@ -9,7 +9,13 @@
package org.telegram.android; package org.telegram.android;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.media.MediaPlayer;
import android.media.ThumbnailUtils;
import android.net.Uri; import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.webkit.MimeTypeMap;
import org.telegram.messenger.BuffersStorage; import org.telegram.messenger.BuffersStorage;
import org.telegram.messenger.ByteBufferDesc; import org.telegram.messenger.ByteBufferDesc;
@ -22,6 +28,7 @@ import org.telegram.messenger.TLObject;
import org.telegram.messenger.TLRPC; import org.telegram.messenger.TLRPC;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities; import org.telegram.messenger.Utilities;
import org.telegram.ui.ApplicationLoader;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
@ -616,10 +623,16 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
performSendMessageRequest(reqSend, newMsgObj, null); performSendMessageRequest(reqSend, newMsgObj, null);
} }
} else { } else {
TLRPC.TL_decryptedMessage_old reqSend = new TLRPC.TL_decryptedMessage_old(); TLRPC.TL_decryptedMessage reqSend;
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
reqSend = new TLRPC.TL_decryptedMessage();
reqSend.ttl = encryptedChat.ttl;
} else {
reqSend = new TLRPC.TL_decryptedMessage_old();
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
Utilities.random.nextBytes(reqSend.random_bytes);
}
reqSend.random_id = newMsg.random_id; reqSend.random_id = newMsg.random_id;
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
Utilities.random.nextBytes(reqSend.random_bytes);
reqSend.message = message; reqSend.message = message;
reqSend.media = new TLRPC.TL_decryptedMessageMediaEmpty(); reqSend.media = new TLRPC.TL_decryptedMessageMediaEmpty();
performSendEncryptedRequest(reqSend, newMsgObj, encryptedChat, null, null, null); performSendEncryptedRequest(reqSend, newMsgObj, encryptedChat, null, null, null);
@ -768,10 +781,16 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
} }
} }
} else { } else {
TLRPC.TL_decryptedMessage_old reqSend = new TLRPC.TL_decryptedMessage_old(); TLRPC.TL_decryptedMessage reqSend;
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
reqSend = new TLRPC.TL_decryptedMessage();
reqSend.ttl = encryptedChat.ttl;
} else {
reqSend = new TLRPC.TL_decryptedMessage_old();
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
Utilities.random.nextBytes(reqSend.random_bytes);
}
reqSend.random_id = newMsg.random_id; reqSend.random_id = newMsg.random_id;
reqSend.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
Utilities.random.nextBytes(reqSend.random_bytes);
reqSend.message = ""; reqSend.message = "";
if (type == 1) { if (type == 1) {
reqSend.media = new TLRPC.TL_decryptedMessageMediaGeoPoint(); reqSend.media = new TLRPC.TL_decryptedMessageMediaGeoPoint();
@ -1124,12 +1143,15 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
if (AndroidUtilities.getPeerLayerVersion(chat.layer) >= 17) { if (AndroidUtilities.getPeerLayerVersion(chat.layer) >= 17) {
TLRPC.TL_decryptedMessageLayer layer = new TLRPC.TL_decryptedMessageLayer(); TLRPC.TL_decryptedMessageLayer layer = new TLRPC.TL_decryptedMessageLayer();
layer.layer = CURRENT_SECRET_CHAT_LAYER; layer.layer = CURRENT_SECRET_CHAT_LAYER;
layer.in_seq_no = 0; //TODO layer.in_seq_no = chat.seq_in;
layer.out_seq_no = 0; layer.out_seq_no = chat.seq_out;
layer.message = req; layer.message = req;
layer.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))]; layer.random_bytes = new byte[Math.max(1, (int) Math.ceil(Utilities.random.nextDouble() * 16))];
Utilities.random.nextBytes(layer.random_bytes); Utilities.random.nextBytes(layer.random_bytes);
toEncryptObject = layer; toEncryptObject = layer;
chat.seq_out += 2;
MessagesStorage.getInstance().updateEncryptedChatSeq(chat);
} else { } else {
toEncryptObject = req; toEncryptObject = req;
} }
@ -1715,4 +1737,319 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
return photo; return photo;
} }
} }
private static void prepareSendingDocumentInternal(final String path, String originalPath, final long dialog_id) {
if (path == null || path.length() == 0) {
return;
}
final File f = new File(path);
if (!f.exists() || f.length() == 0) {
return;
}
boolean isEncrypted = (int)dialog_id == 0;
String name = f.getName();
if (name == null) {
name = "noname";
}
String ext = "";
int idx = path.lastIndexOf(".");
if (idx != -1) {
ext = path.substring(idx + 1);
}
if (originalPath != null) {
originalPath += "" + f.length();
}
TLRPC.TL_document document = (TLRPC.TL_document)MessagesStorage.getInstance().getSentFile(originalPath, !isEncrypted ? 1 : 4);
if (document == null && !path.equals(originalPath)) {
document = (TLRPC.TL_document)MessagesStorage.getInstance().getSentFile(path + f.length(), !isEncrypted ? 1 : 4);
}
if (document == null) {
document = new TLRPC.TL_document();
document.id = 0;
document.user_id = UserConfig.getClientUserId();
document.date = ConnectionsManager.getInstance().getCurrentTime();
document.file_name = name;
document.size = (int)f.length();
document.dc_id = 0;
if (ext.length() != 0) {
MimeTypeMap myMime = MimeTypeMap.getSingleton();
String mimeType = myMime.getMimeTypeFromExtension(ext.toLowerCase());
if (mimeType != null) {
document.mime_type = mimeType;
} else {
document.mime_type = "application/octet-stream";
}
} else {
document.mime_type = "application/octet-stream";
}
if (document.mime_type.equals("image/gif")) {
try {
Bitmap bitmap = ImageLoader.loadBitmap(f.getAbsolutePath(), null, 90, 90);
if (bitmap != null) {
document.thumb = ImageLoader.scaleAndSaveImage(bitmap, 90, 90, 55, isEncrypted);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
if (document.thumb == null) {
document.thumb = new TLRPC.TL_photoSizeEmpty();
document.thumb.type = "s";
}
}
final TLRPC.TL_document documentFinal = document;
final String originalPathFinal = originalPath;
AndroidUtilities.RunOnUIThread(new Runnable() {
@Override
public void run() {
SendMessagesHelper.getInstance().sendMessage(documentFinal, originalPathFinal, path, dialog_id);
}
});
}
public static void prepareSendingDocument(String path, String originalPath, long dialog_id) {
if (path == null || originalPath == null) {
return;
}
ArrayList<String> paths = new ArrayList<String>();
ArrayList<String> originalPaths = new ArrayList<String>();
paths.add(path);
originalPaths.add(originalPath);
prepareSendingDocuments(paths, originalPaths, dialog_id);
}
public static void prepareSendingDocuments(final ArrayList<String> paths, final ArrayList<String> originalPaths, final long dialog_id) {
if (paths == null && originalPaths == null || paths != null && originalPaths != null && paths.size() != originalPaths.size()) {
return;
}
new Thread(new Runnable() {
@Override
public void run() {
for (int a = 0; a < paths.size(); a++) {
prepareSendingDocumentInternal(paths.get(a), originalPaths.get(a), dialog_id);
}
}
}).start();
}
public static void prepareSendingPhoto(String imageFilePath, Uri imageUri, long dialog_id) {
ArrayList<String> paths = null;
ArrayList<Uri> uris = null;
if (imageFilePath != null && imageFilePath.length() != 0) {
paths = new ArrayList<String>();
paths.add(imageFilePath);
}
if (imageUri != null) {
uris = new ArrayList<Uri>();
uris.add(imageUri);
}
prepareSendingPhotos(paths, uris, dialog_id);
}
public static void prepareSendingPhotos(ArrayList<String> paths, ArrayList<Uri> uris, final long dialog_id) {
if (paths == null && uris == null || paths != null && paths.isEmpty() || uris != null && uris.isEmpty()) {
return;
}
final ArrayList<String> pathsCopy = new ArrayList<String>();
final ArrayList<Uri> urisCopy = new ArrayList<Uri>();
if (paths != null) {
pathsCopy.addAll(paths);
}
if (uris != null) {
urisCopy.addAll(uris);
}
new Thread(new Runnable() {
@Override
public void run() {
boolean isEncrypted = (int)dialog_id == 0;
ArrayList<String> sendAsDocuments = null;
ArrayList<String> sendAsDocumentsOriginal = null;
int count = !pathsCopy.isEmpty() ? pathsCopy.size() : urisCopy.size();
String path = null;
Uri uri = null;
for (int a = 0; a < count; a++) {
if (!pathsCopy.isEmpty()) {
path = pathsCopy.get(a);
} else if (!urisCopy.isEmpty()) {
uri = urisCopy.get(a);
}
String originalPath = path;
String tempPath = path;
if (tempPath == null && uri != null) {
tempPath = Utilities.getPath(uri);
originalPath = uri.toString();
}
boolean isGif = false;
if (tempPath != null && tempPath.endsWith(".gif")) {
isGif = true;
} else if (tempPath == null && uri != null) {
isGif = MediaController.isGif(uri);
if (isGif) {
originalPath = uri.toString();
tempPath = MediaController.copyDocumentToCache(uri, "gif");
}
}
if (isGif) {
if (sendAsDocuments == null) {
sendAsDocuments = new ArrayList<String>();
sendAsDocumentsOriginal = new ArrayList<String>();
}
sendAsDocuments.add(tempPath);
sendAsDocumentsOriginal.add(originalPath);
} else {
if (tempPath != null) {
File temp = new File(tempPath);
originalPath += temp.length() + "_" + temp.lastModified();
} else {
originalPath = null;
}
TLRPC.TL_photo photo = (TLRPC.TL_photo)MessagesStorage.getInstance().getSentFile(originalPath, !isEncrypted ? 0 : 3);
if (photo == null && uri != null) {
photo = (TLRPC.TL_photo)MessagesStorage.getInstance().getSentFile(Utilities.getPath(uri), !isEncrypted ? 0 : 3);
}
if (photo == null) {
photo = SendMessagesHelper.getInstance().generatePhotoSizes(path, uri);
}
if (photo != null) {
final String originalPathFinal = originalPath;
final TLRPC.TL_photo photoFinal = photo;
AndroidUtilities.RunOnUIThread(new Runnable() {
@Override
public void run() {
SendMessagesHelper.getInstance().sendMessage(photoFinal, originalPathFinal, dialog_id);
}
});
}
}
}
if (sendAsDocuments != null && !sendAsDocuments.isEmpty()) {
for (int a = 0; a < sendAsDocuments.size(); a++) {
prepareSendingDocumentInternal(sendAsDocuments.get(a), sendAsDocumentsOriginal.get(a), dialog_id);
}
}
}
}).start();
}
public static void prepareSendingVideo(final String videoPath, final long estimatedSize, final long duration, final int width, final int height, final TLRPC.VideoEditedInfo videoEditedInfo, final long dialog_id) {
if (videoPath == null || videoPath.length() == 0) {
return;
}
new Thread(new Runnable() {
@Override
public void run() {
boolean isEncrypted = (int)dialog_id == 0;
String path = videoPath;
String originalPath = videoPath;
File temp = new File(originalPath);
originalPath += temp.length() + "_" + temp.lastModified();
if (videoEditedInfo != null) {
originalPath += duration + "_" + videoEditedInfo.startTime + "_" + videoEditedInfo.endTime;
}
TLRPC.TL_video video = (TLRPC.TL_video)MessagesStorage.getInstance().getSentFile(originalPath, !isEncrypted ? 2 : 5);
if (video == null) {
Bitmap thumb = ThumbnailUtils.createVideoThumbnail(videoPath, MediaStore.Video.Thumbnails.MINI_KIND);
TLRPC.PhotoSize size = ImageLoader.scaleAndSaveImage(thumb, 90, 90, 55, isEncrypted);
video = new TLRPC.TL_video();
video.thumb = size;
if (video.thumb == null) {
video.thumb = new TLRPC.TL_photoSizeEmpty();
video.thumb.type = "s";
} else {
video.thumb.type = "s";
}
video.caption = "";
video.mime_type = "video/mp4";
video.id = 0;
UserConfig.saveConfig(false);
if (videoEditedInfo != null) {
video.duration = (int)(duration / 1000);
if (videoEditedInfo.rotationValue == 90 || videoEditedInfo.rotationValue == 270) {
video.w = height;
video.h = width;
} else {
video.w = width;
video.h = height;
}
video.size = (int)estimatedSize;
video.videoEditedInfo = videoEditedInfo;
String fileName = Integer.MIN_VALUE + "_" + UserConfig.lastLocalId + ".mp4";
UserConfig.lastLocalId--;
File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName);
UserConfig.saveConfig(false);
path = cacheFile.getAbsolutePath();
} else {
if (temp != null && temp.exists()) {
video.size = (int) temp.length();
}
boolean infoObtained = false;
if (Build.VERSION.SDK_INT >= 14) {
MediaMetadataRetriever mediaMetadataRetriever = null;
try {
mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(videoPath);
String width = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
if (width != null) {
video.w = Integer.parseInt(width);
}
String height = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);
if (height != null) {
video.h = Integer.parseInt(height);
}
String duration = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
if (duration != null) {
video.duration = (int) Math.ceil(Long.parseLong(duration) / 1000.0f);
}
infoObtained = true;
} catch (Exception e) {
FileLog.e("tmessages", e);
} finally {
try {
if (mediaMetadataRetriever != null) {
mediaMetadataRetriever.release();
mediaMetadataRetriever = null;
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
}
if (!infoObtained) {
try {
MediaPlayer mp = MediaPlayer.create(ApplicationLoader.applicationContext, Uri.fromFile(new File(videoPath)));
if (mp != null) {
video.duration = (int) Math.ceil(mp.getDuration() / 1000.0f);
video.w = mp.getVideoWidth();
video.h = mp.getVideoHeight();
mp.release();
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
}
}
final TLRPC.TL_video videoFinal = video;
final String originalPathFinal = originalPath;
final String finalPath = path;
AndroidUtilities.RunOnUIThread(new Runnable() {
@Override
public void run() {
SendMessagesHelper.getInstance().sendMessage(videoFinal, originalPathFinal, finalPath, dialog_id);
}
});
}
}).start();
}
} }

View file

@ -9330,6 +9330,8 @@ public class TLRPC {
public int user_id; public int user_id;
public int ttl; public int ttl;
public int layer; public int layer;
public int seq_in;
public int seq_out;
} }
public static class FileLocation extends TLObject { public static class FileLocation extends TLObject {

View file

@ -44,9 +44,9 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
private int buttonState = 0; private int buttonState = 0;
private int buttonX; private int buttonX;
private int buttonY; private int buttonY;
private int buttonPressed = 0; private boolean buttonPressed = false;
private int avatarPressed = 0; private boolean avatarPressed = false;
private StaticLayout timeLayout; private StaticLayout timeLayout;
private int timeX; private int timeX;
@ -56,7 +56,6 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
public TLRPC.User audioUser; public TLRPC.User audioUser;
private TLRPC.FileLocation currentPhoto; private TLRPC.FileLocation currentPhoto;
private String currentNameString;
public ChatAudioCell(Context context) { public ChatAudioCell(Context context) {
super(context); super(context);
@ -115,40 +114,40 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
int side = AndroidUtilities.dp(36); int side = AndroidUtilities.dp(36);
if (event.getAction() == MotionEvent.ACTION_DOWN) { if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (x >= buttonX && x <= buttonX + side && y >= buttonY && y <= buttonY + side) { if (x >= buttonX && x <= buttonX + side && y >= buttonY && y <= buttonY + side) {
buttonPressed = 1; buttonPressed = true;
invalidate(); invalidate();
result = true; result = true;
} else if (avatarImage.isInsideImage(x, y)) { } else if (avatarImage.isInsideImage(x, y)) {
avatarPressed = 1; avatarPressed = true;
result = true; result = true;
} }
} else if (buttonPressed == 1) { } else if (buttonPressed) {
if (event.getAction() == MotionEvent.ACTION_UP) { if (event.getAction() == MotionEvent.ACTION_UP) {
buttonPressed = 0; buttonPressed = false;
playSoundEffect(SoundEffectConstants.CLICK); playSoundEffect(SoundEffectConstants.CLICK);
didPressedButton(); didPressedButton();
invalidate(); invalidate();
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) { } else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
buttonPressed = 0; buttonPressed = false;
invalidate(); invalidate();
} else if (event.getAction() == MotionEvent.ACTION_MOVE) { } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (!(x >= buttonX && x <= buttonX + side && y >= buttonY && y <= buttonY + side)) { if (!(x >= buttonX && x <= buttonX + side && y >= buttonY && y <= buttonY + side)) {
buttonPressed = 0; buttonPressed = false;
invalidate(); invalidate();
} }
} }
} else if (avatarPressed == 1) { } else if (avatarPressed) {
if (event.getAction() == MotionEvent.ACTION_UP) { if (event.getAction() == MotionEvent.ACTION_UP) {
avatarPressed = 0; avatarPressed = false;
playSoundEffect(SoundEffectConstants.CLICK); playSoundEffect(SoundEffectConstants.CLICK);
if (delegate != null) { if (delegate != null) {
delegate.didPressedUserAvatar(this, audioUser); delegate.didPressedUserAvatar(this, audioUser);
} }
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) { } else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
avatarPressed = 0; avatarPressed = false;
} else if (event.getAction() == MotionEvent.ACTION_MOVE) { } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (!avatarImage.isInsideImage(x, y)) { if (!avatarImage.isInsideImage(x, y)) {
avatarPressed = 0; avatarPressed = false;
} }
} }
} }
@ -301,7 +300,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
int x; int x;
if (currentMessageObject.isOut()) { if (currentMessageObject.isOut()) {
x = layoutWidth - backgroundWidth + AndroidUtilities.dp(9); x = layoutWidth - backgroundWidth + AndroidUtilities.dp(8);
seekBarX = layoutWidth - backgroundWidth + AndroidUtilities.dp(97); seekBarX = layoutWidth - backgroundWidth + AndroidUtilities.dp(97);
buttonX = layoutWidth - backgroundWidth + AndroidUtilities.dp(67); buttonX = layoutWidth - backgroundWidth + AndroidUtilities.dp(67);
timeX = layoutWidth - backgroundWidth + AndroidUtilities.dp(71); timeX = layoutWidth - backgroundWidth + AndroidUtilities.dp(71);
@ -356,7 +355,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
} }
avatarImage.setImage(currentPhoto, "50_50", getResources().getDrawable(AndroidUtilities.getUserAvatarForId(uid)), false); avatarImage.setImage(currentPhoto, "50_50", getResources().getDrawable(AndroidUtilities.getUserAvatarForId(uid)), false);
} else { } else {
avatarImage.setImage((TLRPC.FileLocation)null, "50_50", getResources().getDrawable(AndroidUtilities.getUserAvatarForId(uid)), false); avatarImage.setImage(null, "50_50", getResources().getDrawable(AndroidUtilities.getUserAvatarForId(uid)), false);
} }
if (messageObject.isOut()) { if (messageObject.isOut()) {
@ -380,7 +379,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
return; return;
} }
avatarImage.draw(canvas, avatarImage.getImageX(), avatarImage.getImageY(), AndroidUtilities.dp(50), AndroidUtilities.dp(50)); avatarImage.draw(canvas, avatarImage.getImageX(), avatarImage.getImageY(), avatarImage.getImageHeight(), avatarImage.getImageHeight());
canvas.save(); canvas.save();
if (buttonState == 0 || buttonState == 1) { if (buttonState == 0 || buttonState == 1) {
@ -399,7 +398,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
} else { } else {
timePaint.setColor(0xff70b15c); timePaint.setColor(0xff70b15c);
} }
Drawable buttonDrawable = statesDrawable[state][buttonPressed]; Drawable buttonDrawable = statesDrawable[state][buttonPressed ? 1 : 0];
int side = AndroidUtilities.dp(36); int side = AndroidUtilities.dp(36);
int x = (side - buttonDrawable.getIntrinsicWidth()) / 2; int x = (side - buttonDrawable.getIntrinsicWidth()) / 2;
int y = (side - buttonDrawable.getIntrinsicHeight()) / 2; int y = (side - buttonDrawable.getIntrinsicHeight()) / 2;

View file

@ -94,7 +94,7 @@ public class ChatBaseCell extends BaseCell {
private StaticLayout timeLayout; private StaticLayout timeLayout;
protected int timeWidth; protected int timeWidth;
protected int timeX; private int timeX;
private TextPaint currentTimePaint; private TextPaint currentTimePaint;
private String currentTimeString; private String currentTimeString;
protected boolean drawTime = true; protected boolean drawTime = true;

View file

@ -9,263 +9,280 @@
package org.telegram.ui.Cells; package org.telegram.ui.Cells;
import android.content.Context; import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.SoundEffectConstants;
import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.android.AndroidUtilities;
import org.telegram.android.ContactsController;
import org.telegram.android.ImageReceiver;
import org.telegram.android.LocaleController;
import org.telegram.android.MessageObject;
import org.telegram.android.MessagesController;
import org.telegram.messenger.R;
import org.telegram.messenger.TLRPC;
import org.telegram.messenger.UserConfig;
public class ChatContactCell extends ChatBaseCell { public class ChatContactCell extends ChatBaseCell {
public static interface ChatContactCellDelegate {
public abstract void didClickAddButton(ChatContactCell cell, TLRPC.User user);
public abstract void didClickPhone(ChatContactCell cell);
}
private static TextPaint namePaint;
private static TextPaint phonePaint;
private static Drawable addContactDrawable;
private static Paint linePaint;
private ImageReceiver avatarImage;
private StaticLayout nameLayout;
private StaticLayout phoneLayout;
private TLRPC.User contactUser;
private TLRPC.FileLocation currentPhoto;
private boolean avatarPressed = false;
private boolean buttonPressed = false;
private boolean drawAddButton = false;
private int namesWidth = 0;
private ChatContactCellDelegate contactDelegate = null;
public ChatContactCell(Context context) { public ChatContactCell(Context context) {
super(context); super(context);
if (namePaint == null) {
namePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
namePaint.setTextSize(AndroidUtilities.dp(15));
phonePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
phonePaint.setTextSize(AndroidUtilities.dp(15));
phonePaint.setColor(0xff000000);
addContactDrawable = getResources().getDrawable(R.drawable.ic_ab_add_member);
linePaint = new Paint();
linePaint.setStrokeWidth(AndroidUtilities.dp(1));
}
avatarImage = new ImageReceiver(this);
} }
/* public void setContactDelegate(ChatContactCellDelegate delegate) {
public class ChatListRowHolderEx { this.contactDelegate = delegate;
public BackupImageView avatarImageView; }
public TextView nameTextView;
public TextView messageTextView;
public TextView timeTextView;
public ImageView halfCheckImage;
public ImageView checkImage;
public MessageObject message;
public TextView phoneTextView;
public BackupImageView contactAvatar;
public View contactView;
public ImageView addContactButton;
public View addContactView;
public View chatBubbleView;
public void update() { @Override
TLRPC.User fromUser = MessagesController.getInstance().getUser(message.messageOwner.from_id); protected boolean isUserDataChanged() {
if (currentMessageObject == null) {
return false;
}
int type = message.type; contactUser = MessagesController.getInstance().getUser(currentMessageObject.messageOwner.media.user_id);
if (timeTextView != null) { TLRPC.FileLocation newPhoto = null;
timeTextView.setText(LocaleController.formatterDay.format((long) (message.messageOwner.date) * 1000)); if (contactUser != null && contactUser.photo != null) {
newPhoto = contactUser.photo.photo_small;
}
return currentPhoto == null && newPhoto != null || currentPhoto != null && newPhoto == null || currentPhoto != null && newPhoto != null && (currentPhoto.local_id != newPhoto.local_id || currentPhoto.volume_id != newPhoto.volume_id) || super.isUserDataChanged();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
boolean result = false;
int side = AndroidUtilities.dp(36);
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (x >= avatarImage.getImageX() && x <= avatarImage.getImageX() + namesWidth && y >= avatarImage.getImageY() && y <= avatarImage.getImageY() + avatarImage.getImageHeight()) {
avatarPressed = true;
result = true;
} else if (x >= avatarImage.getImageX() - AndroidUtilities.dp(44) && y >= AndroidUtilities.dp(20) && x <= avatarImage.getImageX() - AndroidUtilities.dp(10) && y <= AndroidUtilities.dp(52)) {
buttonPressed = true;
result = true;
} }
if (result) {
if (avatarImageView != null && fromUser != null) { startCheckLongPress();
TLRPC.FileLocation photo = null; }
if (fromUser.photo != null) { } else {
photo = fromUser.photo.photo_small; if (event.getAction() != MotionEvent.ACTION_MOVE) {
cancelCheckLongPress();
}
if (avatarPressed) {
if (event.getAction() == MotionEvent.ACTION_UP) {
avatarPressed = false;
playSoundEffect(SoundEffectConstants.CLICK);
if (contactUser != null) {
if (delegate != null) {
delegate.didPressedUserAvatar(this, contactUser);
}
} else {
if (contactDelegate != null) {
contactDelegate.didClickPhone(this);
}
}
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
avatarPressed = false;
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (!avatarImage.isInsideImage(x, y)) {
avatarPressed = false;
}
} }
int placeHolderId = AndroidUtilities.getUserAvatarForId(fromUser.id); } else if (buttonPressed) {
avatarImageView.setImage(photo, "50_50", placeHolderId); if (event.getAction() == MotionEvent.ACTION_UP) {
} buttonPressed = false;
playSoundEffect(SoundEffectConstants.CLICK);
if (type != 12 && type != 13 && nameTextView != null && fromUser != null && type != 8 && type != 9) { if (contactUser != null && contactDelegate != null) {
nameTextView.setText(ContactsController.formatName(fromUser.first_name, fromUser.last_name)); contactDelegate.didClickAddButton(this, contactUser);
nameTextView.setTextColor(AndroidUtilities.getColorForId(message.messageOwner.from_id));
}
if (type == 12 || type == 13) {
TLRPC.User contactUser = MessagesController.getInstance().getUser(message.messageOwner.media.user_id);
if (contactUser != null) {
nameTextView.setText(ContactsController.formatName(message.messageOwner.media.first_name, message.messageOwner.media.last_name));
nameTextView.setTextColor(AndroidUtilities.getColorForId(contactUser.id));
String phone = message.messageOwner.media.phone_number;
if (phone != null && phone.length() != 0) {
if (!phone.startsWith("+")) {
phone = "+" + phone;
}
phoneTextView.setText(PhoneFormat.getInstance().format(phone));
} else {
phoneTextView.setText("Unknown");
} }
TLRPC.FileLocation photo = null; } else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
if (contactUser.photo != null) { buttonPressed = false;
photo = contactUser.photo.photo_small; } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
} if (!(x >= avatarImage.getImageX() - AndroidUtilities.dp(44) && y >= AndroidUtilities.dp(20) && x <= avatarImage.getImageX() - AndroidUtilities.dp(10) && y <= AndroidUtilities.dp(52))) {
int placeHolderId = AndroidUtilities.getUserAvatarForId(contactUser.id); buttonPressed = false;
contactAvatar.setImage(photo, "50_50", placeHolderId);
if (contactUser.id != UserConfig.getClientUserId() && ContactsController.getInstance().contactsDict.get(contactUser.id) == null) {
addContactView.setVisibility(View.VISIBLE);
} else {
addContactView.setVisibility(View.GONE);
}
} else {
nameTextView.setText(ContactsController.formatName(message.messageOwner.media.first_name, message.messageOwner.media.last_name));
nameTextView.setTextColor(AndroidUtilities.getColorForId(message.messageOwner.media.user_id));
String phone = message.messageOwner.media.phone_number;
if (phone != null && phone.length() != 0) {
if (message.messageOwner.media.user_id != 0 && !phone.startsWith("+")) {
phone = "+" + phone;
}
phoneTextView.setText(PhoneFormat.getInstance().format(phone));
} else {
phoneTextView.setText("Unknown");
}
contactAvatar.setImageResource(AndroidUtilities.getUserAvatarForId(message.messageOwner.media.user_id));
addContactView.setVisibility(View.GONE);
}
} else if (type == 6) {
messageTextView.setTextSize(16);
messageTextView.setText(LocaleController.formatPluralString("NewMessages", unread_to_load));
}
if (message.isFromMe()) {
if (halfCheckImage != null) {
if (message.isSending()) {
checkImage.setVisibility(View.INVISIBLE);
halfCheckImage.setImageResource(R.drawable.msg_clock);
halfCheckImage.setVisibility(View.VISIBLE);
} else if (message.isSendError()) {
halfCheckImage.setVisibility(View.VISIBLE);
halfCheckImage.setImageResource(R.drawable.msg_warning);
if (checkImage != null) {
checkImage.setVisibility(View.INVISIBLE);
}
} else if (message.isSent()) {
if (!message.isUnread()) {
halfCheckImage.setVisibility(View.VISIBLE);
checkImage.setVisibility(View.VISIBLE);
halfCheckImage.setImageResource(R.drawable.msg_halfcheck);
} else {
halfCheckImage.setVisibility(View.VISIBLE);
checkImage.setVisibility(View.INVISIBLE);
halfCheckImage.setImageResource(R.drawable.msg_check);
}
} }
} }
} }
} }
if (!result) {
public ChatListRowHolderEx(View view, int type) { result = super.onTouchEvent(event);
avatarImageView = (BackupImageView)view.findViewById(R.id.chat_group_avatar_image);
nameTextView = (TextView)view.findViewById(R.id.chat_user_group_name);
timeTextView = (TextView)view.findViewById(R.id.chat_time_text);
halfCheckImage = (ImageView)view.findViewById(R.id.chat_row_halfcheck);
checkImage = (ImageView)view.findViewById(R.id.chat_row_check);
messageTextView = (TextView)view.findViewById(R.id.chat_message_text);
phoneTextView = (TextView)view.findViewById(R.id.phone_text_view);
contactAvatar = (BackupImageView)view.findViewById(R.id.contact_avatar);
contactView = view.findViewById(R.id.shared_layout);
addContactButton = (ImageView)view.findViewById(R.id.add_contact_button);
addContactView = view.findViewById(R.id.add_contact_view);
chatBubbleView = view.findViewById(R.id.chat_bubble_layout);
if (messageTextView != null) {
messageTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, MessagesController.getInstance().fontSize);
}
if (addContactButton != null) {
addContactButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (actionBarLayer.isActionModeShowed()) {
processRowSelect(view);
return;
}
Bundle args = new Bundle();
args.putInt("user_id", message.messageOwner.media.user_id);
args.putString("phone", message.messageOwner.media.phone_number);
presentFragment(new ContactAddActivity(args));
}
});
addContactButton.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
createMenu(v, false);
return true;
}
});
}
if (contactView != null) {
contactView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (message.type == 12 || message.type == 13) {
if (actionBarLayer.isActionModeShowed()) {
processRowSelect(view);
return;
}
if (message.messageOwner.media.user_id != UserConfig.getClientUserId()) {
TLRPC.User user = null;
if (message.messageOwner.media.user_id != 0) {
user = MessagesController.getInstance().getUser(message.messageOwner.media.user_id);
}
if (user != null) {
Bundle args = new Bundle();
args.putInt("user_id", message.messageOwner.media.user_id);
presentFragment(new UserProfileActivity(args));
} else {
if (message.messageOwner.media.phone_number == null || message.messageOwner.media.phone_number.length() == 0) {
return;
}
if (getParentActivity() == null) {
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
builder.setItems(new CharSequence[] {LocaleController.getString("Copy", R.string.Copy), LocaleController.getString("Call", R.string.Call)}, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
if (i == 1) {
try {
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + message.messageOwner.media.phone_number));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getParentActivity().startActivity(intent);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
} else if (i == 0) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
android.text.ClipboardManager clipboard = (android.text.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE);
clipboard.setText(message.messageOwner.media.phone_number);
} else {
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE);
android.content.ClipData clip = android.content.ClipData.newPlainText("label", message.messageOwner.media.phone_number);
clipboard.setPrimaryClip(clip);
}
}
}
}
);
showAlertDialog(builder);
}
}
}
}
});
contactView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
createMenu(v, false);
return true;
}
});
}
if (contactAvatar != null) {
contactAvatar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
}
if (avatarImageView != null) {
avatarImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (actionBarLayer.isActionModeShowed()) {
processRowSelect(view);
return;
}
if (message != null) {
Bundle args = new Bundle();
args.putInt("user_id", message.messageOwner.from_id);
presentFragment(new UserProfileActivity(args));
}
}
});
}
} }
private void processOnClick(View view) { return result;
if (actionBarLayer.isActionModeShowed()) { }
processRowSelect(view);
@Override
public void setMessageObject(MessageObject messageObject) {
if (currentMessageObject != messageObject || isUserDataChanged()) {
int uid = messageObject.messageOwner.media.user_id;
contactUser = MessagesController.getInstance().getUser(uid);
drawAddButton = contactUser != null && uid != UserConfig.getClientUserId() && ContactsController.getInstance().contactsDict.get(uid) == null;
int maxWidth;
if (AndroidUtilities.isTablet()) {
maxWidth = (int) (AndroidUtilities.getMinTabletSide() * 0.7f);
} else {
maxWidth = (int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.7f);
} }
maxWidth -= AndroidUtilities.dp(58 + (drawAddButton ? 52 : 0));
if (contactUser != null) {
if (contactUser.photo != null) {
currentPhoto = contactUser.photo.photo_small;
}
avatarImage.setImage(currentPhoto, "50_50", getResources().getDrawable(AndroidUtilities.getUserAvatarForId(uid)), false);
} else {
avatarImage.setImage(null, "50_50", getResources().getDrawable(AndroidUtilities.getUserAvatarForId(uid)), false);
}
String currentNameString = ContactsController.formatName(messageObject.messageOwner.media.first_name, messageObject.messageOwner.media.last_name);
int nameWidth = Math.min((int) Math.ceil(namePaint.measureText(currentNameString)), maxWidth);
CharSequence stringFinal = TextUtils.ellipsize(currentNameString.replace("\n", " "), namePaint, nameWidth, TextUtils.TruncateAt.END);
nameLayout = new StaticLayout(stringFinal, namePaint, nameWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
if (nameLayout.getLineCount() > 0) {
nameWidth = (int)Math.ceil(nameLayout.getLineWidth(0));
} else {
nameWidth = 0;
}
String phone = messageObject.messageOwner.media.phone_number;
if (phone != null && phone.length() != 0) {
if (!phone.startsWith("+")) {
phone = "+" + phone;
}
phone = PhoneFormat.getInstance().format(phone);
} else {
phone = LocaleController.getString("Unknown", R.string.Unknown);
}
int phoneWidth = Math.min((int) Math.ceil(phonePaint.measureText(phone)), maxWidth);
stringFinal = TextUtils.ellipsize(phone.replace("\n", " "), phonePaint, phoneWidth, TextUtils.TruncateAt.END);
phoneLayout = new StaticLayout(stringFinal, phonePaint, phoneWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
if (phoneLayout.getLineCount() > 0) {
phoneWidth = (int)Math.ceil(phoneLayout.getLineWidth(0));
} else {
phoneWidth = 0;
}
namesWidth = Math.max(nameWidth, phoneWidth);
backgroundWidth = AndroidUtilities.dp(75 + (drawAddButton ? 52 : 0)) + namesWidth;
super.setMessageObject(messageObject);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), AndroidUtilities.dp(71));
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (currentMessageObject == null) {
return;
}
int x;
if (currentMessageObject.isOut()) {
x = layoutWidth - backgroundWidth + AndroidUtilities.dp(6);
} else {
if (isChat) {
x = AndroidUtilities.dp(67);
} else {
x = AndroidUtilities.dp(14);
}
}
avatarImage.setImageCoords(x + (drawAddButton ? AndroidUtilities.dp(52) : 0), AndroidUtilities.dp(7), AndroidUtilities.dp(42), AndroidUtilities.dp(42));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (currentMessageObject == null) {
return;
}
avatarImage.draw(canvas, avatarImage.getImageX(), avatarImage.getImageY(), avatarImage.getImageWidth(), avatarImage.getImageWidth());
if (nameLayout != null) {
canvas.save();
canvas.translate(avatarImage.getImageX() + avatarImage.getImageWidth() + AndroidUtilities.dp(9), AndroidUtilities.dp(8));
namePaint.setColor(AndroidUtilities.getColorForId(currentMessageObject.messageOwner.media.user_id));
nameLayout.draw(canvas);
canvas.restore();
}
if (phoneLayout != null) {
canvas.save();
canvas.translate(avatarImage.getImageX() + avatarImage.getImageWidth() + AndroidUtilities.dp(9), AndroidUtilities.dp(29));
phoneLayout.draw(canvas);
canvas.restore();
}
if (drawAddButton) {
if (currentMessageObject.isOut()) {
linePaint.setColor(0x9670b15c);
} else {
linePaint.setColor(0xffe8e8e8);
}
canvas.drawLine(avatarImage.getImageX() - AndroidUtilities.dp(4), avatarImage.getImageY(), avatarImage.getImageX() - AndroidUtilities.dp(4), AndroidUtilities.dp(62), linePaint);
setDrawableBounds(addContactDrawable, avatarImage.getImageX() - AndroidUtilities.dp(44), AndroidUtilities.dp(20));
addContactDrawable.draw(canvas);
} }
} }
*/
} }

View file

@ -569,7 +569,11 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
} }
if (currentMessageObject.isSecretMedia()) { if (currentMessageObject.isSecretMedia()) {
w = h = (int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.5f); if (AndroidUtilities.isTablet()) {
w = h = (int) (AndroidUtilities.getMinTabletSide() * 0.5f);
} else {
w = h = (int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.5f);
}
} }
photoWidth = w; photoWidth = w;

View file

@ -20,12 +20,8 @@ import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.media.MediaMetadataRetriever;
import android.media.MediaPlayer;
import android.media.ThumbnailUtils;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
@ -51,7 +47,6 @@ import android.widget.Toast;
import org.telegram.android.AndroidUtilities; import org.telegram.android.AndroidUtilities;
import org.telegram.PhoneFormat.PhoneFormat; import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.android.ImageLoader;
import org.telegram.android.LocaleController; import org.telegram.android.LocaleController;
import org.telegram.android.MediaController; import org.telegram.android.MediaController;
import org.telegram.android.MessagesStorage; import org.telegram.android.MessagesStorage;
@ -470,7 +465,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
fragment.setDelegate(new PhotoPickerActivity.PhotoPickerActivityDelegate() { fragment.setDelegate(new PhotoPickerActivity.PhotoPickerActivityDelegate() {
@Override @Override
public void didSelectPhotos(ArrayList<String> photos) { public void didSelectPhotos(ArrayList<String> photos) {
processSendingPhotos(photos, null); SendMessagesHelper.prepareSendingPhotos(photos, null, dialog_id);
} }
@Override @Override
@ -531,7 +526,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
@Override @Override
public void didSelectFile(DocumentSelectActivity activity, String path) { public void didSelectFile(DocumentSelectActivity activity, String path) {
activity.finishFragment(); activity.finishFragment();
processSendingDocument(path, path); SendMessagesHelper.prepareSendingDocument(path, path, dialog_id);
} }
@Override @Override
@ -1480,11 +1475,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
videoEditedInfo.resultWidth = resultWidth; videoEditedInfo.resultWidth = resultWidth;
videoEditedInfo.resultHeight = resultHeight; videoEditedInfo.resultHeight = resultHeight;
videoEditedInfo.originalPath = videoPath; videoEditedInfo.originalPath = videoPath;
processSendingVideo(videoPath, estimatedSize, estimatedDuration, resultWidth, resultHeight, videoEditedInfo); SendMessagesHelper.prepareSendingVideo(videoPath, estimatedSize, estimatedDuration, resultWidth, resultHeight, videoEditedInfo, dialog_id);
} }
}); });
if (parentLayout == null || !parentLayout.presentFragment(fragment, removeLast, true, true)) { if (parentLayout == null || !parentLayout.presentFragment(fragment, removeLast, true, true)) {
processSendingVideo(videoPath, 0, 0, 0, 0, null); SendMessagesHelper.prepareSendingVideo(videoPath, 0, 0, 0, 0, null, dialog_id);
return false; return false;
} }
return true; return true;
@ -1503,14 +1498,14 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (resultCode == Activity.RESULT_OK) { if (resultCode == Activity.RESULT_OK) {
if (requestCode == 0) { if (requestCode == 0) {
Utilities.addMediaToGallery(currentPicturePath); Utilities.addMediaToGallery(currentPicturePath);
processSendingPhoto(currentPicturePath, null); SendMessagesHelper.prepareSendingPhoto(currentPicturePath, null, dialog_id);
currentPicturePath = null; currentPicturePath = null;
} else if (requestCode == 1) { } else if (requestCode == 1) {
if (data == null || data.getData() == null) { if (data == null || data.getData() == null) {
showAttachmentError(); showAttachmentError();
return; return;
} }
processSendingPhoto(null, data.getData()); SendMessagesHelper.prepareSendingPhoto(null, data.getData(), dialog_id);
} else if (requestCode == 2) { } else if (requestCode == 2) {
String videoPath = null; String videoPath = null;
if (data != null) { if (data != null) {
@ -1551,7 +1546,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
openVideoEditor(videoPath, false, parentLayout); openVideoEditor(videoPath, false, parentLayout);
} }
} else { } else {
processSendingVideo(videoPath, 0, 0, 0, 0, null); SendMessagesHelper.prepareSendingVideo(videoPath, 0, 0, 0, 0, null, dialog_id);
} }
} else if (requestCode == 21) { } else if (requestCode == 21) {
if (data == null || data.getData() == null) { if (data == null || data.getData() == null) {
@ -1568,7 +1563,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
showAttachmentError(); showAttachmentError();
return; return;
} }
processSendingDocument(tempPath, originalPath); SendMessagesHelper.prepareSendingDocument(tempPath, originalPath, dialog_id);
} }
} }
} }
@ -1603,333 +1598,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
return chatActivityEnterView.processSendingText(text); return chatActivityEnterView.processSendingText(text);
} }
public void processSendingPhoto(String imageFilePath, Uri imageUri) {
ArrayList<String> paths = null;
ArrayList<Uri> uris = null;
if (imageFilePath != null && imageFilePath.length() != 0) {
paths = new ArrayList<String>();
paths.add(imageFilePath);
}
if (imageUri != null) {
uris = new ArrayList<Uri>();
uris.add(imageUri);
}
processSendingPhotos(paths, uris);
}
public void processSendingPhotos(ArrayList<String> paths, ArrayList<Uri> uris) {
if (paths == null && uris == null || paths != null && paths.isEmpty() || uris != null && uris.isEmpty()) {
return;
}
final ArrayList<String> pathsCopy = new ArrayList<String>();
final ArrayList<Uri> urisCopy = new ArrayList<Uri>();
if (paths != null) {
pathsCopy.addAll(paths);
}
if (uris != null) {
urisCopy.addAll(uris);
}
new Thread(new Runnable() {
@Override
public void run() {
ArrayList<String> sendAsDocuments = null;
ArrayList<String> sendAsDocumentsOriginal = null;
int count = !pathsCopy.isEmpty() ? pathsCopy.size() : urisCopy.size();
String path = null;
Uri uri = null;
for (int a = 0; a < count; a++) {
if (!pathsCopy.isEmpty()) {
path = pathsCopy.get(a);
} else if (!urisCopy.isEmpty()) {
uri = urisCopy.get(a);
}
String originalPath = path;
String tempPath = path;
if (tempPath == null && uri != null) {
tempPath = Utilities.getPath(uri);
originalPath = uri.toString();
}
boolean isGif = false;
if (tempPath != null && tempPath.endsWith(".gif")) {
isGif = true;
} else if (tempPath == null && uri != null) {
isGif = MediaController.isGif(uri);
if (isGif) {
originalPath = uri.toString();
tempPath = MediaController.copyDocumentToCache(uri, "gif");
}
}
if (isGif) {
if (sendAsDocuments == null) {
sendAsDocuments = new ArrayList<String>();
sendAsDocumentsOriginal = new ArrayList<String>();
}
sendAsDocuments.add(tempPath);
sendAsDocumentsOriginal.add(originalPath);
} else {
if (tempPath != null) {
File temp = new File(tempPath);
originalPath += temp.length() + "_" + temp.lastModified();
} else {
originalPath = null;
}
TLRPC.TL_photo photo = (TLRPC.TL_photo)MessagesStorage.getInstance().getSentFile(originalPath, currentEncryptedChat == null ? 0 : 3);
if (photo == null && uri != null) {
photo = (TLRPC.TL_photo)MessagesStorage.getInstance().getSentFile(Utilities.getPath(uri), currentEncryptedChat == null ? 0 : 3);
}
if (photo == null) {
photo = SendMessagesHelper.getInstance().generatePhotoSizes(path, uri);
}
if (photo != null) {
final String originalPathFinal = originalPath;
final TLRPC.TL_photo photoFinal = photo;
AndroidUtilities.RunOnUIThread(new Runnable() {
@Override
public void run() {
SendMessagesHelper.getInstance().sendMessage(photoFinal, originalPathFinal, dialog_id);
if (chatListView != null) {
chatListView.setSelectionFromTop(messages.size() - 1, -100000 - chatListView.getPaddingTop());
}
if (paused) {
scrollToTopOnResume = true;
}
}
});
}
}
}
if (sendAsDocuments != null && !sendAsDocuments.isEmpty()) {
for (int a = 0; a < sendAsDocuments.size(); a++) {
processSendingDocumentInternal(sendAsDocuments.get(a), sendAsDocumentsOriginal.get(a));
}
}
}
}).start();
}
private void processSendingDocumentInternal(final String path, String originalPath) {
if (path == null || path.length() == 0) {
return;
}
final File f = new File(path);
if (!f.exists() || f.length() == 0) {
return;
}
String name = f.getName();
if (name == null) {
name = "noname";
}
String ext = "";
int idx = path.lastIndexOf(".");
if (idx != -1) {
ext = path.substring(idx + 1);
}
if (originalPath != null) {
originalPath += "" + f.length();
}
TLRPC.TL_document document = (TLRPC.TL_document)MessagesStorage.getInstance().getSentFile(originalPath, currentEncryptedChat == null ? 1 : 4);
if (document == null && !path.equals(originalPath)) {
document = (TLRPC.TL_document)MessagesStorage.getInstance().getSentFile(path + f.length(), currentEncryptedChat == null ? 1 : 4);
}
if (document == null) {
document = new TLRPC.TL_document();
document.id = 0;
document.user_id = UserConfig.getClientUserId();
document.date = ConnectionsManager.getInstance().getCurrentTime();
document.file_name = name;
document.size = (int)f.length();
document.dc_id = 0;
if (ext.length() != 0) {
MimeTypeMap myMime = MimeTypeMap.getSingleton();
String mimeType = myMime.getMimeTypeFromExtension(ext.toLowerCase());
if (mimeType != null) {
document.mime_type = mimeType;
} else {
document.mime_type = "application/octet-stream";
}
} else {
document.mime_type = "application/octet-stream";
}
if (document.mime_type.equals("image/gif")) {
try {
Bitmap bitmap = ImageLoader.loadBitmap(f.getAbsolutePath(), null, 90, 90);
if (bitmap != null) {
document.thumb = ImageLoader.scaleAndSaveImage(bitmap, 90, 90, 55, currentEncryptedChat != null);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
if (document.thumb == null) {
document.thumb = new TLRPC.TL_photoSizeEmpty();
document.thumb.type = "s";
}
}
final TLRPC.TL_document documentFinal = document;
final String originalPathFinal = originalPath;
AndroidUtilities.RunOnUIThread(new Runnable() {
@Override
public void run() {
SendMessagesHelper.getInstance().sendMessage(documentFinal, originalPathFinal, path, dialog_id);
if (chatListView != null) {
chatListView.setSelectionFromTop(messages.size() - 1, -100000 - chatListView.getPaddingTop());
}
if (paused) {
scrollToTopOnResume = true;
}
}
});
}
public void processSendingDocument(String path, String originalPath) {
if (path == null || originalPath == null) {
return;
}
ArrayList<String> paths = new ArrayList<String>();
ArrayList<String> originalPaths = new ArrayList<String>();
paths.add(path);
originalPaths.add(originalPath);
processSendingDocuments(paths, originalPaths);
}
public void processSendingDocuments(final ArrayList<String> paths, final ArrayList<String> originalPaths) {
if (paths == null && originalPaths == null || paths != null && originalPaths != null && paths.size() != originalPaths.size()) {
return;
}
new Thread(new Runnable() {
@Override
public void run() {
for (int a = 0; a < paths.size(); a++) {
processSendingDocumentInternal(paths.get(a), originalPaths.get(a));
}
}
}).start();
}
public void processSendingVideo(final String videoPath, final long estimatedSize, final long duration, final int width, final int height, final TLRPC.VideoEditedInfo videoEditedInfo) {
if (videoPath == null || videoPath.length() == 0) {
return;
}
new Thread(new Runnable() {
@Override
public void run() {
String path = videoPath;
String originalPath = videoPath;
File temp = new File(originalPath);
originalPath += temp.length() + "_" + temp.lastModified();
if (videoEditedInfo != null) {
originalPath += duration + "_" + videoEditedInfo.startTime + "_" + videoEditedInfo.endTime;
}
TLRPC.TL_video video = (TLRPC.TL_video)MessagesStorage.getInstance().getSentFile(originalPath, currentEncryptedChat == null ? 2 : 5);
if (video == null) {
Bitmap thumb = ThumbnailUtils.createVideoThumbnail(videoPath, MediaStore.Video.Thumbnails.MINI_KIND);
TLRPC.PhotoSize size = ImageLoader.scaleAndSaveImage(thumb, 90, 90, 55, currentEncryptedChat != null);
video = new TLRPC.TL_video();
video.thumb = size;
if (video.thumb == null) {
video.thumb = new TLRPC.TL_photoSizeEmpty();
video.thumb.type = "s";
} else {
video.thumb.type = "s";
}
video.caption = "";
video.mime_type = "video/mp4";
video.id = 0;
UserConfig.saveConfig(false);
if (videoEditedInfo != null) {
video.duration = (int)(duration / 1000);
if (videoEditedInfo.rotationValue == 90 || videoEditedInfo.rotationValue == 270) {
video.w = height;
video.h = width;
} else {
video.w = width;
video.h = height;
}
video.size = (int)estimatedSize;
video.videoEditedInfo = videoEditedInfo;
String fileName = Integer.MIN_VALUE + "_" + UserConfig.lastLocalId + ".mp4";
UserConfig.lastLocalId--;
File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName);
UserConfig.saveConfig(false);
path = cacheFile.getAbsolutePath();
} else {
if (temp != null && temp.exists()) {
video.size = (int) temp.length();
}
boolean infoObtained = false;
if (Build.VERSION.SDK_INT >= 14) {
MediaMetadataRetriever mediaMetadataRetriever = null;
try {
mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(videoPath);
String width = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
if (width != null) {
video.w = Integer.parseInt(width);
}
String height = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);
if (height != null) {
video.h = Integer.parseInt(height);
}
String duration = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
if (duration != null) {
video.duration = (int) Math.ceil(Long.parseLong(duration) / 1000.0f);
}
infoObtained = true;
} catch (Exception e) {
FileLog.e("tmessages", e);
} finally {
try {
if (mediaMetadataRetriever != null) {
mediaMetadataRetriever.release();
mediaMetadataRetriever = null;
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
}
if (!infoObtained) {
try {
MediaPlayer mp = MediaPlayer.create(ApplicationLoader.applicationContext, Uri.fromFile(new File(videoPath)));
if (mp != null) {
video.duration = (int) Math.ceil(mp.getDuration() / 1000.0f);
video.w = mp.getVideoWidth();
video.h = mp.getVideoHeight();
mp.release();
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
}
}
final TLRPC.TL_video videoFinal = video;
final String originalPathFinal = originalPath;
final String finalPath = path;
AndroidUtilities.RunOnUIThread(new Runnable() {
@Override
public void run() {
SendMessagesHelper.getInstance().sendMessage(videoFinal, originalPathFinal, finalPath, dialog_id);
if (chatListView != null) {
chatListView.setSelectionFromTop(messages.size() - 1, -100000 - chatListView.getPaddingTop());
}
if (paused) {
scrollToTopOnResume = true;
}
}
});
}
}).start();
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public void didReceivedNotification(int id, final Object... args) { public void didReceivedNotification(int id, final Object... args) {
@ -2180,6 +1848,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (did == dialog_id) { if (did == dialog_id) {
boolean updateChat = false; boolean updateChat = false;
boolean hasFromMe = false;
ArrayList<MessageObject> arr = (ArrayList<MessageObject>)args[1]; ArrayList<MessageObject> arr = (ArrayList<MessageObject>)args[1];
if (!unread_end_reached) { if (!unread_end_reached) {
@ -2245,6 +1914,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (obj.isOut()) { if (obj.isOut()) {
removeUnreadPlane(false); removeUnreadPlane(false);
hasFromMe = true;
} }
if (!obj.isOut() && unreadMessageObject != null) { if (!obj.isOut() && unreadMessageObject != null) {
@ -2299,7 +1969,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (endReached) { if (endReached) {
lastVisible++; lastVisible++;
} }
if (lastVisible == oldCount) { if (lastVisible == oldCount || hasFromMe) {
if (!firstLoading) { if (!firstLoading) {
if (paused) { if (paused) {
scrollToTopOnResume = true; scrollToTopOnResume = true;
@ -3385,6 +3055,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
((ChatBaseCell)view).setDelegate(new ChatBaseCell.ChatBaseCellDelegate() { ((ChatBaseCell)view).setDelegate(new ChatBaseCell.ChatBaseCellDelegate() {
@Override @Override
public void didPressedUserAvatar(ChatBaseCell cell, TLRPC.User user) { public void didPressedUserAvatar(ChatBaseCell cell, TLRPC.User user) {
if (actionBarLayer.isActionModeShowed()) {
processRowSelect(cell);
return;
}
if (user != null && user.id != UserConfig.getClientUserId()) { if (user != null && user.id != UserConfig.getClientUserId()) {
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putInt("user_id", user.id); args.putInt("user_id", user.id);
@ -3496,6 +3170,58 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
createMenu(cell, true); createMenu(cell, true);
} }
}); });
} else if (view instanceof ChatContactCell) {
((ChatContactCell)view).setContactDelegate(new ChatContactCell.ChatContactCellDelegate() {
@Override
public void didClickAddButton(ChatContactCell cell, TLRPC.User user) {
if (actionBarLayer.isActionModeShowed()) {
processRowSelect(cell);
return;
}
Bundle args = new Bundle();
args.putInt("user_id", message.messageOwner.media.user_id);
args.putString("phone", message.messageOwner.media.phone_number);
presentFragment(new ContactAddActivity(args));
}
@Override
public void didClickPhone(ChatContactCell cell) {
if (actionBarLayer.isActionModeShowed()) {
processRowSelect(cell);
return;
}
final MessageObject messageObject = cell.getMessageObject();
if (getParentActivity() == null || messageObject.messageOwner.media.phone_number == null || messageObject.messageOwner.media.phone_number.length() == 0) {
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
builder.setItems(new CharSequence[] {LocaleController.getString("Copy", R.string.Copy), LocaleController.getString("Call", R.string.Call)}, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
if (i == 1) {
try {
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + messageObject.messageOwner.media.phone_number));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getParentActivity().startActivity(intent);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
} else if (i == 0) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
android.text.ClipboardManager clipboard = (android.text.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE);
clipboard.setText(messageObject.messageOwner.media.phone_number);
} else {
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE);
android.content.ClipData clip = android.content.ClipData.newPlainText("label", messageObject.messageOwner.media.phone_number);
clipboard.setPrimaryClip(clip);
}
}
}
}
);
showAlertDialog(builder);
}
});
} }
} else if (view instanceof ChatActionCell) { } else if (view instanceof ChatActionCell) {
((ChatActionCell)view).setDelegate(new ChatActionCell.ChatActionCellDelegate() { ((ChatActionCell)view).setDelegate(new ChatActionCell.ChatActionCellDelegate() {

View file

@ -670,7 +670,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
} }
} else { } else {
actionBarLayout.presentFragment(fragment, true); actionBarLayout.presentFragment(fragment, true);
fragment.processSendingVideo(videoPath, 0, 0, 0, 0, null); SendMessagesHelper.prepareSendingVideo(videoPath, 0, 0, 0, 0, null, dialog_id);
} }
} else { } else {
actionBarLayout.presentFragment(fragment, true); actionBarLayout.presentFragment(fragment, true);
@ -678,10 +678,10 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
fragment.processSendingText(sendingText); fragment.processSendingText(sendingText);
} }
if (photoPathsArray != null) { if (photoPathsArray != null) {
fragment.processSendingPhotos(null, photoPathsArray); SendMessagesHelper.prepareSendingPhotos(null, photoPathsArray, dialog_id);
} }
if (documentsPathsArray != null) { if (documentsPathsArray != null) {
fragment.processSendingDocuments(documentsPathsArray, documentsOriginalPathsArray); SendMessagesHelper.prepareSendingDocuments(documentsPathsArray, documentsOriginalPathsArray, dialog_id);
} }
if (contactsToSend != null && !contactsToSend.isEmpty()) { if (contactsToSend != null && !contactsToSend.isEmpty()) {
for (TLRPC.User user : contactsToSend) { for (TLRPC.User user : contactsToSend) {
@ -1190,7 +1190,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
buttonLayoutTablet.setVisibility(View.VISIBLE); buttonLayoutTablet.setVisibility(View.VISIBLE);
backgroundTablet.setVisibility(View.VISIBLE); backgroundTablet.setVisibility(View.VISIBLE);
} }
} else if (layout == layersActionBarLayout && actionBarLayout.fragmentsStack.isEmpty()) { } else if (layout == layersActionBarLayout && actionBarLayout.fragmentsStack.isEmpty() && layersActionBarLayout.fragmentsStack.size() == 1) {
onFinish(); onFinish();
finish(); finish();
return false; return false;

View file

@ -853,7 +853,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter
if (user != null && user.phone != null && user.phone.length() != 0) { if (user != null && user.phone != null && user.phone.length() != 0) {
textView.setText(PhoneFormat.getInstance().format("+" + user.phone)); textView.setText(PhoneFormat.getInstance().format("+" + user.phone));
} else { } else {
textView.setText("Unknown"); textView.setText(LocaleController.getString("Unknown", R.string.Unknown));
} }
divider.setVisibility(View.INVISIBLE); divider.setVisibility(View.INVISIBLE);
} else if (i == notificationRow) { } else if (i == notificationRow) {

View file

@ -249,7 +249,7 @@ public class SettingsBlockedUsersActivity extends BaseFragment implements Notifi
((ChatOrUserCell)view).useSeparator = true; ((ChatOrUserCell)view).useSeparator = true;
} }
TLRPC.User user = MessagesController.getInstance().getUser(MessagesController.getInstance().blockedUsers.get(i)); TLRPC.User user = MessagesController.getInstance().getUser(MessagesController.getInstance().blockedUsers.get(i));
((ChatOrUserCell)view).setData(user, null, null, null, user.phone != null && user.phone.length() != 0 ? PhoneFormat.getInstance().format("+" + user.phone) : "Unknown"); ((ChatOrUserCell)view).setData(user, null, null, null, user.phone != null && user.phone.length() != 0 ? PhoneFormat.getInstance().format("+" + user.phone) : LocaleController.getString("Unknown", R.string.Unknown));
} else if (type == 1) { } else if (type == 1) {
if (view == null) { if (view == null) {
LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

View file

@ -608,7 +608,7 @@ public class UserProfileActivity extends BaseFragment implements NotificationCen
if (user.phone != null && user.phone.length() != 0) { if (user.phone != null && user.phone.length() != 0) {
textView.setText(PhoneFormat.getInstance().format("+" + user.phone)); textView.setText(PhoneFormat.getInstance().format("+" + user.phone));
} else { } else {
textView.setText("Unknown"); textView.setText(LocaleController.getString("Unknown", R.string.Unknown));
} }
divider.setVisibility(View.INVISIBLE); divider.setVisibility(View.INVISIBLE);
detailTextView.setText(LocaleController.getString("PhoneMobile", R.string.PhoneMobile)); detailTextView.setText(LocaleController.getString("PhoneMobile", R.string.PhoneMobile));

View file

@ -1,95 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="1dp"
android:paddingTop="1dp"
android:layout_gravity="top">
<org.telegram.ui.Views.BackupImageView
android:layout_width="42dp"
android:layout_height="42dp"
android:layout_marginLeft="6dp"
android:id="@+id/chat_group_avatar_image"
android:layout_marginBottom="2dp"
android:layout_marginRight="4dp"
android:layout_gravity="bottom"/>
<LinearLayout
android:orientation="horizontal"
android:layout_height="69dp"
android:layout_width="wrap_content"
android:layout_marginRight="40dp"
android:layout_gravity="top"
android:baselineAligned="false"
android:id="@+id/chat_bubble_layout">
<FrameLayout
android:layout_height="58dp"
android:layout_width="0dp"
android:id="@+id/shared_layout"
android:layout_weight="1">
<org.telegram.ui.Views.BackupImageView
android:layout_height="42dp"
android:layout_width="42dp"
android:id="@+id/contact_avatar"/>
<TextView android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:scrollHorizontally="true"
android:paddingLeft="51dp"
android:layout_marginTop="1dp"
android:textSize="15dp"
android:lines="1"
android:layout_gravity="top|left"
android:singleLine="true"
android:ellipsize="end"
android:id="@+id/chat_user_group_name"/>
<TextView android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:paddingLeft="51dp"
android:layout_marginTop="20dp"
android:textSize="15dp"
android:layout_gravity="top|left"
android:maxLines="1"
android:id="@+id/phone_text_view"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/chat_time_text"
android:textColor="#a1aab3"
android:textSize="12dp"
android:layout_gravity="bottom|right"/>
</FrameLayout>
<FrameLayout android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_gravity="top"
android:id="@+id/add_contact_view">
<FrameLayout android:layout_height="54dp"
android:layout_width="1dp"
android:background="#e8e8e8"
android:paddingRight="8dp"/>
<ImageView android:layout_width="38dp"
android:layout_height="54dp"
android:src="@drawable/ic_ab_add_member"
android:scaleType="center"
android:layout_marginLeft="8dp"
android:paddingRight="4dp"
android:id="@+id/add_contact_button"/>
</FrameLayout>
</LinearLayout>
</LinearLayout>

View file

@ -1,87 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="1dp"
android:paddingTop="1dp"
android:layout_gravity="top">
<LinearLayout
android:orientation="horizontal"
android:layout_height="69dp"
android:layout_width="wrap_content"
android:layout_marginRight="40dp"
android:layout_gravity="top"
android:id="@+id/chat_bubble_layout">
<FrameLayout android:layout_height="58dp"
android:layout_width="0dp"
android:id="@+id/shared_layout"
android:layout_weight="1">
<org.telegram.ui.Views.BackupImageView
android:layout_height="42dp"
android:layout_width="42dp"
android:id="@+id/contact_avatar"/>
<TextView android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:scrollHorizontally="true"
android:paddingLeft="51dp"
android:layout_marginTop="1dp"
android:textSize="15dp"
android:lines="1"
android:singleLine="true"
android:ellipsize="end"
android:layout_gravity="top"
android:id="@+id/chat_user_group_name"/>
<TextView android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:paddingLeft="51dp"
android:layout_marginTop="20dp"
android:textSize="15dp"
android:maxLines="1"
android:layout_gravity="top"
android:id="@+id/phone_text_view"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/chat_time_text"
android:textColor="#a1aab3"
android:textSize="12dp"
android:layout_gravity="bottom|right"/>
</FrameLayout>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_gravity="top"
android:id="@+id/add_contact_view">
<FrameLayout
android:layout_height="54dp"
android:layout_width="1dp"
android:background="#e8e8e8"
android:paddingRight="8dp"/>
<ImageView
android:layout_width="38dp"
android:layout_height="54dp"
android:src="@drawable/ic_ab_add_member"
android:scaleType="center"
android:layout_marginLeft="8dp"
android:paddingRight="4dp"
android:id="@+id/add_contact_button"/>
</FrameLayout>
</LinearLayout>
</FrameLayout>

View file

@ -1,117 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="1dp"
android:paddingTop="1dp"
android:layout_gravity="top">
<LinearLayout
android:orientation="horizontal"
android:layout_height="69dp"
android:layout_width="wrap_content"
android:layout_marginLeft="40dp"
android:layout_gravity="top|right"
android:id="@+id/chat_bubble_layout">
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="8dp"
android:layout_gravity="top"
android:id="@+id/add_contact_view">
<FrameLayout
android:layout_height="54dp"
android:layout_width="1dp"
android:background="#aa70b15c"
android:paddingLeft="8dp"
android:layout_gravity="right"/>
<ImageView
android:layout_width="40dp"
android:layout_height="54dp"
android:src="@drawable/ic_ab_add_member"
android:scaleType="center"
android:layout_marginRight="8dp"
android:paddingLeft="4dp"
android:id="@+id/add_contact_button"/>
</FrameLayout>
<FrameLayout
android:layout_height="58dp"
android:layout_width="0dp"
android:id="@+id/shared_layout"
android:layout_weight="1">
<org.telegram.ui.Views.BackupImageView
android:layout_height="42dp"
android:layout_width="42dp"
android:id="@+id/contact_avatar"/>
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:scrollHorizontally="true"
android:paddingLeft="51dp"
android:layout_marginTop="1dp"
android:textSize="15dp"
android:lines="1"
android:singleLine="true"
android:layout_gravity="top"
android:ellipsize="end"
android:id="@+id/chat_user_group_name"/>
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:paddingLeft="51dp"
android:layout_marginTop="20dp"
android:layout_gravity="top"
android:textSize="15dp"
android:maxLines="1"
android:id="@+id/phone_text_view"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/chat_time_layout"
android:layout_gravity="bottom|right">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/chat_time_text"
android:textColor="#70b15c"
android:textSize="12dp"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/msg_check"
android:layout_marginTop="2dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="-8dp"
android:id="@+id/chat_row_check"
android:visibility="visible"
android:layout_gravity="top"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/msg_halfcheck"
android:layout_marginTop="2dp"
android:id="@+id/chat_row_halfcheck"
android:visibility="visible"
android:layout_gravity="top"/>
</LinearLayout>
</FrameLayout>
</LinearLayout>
</FrameLayout>

View file

@ -197,6 +197,7 @@
<string name="MessageLifetime">عداد التدمير الذاتي</string> <string name="MessageLifetime">عداد التدمير الذاتي</string>
<string name="ShortMessageLifetimeForever">إيقاف</string> <string name="ShortMessageLifetimeForever">إيقاف</string>
<string name="EncryptionKeyDescription">هذه الصورة هي تصور لمفتاح التشفير لهذه المحادثة السرية مع <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>.<![CDATA[<br><br>]]>إذا كانت مطابقة للصورة التي في جهاز <![CDATA[<b>]]>%2$s<![CDATA[</b>]]>, فمحادثتكم آمنة ٢٠٠٪.<![CDATA[<br><br>]]>للمزيد نرجو الذهاب إلى telegram.org</string> <string name="EncryptionKeyDescription">هذه الصورة هي تصور لمفتاح التشفير لهذه المحادثة السرية مع <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>.<![CDATA[<br><br>]]>إذا كانت مطابقة للصورة التي في جهاز <![CDATA[<b>]]>%2$s<![CDATA[</b>]]>, فمحادثتكم آمنة ٢٠٠٪.<![CDATA[<br><br>]]>للمزيد نرجو الذهاب إلى telegram.org</string>
<string name="Unknown">Unknown</string>
<!--settings view--> <!--settings view-->
<string name="ResetNotificationsText">تم تعيين كافة الإشعارات افتراضيا</string> <string name="ResetNotificationsText">تم تعيين كافة الإشعارات افتراضيا</string>
<string name="TextSize">حجم نص الرسائل</string> <string name="TextSize">حجم نص الرسائل</string>

View file

@ -197,6 +197,7 @@
<string name="MessageLifetime">Selbstzerstörungs-Timer</string> <string name="MessageLifetime">Selbstzerstörungs-Timer</string>
<string name="ShortMessageLifetimeForever">Aus</string> <string name="ShortMessageLifetimeForever">Aus</string>
<string name="EncryptionKeyDescription">Das ist eine Darstellung des Schlüssels für den Geheimen Chat mit <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>.<![CDATA[<br><br>]]>Wenn dieses Bild auf <![CDATA[<b>]]>%2$s\s<![CDATA[</b>]]>s Telefon genau so aussieht, ist euer Chat zu 200%% sicher.<![CDATA[<br><br>]]>Erfahre mehr auf telegram.org</string> <string name="EncryptionKeyDescription">Das ist eine Darstellung des Schlüssels für den Geheimen Chat mit <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>.<![CDATA[<br><br>]]>Wenn dieses Bild auf <![CDATA[<b>]]>%2$s\s<![CDATA[</b>]]>s Telefon genau so aussieht, ist euer Chat zu 200%% sicher.<![CDATA[<br><br>]]>Erfahre mehr auf telegram.org</string>
<string name="Unknown">Unknown</string>
<!--settings view--> <!--settings view-->
<string name="ResetNotificationsText">Alle Einstellungen für Mitteilungen zurücksetzen</string> <string name="ResetNotificationsText">Alle Einstellungen für Mitteilungen zurücksetzen</string>
<string name="TextSize">Textgröße für Nachrichten</string> <string name="TextSize">Textgröße für Nachrichten</string>

View file

@ -197,6 +197,7 @@
<string name="MessageLifetime">Autodestrucción</string> <string name="MessageLifetime">Autodestrucción</string>
<string name="ShortMessageLifetimeForever">Apagada</string> <string name="ShortMessageLifetimeForever">Apagada</string>
<string name="EncryptionKeyDescription">Esta imagen es una visualización de la clave de cifrado para el chat secreto con <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>.<![CDATA[<br><br>]]>Si esta imagen se ve igual en el teléfono de <![CDATA[<b>]]>%2$s<![CDATA[</b>]]>, tu chat es seguro en un 200%%.<![CDATA[<br><br>]]>Aprende más en telegram.org</string> <string name="EncryptionKeyDescription">Esta imagen es una visualización de la clave de cifrado para el chat secreto con <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>.<![CDATA[<br><br>]]>Si esta imagen se ve igual en el teléfono de <![CDATA[<b>]]>%2$s<![CDATA[</b>]]>, tu chat es seguro en un 200%%.<![CDATA[<br><br>]]>Aprende más en telegram.org</string>
<string name="Unknown">Unknown</string>
<!--settings view--> <!--settings view-->
<string name="ResetNotificationsText">Restablecer las notificaciones</string> <string name="ResetNotificationsText">Restablecer las notificaciones</string>
<string name="TextSize">Tamaño del texto</string> <string name="TextSize">Tamaño del texto</string>

View file

@ -197,6 +197,7 @@
<string name="MessageLifetime">Timer di autodistruzione</string> <string name="MessageLifetime">Timer di autodistruzione</string>
<string name="ShortMessageLifetimeForever">Spento</string> <string name="ShortMessageLifetimeForever">Spento</string>
<string name="EncryptionKeyDescription">Questa immagine è una visualizzazione della chiave di cifratura per questa chat segreta con <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>.<![CDATA[<br><br>]]>Se questa immagine è uguale sul telefono di <![CDATA[<b>]]>%2$s<![CDATA[</b>]]>, la chat è sicura al 200%%.<![CDATA[<br><br>]]>Per saperne di più, visita Telegram.org</string> <string name="EncryptionKeyDescription">Questa immagine è una visualizzazione della chiave di cifratura per questa chat segreta con <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>.<![CDATA[<br><br>]]>Se questa immagine è uguale sul telefono di <![CDATA[<b>]]>%2$s<![CDATA[</b>]]>, la chat è sicura al 200%%.<![CDATA[<br><br>]]>Per saperne di più, visita Telegram.org</string>
<string name="Unknown">Unknown</string>
<!--settings view--> <!--settings view-->
<string name="ResetNotificationsText">Ripristina tutte le impostazioni di notifica predefinite</string> <string name="ResetNotificationsText">Ripristina tutte le impostazioni di notifica predefinite</string>
<string name="TextSize">Dimensione testo messaggi</string> <string name="TextSize">Dimensione testo messaggi</string>

View file

@ -197,6 +197,7 @@
<string name="MessageLifetime">자동삭제 타이머</string> <string name="MessageLifetime">자동삭제 타이머</string>
<string name="ShortMessageLifetimeForever">해제</string> <string name="ShortMessageLifetimeForever">해제</string>
<string name="EncryptionKeyDescription">이 이미지는 <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>님과의 비밀대화에 사용 중인 암호화 키의 모습입니다.<![CDATA[<br><br>]]>이 이미지가 <![CDATA[<b>]]>%2$s<![CDATA[</b>]]>님의 암호화 키와 똑같다면 대화는 200%% 안전합니다.<![CDATA[<br><br>]]>더 자세한 사항은 telegram.org 를 참고해 주세요.</string> <string name="EncryptionKeyDescription">이 이미지는 <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>님과의 비밀대화에 사용 중인 암호화 키의 모습입니다.<![CDATA[<br><br>]]>이 이미지가 <![CDATA[<b>]]>%2$s<![CDATA[</b>]]>님의 암호화 키와 똑같다면 대화는 200%% 안전합니다.<![CDATA[<br><br>]]>더 자세한 사항은 telegram.org 를 참고해 주세요.</string>
<string name="Unknown">Unknown</string>
<!--settings view--> <!--settings view-->
<string name="ResetNotificationsText">모든 알림 설정이 초기화되었습니다</string> <string name="ResetNotificationsText">모든 알림 설정이 초기화되었습니다</string>
<string name="TextSize">채팅 글자 크기</string> <string name="TextSize">채팅 글자 크기</string>

View file

@ -197,6 +197,7 @@
<string name="MessageLifetime">Zelfvernietigingstimer</string> <string name="MessageLifetime">Zelfvernietigingstimer</string>
<string name="ShortMessageLifetimeForever">Uit</string> <string name="ShortMessageLifetimeForever">Uit</string>
<string name="EncryptionKeyDescription">Dit is een weergave van de encryptiesleutel voor deze geheime chat met <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>.<![CDATA[<br><br>]]>Als deze afbeelding er bij <![CDATA[<b>]]>%2$s<![CDATA[</b>]]> hetzelfde uitziet, is jullie gesprek 200%% beveiligd.<![CDATA[<br><br>]]>Lees meer op telegram.org.</string> <string name="EncryptionKeyDescription">Dit is een weergave van de encryptiesleutel voor deze geheime chat met <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>.<![CDATA[<br><br>]]>Als deze afbeelding er bij <![CDATA[<b>]]>%2$s<![CDATA[</b>]]> hetzelfde uitziet, is jullie gesprek 200%% beveiligd.<![CDATA[<br><br>]]>Lees meer op telegram.org.</string>
<string name="Unknown">Unknown</string>
<!--settings view--> <!--settings view-->
<string name="ResetNotificationsText">Alle meldingsinstellingen herstellen</string> <string name="ResetNotificationsText">Alle meldingsinstellingen herstellen</string>
<string name="TextSize">Tekstgrootte berichten</string> <string name="TextSize">Tekstgrootte berichten</string>

View file

@ -197,6 +197,7 @@
<string name="MessageLifetime">Tempo de autodestruição</string> <string name="MessageLifetime">Tempo de autodestruição</string>
<string name="ShortMessageLifetimeForever">Desativado</string> <string name="ShortMessageLifetimeForever">Desativado</string>
<string name="EncryptionKeyDescription">Esta imagem é uma visualização da chave criptográfica para esta conversa secreta com <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>.<![CDATA[<br><br>]]>Se esta imagem aparecer da mesma forma no telefone de <![CDATA[<b>]]>%2$s\'s<![CDATA[</b>]]>, sua conversa é 200%% segura.<![CDATA[<br><br>]]>Saiba mais em telegram.org</string> <string name="EncryptionKeyDescription">Esta imagem é uma visualização da chave criptográfica para esta conversa secreta com <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>.<![CDATA[<br><br>]]>Se esta imagem aparecer da mesma forma no telefone de <![CDATA[<b>]]>%2$s\'s<![CDATA[</b>]]>, sua conversa é 200%% segura.<![CDATA[<br><br>]]>Saiba mais em telegram.org</string>
<string name="Unknown">Unknown</string>
<!--settings view--> <!--settings view-->
<string name="ResetNotificationsText">Restaurar todas as configurações de notificação</string> <string name="ResetNotificationsText">Restaurar todas as configurações de notificação</string>
<string name="TextSize">Tamanho do texto nas mensagens</string> <string name="TextSize">Tamanho do texto nas mensagens</string>

View file

@ -197,6 +197,7 @@
<string name="MessageLifetime">Tempo de autodestruição</string> <string name="MessageLifetime">Tempo de autodestruição</string>
<string name="ShortMessageLifetimeForever">Desativado</string> <string name="ShortMessageLifetimeForever">Desativado</string>
<string name="EncryptionKeyDescription">Esta imagem é uma visualização da chave criptográfica para esta conversa secreta com <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>.<![CDATA[<br><br>]]>Se esta imagem aparecer da mesma forma no telefone de <![CDATA[<b>]]>%2$s\'s<![CDATA[</b>]]>, sua conversa é 200%% segura.<![CDATA[<br><br>]]>Saiba mais em telegram.org</string> <string name="EncryptionKeyDescription">Esta imagem é uma visualização da chave criptográfica para esta conversa secreta com <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>.<![CDATA[<br><br>]]>Se esta imagem aparecer da mesma forma no telefone de <![CDATA[<b>]]>%2$s\'s<![CDATA[</b>]]>, sua conversa é 200%% segura.<![CDATA[<br><br>]]>Saiba mais em telegram.org</string>
<string name="Unknown">Unknown</string>
<!--settings view--> <!--settings view-->
<string name="ResetNotificationsText">Restaurar todas as configurações de notificação</string> <string name="ResetNotificationsText">Restaurar todas as configurações de notificação</string>
<string name="TextSize">Tamanho do texto nas mensagens</string> <string name="TextSize">Tamanho do texto nas mensagens</string>

View file

@ -197,6 +197,7 @@
<string name="MessageLifetime">Self-Destruct Timer</string> <string name="MessageLifetime">Self-Destruct Timer</string>
<string name="ShortMessageLifetimeForever">Off</string> <string name="ShortMessageLifetimeForever">Off</string>
<string name="EncryptionKeyDescription">This image is a visualization of the encryption key for this secret chat with <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>.<![CDATA[<br><br>]]>If this image looks the same on <![CDATA[<b>]]>%2$s\'s<![CDATA[</b>]]> phone, your chat is 200%% secure.<![CDATA[<br><br>]]>Learn more at telegram.org</string> <string name="EncryptionKeyDescription">This image is a visualization of the encryption key for this secret chat with <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>.<![CDATA[<br><br>]]>If this image looks the same on <![CDATA[<b>]]>%2$s\'s<![CDATA[</b>]]> phone, your chat is 200%% secure.<![CDATA[<br><br>]]>Learn more at telegram.org</string>
<string name="Unknown">Unknown</string>
<!--settings view--> <!--settings view-->
<string name="ResetNotificationsText">Reset all notification settings to default</string> <string name="ResetNotificationsText">Reset all notification settings to default</string>
<string name="TextSize">Messages Text Size</string> <string name="TextSize">Messages Text Size</string>