Commit ec533c5f authored by DrKLO's avatar DrKLO

Optimize files upload, gif auto play after download, crash and bug fixes

parent 51aa4141
...@@ -82,7 +82,7 @@ android { ...@@ -82,7 +82,7 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 8 minSdkVersion 8
targetSdkVersion 19 targetSdkVersion 19
versionCode 219 versionCode 220
versionName "1.4.9" versionName "1.4.10"
} }
} }
...@@ -18,38 +18,29 @@ ...@@ -18,38 +18,29 @@
package jawnae.pyronet; package jawnae.pyronet;
import org.telegram.messenger.BuffersStorage;
import org.telegram.messenger.ByteBufferDesc;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
public class ByteStream { public class ByteStream {
private final List<ByteBuffer> queue; private final ArrayList<ByteBufferDesc> queue;
public ByteStream() { public ByteStream() {
// the queue is expected to be relatively small, and iterated often. this.queue = new ArrayList<ByteBufferDesc>();
// hence removing the first element will be fast, even when using an
// ArrayList
this.queue = new ArrayList<ByteBuffer>();
} }
/** public void append(ByteBufferDesc buf) {
* Appends the ByteBuffer instance to the ByteStream. The bytes are not if (buf == null) {
* copied, so do not modify the contents of the ByteBuffer.
*/
public void append(ByteBuffer buf) {
if (buf == null)
throw new NullPointerException(); throw new NullPointerException();
}
this.queue.add(buf); this.queue.add(buf);
} }
/**
* Returns whether there are any bytes pending in this stream
*/
public boolean hasData() { public boolean hasData() {
int size = this.queue.size(); int size = this.queue.size();
for (ByteBuffer aQueue : this.queue) { for (ByteBufferDesc aQueue : this.queue) {
if (aQueue.hasRemaining()) { if (aQueue.hasRemaining()) {
return true; return true;
} }
...@@ -57,29 +48,13 @@ public class ByteStream { ...@@ -57,29 +48,13 @@ public class ByteStream {
return false; return false;
} }
public int getByteCount() {
int size = this.queue.size();
int sum = 0;
for (ByteBuffer aQueue : this.queue) {
sum += aQueue.remaining();
}
return sum;
}
/**
* Fills the specified buffer with as much bytes as possible. When N bytes
* are read, the buffer position will be increased by N
*/
public void get(ByteBuffer dst) { public void get(ByteBuffer dst) {
if (dst == null) { if (dst == null) {
throw new NullPointerException(); throw new NullPointerException();
} }
for (ByteBuffer data: this.queue) { for (ByteBufferDesc bufferDesc : this.queue) {
// data pos/lim must not be modified ByteBuffer data = bufferDesc.buffer.slice();
data = data.slice();
if (data.remaining() > dst.remaining()) { if (data.remaining() > dst.remaining()) {
data.limit(dst.remaining()); data.limit(dst.remaining());
...@@ -95,48 +70,25 @@ public class ByteStream { ...@@ -95,48 +70,25 @@ public class ByteStream {
} }
} }
/**
* Discards the specified amount of bytes from the stream.
*
* @throws PyroException
* if it failed to discard the specified number of bytes
*/
public void discard(int count) { public void discard(int count) {
int original = count; int original = count;
while (count > 0) { while (count > 0) {
// peek at the first buffer ByteBufferDesc data = this.queue.get(0);
ByteBuffer data = this.queue.get(0);
if (count < data.remaining()) { if (count < data.buffer.remaining()) {
// discarding less bytes than remaining in buffer
data.position(data.position() + count); data.position(data.position() + count);
count = 0; count = 0;
break; break;
} }
// discard the first buffer
this.queue.remove(0); this.queue.remove(0);
count -= data.remaining(); BuffersStorage.getInstance().reuseFreeBuffer(data);
count -= data.buffer.remaining();
} }
if (count != 0) { if (count != 0) {
// apparantly we cannot discard the amount of bytes throw new PyroException("discarded " + (original - count) + "/" + original + " bytes");
// the user demanded, this is a bug in other code
throw new PyroException("discarded " + (original - count) + "/"
+ original + " bytes");
}
}
public byte read() {
ByteBuffer data = this.queue.get(0);
byte result = data.get();
if (!data.hasRemaining()) {
// discard the first buffer
this.queue.remove(0);
} }
return result;
} }
} }
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
package jawnae.pyronet; package jawnae.pyronet;
import org.telegram.messenger.ByteBufferDesc;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.net.ConnectException; import java.net.ConnectException;
...@@ -167,12 +169,6 @@ public class PyroClient { ...@@ -167,12 +169,6 @@ public class PyroClient {
this.doEagerWrite = enabled; this.doEagerWrite = enabled;
} }
//
public void writeCopy(ByteBuffer data) throws PyroException {
this.write(this.selector.copy(data));
}
/** /**
* Will enqueue the bytes to send them<br> * Will enqueue the bytes to send them<br>
* 1. when the selector is ready to write, if eagerWrite is disabled * 1. when the selector is ready to write, if eagerWrite is disabled
...@@ -185,7 +181,7 @@ public class PyroClient { ...@@ -185,7 +181,7 @@ public class PyroClient {
* when shutdown() has been called. * when shutdown() has been called.
*/ */
public void write(ByteBuffer data) throws PyroException { public void write(ByteBufferDesc data) throws PyroException {
this.selector.checkThread(); this.selector.checkThread();
if (!this.key.isValid()) { if (!this.key.isValid()) {
......
...@@ -56,25 +56,6 @@ public class PyroSelector { ...@@ -56,25 +56,6 @@ public class PyroSelector {
// //
public ByteBuffer malloc(int size) {
return ByteBuffer.allocate(size);
}
public ByteBuffer malloc(byte[] array) {
ByteBuffer copy = this.malloc(array.length);
copy.put(array);
copy.flip();
return copy;
}
public ByteBuffer copy(ByteBuffer buffer) {
ByteBuffer copy = this.malloc(buffer.remaining());
copy.put(buffer);
buffer.position(buffer.position() - copy.remaining());
copy.flip();
return copy;
}
public final boolean isNetworkThread() { public final boolean isNetworkThread() {
return DO_NOT_CHECK_NETWORK_THREAD || networkThread == Thread.currentThread(); return DO_NOT_CHECK_NETWORK_THREAD || networkThread == Thread.currentThread();
} }
......
...@@ -30,6 +30,7 @@ public abstract class AbsSerializedData { ...@@ -30,6 +30,7 @@ public abstract class AbsSerializedData {
public abstract String readString(); public abstract String readString();
public abstract byte[] readByteArray(); public abstract byte[] readByteArray();
public abstract ByteBufferDesc readByteBuffer(); public abstract ByteBufferDesc readByteBuffer();
public abstract void writeByteBuffer(ByteBufferDesc buffer);
public abstract double readDouble(); public abstract double readDouble();
public abstract int length(); public abstract int length();
} }
...@@ -78,7 +78,7 @@ public class ByteBufferDesc extends AbsSerializedData { ...@@ -78,7 +78,7 @@ public class ByteBufferDesc extends AbsSerializedData {
if (!justCalc) { if (!justCalc) {
buffer.putLong(x); buffer.putLong(x);
} else { } else {
len += 4; len += 8;
} }
} catch(Exception e) { } catch(Exception e) {
FileLog.e("tmessages", "write int64 error"); FileLog.e("tmessages", "write int64 error");
...@@ -227,6 +227,54 @@ public class ByteBufferDesc extends AbsSerializedData { ...@@ -227,6 +227,54 @@ public class ByteBufferDesc extends AbsSerializedData {
} }
} }
public void writeByteBuffer(ByteBufferDesc b) {
try {
int l = b.limit();
if (l <= 253) {
if (!justCalc) {
buffer.put((byte) l);
} else {
len += 1;
}
} else {
if (!justCalc) {
buffer.put((byte) 254);
buffer.put((byte) l);
buffer.put((byte) (l >> 8));
buffer.put((byte) (l >> 16));
} else {
len += 4;
}
}
if (!justCalc) {
b.rewind();
buffer.put(b.buffer);
} else {
len += l;
}
int i = l <= 253 ? 1 : 4;
while((l + i) % 4 != 0) {
if (!justCalc) {
buffer.put((byte) 0);
} else {
len += 1;
}
i++;
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
public void writeRaw(ByteBufferDesc b) {
if (justCalc) {
len += b.limit();
} else {
b.rewind();
buffer.put(b.buffer);
}
}
public int readInt32() { public int readInt32() {
return readInt32(null); return readInt32(null);
} }
......
...@@ -125,15 +125,21 @@ public class FileUploadOperation { ...@@ -125,15 +125,21 @@ public class FileUploadOperation {
if (key != null && readed % 16 != 0) { if (key != null && readed % 16 != 0) {
toAdd += 16 - readed % 16; toAdd += 16 - readed % 16;
} }
byte[] sendBuffer = new byte[readed + toAdd]; ByteBufferDesc sendBuffer = BuffersStorage.getInstance().getFreeBuffer(readed + toAdd);
if (readed != uploadChunkSize) { if (readed != uploadChunkSize) {
isLastPart = true; isLastPart = true;
} }
System.arraycopy(readBuffer, 0, sendBuffer, 0, readed); sendBuffer.writeRaw(readBuffer, 0, readed);
sendBuffer.rewind();
if (key != null) { if (key != null) {
sendBuffer = Utilities.aesIgeEncryption(sendBuffer, key, iv, true, true, 0); for (int a = 0; a < toAdd; a++) {
sendBuffer.writeByte(0);
}
Utilities.aesIgeEncryption2(sendBuffer.buffer, key, iv, true, true, readed + toAdd);
}
if (!isBigFile) {
mdEnc.update(sendBuffer.buffer);
} }
mdEnc.update(sendBuffer, 0, readed + toAdd);
if (isBigFile) { if (isBigFile) {
TLRPC.TL_upload_saveBigFilePart req = new TLRPC.TL_upload_saveBigFilePart(); TLRPC.TL_upload_saveBigFilePart req = new TLRPC.TL_upload_saveBigFilePart();
req.file_part = currentPartNum; req.file_part = currentPartNum;
......
...@@ -179,7 +179,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti ...@@ -179,7 +179,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
byte[] transportData = messageOs.toByteArray(); byte[] transportData = messageOs.toByteArray();
datacenter.connection.sendData(transportData, false, false); datacenter.connection.sendData(transportData, null, false, false);
return transportData; return transportData;
} }
...@@ -576,11 +576,11 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti ...@@ -576,11 +576,11 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
return; return;
} }
if (reqPQMsgData != null) { if (reqPQMsgData != null) {
datacenter.connection.sendData(reqPQMsgData, false, false); datacenter.connection.sendData(reqPQMsgData, null, false, false);
} else if (reqDHMsgData != null) { } else if (reqDHMsgData != null) {
datacenter.connection.sendData(reqDHMsgData, false, false); datacenter.connection.sendData(reqDHMsgData, null, false, false);
} else if (setClientDHParamsMsgData != null) { } else if (setClientDHParamsMsgData != null) {
datacenter.connection.sendData(setClientDHParamsMsgData, false, false); datacenter.connection.sendData(setClientDHParamsMsgData, null, false, false);
} }
} }
......
...@@ -1016,8 +1016,23 @@ public class MediaController implements NotificationCenter.NotificationCenterDel ...@@ -1016,8 +1016,23 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
}); });
} }
public static void saveFile(String path, Context context, final int type, final String name) { public static void saveFile(String path, String fullPath, Context context, final int type, final String name) {
final File sourceFile = new File(Utilities.getCacheDir(), path); if (path == null && fullPath == null) {
return;
}
File file = null;
if (fullPath != null && fullPath.length() != 0) {
file = new File(fullPath);
if (!file.exists()) {
file = null;
}
}
if (file == null) {
file = new File(Utilities.getCacheDir(), path);
}
final File sourceFile = file;
if (sourceFile.exists()) { if (sourceFile.exists()) {
ProgressDialog progressDialog = null; ProgressDialog progressDialog = null;
if (context != null) { if (context != null) {
...@@ -1121,7 +1136,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel ...@@ -1121,7 +1136,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
return null; return null;
} }
if (currentGifMessageObject != null && messageObject.messageOwner.id == currentGifMessageObject.messageOwner.id) { if (currentGifDrawable != null && currentGifMessageObject != null && messageObject.messageOwner.id == currentGifMessageObject.messageOwner.id) {
currentMediaCell = cell; currentMediaCell = cell;
currentGifDrawable.parentView = new WeakReference<View>(cell); currentGifDrawable.parentView = new WeakReference<View>(cell);
return currentGifDrawable; return currentGifDrawable;
......
...@@ -34,7 +34,7 @@ public class NativeLoader { ...@@ -34,7 +34,7 @@ public class NativeLoader {
return; return;
} }
if (Build.VERSION.SDK_INT > 10) { if (Build.VERSION.SDK_INT >= 9) {
try { try {
String folder = null; String folder = null;
long libSize = 0; long libSize = 0;
......
...@@ -119,6 +119,25 @@ public class SerializedData extends AbsSerializedData { ...@@ -119,6 +119,25 @@ public class SerializedData extends AbsSerializedData {
} }
} }
public void writeByteBuffer(ByteBufferDesc buffer) {
if (!justCalc) {
//TODO ?
} else {
int l = buffer.limit();
if (l <= 253) {
len += 1;
} else {
len += 4;
}
len += l;
int i = l <= 253 ? 1 : 4;
while((l + i) % 4 != 0) {
len += 1;
i++;
}
}
}
public int readInt32() { public int readInt32() {
return readInt32(null); return readInt32(null);
} }
......
...@@ -7360,31 +7360,6 @@ public class TLRPC { ...@@ -7360,31 +7360,6 @@ public class TLRPC {
} }
} }
public static class TL_upload_saveFilePart extends TLObject {
public static int constructor = 0xb304a621;
public long file_id;
public int file_part;
public byte[] bytes;
public Class responseClass () {
return Bool.class;
}
public void readParams(AbsSerializedData stream) {
file_id = stream.readInt64();
file_part = stream.readInt32();
bytes = stream.readByteArray();
}
public void serializeToStream(AbsSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt64(file_id);
stream.writeInt32(file_part);
stream.writeByteArray(bytes);
}
}
public static class TL_upload_getFile extends TLObject { public static class TL_upload_getFile extends TLObject {
public static int constructor = 0xe3a6cfb5; public static int constructor = 0xe3a6cfb5;
...@@ -8111,34 +8086,6 @@ public class TLRPC { ...@@ -8111,34 +8086,6 @@ public class TLRPC {
} }
} }
public static class TL_upload_saveBigFilePart extends TLObject {
public static int constructor = 0xde7b673d;
public long file_id;
public int file_part;
public int file_total_parts;
public byte[] bytes;
public Class responseClass () {
return Bool.class;
}
public void readParams(AbsSerializedData stream) {
file_id = stream.readInt64();
file_part = stream.readInt32();
file_total_parts = stream.readInt32();
bytes = stream.readByteArray();
}
public void serializeToStream(AbsSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt64(file_id);
stream.writeInt32(file_part);
stream.writeInt32(file_total_parts);
stream.writeByteArray(bytes);
}
}
//manually created //manually created
public static class UserStatus extends TLObject { public static class UserStatus extends TLObject {
...@@ -9162,4 +9109,60 @@ public class TLRPC { ...@@ -9162,4 +9109,60 @@ public class TLRPC {
} }
} }
} }
public static class TL_upload_saveBigFilePart extends TLObject {
public static int constructor = 0xde7b673d;
public long file_id;
public int file_part;
public int file_total_parts;
public ByteBufferDesc bytes;
public Class responseClass () {
return Bool.class;
}
public void serializeToStream(AbsSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt64(file_id);
stream.writeInt32(file_part);
stream.writeInt32(file_total_parts);
stream.writeByteBuffer(bytes);
}
@Override
public void freeResources() {
if (bytes != null) {
BuffersStorage.getInstance().reuseFreeBuffer(bytes);
bytes = null;
}
}
}
public static class TL_upload_saveFilePart extends TLObject {
public static int constructor = 0xb304a621;
public long file_id;
public int file_part;
public ByteBufferDesc bytes;
public Class responseClass () {
return Bool.class;
}
public void serializeToStream(AbsSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt64(file_id);
stream.writeInt32(file_part);
stream.writeByteBuffer(bytes);
}
@Override
public void freeResources() {
if (bytes != null) {
BuffersStorage.getInstance().reuseFreeBuffer(bytes);
bytes = null;
}
}
}
} }
...@@ -271,7 +271,10 @@ public class TcpConnection extends PyroClientAdapter { ...@@ -271,7 +271,10 @@ public class TcpConnection extends PyroClientAdapter {
connect(); connect();
} }
public void sendData(final byte[] data, final boolean reportAck, final boolean startResponseTimeout) { public void sendData(final byte[] data, final ByteBufferDesc buff, final boolean reportAck, final boolean startResponseTimeout) {
if (data == null && buff == null) {
return;
}
selector.scheduleTask(new Runnable() { selector.scheduleTask(new Runnable() {
@Override @Override
public void run() { public void run() {
...@@ -285,9 +288,28 @@ public class TcpConnection extends PyroClientAdapter { ...@@ -285,9 +288,28 @@ public class TcpConnection extends PyroClientAdapter {
return; return;
} }
int packetLength = data.length / 4; int bufferLen = 0;
if (data != null) {
bufferLen = data.length;
} else if (buff != null) {
bufferLen = buff.limit();
}
int packetLength = bufferLen / 4;
SerializedData buffer = new SerializedData(); if (packetLength < 0x7f) {
bufferLen++;
} else {
bufferLen += 4;
}
if (firstPacket) {
bufferLen++;
}
ByteBufferDesc buffer = BuffersStorage.getInstance().getFreeBuffer(bufferLen);
if (firstPacket) {
buffer.writeByte((byte)0xef);
firstPacket = false;
}
if (packetLength < 0x7f) { if (packetLength < 0x7f) {
if (reportAck) { if (reportAck) {
packetLength |= (1 << 7); packetLength |= (1 << 7);
...@@ -300,20 +322,16 @@ public class TcpConnection extends PyroClientAdapter { ...@@ -300,20 +322,16 @@ public class TcpConnection extends PyroClientAdapter {
} }
buffer.writeInt32(packetLength); buffer.writeInt32(packetLength);
} }
buffer.writeRaw(data); if (data != null) {
buffer.writeRaw(data);
} else {
buffer.writeRaw(buff);
BuffersStorage.getInstance().reuseFreeBuffer(buff);
}
final byte[] packet = buffer.toByteArray(); buffer.rewind();
ByteBuffer sendBuffer = ByteBuffer.allocate((firstPacket ? 1 : 0) + packet.length); client.write(buffer);
sendBuffer.rewind();
sendBuffer.order(ByteOrder.LITTLE_ENDIAN);
if (firstPacket) {
sendBuffer.put((byte)0xef);
firstPacket = false;
}
sendBuffer.put(packet);
sendBuffer.rewind();
client.write(sendBuffer);
} }
}); });
} }
......
...@@ -77,7 +77,7 @@ public class MessageObject { ...@@ -77,7 +77,7 @@ public class MessageObject {
fromUser = MessagesController.getInstance().users.get(message.from_id); fromUser = MessagesController.getInstance().users.get(message.from_id);
} }
if (message.action instanceof TLRPC.TL_messageActionChatCreate) { if (message.action instanceof TLRPC.TL_messageActionChatCreate) {
if (message.from_id == UserConfig.clientUserId) { if (isFromMe()) {
messageText = LocaleController.getString("ActionYouCreateGroup", R.string.ActionYouCreateGroup); messageText = LocaleController.getString("ActionYouCreateGroup", R.string.ActionYouCreateGroup);
} else { } else {
if (fromUser != null) { if (fromUser != null) {
...@@ -88,7 +88,7 @@ public class MessageObject { ...@@ -88,7 +88,7 @@ public class MessageObject {
} }
} else if (message.action instanceof TLRPC.TL_messageActionChatDeleteUser) { } else if (message.action instanceof TLRPC.TL_messageActionChatDeleteUser) {
if (message.action.user_id == message.from_id) { if (message.action.user_id == message.from_id) {
if (message.from_id == UserConfig.clientUserId) { if (isFromMe()) {
messageText = LocaleController.getString("ActionYouLeftUser", R.string.ActionYouLeftUser); messageText = LocaleController.getString("ActionYouLeftUser", R.string.ActionYouLeftUser);
} else { } else {
if (fromUser != null) { if (fromUser != null) {
...@@ -103,7 +103,7 @@ public class MessageObject { ...@@ -103,7 +103,7 @@ public class MessageObject {
MessagesController.getInstance().users.get(message.action.user_id); MessagesController.getInstance().users.get(message.action.user_id);
} }
if (who != null && fromUser != null) { if (who != null && fromUser != null) {
if (message.from_id == UserConfig.clientUserId) { if (isFromMe()) {
messageText = LocaleController.getString("ActionYouKickUser", R.string.ActionYouKickUser).replace("un2", Utilities.formatName(who.first_name, who.last_name)); messageText = LocaleController.getString("ActionYouKickUser", R.string.ActionYouKickUser).replace("un2", Utilities.formatName(who.first_name, who.last_name));
} else if (message.action.user_id == UserConfig.clientUserId) { } else if (message.action.user_id == UserConfig.clientUserId) {
messageText = LocaleController.getString("ActionKickUserYou", R.string.ActionKickUserYou).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); messageText = LocaleController.getString("ActionKickUserYou", R.string.ActionKickUserYou).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name));
...@@ -120,7 +120,7 @@ public class MessageObject { ...@@ -120,7 +120,7 @@ public class MessageObject {
MessagesController.getInstance().users.get(message.action.user_id); MessagesController.getInstance().users.get(message.action.user_id);
} }
if (whoUser != null && fromUser != null) { if (whoUser != null && fromUser != null) {
if (message.from_id == UserConfig.clientUserId) { if (isFromMe()) {
messageText = LocaleController.getString("ActionYouAddUser", R.string.ActionYouAddUser).replace("un2", Utilities.formatName(whoUser.first_name, whoUser.last_name)); messageText = LocaleController.getString("ActionYouAddUser", R.string.ActionYouAddUser).replace("un2", Utilities.formatName(whoUser.first_name, whoUser.last_name));
} else if (message.action.user_id == UserConfig.clientUserId) { } else if (message.action.user_id == UserConfig.clientUserId) {
messageText = LocaleController.getString("ActionAddUserYou", R.string.ActionAddUserYou).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name)); messageText = LocaleController.getString("ActionAddUserYou", R.string.ActionAddUserYou).replace("un1", Utilities.formatName(fromUser.first_name, fromUser.last_name));
...@@ -135,7 +135,7 @@ public class MessageObject { ...@@ -135,7 +135,7 @@ public class MessageObject {
for (TLRPC.PhotoSize size : message.action.photo.sizes) { for (TLRPC.PhotoSize size : message.action.photo.sizes) {
photoThumbs.add(new PhotoObject(size)); photoThumbs.add(new PhotoObject(size));
} }
if (message.from_id == UserConfig.clientUserId) { if (isFromMe()) {
messageText = LocaleController.getString("ActionYouChangedPhoto", R.string.ActionYouChangedPhoto); messageText = LocaleController.getString("ActionYouChangedPhoto", R.string.ActionYouChangedPhoto);
} else { } else {
if (fromUser != null) { if (fromUser != null) {
...@@ -145,7 +145,7 @@ public class MessageObject { ...@@ -145,7 +145,7 @@ public class MessageObject {
} }
} }
} else if (message.action instanceof TLRPC.TL_messageActionChatEditTitle) { } else if (message.action instanceof TLRPC.TL_messageActionChatEditTitle) {
if (message.from_id == UserConfig.clientUserId) { if (isFromMe()) {
messageText = LocaleController.getString("ActionYouChangedTitle", R.string.ActionYouChangedTitle).replace("un2", message.action.title); messageText = LocaleController.getString("ActionYouChangedTitle", R.string.ActionYouChangedTitle).replace("un2", message.action.title);
} else { } else {
if (fromUser != null) { if (fromUser != null) {
...@@ -155,7 +155,7 @@ public class MessageObject { ...@@ -155,7 +155,7 @@ public class MessageObject {
} }
} }
} else if (message.action instanceof TLRPC.TL_messageActionChatDeletePhoto) { } else if (message.action instanceof TLRPC.TL_messageActionChatDeletePhoto) {
if (message.from_id == UserConfig.clientUserId) { if (isFromMe()) {
messageText = LocaleController.getString("ActionYouRemovedPhoto", R.string.ActionYouRemovedPhoto); messageText = LocaleController.getString("ActionYouRemovedPhoto", R.string.ActionYouRemovedPhoto);
} else { } else {
if (fromUser != null) { if (fromUser != null) {
...@@ -182,7 +182,7 @@ public class MessageObject { ...@@ -182,7 +182,7 @@ public class MessageObject {
} else { } else {
timeString = String.format("%d", message.action.ttl); timeString = String.format("%d", message.action.ttl);
} }
if (message.from_id == UserConfig.clientUserId) { if (isFromMe()) {
messageText = LocaleController.formatString("MessageLifetimeChangedOutgoing", R.string.MessageLifetimeChangedOutgoing, timeString); messageText = LocaleController.formatString("MessageLifetimeChangedOutgoing", R.string.MessageLifetimeChangedOutgoing, timeString);
} else { } else {
if (fromUser != null) { if (fromUser != null) {
...@@ -192,7 +192,7 @@ public class MessageObject { ...@@ -192,7 +192,7 @@ public class MessageObject {
} }
} }
} else { } else {
if (message.from_id == UserConfig.clientUserId) { if (isFromMe()) {
messageText = LocaleController.getString("MessageLifetimeYouRemoved", R.string.MessageLifetimeYouRemoved); messageText = LocaleController.getString("MessageLifetimeYouRemoved", R.string.MessageLifetimeYouRemoved);
} else { } else {
if (fromUser != null) { if (fromUser != null) {
...@@ -265,22 +265,18 @@ public class MessageObject { ...@@ -265,22 +265,18 @@ public class MessageObject {
} else if (message.media != null && message.media instanceof TLRPC.TL_messageMediaPhoto) { } else if (message.media != null && message.media instanceof TLRPC.TL_messageMediaPhoto) {
contentType = type = 1; contentType = type = 1;
} else if (message.media != null && message.media instanceof TLRPC.TL_messageMediaGeo) { } else if (message.media != null && message.media instanceof TLRPC.TL_messageMediaGeo) {
if (message.from_id == UserConfig.clientUserId) { contentType = 1;
contentType = type = 4; type = 4;
} else {
contentType = type = 5;
}
} else if (message.media != null && message.media instanceof TLRPC.TL_messageMediaVideo) { } else if (message.media != null && message.media instanceof TLRPC.TL_messageMediaVideo) {
if (message.from_id == UserConfig.clientUserId) { contentType = 1;
contentType = type = 6; type = 3;
} else {
contentType = type = 7;
}
} else if (message.media != null && message.media instanceof TLRPC.TL_messageMediaContact) { } else if (message.media != null && message.media instanceof TLRPC.TL_messageMediaContact) {
if (message.from_id == UserConfig.clientUserId) { if (isFromMe()) {
contentType = type = 12; contentType = 4;
type = 12;
} else { } else {
contentType = type = 13; contentType = 5;
type = 13;
} }
} else if (message.media != null && message.media instanceof TLRPC.TL_messageMediaUnsupported) { } else if (message.media != null && message.media instanceof TLRPC.TL_messageMediaUnsupported) {
contentType = type = 0; contentType = type = 0;
...@@ -289,7 +285,7 @@ public class MessageObject { ...@@ -289,7 +285,7 @@ public class MessageObject {
contentType = 1; contentType = 1;
type = 8; type = 8;
} else { } else {
if (message.from_id == UserConfig.clientUserId) { if (isFromMe()) {
contentType = type = 8; contentType = type = 8;
} else { } else {
contentType = type = 9; contentType = type = 9;
...@@ -525,4 +521,12 @@ public class MessageObject { ...@@ -525,4 +521,12 @@ public class MessageObject {
linesOffset += currentBlockLinesCount; linesOffset += currentBlockLinesCount;
} }
} }
public boolean isOut() {
return messageOwner.out;
}
public boolean isFromMe() {
return messageOwner.from_id == UserConfig.clientUserId;
}
} }
...@@ -37,6 +37,9 @@ public class PhotoObject { ...@@ -37,6 +37,9 @@ public class PhotoObject {
} }
public static PhotoObject getClosestImageWithSize(ArrayList<PhotoObject> arr, int width, int height) { public static PhotoObject getClosestImageWithSize(ArrayList<PhotoObject> arr, int width, int height) {
if (arr == null) {
return null;
}
int closestWidth = 9999; int closestWidth = 9999;
int closestHeight = 9999; int closestHeight = 9999;
PhotoObject closestObject = null; PhotoObject closestObject = null;
...@@ -56,6 +59,9 @@ public class PhotoObject { ...@@ -56,6 +59,9 @@ public class PhotoObject {
} }
public static TLRPC.PhotoSize getClosestPhotoSizeWithSize(ArrayList<TLRPC.PhotoSize> sizes, int width, int height) { public static TLRPC.PhotoSize getClosestPhotoSizeWithSize(ArrayList<TLRPC.PhotoSize> sizes, int width, int height) {
if (sizes == null) {
return null;
}
int closestWidth = 9999; int closestWidth = 9999;
int closestHeight = 9999; int closestHeight = 9999;
TLRPC.PhotoSize closestObject = null; TLRPC.PhotoSize closestObject = null;
......
...@@ -298,7 +298,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega ...@@ -298,7 +298,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
protected void onLayout(boolean changed, int left, int top, int right, int bottom) { protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom); super.onLayout(changed, left, top, right, bottom);
if (currentMessageObject.messageOwner.out) { if (currentMessageObject.isOut()) {
avatarImage.imageX = layoutWidth - backgroundWidth + Utilities.dp(9); avatarImage.imageX = layoutWidth - backgroundWidth + Utilities.dp(9);
seekBarX = layoutWidth - backgroundWidth + Utilities.dp(97); seekBarX = layoutWidth - backgroundWidth + Utilities.dp(97);
buttonX = layoutWidth - backgroundWidth + Utilities.dp(67); buttonX = layoutWidth - backgroundWidth + Utilities.dp(67);
...@@ -359,7 +359,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega ...@@ -359,7 +359,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
avatarImage.setImage((TLRPC.FileLocation)null, "50_50", getResources().getDrawable(Utilities.getUserAvatarForId(uid))); avatarImage.setImage((TLRPC.FileLocation)null, "50_50", getResources().getDrawable(Utilities.getUserAvatarForId(uid)));
} }
if (messageObject.messageOwner.out) { if (messageObject.isOut()) {
seekBar.type = 0; seekBar.type = 0;
progressView.setProgressColors(0xffb4e396, 0xff6ac453); progressView.setProgressColors(0xffb4e396, 0xff6ac453);
} else { } else {
...@@ -393,7 +393,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega ...@@ -393,7 +393,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
canvas.restore(); canvas.restore();
int state = buttonState; int state = buttonState;
if (!currentMessageObject.messageOwner.out) { if (!currentMessageObject.isOut()) {
state += 4; state += 4;
timePaint.setColor(0xffa1aab3); timePaint.setColor(0xffa1aab3);
} else { } else {
......
...@@ -38,7 +38,7 @@ public class ChatBaseCell extends BaseCell { ...@@ -38,7 +38,7 @@ public class ChatBaseCell extends BaseCell {
public static interface ChatBaseCellDelegate { public static interface ChatBaseCellDelegate {
public abstract void didPressedUserAvatar(ChatBaseCell cell, TLRPC.User user); public abstract void didPressedUserAvatar(ChatBaseCell cell, TLRPC.User user);
public abstract void didPressedCanceSendButton(ChatBaseCell cell); public abstract void didPressedCancelSendButton(ChatBaseCell cell);
public abstract void didLongPressed(ChatBaseCell cell); public abstract void didLongPressed(ChatBaseCell cell);
public abstract boolean canPerformActions(); public abstract boolean canPerformActions();
public boolean onSwipeLeft(); public boolean onSwipeLeft();
...@@ -246,7 +246,7 @@ public class ChatBaseCell extends BaseCell { ...@@ -246,7 +246,7 @@ public class ChatBaseCell extends BaseCell {
} }
String newNameString = null; String newNameString = null;
if (drawName && isChat && newUser != null && !currentMessageObject.messageOwner.out) { if (drawName && isChat && newUser != null && !currentMessageObject.isOut()) {
newNameString = Utilities.formatName(newUser.first_name, newUser.last_name); newNameString = Utilities.formatName(newUser.first_name, newUser.last_name);
} }
...@@ -276,7 +276,7 @@ public class ChatBaseCell extends BaseCell { ...@@ -276,7 +276,7 @@ public class ChatBaseCell extends BaseCell {
} }
currentUser = MessagesController.getInstance().users.get(messageObject.messageOwner.from_id); currentUser = MessagesController.getInstance().users.get(messageObject.messageOwner.from_id);
if (isChat && !messageObject.messageOwner.out) { if (isChat && !messageObject.isOut()) {
isAvatarVisible = true; isAvatarVisible = true;
if (currentUser != null) { if (currentUser != null) {
if (currentUser.photo != null) { if (currentUser.photo != null) {
...@@ -289,7 +289,7 @@ public class ChatBaseCell extends BaseCell { ...@@ -289,7 +289,7 @@ public class ChatBaseCell extends BaseCell {
} }
if (!media) { if (!media) {
if (currentMessageObject.messageOwner.out) { if (currentMessageObject.isOut()) {
currentTimePaint = timePaintOut; currentTimePaint = timePaintOut;
} else { } else {
currentTimePaint = timePaintIn; currentTimePaint = timePaintIn;
...@@ -303,7 +303,7 @@ public class ChatBaseCell extends BaseCell { ...@@ -303,7 +303,7 @@ public class ChatBaseCell extends BaseCell {
namesOffset = 0; namesOffset = 0;
if (drawName && isChat && currentUser != null && !currentMessageObject.messageOwner.out) { if (drawName && isChat && currentUser != null && !currentMessageObject.isOut()) {
currentNameString = Utilities.formatName(currentUser.first_name, currentUser.last_name); currentNameString = Utilities.formatName(currentUser.first_name, currentUser.last_name);
nameWidth = getMaxNameWidth(); nameWidth = getMaxNameWidth();
...@@ -457,13 +457,13 @@ public class ChatBaseCell extends BaseCell { ...@@ -457,13 +457,13 @@ public class ChatBaseCell extends BaseCell {
timeLayout = new StaticLayout(currentTimeString, currentTimePaint, timeWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); timeLayout = new StaticLayout(currentTimeString, currentTimePaint, timeWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
if (!media) { if (!media) {
if (!currentMessageObject.messageOwner.out) { if (!currentMessageObject.isOut()) {
timeX = backgroundWidth - Utilities.dp(9) - timeWidth + (isChat ? Utilities.dp(52) : 0); timeX = backgroundWidth - Utilities.dp(9) - timeWidth + (isChat ? Utilities.dp(52) : 0);
} else { } else {
timeX = layoutWidth - timeWidth - Utilities.dpf(38.5f); timeX = layoutWidth - timeWidth - Utilities.dpf(38.5f);
} }
} else { } else {
if (!currentMessageObject.messageOwner.out) { if (!currentMessageObject.isOut()) {
timeX = backgroundWidth - Utilities.dp(4) - timeWidth + (isChat ? Utilities.dp(52) : 0); timeX = backgroundWidth - Utilities.dp(4) - timeWidth + (isChat ? Utilities.dp(52) : 0);
} else { } else {
timeX = layoutWidth - timeWidth - Utilities.dpf(42.0f); timeX = layoutWidth - timeWidth - Utilities.dpf(42.0f);
...@@ -502,7 +502,7 @@ public class ChatBaseCell extends BaseCell { ...@@ -502,7 +502,7 @@ public class ChatBaseCell extends BaseCell {
} }
Drawable currentBackgroundDrawable = null; Drawable currentBackgroundDrawable = null;
if (currentMessageObject.messageOwner.out) { if (currentMessageObject.isOut()) {
if (isPressed() && isCheckPressed || !isCheckPressed && isPressed) { if (isPressed() && isCheckPressed || !isCheckPressed && isPressed) {
if (!media) { if (!media) {
currentBackgroundDrawable = backgroundDrawableOutSelected; currentBackgroundDrawable = backgroundDrawableOutSelected;
...@@ -551,7 +551,7 @@ public class ChatBaseCell extends BaseCell { ...@@ -551,7 +551,7 @@ public class ChatBaseCell extends BaseCell {
if (drawForwardedName && forwardedNameLayout != null) { if (drawForwardedName && forwardedNameLayout != null) {
canvas.save(); canvas.save();
if (currentMessageObject.messageOwner.out) { if (currentMessageObject.isOut()) {
forwardNamePaint.setColor(0xff4a923c); forwardNamePaint.setColor(0xff4a923c);
forwardNameX = currentBackgroundDrawable.getBounds().left + Utilities.dp(10); forwardNameX = currentBackgroundDrawable.getBounds().left + Utilities.dp(10);
forwardNameY = Utilities.dp(10 + (drawName ? 18 : 0)); forwardNameY = Utilities.dp(10 + (drawName ? 18 : 0));
...@@ -566,7 +566,7 @@ public class ChatBaseCell extends BaseCell { ...@@ -566,7 +566,7 @@ public class ChatBaseCell extends BaseCell {
} }
if (media) { if (media) {
setDrawableBounds(mediaBackgroundDrawable, timeX - Utilities.dp(3), layoutHeight - Utilities.dpf(27.5f), timeWidth + Utilities.dp(6 + (currentMessageObject.messageOwner.out ? 20 : 0)), Utilities.dpf(16.5f)); setDrawableBounds(mediaBackgroundDrawable, timeX - Utilities.dp(3), layoutHeight - Utilities.dpf(27.5f), timeWidth + Utilities.dp(6 + (currentMessageObject.isOut() ? 20 : 0)), Utilities.dpf(16.5f));
mediaBackgroundDrawable.draw(canvas); mediaBackgroundDrawable.draw(canvas);
canvas.save(); canvas.save();
...@@ -580,7 +580,7 @@ public class ChatBaseCell extends BaseCell { ...@@ -580,7 +580,7 @@ public class ChatBaseCell extends BaseCell {
canvas.restore(); canvas.restore();
} }
if (currentMessageObject.messageOwner.out) { if (currentMessageObject.isOut()) {
boolean drawCheck1 = false; boolean drawCheck1 = false;
boolean drawCheck2 = false; boolean drawCheck2 = false;
boolean drawClock = false; boolean drawClock = false;
......
...@@ -131,7 +131,7 @@ public class ChatMessageCell extends ChatBaseCell { ...@@ -131,7 +131,7 @@ public class ChatMessageCell extends ChatBaseCell {
} }
pressedLink = null; pressedLink = null;
int maxWidth; int maxWidth;
if (isChat && !messageObject.messageOwner.out) { if (isChat && !messageObject.isOut()) {
maxWidth = Utilities.displaySize.x - Utilities.dp(122); maxWidth = Utilities.displaySize.x - Utilities.dp(122);
drawName = true; drawName = true;
} else { } else {
...@@ -149,7 +149,7 @@ public class ChatMessageCell extends ChatBaseCell { ...@@ -149,7 +149,7 @@ public class ChatMessageCell extends ChatBaseCell {
maxChildWidth = Math.max(maxChildWidth, forwardedNameWidth); maxChildWidth = Math.max(maxChildWidth, forwardedNameWidth);
int timeMore = timeWidth + Utilities.dp(6); int timeMore = timeWidth + Utilities.dp(6);
if (messageObject.messageOwner.out) { if (messageObject.isOut()) {
timeMore += Utilities.dpf(20.5f); timeMore += Utilities.dpf(20.5f);
} }
...@@ -176,7 +176,7 @@ public class ChatMessageCell extends ChatBaseCell { ...@@ -176,7 +176,7 @@ public class ChatMessageCell extends ChatBaseCell {
protected void onLayout(boolean changed, int left, int top, int right, int bottom) { protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom); super.onLayout(changed, left, top, right, bottom);
if (currentMessageObject.messageOwner.out) { if (currentMessageObject.isOut()) {
textX = layoutWidth - backgroundWidth + Utilities.dp(10); textX = layoutWidth - backgroundWidth + Utilities.dp(10);
textY = Utilities.dp(10) + namesOffset; textY = Utilities.dp(10) + namesOffset;
} else { } else {
...@@ -192,7 +192,7 @@ public class ChatMessageCell extends ChatBaseCell { ...@@ -192,7 +192,7 @@ public class ChatMessageCell extends ChatBaseCell {
return; return;
} }
if (currentMessageObject.messageOwner.out) { if (currentMessageObject.isOut()) {
textX = layoutWidth - backgroundWidth + Utilities.dp(10); textX = layoutWidth - backgroundWidth + Utilities.dp(10);
textY = Utilities.dp(10) + namesOffset; textY = Utilities.dp(10) + namesOffset;
} else { } else {
......
...@@ -465,7 +465,7 @@ public class DialogCell extends BaseCell { ...@@ -465,7 +465,7 @@ public class DialogCell extends BaseCell {
} else { } else {
if (chat != null) { if (chat != null) {
String name = ""; String name = "";
if (message.messageOwner.from_id == UserConfig.clientUserId) { if (message.isFromMe()) {
name = LocaleController.getString("FromYou", R.string.FromYou); name = LocaleController.getString("FromYou", R.string.FromYou);
} else { } else {
if (fromUser != null) { if (fromUser != null) {
...@@ -507,7 +507,7 @@ public class DialogCell extends BaseCell { ...@@ -507,7 +507,7 @@ public class DialogCell extends BaseCell {
} }
} }
if (message.messageOwner.from_id == UserConfig.clientUserId) { if (message.isFromMe()) {
if (message.messageOwner.send_state == MessagesController.MESSAGE_SEND_STATE_SENDING) { if (message.messageOwner.send_state == MessagesController.MESSAGE_SEND_STATE_SENDING) {
drawCheck1 = false; drawCheck1 = false;
drawCheck2 = false; drawCheck2 = false;
......
...@@ -726,9 +726,9 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif ...@@ -726,9 +726,9 @@ public class GalleryImageViewer extends AbstractGalleryActivity implements Notif
return; return;
} }
if (isVideo) { if (isVideo) {
MediaController.saveFile(currentFileName, this, 1, null); MediaController.saveFile(currentFileName, null, this, 1, null);
} else { } else {
MediaController.saveFile(currentFileName, this, 0, null); MediaController.saveFile(currentFileName, null, this, 0, null);
} }
break; break;
// case R.id.gallery_menu_send: { // case R.id.gallery_menu_send: {
......
...@@ -182,7 +182,7 @@ public class PhotoCropActivity extends BaseFragment { ...@@ -182,7 +182,7 @@ public class PhotoCropActivity extends BaseFragment {
} }
private void updateBitmapSize() { private void updateBitmapSize() {
if (viewWidth == 0 || viewHeight == 0) { if (viewWidth == 0 || viewHeight == 0 || imageToCrop == null) {
return; return;
} }
float percX = (rectX - bitmapX) / bitmapWidth; float percX = (rectX - bitmapX) / bitmapWidth;
......
...@@ -21,10 +21,12 @@ import android.os.Bundle; ...@@ -21,10 +21,12 @@ import android.os.Bundle;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity; import android.support.v7.app.ActionBarActivity;
import android.text.Html; import android.text.Html;
import android.text.Spannable;
import android.text.method.LinkMovementMethod; import android.text.method.LinkMovementMethod;
import android.util.Base64; import android.util.Base64;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.AdapterView; import android.widget.AdapterView;
...@@ -93,6 +95,18 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter ...@@ -93,6 +95,18 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter
private int telegramFaqRow; private int telegramFaqRow;
private int languageRow; private int languageRow;
private static class LinkMovementMethodMy extends LinkMovementMethod {
@Override
public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
try {
return super.onTouchEvent(widget, buffer, event);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
return false;
}
}
@Override @Override
public boolean onFragmentCreate() { public boolean onFragmentCreate() {
super.onFragmentCreate(); super.onFragmentCreate();
...@@ -252,7 +266,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter ...@@ -252,7 +266,7 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter
message.setText(Html.fromHtml(LocaleController.getString("AskAQuestionInfo", R.string.AskAQuestionInfo))); message.setText(Html.fromHtml(LocaleController.getString("AskAQuestionInfo", R.string.AskAQuestionInfo)));
message.setTextSize(18); message.setTextSize(18);
message.setPadding(Utilities.dp(8), Utilities.dp(5), Utilities.dp(8), Utilities.dp(6)); message.setPadding(Utilities.dp(8), Utilities.dp(5), Utilities.dp(8), Utilities.dp(6));
message.setMovementMethod(LinkMovementMethod.getInstance()); message.setMovementMethod(new LinkMovementMethodMy());
AlertDialog.Builder builder = new AlertDialog.Builder(parentActivity); AlertDialog.Builder builder = new AlertDialog.Builder(parentActivity);
builder.setView(message); builder.setView(message);
...@@ -642,6 +656,9 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter ...@@ -642,6 +656,9 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter
button2.setOnClickListener(new View.OnClickListener() { button2.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View view) { public void onClick(View view) {
if (parentActivity == null) {
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(parentActivity); AlertDialog.Builder builder = new AlertDialog.Builder(parentActivity);
......
<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:drawable="@drawable/msg_in_photo_selected" />
<item android:state_checked="true" android:drawable="@drawable/msg_in_photo_selected" />
<item android:state_pressed="true" android:drawable="@drawable/msg_in_photo_selected" />
<item android:drawable="@drawable/msg_in_photo" />
</selector>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:drawable="@drawable/msg_out_photo_selected" />
<item android:state_checked="true" android:drawable="@drawable/msg_out_photo_selected" />
<item android:state_pressed="true" android:drawable="@drawable/msg_out_photo_selected" />
<item android:drawable="@drawable/msg_out_photo"/>
</selector>
\ No newline at end of file
<?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:scaleType="fitCenter"
android:layout_marginBottom="2dp"
android:layout_gravity="bottom"/>
<org.telegram.ui.Views.FrameLayoutFixed
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="13dp"
android:layout_gravity="top"
android:id="@+id/chat_bubble_layout"
android:addStatesFromChildren="true">
<org.telegram.ui.Views.BackupImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_margin="6dp"
android:layout_gravity="top"
android:scaleType="centerCrop"
android:minHeight="100dp"
android:minWidth="100dp"
android:id="@+id/chat_photo_image"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="16dp"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_gravity="top"
android:background="@drawable/phototime"
android:orientation="horizontal"
android:gravity="center_vertical">
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/ic_video"/>
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textColor="#ffffff"
android:textSize="12dp"
android:layout_marginLeft="4dp"
android:gravity="center_vertical"
android:layout_gravity="center_vertical"
android:layout_marginBottom="1dp"
android:id="@+id/chat_video_time"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="16dp"
android:id="@+id/chat_time_layout"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
android:layout_gravity="right|bottom"
android:background="@drawable/phototime">
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textColor="#ffffff"
android:textSize="12dp"
android:layout_gravity="bottom"
android:layout_marginBottom="1dp"
android:id="@+id/chat_time_text"/>
</LinearLayout>
</org.telegram.ui.Views.FrameLayoutFixed>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#54759e"
android:background="@drawable/chat_incoming_media_states"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:id="@+id/chat_view_action_button"
android:textSize="14dp"
android:layout_gravity="center"
android:descendantFocusability="blocksDescendants"
android:clickable="true"
android:gravity="center"
android:textStyle="bold"
android:layout_marginLeft="10dp"
android:visibility="gone"/>
<org.telegram.ui.Views.FrameLayoutFixed
android:layout_height="wrap_content"
android:layout_width="140dp"
android:layout_marginLeft="10dp"
android:layout_gravity="center_vertical"
android:id="@+id/chat_view_action_layout"
android:visibility="gone">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:scaleType="centerInside"
android:layout_marginRight="4dp"
android:layout_gravity="right|center"
android:id="@+id/chat_view_action_cancel_button"
android:src="@drawable/ic_msg_btn_cross_custom"
android:clickable="true"/>
<ProgressBar
android:layout_width="fill_parent"
android:layout_height="3dp"
android:layout_gravity="left|center_vertical"
android:progressDrawable="@drawable/progress_chat"
style="?android:attr/progressBarStyleHorizontal"
android:progress="50"
android:layout_marginLeft="12dp"
android:layout_marginRight="36dp"
android:id="@+id/chat_view_action_progress"
android:max="100"/>
</org.telegram.ui.Views.FrameLayoutFixed>
</LinearLayout>
\ No newline at end of file
<?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.FrameLayoutFixed
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="9dp"
android:id="@+id/chat_bubble_layout"
android:layout_gravity="top"
android:addStatesFromChildren="true">
<org.telegram.ui.Views.BackupImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_margin="6dp"
android:layout_gravity="top"
android:scaleType="centerCrop"
android:minHeight="100dp"
android:minWidth="100dp"
android:id="@+id/chat_photo_image"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="16dp"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_gravity="top"
android:background="@drawable/phototime"
android:orientation="horizontal"
android:gravity="center_vertical">
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/ic_video"/>
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textColor="#ffffff"
android:textSize="12dp"
android:layout_marginLeft="4dp"
android:gravity="center_vertical"
android:layout_gravity="center_vertical"
android:layout_marginBottom="1dp"
android:id="@+id/chat_video_time"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="16dp"
android:id="@+id/chat_time_layout"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
android:layout_gravity="right|bottom"
android:background="@drawable/phototime">
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textColor="#ffffff"
android:textSize="12dp"
android:layout_gravity="bottom"
android:layout_marginBottom="1dp"
android:id="@+id/chat_time_text"/>
</LinearLayout>
</org.telegram.ui.Views.FrameLayoutFixed>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#54759e"
android:background="@drawable/chat_incoming_media_states"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:id="@+id/chat_view_action_button"
android:textSize="14dp"
android:layout_gravity="center"
android:descendantFocusability="blocksDescendants"
android:clickable="true"
android:gravity="center"
android:visibility="gone"
android:textStyle="bold"
android:layout_marginLeft="10dp"/>
<org.telegram.ui.Views.FrameLayoutFixed
android:layout_height="wrap_content"
android:layout_width="140dp"
android:layout_marginLeft="10dp"
android:layout_gravity="center_vertical"
android:id="@+id/chat_view_action_layout"
android:visibility="gone">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:scaleType="centerInside"
android:layout_marginRight="4dp"
android:layout_gravity="right|center"
android:id="@+id/chat_view_action_cancel_button"
android:src="@drawable/ic_msg_btn_cross_custom"
android:clickable="true"/>
<ProgressBar
android:layout_width="fill_parent"
android:layout_height="3dp"
android:layout_gravity="left|center_vertical"
android:progressDrawable="@drawable/progress_chat"
style="?android:attr/progressBarStyleHorizontal"
android:progress="50"
android:layout_marginLeft="12dp"
android:layout_marginRight="36dp"
android:id="@+id/chat_view_action_progress"
android:max="100"/>
</org.telegram.ui.Views.FrameLayoutFixed>
</LinearLayout>
\ No newline at end of file
<?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:gravity="right"
android:paddingBottom="1dp"
android:paddingTop="1dp">
<org.telegram.ui.Views.FrameLayoutFixed
android:layout_height="wrap_content"
android:layout_width="140dp"
android:layout_marginRight="10dp"
android:id="@+id/chat_view_action_layout"
android:layout_gravity="center"
android:visibility="gone">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:scaleType="centerInside"
android:layout_marginLeft="4dp"
android:id="@+id/chat_view_action_cancel_button"
android:src="@drawable/ic_msg_btn_cross_custom"
android:layout_gravity="left|center"
android:clickable="true"/>
<ProgressBar
android:layout_width="fill_parent"
android:layout_height="3dp"
android:layout_gravity="right|center_vertical"
android:progressDrawable="@drawable/progress_chat"
style="?android:attr/progressBarStyleHorizontal"
android:progress="50"
android:layout_marginLeft="36dp"
android:layout_marginRight="12dp"
android:id="@+id/chat_view_action_progress"
android:max="100"/>
</org.telegram.ui.Views.FrameLayoutFixed>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#54759e"
android:background="@drawable/chat_incoming_media_states"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:id="@+id/chat_view_action_button"
android:textSize="14dp"
android:layout_marginRight="10dp"
android:descendantFocusability="blocksDescendants"
android:clickable="true"
android:gravity="center"
android:visibility="gone"
android:textStyle="bold"
android:layout_gravity="center"/>
<org.telegram.ui.Views.FrameLayoutFixed
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="9dp"
android:id="@+id/chat_bubble_layout"
android:layout_gravity="top"
android:addStatesFromChildren="true">
<org.telegram.ui.Views.BackupImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_margin="6dp"
android:layout_gravity="top"
android:scaleType="centerCrop"
android:minHeight="100dp"
android:minWidth="100dp"
android:id="@+id/chat_photo_image"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="16dp"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_gravity="top"
android:background="@drawable/phototime"
android:orientation="horizontal"
android:gravity="center_vertical">
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/ic_video"/>
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textColor="#ffffff"
android:textSize="12dp"
android:layout_marginLeft="4dp"
android:gravity="center_vertical"
android:layout_gravity="center_vertical"
android:layout_marginBottom="1dp"
android:id="@+id/chat_video_time"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="16dp"
android:id="@+id/chat_time_layout"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
android:layout_gravity="right|bottom"
android:background="@drawable/phototime">
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textColor="#ffffff"
android:textSize="12dp"
android:layout_gravity="bottom"
android:id="@+id/chat_time_text"
android:layout_marginBottom="1dp"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/msg_check_w"
android:layout_marginTop="1dp"
android:layout_marginLeft="3dp"
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:layout_marginTop="1dp"
android:id="@+id/chat_row_halfcheck"
android:visibility="visible"
android:src="@drawable/msg_halfcheck_w"
android:layout_gravity="top"/>
</LinearLayout>
</org.telegram.ui.Views.FrameLayoutFixed>
</LinearLayout>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment