Fixes (unstable, don't upload to markets)
@ -9,12 +9,11 @@ static inline uint64_t get_colors (const uint8_t *p) {
|
||||
return p[0] + (p[1] << 16) + ((uint64_t)p[2] << 32);
|
||||
}
|
||||
|
||||
static void fastBlur(int imageWidth, int imageHeight, int imageStride, void *pixels) {
|
||||
static void fastBlurMore(int imageWidth, int imageHeight, int imageStride, void *pixels, int radius) {
|
||||
uint8_t *pix = (uint8_t *)pixels;
|
||||
const int w = imageWidth;
|
||||
const int h = imageHeight;
|
||||
const int stride = imageStride;
|
||||
const int radius = 3;
|
||||
const int r1 = radius + 1;
|
||||
const int div = radius * 2 + 1;
|
||||
|
||||
@ -23,6 +22,98 @@ static void fastBlur(int imageWidth, int imageHeight, int imageStride, void *pix
|
||||
}
|
||||
|
||||
uint64_t *rgb = malloc(imageWidth * imageHeight * sizeof(uint64_t));
|
||||
if (rgb == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
int x, y, i;
|
||||
|
||||
int yw = 0;
|
||||
const int we = w - r1;
|
||||
for (y = 0; y < h; y++) {
|
||||
uint64_t cur = get_colors (&pix[yw]);
|
||||
uint64_t rgballsum = -radius * cur;
|
||||
uint64_t rgbsum = cur * ((r1 * (r1 + 1)) >> 1);
|
||||
|
||||
for (i = 1; i <= radius; i++) {
|
||||
uint64_t cur = get_colors (&pix[yw + i * 4]);
|
||||
rgbsum += cur * (r1 - i);
|
||||
rgballsum += cur;
|
||||
}
|
||||
|
||||
x = 0;
|
||||
|
||||
#define update(start, middle, end) \
|
||||
rgb[y * w + x] = (rgbsum >> 6) & 0x00FF00FF00FF00FF; \
|
||||
rgballsum += get_colors (&pix[yw + (start) * 4]) - 2 * get_colors (&pix[yw + (middle) * 4]) + get_colors (&pix[yw + (end) * 4]); \
|
||||
rgbsum += rgballsum; \
|
||||
x++; \
|
||||
|
||||
while (x < r1) {
|
||||
update (0, x, x + r1);
|
||||
}
|
||||
while (x < we) {
|
||||
update (x - r1, x, x + r1);
|
||||
}
|
||||
while (x < w) {
|
||||
update (x - r1, x, w - 1);
|
||||
}
|
||||
#undef update
|
||||
|
||||
yw += stride;
|
||||
}
|
||||
|
||||
const int he = h - r1;
|
||||
for (x = 0; x < w; x++) {
|
||||
uint64_t rgballsum = -radius * rgb[x];
|
||||
uint64_t rgbsum = rgb[x] * ((r1 * (r1 + 1)) >> 1);
|
||||
for (i = 1; i <= radius; i++) {
|
||||
rgbsum += rgb[i * w + x] * (r1 - i);
|
||||
rgballsum += rgb[i * w + x];
|
||||
}
|
||||
|
||||
y = 0;
|
||||
int yi = x * 4;
|
||||
|
||||
#define update(start, middle, end) \
|
||||
int64_t res = rgbsum >> 6; \
|
||||
pix[yi] = res; \
|
||||
pix[yi + 1] = res >> 16; \
|
||||
pix[yi + 2] = res >> 32; \
|
||||
rgballsum += rgb[x + (start) * w] - 2 * rgb[x + (middle) * w] + rgb[x + (end) * w]; \
|
||||
rgbsum += rgballsum; \
|
||||
y++; \
|
||||
yi += stride;
|
||||
|
||||
while (y < r1) {
|
||||
update (0, y, y + r1);
|
||||
}
|
||||
while (y < he) {
|
||||
update (y - r1, y, y + r1);
|
||||
}
|
||||
while (y < h) {
|
||||
update (y - r1, y, h - 1);
|
||||
}
|
||||
#undef update
|
||||
}
|
||||
}
|
||||
|
||||
static void fastBlur(int imageWidth, int imageHeight, int imageStride, void *pixels, int radius) {
|
||||
uint8_t *pix = (uint8_t *)pixels;
|
||||
const int w = imageWidth;
|
||||
const int h = imageHeight;
|
||||
const int stride = imageStride;
|
||||
const int r1 = radius + 1;
|
||||
const int div = radius * 2 + 1;
|
||||
|
||||
if (radius > 15 || div >= w || div >= h || w * h > 90 * 90 || imageStride > imageWidth * 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t *rgb = malloc(imageWidth * imageHeight * sizeof(uint64_t));
|
||||
if (rgb == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
int x, y, i;
|
||||
|
||||
@ -111,7 +202,7 @@ METHODDEF(void) my_error_exit(j_common_ptr cinfo) {
|
||||
longjmp(myerr->setjmp_buffer, 1);
|
||||
}
|
||||
|
||||
JNIEXPORT void Java_org_telegram_messenger_Utilities_blurBitmap(JNIEnv *env, jclass class, jobject bitmap) {
|
||||
JNIEXPORT void Java_org_telegram_messenger_Utilities_blurBitmap(JNIEnv *env, jclass class, jobject bitmap, int radius) {
|
||||
if (!bitmap) {
|
||||
return;
|
||||
}
|
||||
@ -130,7 +221,11 @@ JNIEXPORT void Java_org_telegram_messenger_Utilities_blurBitmap(JNIEnv *env, jcl
|
||||
if (AndroidBitmap_lockPixels(env, bitmap, &pixels) < 0) {
|
||||
return;
|
||||
}
|
||||
fastBlur(info.width, info.height, info.stride, pixels);
|
||||
if (radius <= 3) {
|
||||
fastBlur(info.width, info.height, info.stride, pixels, radius);
|
||||
} else {
|
||||
fastBlurMore(info.width, info.height, info.stride, pixels, radius);
|
||||
}
|
||||
AndroidBitmap_unlockPixels(env, bitmap);
|
||||
}
|
||||
|
||||
|
@ -274,6 +274,10 @@ public class AndroidUtilities {
|
||||
}
|
||||
}
|
||||
|
||||
public static void CancelRunOnUIThread(Runnable runnable) {
|
||||
ApplicationLoader.applicationHandler.removeCallbacks(runnable);
|
||||
}
|
||||
|
||||
public static boolean isTablet() {
|
||||
if (isTablet == null) {
|
||||
isTablet = ApplicationLoader.applicationContext.getResources().getBoolean(R.bool.isTablet);
|
||||
|
@ -28,7 +28,6 @@ import android.provider.MediaStore;
|
||||
import org.telegram.messenger.DispatchQueue;
|
||||
import org.telegram.messenger.FileLoader;
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.messenger.R;
|
||||
import org.telegram.messenger.TLRPC;
|
||||
import org.telegram.messenger.UserConfig;
|
||||
import org.telegram.messenger.Utilities;
|
||||
@ -293,7 +292,7 @@ public class ImageLoader {
|
||||
}
|
||||
}
|
||||
if (image != null && blur && bitmapH < 100 && bitmapW < 100) {
|
||||
Utilities.blurBitmap(image);
|
||||
Utilities.blurBitmap(image, 3);
|
||||
}
|
||||
}
|
||||
if (runtimeHack != null) {
|
||||
|
@ -35,6 +35,7 @@ public class ImageReceiver {
|
||||
private boolean isVisible = true;
|
||||
private boolean isAspectFit = false;
|
||||
private boolean lastCacheOnly = false;
|
||||
private boolean forcePreview = false;
|
||||
|
||||
public ImageReceiver() {
|
||||
|
||||
@ -195,7 +196,7 @@ public class ImageReceiver {
|
||||
public boolean draw(Canvas canvas, int x, int y, int w, int h) {
|
||||
try {
|
||||
Drawable bitmapDrawable = currentImage;
|
||||
if (bitmapDrawable == null && last_placeholder != null && last_placeholder instanceof BitmapDrawable) {
|
||||
if (forcePreview || bitmapDrawable == null && last_placeholder != null && last_placeholder instanceof BitmapDrawable) {
|
||||
bitmapDrawable = last_placeholder;
|
||||
}
|
||||
if (bitmapDrawable != null) {
|
||||
@ -371,4 +372,8 @@ public class ImageReceiver {
|
||||
public String getKey() {
|
||||
return currentPath;
|
||||
}
|
||||
|
||||
public void setForcePreview(boolean value) {
|
||||
forcePreview = value;
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import android.text.StaticLayout;
|
||||
import android.text.TextPaint;
|
||||
import android.text.util.Linkify;
|
||||
|
||||
import org.telegram.messenger.ConnectionsManager;
|
||||
import org.telegram.messenger.FileLoader;
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.messenger.TLRPC;
|
||||
@ -340,7 +341,7 @@ public class MessageObject {
|
||||
if (!update) {
|
||||
photoThumbs = new ArrayList<PhotoObject>();
|
||||
for (TLRPC.PhotoSize size : messageOwner.action.photo.sizes) {
|
||||
photoThumbs.add(new PhotoObject(size, preview));
|
||||
photoThumbs.add(new PhotoObject(size, preview, isSecretMedia()));
|
||||
}
|
||||
} else if (photoThumbs != null && !photoThumbs.isEmpty()) {
|
||||
for (PhotoObject photoObject : photoThumbs) {
|
||||
@ -361,7 +362,7 @@ public class MessageObject {
|
||||
if (!update) {
|
||||
photoThumbs = new ArrayList<PhotoObject>();
|
||||
for (TLRPC.PhotoSize size : messageOwner.media.photo.sizes) {
|
||||
PhotoObject obj = new PhotoObject(size, preview);
|
||||
PhotoObject obj = new PhotoObject(size, preview, isSecretMedia());
|
||||
photoThumbs.add(obj);
|
||||
if (imagePreview == null && obj.image != null) {
|
||||
imagePreview = obj.image;
|
||||
@ -383,7 +384,7 @@ public class MessageObject {
|
||||
} else if (messageOwner.media instanceof TLRPC.TL_messageMediaVideo) {
|
||||
if (!update) {
|
||||
photoThumbs = new ArrayList<PhotoObject>();
|
||||
PhotoObject obj = new PhotoObject(messageOwner.media.video.thumb, preview);
|
||||
PhotoObject obj = new PhotoObject(messageOwner.media.video.thumb, preview, isSecretMedia());
|
||||
photoThumbs.add(obj);
|
||||
if (imagePreview == null && obj.image != null) {
|
||||
imagePreview = obj.image;
|
||||
@ -396,7 +397,7 @@ public class MessageObject {
|
||||
if (!(messageOwner.media.document.thumb instanceof TLRPC.TL_photoSizeEmpty)) {
|
||||
if (!update) {
|
||||
photoThumbs = new ArrayList<PhotoObject>();
|
||||
PhotoObject obj = new PhotoObject(messageOwner.media.document.thumb, preview);
|
||||
PhotoObject obj = new PhotoObject(messageOwner.media.document.thumb, preview, isSecretMedia());
|
||||
photoThumbs.add(obj);
|
||||
} else if (photoThumbs != null && !photoThumbs.isEmpty() && messageOwner.media.document.thumb != null) {
|
||||
PhotoObject photoObject = photoThumbs.get(0);
|
||||
@ -599,15 +600,39 @@ public class MessageObject {
|
||||
}
|
||||
|
||||
public boolean isOut() {
|
||||
return messageOwner.out;
|
||||
return (messageOwner.flags & TLRPC.MESSAGE_FLAG_OUT) != 0;
|
||||
}
|
||||
|
||||
public boolean isFromMe() {
|
||||
return messageOwner.from_id == UserConfig.getClientUserId();
|
||||
}
|
||||
|
||||
public boolean isUnread () {
|
||||
return messageOwner.unread;
|
||||
public boolean isUnread() {
|
||||
return (messageOwner.flags & TLRPC.MESSAGE_FLAG_UNREAD) != 0;
|
||||
}
|
||||
|
||||
public void setIsRead() {
|
||||
messageOwner.flags &=~ TLRPC.MESSAGE_FLAG_UNREAD;
|
||||
}
|
||||
|
||||
public boolean isSecretMedia() {
|
||||
return messageOwner.media instanceof TLRPC.TL_messageMediaPhoto && messageOwner.ttl != 0;
|
||||
}
|
||||
|
||||
public static void setIsUnread(TLRPC.Message message, boolean unread) {
|
||||
if (unread) {
|
||||
message.flags |= TLRPC.MESSAGE_FLAG_UNREAD;
|
||||
} else {
|
||||
message.flags &=~ TLRPC.MESSAGE_FLAG_UNREAD;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isUnread(TLRPC.Message message) {
|
||||
return (message.flags & TLRPC.MESSAGE_FLAG_UNREAD) != 0;
|
||||
}
|
||||
|
||||
public static boolean isOut(TLRPC.Message message) {
|
||||
return (message.flags & TLRPC.MESSAGE_FLAG_OUT) != 0;
|
||||
}
|
||||
|
||||
public long getDialogId() {
|
||||
@ -635,4 +660,25 @@ public class MessageObject {
|
||||
public boolean isSent() {
|
||||
return messageOwner.send_state == MESSAGE_SEND_STATE_SENT;
|
||||
}
|
||||
|
||||
public String getSecretTimeString() {
|
||||
if (!isSecretMedia()) {
|
||||
return null;
|
||||
}
|
||||
int secondsLeft = messageOwner.ttl;
|
||||
if (messageOwner.destroyTime != 0) {
|
||||
secondsLeft = Math.max(0, messageOwner.destroyTime - ConnectionsManager.getInstance().getCurrentTime());
|
||||
}
|
||||
String str;
|
||||
if (secondsLeft < 60) {
|
||||
str = secondsLeft + "s";
|
||||
} else if (secondsLeft < 60 * 60) {
|
||||
str = secondsLeft / 60 + "m";
|
||||
} else if (secondsLeft < 60 * 60 * 24) {
|
||||
str = secondsLeft / 60 / 60 + "h";
|
||||
} else {
|
||||
str = secondsLeft / 60 / 60 / 24 + "d";
|
||||
}
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
@ -1649,6 +1649,28 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
});
|
||||
}
|
||||
|
||||
public void markMessageAsRead(final long dialog_id, final long random_id) {
|
||||
if (random_id == 0 || dialog_id == 0) {
|
||||
return;
|
||||
}
|
||||
int lower_part = (int)dialog_id;
|
||||
int high_id = (int)(dialog_id >> 32);
|
||||
if (lower_part != 0) {
|
||||
return;
|
||||
}
|
||||
TLRPC.EncryptedChat chat = getEncryptedChat(high_id);
|
||||
if (chat == null) {
|
||||
return;
|
||||
}
|
||||
ArrayList<Long> random_ids = new ArrayList<Long>();
|
||||
random_ids.add(random_id);
|
||||
SendMessagesHelper.getInstance().sendMessagesReadMessage(random_ids, chat);
|
||||
if (chat.ttl > 0) {
|
||||
MessagesStorage.getInstance().createTaskForSecretChat(chat.id, 0, ConnectionsManager.getInstance().getCurrentTime(), 0, random_ids);
|
||||
}
|
||||
//TODO resend request
|
||||
}
|
||||
|
||||
public void markDialogAsRead(final long dialog_id, final int max_id, final int max_positive_id, final int offset, final int max_date, final boolean was, final boolean popup) {
|
||||
int lower_part = (int)dialog_id;
|
||||
int high_id = (int)(dialog_id >> 32);
|
||||
@ -1762,18 +1784,17 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
|
||||
if (chat.ttl > 0 && was) {
|
||||
int serverTime = Math.max(ConnectionsManager.getInstance().getCurrentTime(), max_date);
|
||||
MessagesStorage.getInstance().createTaskForDate(chat.id, serverTime, serverTime, 0);
|
||||
MessagesStorage.getInstance().createTaskForSecretChat(chat.id, serverTime, serverTime, 0, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processPendingEncMessages() {
|
||||
if (pendingEncMessagesToDelete.isEmpty()) {
|
||||
return;
|
||||
if (!pendingEncMessagesToDelete.isEmpty()) {
|
||||
ArrayList<Long> arr = new ArrayList<Long>(pendingEncMessagesToDelete);
|
||||
MessagesStorage.getInstance().markMessagesAsDeletedByRandoms(arr);
|
||||
pendingEncMessagesToDelete.clear();
|
||||
}
|
||||
ArrayList<Long> arr = new ArrayList<Long>(pendingEncMessagesToDelete);
|
||||
MessagesStorage.getInstance().markMessagesAsDeletedByRandoms(arr);
|
||||
pendingEncMessagesToDelete.clear();
|
||||
}
|
||||
|
||||
public long createChat(String title, ArrayList<Integer> selectedContacts, final TLRPC.InputFile uploadedAvatar, boolean isBroadcast) {
|
||||
@ -1809,11 +1830,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
newMsg.action = new TLRPC.TL_messageActionCreatedBroadcastList();
|
||||
newMsg.local_id = newMsg.id = UserConfig.getNewMessageId();
|
||||
newMsg.from_id = UserConfig.getClientUserId();
|
||||
newMsg.unread = false;
|
||||
newMsg.dialog_id = AndroidUtilities.makeBroadcastId(chat.id);
|
||||
newMsg.to_id = new TLRPC.TL_peerChat();
|
||||
newMsg.to_id.chat_id = chat.id;
|
||||
newMsg.out = false;
|
||||
newMsg.date = ConnectionsManager.getInstance().getCurrentTime();
|
||||
newMsg.random_id = 0;
|
||||
UserConfig.saveConfig(false);
|
||||
@ -2576,7 +2595,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
message.message = updates.message;
|
||||
message.date = updates.date;
|
||||
message.flags = TLRPC.MESSAGE_FLAG_UNREAD;
|
||||
message.unread = true;
|
||||
message.media = new TLRPC.TL_messageMediaEmpty();
|
||||
MessagesStorage.lastSeqValue = updates.seq;
|
||||
MessagesStorage.lastPtsValue = updates.pts;
|
||||
@ -2641,7 +2659,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
message.to_id.user_id = updates.from_id;
|
||||
message.message = updates.message;
|
||||
message.date = updates.date;
|
||||
message.unread = true;
|
||||
message.flags = TLRPC.MESSAGE_FLAG_UNREAD;
|
||||
message.media = new TLRPC.TL_messageMediaEmpty();
|
||||
MessagesStorage.lastSeqValue = updates.seq;
|
||||
@ -2920,13 +2937,11 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
newMessage.action = new TLRPC.TL_messageActionUserJoined();
|
||||
newMessage.local_id = newMessage.id = UserConfig.getNewMessageId();
|
||||
UserConfig.saveConfig(false);
|
||||
newMessage.unread = true;
|
||||
newMessage.flags = TLRPC.MESSAGE_FLAG_UNREAD;
|
||||
newMessage.date = update.date;
|
||||
newMessage.from_id = update.user_id;
|
||||
newMessage.to_id = new TLRPC.TL_peerUser();
|
||||
newMessage.to_id.user_id = UserConfig.getClientUserId();
|
||||
newMessage.out = false;
|
||||
newMessage.dialog_id = update.user_id;
|
||||
|
||||
messagesArr.add(newMessage);
|
||||
@ -2966,13 +2981,11 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
newMessage.action.address = update.location;
|
||||
newMessage.local_id = newMessage.id = UserConfig.getNewMessageId();
|
||||
UserConfig.saveConfig(false);
|
||||
newMessage.unread = true;
|
||||
newMessage.flags = TLRPC.MESSAGE_FLAG_UNREAD;
|
||||
newMessage.date = update.date;
|
||||
newMessage.from_id = 777000;
|
||||
newMessage.to_id = new TLRPC.TL_peerUser();
|
||||
newMessage.to_id.user_id = UserConfig.getClientUserId();
|
||||
newMessage.out = false;
|
||||
newMessage.dialog_id = 777000;
|
||||
|
||||
messagesArr.add(newMessage);
|
||||
@ -3301,7 +3314,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
for (Integer id : markAsReadMessages) {
|
||||
MessageObject obj = dialogMessage.get(id);
|
||||
if (obj != null) {
|
||||
obj.messageOwner.unread = false;
|
||||
obj.setIsRead();
|
||||
updateMask |= UPDATE_MASK_READ_DIALOG_MESSAGE;
|
||||
}
|
||||
}
|
||||
@ -3314,7 +3327,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
if (dialog != null) {
|
||||
MessageObject message = dialogMessage.get(dialog.top_message);
|
||||
if (message != null && message.messageOwner.date <= entry.getValue()) {
|
||||
message.messageOwner.unread = false;
|
||||
message.setIsRead();
|
||||
updateMask |= UPDATE_MASK_READ_DIALOG_MESSAGE;
|
||||
}
|
||||
}
|
||||
@ -3351,7 +3364,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
}
|
||||
if (!tasks.isEmpty()) {
|
||||
for (TLRPC.TL_updateEncryptedMessagesRead update : tasks) {
|
||||
MessagesStorage.getInstance().createTaskForDate(update.chat_id, update.max_date, update.date, 1);
|
||||
MessagesStorage.getInstance().createTaskForSecretChat(update.chat_id, update.max_date, update.date, 1, null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3504,7 +3517,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
|
||||
if (object instanceof TLRPC.TL_decryptedMessage) {
|
||||
TLRPC.TL_decryptedMessage decryptedMessage = (TLRPC.TL_decryptedMessage)object;
|
||||
TLRPC.TL_message newMessage = new TLRPC.TL_message();
|
||||
TLRPC.TL_message_secret newMessage = new TLRPC.TL_message_secret();
|
||||
newMessage.message = decryptedMessage.message;
|
||||
newMessage.date = message.date;
|
||||
newMessage.local_id = newMessage.id = UserConfig.getNewMessageId();
|
||||
@ -3514,8 +3527,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
newMessage.random_id = message.random_id;
|
||||
newMessage.to_id.user_id = UserConfig.getClientUserId();
|
||||
newMessage.flags = TLRPC.MESSAGE_FLAG_UNREAD;
|
||||
newMessage.out = false;
|
||||
newMessage.unread = true;
|
||||
newMessage.dialog_id = ((long)chat.id) << 32;
|
||||
newMessage.ttl = chat.ttl;
|
||||
if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaEmpty) {
|
||||
@ -3663,12 +3674,10 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
newMessage.local_id = newMessage.id = UserConfig.getNewMessageId();
|
||||
UserConfig.saveConfig(false);
|
||||
newMessage.flags = TLRPC.MESSAGE_FLAG_UNREAD;
|
||||
newMessage.unread = true;
|
||||
newMessage.date = message.date;
|
||||
newMessage.from_id = from_id;
|
||||
newMessage.to_id = new TLRPC.TL_peerUser();
|
||||
newMessage.to_id.user_id = UserConfig.getClientUserId();
|
||||
newMessage.out = false;
|
||||
newMessage.dialog_id = ((long)chat.id) << 32;
|
||||
MessagesStorage.getInstance().updateEncryptedChatTTL(chat);
|
||||
return newMessage;
|
||||
@ -3707,6 +3716,10 @@ public class MessagesController implements NotificationCenter.NotificationCenter
|
||||
pendingEncMessagesToDelete.addAll(serviceMessage.action.random_ids);
|
||||
}
|
||||
return null;
|
||||
} else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionReadMessages) {
|
||||
if (!serviceMessage.action.random_ids.isEmpty()) {
|
||||
MessagesStorage.getInstance().createTaskForSecretChat(chat.id, 0, message.date, 1, serviceMessage.action.random_ids);
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
@ -282,7 +282,7 @@ public class MessagesStorage {
|
||||
database.executeFast("DROP INDEX IF EXISTS date_idx_enc_tasks;").stepThis().dispose();
|
||||
database.executeFast("DROP TABLE IF EXISTS enc_tasks;").stepThis().dispose();
|
||||
|
||||
database.executeFast("ALTER TABLE messages ADD COLUMN media INTEGER").stepThis().dispose();
|
||||
database.executeFast("ALTER TABLE messages ADD COLUMN media INTEGER default 0").stepThis().dispose();
|
||||
database.executeFast("PRAGMA user_version = 6").stepThis().dispose();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@ -428,8 +428,7 @@ public class MessagesStorage {
|
||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(1));
|
||||
if (data != null && cursor.byteBufferValue(1, data.buffer) != 0) {
|
||||
TLRPC.Message message = (TLRPC.Message)TLClassStore.Instance().TLdeserialize(data, data.readInt32());
|
||||
int read_state = cursor.intValue(0);
|
||||
message.unread = (cursor.intValue(0) != 1);
|
||||
MessageObject.setIsUnread(message, cursor.intValue(0) != 1);
|
||||
message.id = cursor.intValue(3);
|
||||
message.date = cursor.intValue(4);
|
||||
message.dialog_id = cursor.longValue(5);
|
||||
@ -470,7 +469,7 @@ public class MessagesStorage {
|
||||
userIds.add(message.fwd_from_id);
|
||||
}
|
||||
message.send_state = cursor.intValue(2);
|
||||
if (!message.unread && lower_id != 0 || message.id > 0) {
|
||||
if (!MessageObject.isUnread(message) && lower_id != 0 || message.id > 0) {
|
||||
message.send_state = 0;
|
||||
}
|
||||
if (lower_id == 0 && !cursor.isNull(5)) {
|
||||
@ -836,7 +835,7 @@ public class MessagesStorage {
|
||||
});
|
||||
}
|
||||
|
||||
public void createTaskForDate(final int chat_id, final int time, final int readTime, final int isOut) {
|
||||
public void createTaskForSecretChat(final int chat_id, final int time, final int readTime, final int isOut, final ArrayList<Long> random_ids) {
|
||||
storageQueue.postRunnable(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@ -844,7 +843,13 @@ public class MessagesStorage {
|
||||
int minDate = Integer.MAX_VALUE;
|
||||
SparseArray<ArrayList<Integer>> messages = new SparseArray<ArrayList<Integer>>();
|
||||
StringBuilder mids = new StringBuilder();
|
||||
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT mid, ttl FROM messages WHERE uid = %d AND out = %d AND read_state = 1 AND ttl > 0 AND date <= %d AND send_state = 0 AND media != 1", ((long)chat_id) << 32, isOut, time));
|
||||
SQLiteCursor cursor = null;
|
||||
if (random_ids == null) {
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT mid, ttl FROM messages WHERE uid = %d AND out = %d AND read_state = 1 AND ttl > 0 AND date <= %d AND send_state = 0 AND media != 1", ((long) chat_id) << 32, isOut, time));
|
||||
} else {
|
||||
String ids = TextUtils.join(",", random_ids);
|
||||
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.mid, m.ttl FROM messages as m INNER JOIN randoms as r ON m.mid = r.mid WHERE r.random_id IN (%s)", ids));
|
||||
}
|
||||
while (cursor.next()) {
|
||||
int mid = cursor.intValue(0);
|
||||
int date = readTime + cursor.intValue(1);
|
||||
@ -1640,8 +1645,7 @@ public class MessagesStorage {
|
||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(1));
|
||||
if (data != null && cursor.byteBufferValue(1, data.buffer) != 0) {
|
||||
TLRPC.Message message = (TLRPC.Message)TLClassStore.Instance().TLdeserialize(data, data.readInt32());
|
||||
int read_state = cursor.intValue(0);
|
||||
message.unread = (cursor.intValue(0) != 1);
|
||||
MessageObject.setIsUnread(message, cursor.intValue(0) != 1);
|
||||
message.id = cursor.intValue(3);
|
||||
message.date = cursor.intValue(4);
|
||||
if (!cursor.isNull(5)) {
|
||||
@ -1691,7 +1695,7 @@ public class MessagesStorage {
|
||||
userIds.add(message.fwd_from_id);
|
||||
}
|
||||
message.send_state = cursor.intValue(2);
|
||||
if (!message.unread && lower_id != 0 || message.id > 0) {
|
||||
if (!MessageObject.isUnread(message) && lower_id != 0 || message.id > 0) {
|
||||
message.send_state = 0;
|
||||
}
|
||||
if (lower_id == 0 && !cursor.isNull(5)) {
|
||||
@ -1879,8 +1883,7 @@ public class MessagesStorage {
|
||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(1));
|
||||
if (data != null && cursor.byteBufferValue(1, data.buffer) != 0) {
|
||||
TLRPC.Message message = (TLRPC.Message)TLClassStore.Instance().TLdeserialize(data, data.readInt32());
|
||||
int read_state = cursor.intValue(0);
|
||||
message.unread = (cursor.intValue(0) != 1);
|
||||
MessageObject.setIsUnread(message, cursor.intValue(0) != 1);
|
||||
message.id = cursor.intValue(3);
|
||||
message.date = cursor.intValue(4);
|
||||
message.dialog_id = dialog_id;
|
||||
@ -1899,12 +1902,23 @@ public class MessagesStorage {
|
||||
fromUser.add(message.fwd_from_id);
|
||||
}
|
||||
message.send_state = cursor.intValue(2);
|
||||
if (!message.unread && lower_id != 0 || message.id > 0) {
|
||||
if (!MessageObject.isUnread(message) && lower_id != 0 || message.id > 0) {
|
||||
message.send_state = 0;
|
||||
}
|
||||
if (lower_id == 0 && !cursor.isNull(5)) {
|
||||
message.random_id = cursor.longValue(5);
|
||||
}
|
||||
if ((int)dialog_id == 0 && message.media != null && message.media.photo != null) {
|
||||
try {
|
||||
SQLiteCursor cursor2 = database.queryFinalized(String.format(Locale.US, "SELECT date FROM enc_tasks_v2 WHERE mid = %d", message.id));
|
||||
if (cursor2.next()) {
|
||||
message.destroyTime = cursor2.intValue(0);
|
||||
}
|
||||
cursor2.dispose();
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
buffersStorage.reuseFreeBuffer(data);
|
||||
|
||||
@ -2456,7 +2470,7 @@ public class MessagesStorage {
|
||||
}
|
||||
}
|
||||
|
||||
if (message.unread && !message.out) {
|
||||
if (MessageObject.isUnread(message) && !MessageObject.isOut(message)) {
|
||||
if (messageIds.length() > 0) {
|
||||
messageIds.append(",");
|
||||
}
|
||||
@ -2532,11 +2546,11 @@ public class MessagesStorage {
|
||||
}
|
||||
state.bindInteger(1, messageId);
|
||||
state.bindLong(2, dialog_id);
|
||||
state.bindInteger(3, (message.unread ? 0 : 1));
|
||||
state.bindInteger(3, (MessageObject.isUnread(message) ? 0 : 1));
|
||||
state.bindInteger(4, message.send_state);
|
||||
state.bindInteger(5, message.date);
|
||||
state.bindByteBuffer(6, data.buffer);
|
||||
state.bindInteger(7, (message.out ? 1 : 0));
|
||||
state.bindInteger(7, (MessageObject.isOut(message) ? 1 : 0));
|
||||
state.bindInteger(8, message.ttl);
|
||||
state.bindInteger(9, getMessageMediaType(message));
|
||||
state.step();
|
||||
@ -3061,7 +3075,7 @@ public class MessagesStorage {
|
||||
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(4));
|
||||
if (data != null && cursor.byteBufferValue(4, data.buffer) != 0) {
|
||||
TLRPC.Message message = (TLRPC.Message)TLClassStore.Instance().TLdeserialize(data, data.readInt32());
|
||||
message.unread = (cursor.intValue(5) != 1);
|
||||
MessageObject.setIsUnread(message, cursor.intValue(5) != 1);
|
||||
message.id = cursor.intValue(6);
|
||||
message.send_state = cursor.intValue(7);
|
||||
dialogs.messages.add(message);
|
||||
@ -3218,11 +3232,11 @@ public class MessagesStorage {
|
||||
message.serializeToStream(data);
|
||||
state.bindInteger(1, message.id);
|
||||
state.bindLong(2, dialog_id);
|
||||
state.bindInteger(3, (message.unread ? 0 : 1));
|
||||
state.bindInteger(3, (MessageObject.isUnread(message) ? 0 : 1));
|
||||
state.bindInteger(4, message.send_state);
|
||||
state.bindInteger(5, message.date);
|
||||
state.bindByteBuffer(6, data.buffer);
|
||||
state.bindInteger(7, (message.out ? 1 : 0));
|
||||
state.bindInteger(7, (MessageObject.isOut(message) ? 1 : 0));
|
||||
state.bindInteger(8, 0);
|
||||
state.bindInteger(9, getMessageMediaType(message));
|
||||
state.step();
|
||||
@ -3316,7 +3330,7 @@ public class MessagesStorage {
|
||||
if (data != null && cursor.byteBufferValue(4, data.buffer) != 0) {
|
||||
TLRPC.Message message = (TLRPC.Message)TLClassStore.Instance().TLdeserialize(data, data.readInt32());
|
||||
if (message != null) {
|
||||
message.unread = (cursor.intValue(5) != 1);
|
||||
MessageObject.setIsUnread(message, cursor.intValue(5) != 1);
|
||||
message.id = cursor.intValue(6);
|
||||
message.send_state = cursor.intValue(7);
|
||||
dialogs.messages.add(message);
|
||||
@ -3485,11 +3499,11 @@ public class MessagesStorage {
|
||||
|
||||
state.bindInteger(1, message.id);
|
||||
state.bindInteger(2, uid);
|
||||
state.bindInteger(3, (message.unread ? 0 : 1));
|
||||
state.bindInteger(3, (MessageObject.isUnread(message) ? 0 : 1));
|
||||
state.bindInteger(4, message.send_state);
|
||||
state.bindInteger(5, message.date);
|
||||
state.bindByteBuffer(6, data.buffer);
|
||||
state.bindInteger(7, (message.out ? 1 : 0));
|
||||
state.bindInteger(7, (MessageObject.isOut(message) ? 1 : 0));
|
||||
state.bindInteger(8, 0);
|
||||
state.bindInteger(9, getMessageMediaType(message));
|
||||
state.step();
|
||||
|
@ -24,9 +24,9 @@ import java.util.zip.ZipFile;
|
||||
public class NativeLoader {
|
||||
|
||||
private static final long sizes[] = new long[] {
|
||||
951052, //armeabi
|
||||
1032992, //armeabi-v7a
|
||||
1612020, //x86
|
||||
955148, //armeabi
|
||||
1041184, //armeabi-v7a
|
||||
1616116, //x86
|
||||
0, //mips
|
||||
};
|
||||
|
||||
|
@ -21,7 +21,7 @@ public class PhotoObject {
|
||||
public TLRPC.PhotoSize photoOwner;
|
||||
public Bitmap image;
|
||||
|
||||
public PhotoObject(TLRPC.PhotoSize photo, int preview) {
|
||||
public PhotoObject(TLRPC.PhotoSize photo, int preview, boolean secret) {
|
||||
photoOwner = photo;
|
||||
|
||||
if (preview != 0 && photo instanceof TLRPC.TL_photoCachedSize) {
|
||||
@ -34,7 +34,13 @@ public class PhotoObject {
|
||||
image = BitmapFactory.decodeByteArray(photoOwner.bytes, 0, photoOwner.bytes.length, opts);
|
||||
if (image != null) {
|
||||
if (preview == 2) {
|
||||
Utilities.blurBitmap(image);
|
||||
if (secret) {
|
||||
Utilities.blurBitmap(image, 7);
|
||||
Utilities.blurBitmap(image, 7);
|
||||
Utilities.blurBitmap(image, 7);
|
||||
} else {
|
||||
Utilities.blurBitmap(image, 3);
|
||||
}
|
||||
}
|
||||
if (ImageLoader.getInstance().runtimeHack != null) {
|
||||
ImageLoader.getInstance().runtimeHack.trackFree(image.getRowBytes() * image.getHeight());
|
||||
|
@ -364,6 +364,9 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||
private int sendMessage(String message, double lat, double lon, TLRPC.TL_photo photo, TLRPC.TL_video video, MessageObject msgObj, TLRPC.User user, TLRPC.TL_document document, TLRPC.TL_audio audio, String originalPath, long peer, boolean retry, String path) {
|
||||
TLRPC.Message newMsg = null;
|
||||
int type = -1;
|
||||
int lower_id = (int) peer;
|
||||
int high_id = (int) (peer >> 32);
|
||||
|
||||
if (retry) {
|
||||
newMsg = msgObj.messageOwner;
|
||||
|
||||
@ -409,12 +412,20 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||
}
|
||||
} else {
|
||||
if (message != null) {
|
||||
newMsg = new TLRPC.TL_message();
|
||||
if (lower_id != 0) {
|
||||
newMsg = new TLRPC.TL_message();
|
||||
} else {
|
||||
newMsg = new TLRPC.TL_message_secret();
|
||||
}
|
||||
newMsg.media = new TLRPC.TL_messageMediaEmpty();
|
||||
type = 0;
|
||||
newMsg.message = message;
|
||||
} else if (lat != 0 && lon != 0) {
|
||||
newMsg = new TLRPC.TL_message();
|
||||
if (lower_id != 0) {
|
||||
newMsg = new TLRPC.TL_message();
|
||||
} else {
|
||||
newMsg = new TLRPC.TL_message_secret();
|
||||
}
|
||||
newMsg.media = new TLRPC.TL_messageMediaGeo();
|
||||
newMsg.media.geo = new TLRPC.TL_geoPoint();
|
||||
newMsg.media.geo.lat = lat;
|
||||
@ -422,7 +433,11 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||
newMsg.message = "";
|
||||
type = 1;
|
||||
} else if (photo != null) {
|
||||
newMsg = new TLRPC.TL_message();
|
||||
if (lower_id != 0) {
|
||||
newMsg = new TLRPC.TL_message();
|
||||
} else {
|
||||
newMsg = new TLRPC.TL_message_secret();
|
||||
}
|
||||
newMsg.media = new TLRPC.TL_messageMediaPhoto();
|
||||
newMsg.media.photo = photo;
|
||||
type = 2;
|
||||
@ -430,7 +445,11 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||
TLRPC.FileLocation location1 = photo.sizes.get(photo.sizes.size() - 1).location;
|
||||
newMsg.attachPath = FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE) + "/" + location1.volume_id + "_" + location1.local_id + ".jpg";
|
||||
} else if (video != null) {
|
||||
newMsg = new TLRPC.TL_message();
|
||||
if (lower_id != 0) {
|
||||
newMsg = new TLRPC.TL_message();
|
||||
} else {
|
||||
newMsg = new TLRPC.TL_message_secret();
|
||||
}
|
||||
newMsg.media = new TLRPC.TL_messageMediaVideo();
|
||||
newMsg.media.video = video;
|
||||
newMsg.videoEditedInfo = video.videoEditedInfo;
|
||||
@ -461,7 +480,11 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||
type = 4;
|
||||
}
|
||||
} else if (user != null) {
|
||||
newMsg = new TLRPC.TL_message();
|
||||
if (lower_id != 0) {
|
||||
newMsg = new TLRPC.TL_message();
|
||||
} else {
|
||||
newMsg = new TLRPC.TL_message_secret();
|
||||
}
|
||||
newMsg.media = new TLRPC.TL_messageMediaContact();
|
||||
newMsg.media.phone_number = user.phone;
|
||||
newMsg.media.first_name = user.first_name;
|
||||
@ -470,14 +493,22 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||
newMsg.message = "";
|
||||
type = 6;
|
||||
} else if (document != null) {
|
||||
newMsg = new TLRPC.TL_message();
|
||||
if (lower_id != 0) {
|
||||
newMsg = new TLRPC.TL_message();
|
||||
} else {
|
||||
newMsg = new TLRPC.TL_message_secret();
|
||||
}
|
||||
newMsg.media = new TLRPC.TL_messageMediaDocument();
|
||||
newMsg.media.document = document;
|
||||
type = 7;
|
||||
newMsg.message = "-1";
|
||||
newMsg.attachPath = path;
|
||||
} else if (audio != null) {
|
||||
newMsg = new TLRPC.TL_message();
|
||||
if (lower_id != 0) {
|
||||
newMsg = new TLRPC.TL_message();
|
||||
} else {
|
||||
newMsg = new TLRPC.TL_message_secret();
|
||||
}
|
||||
newMsg.media = new TLRPC.TL_messageMediaAudio();
|
||||
newMsg.media.audio = audio;
|
||||
type = 8;
|
||||
@ -487,7 +518,6 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||
newMsg.local_id = newMsg.id = UserConfig.getNewMessageId();
|
||||
newMsg.from_id = UserConfig.getClientUserId();
|
||||
newMsg.flags |= TLRPC.MESSAGE_FLAG_OUT;
|
||||
newMsg.out = true;
|
||||
UserConfig.saveConfig(false);
|
||||
}
|
||||
if (newMsg.random_id == 0) {
|
||||
@ -495,10 +525,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||
}
|
||||
newMsg.date = ConnectionsManager.getInstance().getCurrentTime();
|
||||
newMsg.flags |= TLRPC.MESSAGE_FLAG_UNREAD;
|
||||
newMsg.unread = true;
|
||||
newMsg.dialog_id = peer;
|
||||
int lower_id = (int) peer;
|
||||
int high_id = (int) (peer >> 32);
|
||||
TLRPC.EncryptedChat encryptedChat = null;
|
||||
TLRPC.InputPeer sendToPeer = null;
|
||||
ArrayList<TLRPC.InputUser> sendToPeers = null;
|
||||
@ -1405,6 +1432,19 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||
}
|
||||
}
|
||||
|
||||
public void sendMessagesReadMessage(ArrayList<Long> random_ids, TLRPC.EncryptedChat encryptedChat) {
|
||||
if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) {
|
||||
return;
|
||||
}
|
||||
TLRPC.TL_decryptedMessageService_old reqSend = new TLRPC.TL_decryptedMessageService_old();
|
||||
reqSend.random_id = getNextRandomId();
|
||||
reqSend.random_bytes = new byte[Math.max(1, (int)Math.ceil(Utilities.random.nextDouble() * 16))];
|
||||
Utilities.random.nextBytes(reqSend.random_bytes);
|
||||
reqSend.action = new TLRPC.TL_decryptedMessageActionReadMessages();
|
||||
reqSend.action.random_ids = random_ids;
|
||||
performSendEncryptedRequest(reqSend, null, encryptedChat, null, null);
|
||||
}
|
||||
|
||||
public void sendMessagesDeleteMessage(ArrayList<Long> random_ids, TLRPC.EncryptedChat encryptedChat) {
|
||||
if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) {
|
||||
return;
|
||||
@ -1440,7 +1480,6 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||
newMsg.action.ttl = encryptedChat.ttl;
|
||||
newMsg.local_id = newMsg.id = UserConfig.getNewMessageId();
|
||||
newMsg.from_id = UserConfig.getClientUserId();
|
||||
newMsg.unread = true;
|
||||
newMsg.flags = TLRPC.MESSAGE_FLAG_UNREAD | TLRPC.MESSAGE_FLAG_OUT;
|
||||
newMsg.dialog_id = ((long)encryptedChat.id) << 32;
|
||||
newMsg.to_id = new TLRPC.TL_peerUser();
|
||||
@ -1449,7 +1488,6 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||
} else {
|
||||
newMsg.to_id.user_id = encryptedChat.participant_id;
|
||||
}
|
||||
newMsg.out = true;
|
||||
newMsg.date = ConnectionsManager.getInstance().getCurrentTime();
|
||||
newMsg.random_id = getNextRandomId();
|
||||
UserConfig.saveConfig(false);
|
||||
@ -1488,7 +1526,6 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||
|
||||
newMsg.local_id = newMsg.id = UserConfig.getNewMessageId();
|
||||
newMsg.from_id = UserConfig.getClientUserId();
|
||||
newMsg.unread = true;
|
||||
newMsg.flags = TLRPC.MESSAGE_FLAG_UNREAD | TLRPC.MESSAGE_FLAG_OUT;
|
||||
newMsg.dialog_id = ((long)encryptedChat.id) << 32;
|
||||
newMsg.to_id = new TLRPC.TL_peerUser();
|
||||
@ -1497,7 +1534,6 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
|
||||
} else {
|
||||
newMsg.to_id.user_id = encryptedChat.participant_id;
|
||||
}
|
||||
newMsg.out = true;
|
||||
newMsg.date = ConnectionsManager.getInstance().getCurrentTime();
|
||||
newMsg.random_id = getNextRandomId();
|
||||
UserConfig.saveConfig(false);
|
||||
|
@ -997,6 +997,10 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
|
||||
return (int)(System.currentTimeMillis() / 1000) + timeDifference;
|
||||
}
|
||||
|
||||
public int getTimeDifference() {
|
||||
return timeDifference;
|
||||
}
|
||||
|
||||
private void processRequestQueue(int requestClass, int _datacenterId) {
|
||||
boolean haveNetwork = true;//isNetworkOnline();
|
||||
|
||||
|
@ -362,6 +362,7 @@ public class TLClassStore {
|
||||
classStore.put(TLRPC.TL_messageService_old.constructor, TLRPC.TL_messageService_old.class);
|
||||
classStore.put(TLRPC.TL_decryptedMessageService_old.constructor, TLRPC.TL_decryptedMessageService_old.class);
|
||||
classStore.put(TLRPC.TL_decryptedMessage_old.constructor, TLRPC.TL_decryptedMessage_old.class);
|
||||
classStore.put(TLRPC.TL_message_secret.constructor, TLRPC.TL_message_secret.class);
|
||||
}
|
||||
|
||||
static TLClassStore store = null;
|
||||
|
@ -8769,8 +8769,6 @@ public class TLRPC {
|
||||
public int fwd_date;
|
||||
public int from_id;
|
||||
public Peer to_id;
|
||||
public boolean out;
|
||||
public boolean unread;
|
||||
public int date;
|
||||
public String message;
|
||||
public MessageMedia media;
|
||||
@ -8782,6 +8780,7 @@ public class TLRPC {
|
||||
public int local_id = 0;
|
||||
public long dialog_id;
|
||||
public int ttl;
|
||||
public int destroyTime;
|
||||
public VideoEditedInfo videoEditedInfo = null;
|
||||
}
|
||||
|
||||
@ -8799,8 +8798,6 @@ public class TLRPC {
|
||||
date = stream.readInt32();
|
||||
message = stream.readString();
|
||||
media = (MessageMedia)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
|
||||
out = (flags & MESSAGE_FLAG_OUT) != 0;
|
||||
unread = (flags & MESSAGE_FLAG_UNREAD) != 0;
|
||||
if (id < 0) {
|
||||
fwd_msg_id = stream.readInt32();
|
||||
}
|
||||
@ -8843,8 +8840,6 @@ public class TLRPC {
|
||||
date = stream.readInt32();
|
||||
message = stream.readString();
|
||||
media = (MessageMedia)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
|
||||
out = (flags & 2) != 0;
|
||||
unread = (flags & 1) != 0;
|
||||
if (id < 0 || (media != null && !(media instanceof TL_messageMediaEmpty) && message != null && message.length() != 0 && message.startsWith("-1"))) {
|
||||
attachPath = stream.readString();
|
||||
}
|
||||
@ -8878,8 +8873,6 @@ public class TLRPC {
|
||||
to_id = (Peer)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
|
||||
date = stream.readInt32();
|
||||
action = (MessageAction)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
|
||||
out = (flags & 2) != 0;
|
||||
unread = (flags & 1) != 0;
|
||||
}
|
||||
|
||||
public void serializeToStream(AbsSerializedData stream) {
|
||||
@ -8901,8 +8894,8 @@ public class TLRPC {
|
||||
id = stream.readInt32();
|
||||
from_id = stream.readInt32();
|
||||
to_id = (Peer)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
|
||||
out = stream.readBool();
|
||||
unread = stream.readBool();
|
||||
flags |= stream.readBool() ? MESSAGE_FLAG_OUT : 0;
|
||||
flags |= stream.readBool() ? MESSAGE_FLAG_UNREAD : 0;
|
||||
date = stream.readInt32();
|
||||
action = (MessageAction)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
|
||||
}
|
||||
@ -8912,8 +8905,8 @@ public class TLRPC {
|
||||
stream.writeInt32(id);
|
||||
stream.writeInt32(from_id);
|
||||
to_id.serializeToStream(stream);
|
||||
stream.writeBool(out);
|
||||
stream.writeBool(unread);
|
||||
stream.writeBool((flags & MESSAGE_FLAG_OUT) != 0);
|
||||
stream.writeBool((flags & MESSAGE_FLAG_UNREAD) != 0);
|
||||
stream.writeInt32(date);
|
||||
action.serializeToStream(stream);
|
||||
}
|
||||
@ -8929,8 +8922,8 @@ public class TLRPC {
|
||||
fwd_date = stream.readInt32();
|
||||
from_id = stream.readInt32();
|
||||
to_id = (Peer)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
|
||||
out = stream.readBool();
|
||||
unread = stream.readBool();
|
||||
flags |= stream.readBool() ? MESSAGE_FLAG_OUT : 0;
|
||||
flags |= stream.readBool() ? MESSAGE_FLAG_UNREAD : 0;
|
||||
date = stream.readInt32();
|
||||
message = stream.readString();
|
||||
media = (MessageMedia)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
|
||||
@ -8953,8 +8946,8 @@ public class TLRPC {
|
||||
stream.writeInt32(fwd_date);
|
||||
stream.writeInt32(from_id);
|
||||
to_id.serializeToStream(stream);
|
||||
stream.writeBool(out);
|
||||
stream.writeBool(unread);
|
||||
stream.writeBool((flags & MESSAGE_FLAG_OUT) != 0);
|
||||
stream.writeBool((flags & MESSAGE_FLAG_UNREAD) != 0);
|
||||
stream.writeInt32(date);
|
||||
stream.writeString(message);
|
||||
media.serializeToStream(stream);
|
||||
@ -8972,8 +8965,8 @@ public class TLRPC {
|
||||
id = stream.readInt32();
|
||||
from_id = stream.readInt32();
|
||||
to_id = (Peer)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
|
||||
out = stream.readBool();
|
||||
unread = stream.readBool();
|
||||
flags |= stream.readBool() ? MESSAGE_FLAG_OUT : 0;
|
||||
flags |= stream.readBool() ? MESSAGE_FLAG_UNREAD : 0;
|
||||
date = stream.readInt32();
|
||||
message = stream.readString();
|
||||
media = (MessageMedia)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
|
||||
@ -8991,8 +8984,8 @@ public class TLRPC {
|
||||
stream.writeInt32(id);
|
||||
stream.writeInt32(from_id);
|
||||
to_id.serializeToStream(stream);
|
||||
stream.writeBool(out);
|
||||
stream.writeBool(unread);
|
||||
stream.writeBool((flags & MESSAGE_FLAG_OUT) != 0);
|
||||
stream.writeBool((flags & MESSAGE_FLAG_UNREAD) != 0);
|
||||
stream.writeInt32(date);
|
||||
stream.writeString(message);
|
||||
media.serializeToStream(stream);
|
||||
@ -9004,11 +8997,11 @@ public class TLRPC {
|
||||
public static int constructor = 0x555555F8;
|
||||
|
||||
public void readParams(AbsSerializedData stream) {
|
||||
flags = stream.readInt32();
|
||||
id = stream.readInt32();
|
||||
ttl = stream.readInt32();
|
||||
from_id = stream.readInt32();
|
||||
to_id = (Peer)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
|
||||
out = stream.readBool();
|
||||
unread = stream.readBool();
|
||||
date = stream.readInt32();
|
||||
message = stream.readString();
|
||||
media = (MessageMedia)TLClassStore.Instance().TLdeserialize(stream, stream.readInt32());
|
||||
@ -9023,11 +9016,11 @@ public class TLRPC {
|
||||
|
||||
public void serializeToStream(AbsSerializedData stream) {
|
||||
stream.writeInt32(constructor);
|
||||
stream.writeInt32(flags);
|
||||
stream.writeInt32(id);
|
||||
stream.writeInt32(ttl);
|
||||
stream.writeInt32(from_id);
|
||||
to_id.serializeToStream(stream);
|
||||
stream.writeBool(out);
|
||||
stream.writeBool(unread);
|
||||
stream.writeInt32(date);
|
||||
stream.writeString(message);
|
||||
media.serializeToStream(stream);
|
||||
@ -9773,7 +9766,7 @@ public class TLRPC {
|
||||
}
|
||||
|
||||
public static class TL_decryptedMessageActionScreenshotMessages extends DecryptedMessageAction {
|
||||
public static int constructor = 0x954bd30;
|
||||
public static int constructor = 0x8ac1f475;
|
||||
|
||||
|
||||
public void readParams(AbsSerializedData stream) {
|
||||
|
@ -28,7 +28,6 @@ import net.hockeyapp.android.CrashManager;
|
||||
import net.hockeyapp.android.CrashManagerListener;
|
||||
import net.hockeyapp.android.UpdateManager;
|
||||
|
||||
import org.telegram.android.LocaleController;
|
||||
import org.telegram.ui.ApplicationLoader;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
@ -112,7 +111,7 @@ public class Utilities {
|
||||
|
||||
public native static long doPQNative(long _what);
|
||||
public native static void loadBitmap(String path, int[] bitmap, int scale, int format, int width, int height);
|
||||
public native static void blurBitmap(Object bitmap);
|
||||
public native static void blurBitmap(Object bitmap, int radius);
|
||||
public native static int convertVideoFrame(ByteBuffer src, ByteBuffer dest, int destFormat, int width, int height, int padding, int swap);
|
||||
private native static void aesIgeEncryption(ByteBuffer buffer, byte[] key, byte[] iv, boolean encrypt, int offset, int length);
|
||||
|
||||
|
@ -25,6 +25,7 @@ import android.view.animation.DecelerateInterpolator;
|
||||
import org.telegram.android.AndroidUtilities;
|
||||
import org.telegram.android.ImageLoader;
|
||||
import org.telegram.android.LocaleController;
|
||||
import org.telegram.messenger.ConnectionsManager;
|
||||
import org.telegram.messenger.FileLoader;
|
||||
import org.telegram.android.MediaController;
|
||||
import org.telegram.messenger.R;
|
||||
@ -41,7 +42,9 @@ import java.util.Locale;
|
||||
public class ChatMediaCell extends ChatBaseCell implements MediaController.FileDownloadProgressListener {
|
||||
|
||||
public static interface ChatMediaCellDelegate {
|
||||
public abstract void didPressedImage(ChatMediaCell cell);
|
||||
public abstract boolean didPressedImage(ChatMediaCell cell);
|
||||
public abstract void didUnpressedImage(ChatMediaCell cell);
|
||||
public abstract void didClickedImage(ChatMediaCell cell);
|
||||
public abstract void didPressedOther(ChatMediaCell cell);
|
||||
}
|
||||
|
||||
@ -52,13 +55,14 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
||||
private static Drawable videoIconDrawable;
|
||||
private static Drawable docMenuInDrawable;
|
||||
private static Drawable docMenuOutDrawable;
|
||||
private static Drawable[] buttonStatesDrawables = new Drawable[5];
|
||||
private static Drawable[] buttonStatesDrawables = new Drawable[8];
|
||||
private static Drawable[][] buttonStatesDrawablesDoc = new Drawable[3][2];
|
||||
private static TextPaint infoPaint;
|
||||
private static MessageObject lastDownloadedGifMessage = null;
|
||||
private static TextPaint namePaint;
|
||||
private static Paint docBackPaint;
|
||||
private static Paint progressPaint;
|
||||
private static Paint deleteProgressPaint;
|
||||
private static DecelerateInterpolator decelerateInterpolator;
|
||||
|
||||
private GifDrawable gifDrawable = null;
|
||||
@ -81,6 +85,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
||||
private boolean otherPressed = false;
|
||||
private int buttonX;
|
||||
private int buttonY;
|
||||
private boolean listenForUnpressed = false;
|
||||
|
||||
private StaticLayout infoLayout;
|
||||
private int infoWidth;
|
||||
@ -101,6 +106,8 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
||||
private float animatedProgressValue = 0;
|
||||
private long currentProgressTime = 0;
|
||||
private float animationProgressStart = 0;
|
||||
private RectF deleteProgressRect = new RectF();
|
||||
private int lastSecretSecondsLeft = 0;
|
||||
|
||||
public ChatMediaCell(Context context) {
|
||||
super(context);
|
||||
@ -115,6 +122,9 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
||||
buttonStatesDrawables[2] = getResources().getDrawable(R.drawable.photogif);
|
||||
buttonStatesDrawables[3] = getResources().getDrawable(R.drawable.playvideo);
|
||||
buttonStatesDrawables[4] = getResources().getDrawable(R.drawable.photopause);
|
||||
buttonStatesDrawables[5] = getResources().getDrawable(R.drawable.burn);
|
||||
buttonStatesDrawables[6] = getResources().getDrawable(R.drawable.circle);
|
||||
buttonStatesDrawables[7] = getResources().getDrawable(R.drawable.photocheck);
|
||||
buttonStatesDrawablesDoc[0][0] = getResources().getDrawable(R.drawable.docload_b);
|
||||
buttonStatesDrawablesDoc[1][0] = getResources().getDrawable(R.drawable.doccancel_b);
|
||||
buttonStatesDrawablesDoc[2][0] = getResources().getDrawable(R.drawable.docpause_b);
|
||||
@ -139,6 +149,9 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
||||
progressPaint.setStrokeCap(Paint.Cap.ROUND);
|
||||
progressPaint.setStrokeWidth(AndroidUtilities.dp(2));
|
||||
|
||||
deleteProgressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
deleteProgressPaint.setColor(0xffe4e2e0);
|
||||
|
||||
decelerateInterpolator = new DecelerateInterpolator();
|
||||
}
|
||||
|
||||
@ -199,7 +212,11 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result) {
|
||||
listenForUnpressed = false;
|
||||
if (imagePressed && mediaDelegate != null && mediaDelegate.didPressedImage(this)) {
|
||||
imagePressed = false;
|
||||
listenForUnpressed = true;
|
||||
} else if (result) {
|
||||
startCheckLongPress();
|
||||
}
|
||||
}
|
||||
@ -226,7 +243,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
||||
if (event.getAction() == MotionEvent.ACTION_UP) {
|
||||
imagePressed = false;
|
||||
playSoundEffect(SoundEffectConstants.CLICK);
|
||||
didPressedImage();
|
||||
didClickedImage();
|
||||
invalidate();
|
||||
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
|
||||
imagePressed = false;
|
||||
@ -260,6 +277,14 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (listenForUnpressed) {
|
||||
if (event.getAction() == MotionEvent.ACTION_POINTER_UP || event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
|
||||
if (listenForUnpressed && mediaDelegate != null) {
|
||||
mediaDelegate.didUnpressedImage(this);
|
||||
}
|
||||
listenForUnpressed = false;
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
if (!result) {
|
||||
@ -269,11 +294,11 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
||||
return result;
|
||||
}
|
||||
|
||||
private void didPressedImage() {
|
||||
private void didClickedImage() {
|
||||
if (currentMessageObject.type == 1) {
|
||||
if (buttonState == -1) {
|
||||
if (mediaDelegate != null) {
|
||||
mediaDelegate.didPressedImage(this);
|
||||
mediaDelegate.didClickedImage(this);
|
||||
}
|
||||
} else if (buttonState == 0) {
|
||||
didPressedButton();
|
||||
@ -294,12 +319,12 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
||||
}
|
||||
} else if (currentMessageObject.type == 4) {
|
||||
if (mediaDelegate != null) {
|
||||
mediaDelegate.didPressedImage(this);
|
||||
mediaDelegate.didClickedImage(this);
|
||||
}
|
||||
} else if (currentMessageObject.type == 9) {
|
||||
if (buttonState == -1) {
|
||||
if (mediaDelegate != null) {
|
||||
mediaDelegate.didPressedImage(this);
|
||||
mediaDelegate.didClickedImage(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -358,7 +383,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
||||
}
|
||||
} else if (buttonState == 3) {
|
||||
if (mediaDelegate != null) {
|
||||
mediaDelegate.didPressedImage(this);
|
||||
mediaDelegate.didClickedImage(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -467,6 +492,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
||||
currentNameString = null;
|
||||
infoLayout = null;
|
||||
nameLayout = null;
|
||||
updateSecretTimeText();
|
||||
}
|
||||
|
||||
if (messageObject.type == 9) {
|
||||
@ -589,6 +615,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
||||
photoImage.setImageBitmap(messageObject.isOut() ? placeholderOutDrawable : placeholderInDrawable);
|
||||
}
|
||||
}
|
||||
photoImage.setForcePreview(messageObject.isSecretMedia());
|
||||
|
||||
invalidate();
|
||||
}
|
||||
@ -754,6 +781,25 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
||||
buttonX = (int)(x + (photoWidth - size) / 2.0f);
|
||||
buttonY = (int)(AndroidUtilities.dp(7) + (photoHeight - size) / 2.0f);
|
||||
progressRect.set(buttonX + AndroidUtilities.dp(1), buttonY + AndroidUtilities.dp(1), buttonX + AndroidUtilities.dp(47), buttonY + AndroidUtilities.dp(47));
|
||||
deleteProgressRect.set(buttonX + AndroidUtilities.dp(3), buttonY + AndroidUtilities.dp(3), buttonX + AndroidUtilities.dp(45), buttonY + AndroidUtilities.dp(45));
|
||||
}
|
||||
|
||||
private void updateSecretTimeText() {
|
||||
if (currentMessageObject == null) {
|
||||
return;
|
||||
}
|
||||
String str = currentMessageObject.getSecretTimeString();
|
||||
if (str == null) {
|
||||
return;
|
||||
}
|
||||
if (currentInfoString == null || !currentInfoString.equals(str)) {
|
||||
currentInfoString = str;
|
||||
infoOffset = 0;
|
||||
infoWidth = (int)Math.ceil(infoPaint.measureText(currentInfoString));
|
||||
CharSequence str2 = TextUtils.ellipsize(currentInfoString, infoPaint, infoWidth, TextUtils.TruncateAt.END);
|
||||
infoLayout = new StaticLayout(str2, infoPaint, infoWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -826,6 +872,29 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
||||
currentButtonDrawable.draw(canvas);
|
||||
}
|
||||
|
||||
if (buttonState == -1 && currentMessageObject.isSecretMedia()) {
|
||||
int drawable = 5;
|
||||
if (currentMessageObject.messageOwner.destroyTime != 0) {
|
||||
if (currentMessageObject.isOut()) {
|
||||
drawable = 7;
|
||||
} else {
|
||||
drawable = 6;
|
||||
}
|
||||
}
|
||||
setDrawableBounds(buttonStatesDrawables[drawable], buttonX, buttonY);
|
||||
buttonStatesDrawables[drawable].draw(canvas);
|
||||
if (!currentMessageObject.isOut() && currentMessageObject.messageOwner.destroyTime != 0) {
|
||||
long msTime = System.currentTimeMillis() + ConnectionsManager.getInstance().getTimeDifference() * 1000;
|
||||
float progress = Math.max(0, (long)currentMessageObject.messageOwner.destroyTime * 1000 - msTime) / (currentMessageObject.messageOwner.ttl * 1000.0f);
|
||||
canvas.drawArc(deleteProgressRect, -90, -360 * progress, true, deleteProgressPaint);
|
||||
if (progress != 0) {
|
||||
int offset = AndroidUtilities.dp(2);
|
||||
invalidate((int)deleteProgressRect.left - offset, (int)deleteProgressRect.top - offset, (int)deleteProgressRect.right + offset * 2, (int)deleteProgressRect.bottom + offset * 2);
|
||||
}
|
||||
updateSecretTimeText();
|
||||
}
|
||||
}
|
||||
|
||||
if (progressVisible) {
|
||||
canvas.drawArc(progressRect, -90 + radOffset, Math.max(4, 360 * animatedProgressValue), false, progressPaint);
|
||||
}
|
||||
@ -842,7 +911,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
|
||||
infoLayout.draw(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
} else if (infoLayout != null && (buttonState == 1 || buttonState == 0 || buttonState == 3)) {
|
||||
} else if (infoLayout != null && (buttonState == 1 || buttonState == 0 || buttonState == 3 || currentMessageObject.isSecretMedia())) {
|
||||
infoPaint.setColor(0xffffffff);
|
||||
setDrawableBounds(mediaBackgroundDrawable, photoImage.getImageX() + AndroidUtilities.dp(4), photoImage.getImageY() + AndroidUtilities.dp(4), infoWidth + AndroidUtilities.dp(8) + infoOffset, AndroidUtilities.dpf(16.5f));
|
||||
mediaBackgroundDrawable.draw(canvas);
|
||||
|
@ -117,7 +117,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||
private TypingDotsDrawable typingDotsDrawable;
|
||||
private View emptyViewContainer;
|
||||
private ArrayList<View> actionModeViews = new ArrayList<View>();
|
||||
private Semaphore testSemaphore = new Semaphore(0);
|
||||
|
||||
private TextView bottomOverlayText;
|
||||
|
||||
@ -175,6 +174,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||
|
||||
private String startVideoEdit = null;
|
||||
|
||||
private Runnable openSecretPhotoRunnable = null;
|
||||
|
||||
private final static int copy = 1;
|
||||
private final static int forward = 2;
|
||||
private final static int delete = 3;
|
||||
@ -354,12 +355,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||
|
||||
loading = true;
|
||||
|
||||
MessagesController.getInstance().loadMessages(dialog_id, AndroidUtilities.isTablet() ? 30 : 20, 0, true, 0, classGuid, true, false, testSemaphore);
|
||||
try {
|
||||
testSemaphore.acquire();
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
MessagesController.getInstance().loadMessages(dialog_id, AndroidUtilities.isTablet() ? 30 : 20, 0, true, 0, classGuid, true, false, null);
|
||||
|
||||
if (currentUser != null) {
|
||||
userBlocked = MessagesController.getInstance().blockedUsers.contains(currentUser.id);
|
||||
@ -2143,7 +2139,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||
}
|
||||
if (!obj.isOut() && obj.isUnread()) {
|
||||
if (!paused) {
|
||||
obj.messageOwner.unread = false;
|
||||
obj.setIsRead();
|
||||
}
|
||||
markAsRead = true;
|
||||
}
|
||||
@ -2217,7 +2213,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||
for (Integer ids : markAsReadMessages) {
|
||||
MessageObject obj = messagesDict.get(ids);
|
||||
if (obj != null) {
|
||||
obj.messageOwner.unread = false;
|
||||
obj.setIsRead();
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
@ -2322,11 +2318,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||
for (MessageObject obj : messages) {
|
||||
if (!obj.isOut()) {
|
||||
continue;
|
||||
} else if (obj.isOut() && !obj.messageOwner.unread) {
|
||||
} else if (obj.isOut() && !obj.isUnread()) {
|
||||
break;
|
||||
}
|
||||
if (obj.messageOwner.date <= date) {
|
||||
obj.messageOwner.unread = false;
|
||||
obj.setIsRead();
|
||||
}
|
||||
}
|
||||
updateVisibleRows();
|
||||
@ -2539,7 +2535,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||
break;
|
||||
}
|
||||
if (!messageObject.isOut()) {
|
||||
messageObject.messageOwner.unread = false;
|
||||
messageObject.setIsRead();
|
||||
}
|
||||
}
|
||||
readWhenResume = false;
|
||||
@ -3354,7 +3350,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||
return view;
|
||||
}
|
||||
}
|
||||
MessageObject message = messages.get(messages.size() - i - offset);
|
||||
final MessageObject message = messages.get(messages.size() - i - offset);
|
||||
int type = message.contentType;
|
||||
if (view == null) {
|
||||
LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
@ -3427,7 +3423,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||
if (view instanceof ChatMediaCell) {
|
||||
((ChatMediaCell)view).mediaDelegate = new ChatMediaCell.ChatMediaCellDelegate() {
|
||||
@Override
|
||||
public void didPressedImage(ChatMediaCell cell) {
|
||||
public void didClickedImage(ChatMediaCell cell) {
|
||||
MessageObject message = cell.getMessageObject();
|
||||
if (message.isSendError()) {
|
||||
createMenu(cell, false);
|
||||
@ -3509,6 +3505,43 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||
public void didPressedOther(ChatMediaCell cell) {
|
||||
createMenu(cell, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean didPressedImage(final ChatMediaCell cell) {
|
||||
final MessageObject messageObject = cell.getMessageObject();
|
||||
if (messageObject == null || !messageObject.isSecretMedia()) {
|
||||
return false;
|
||||
}
|
||||
openSecretPhotoRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (openSecretPhotoRunnable == null) {
|
||||
return;
|
||||
}
|
||||
chatListView.requestDisallowInterceptTouchEvent(true);
|
||||
openSecretPhotoRunnable = null;
|
||||
if (!messageObject.isOut() && messageObject.messageOwner.destroyTime == 0) {
|
||||
MessagesController.getInstance().markMessageAsRead(dialog_id, message.messageOwner.random_id);
|
||||
messageObject.messageOwner.destroyTime = messageObject.messageOwner.ttl + ConnectionsManager.getInstance().getCurrentTime();
|
||||
cell.invalidate();
|
||||
}
|
||||
SecretPhotoViewer.getInstance().setParentActivity(getParentActivity());
|
||||
SecretPhotoViewer.getInstance().openPhoto(messageObject);
|
||||
}
|
||||
};
|
||||
AndroidUtilities.RunOnUIThread(openSecretPhotoRunnable, 100);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void didUnpressedImage(ChatMediaCell cell) {
|
||||
if (openSecretPhotoRunnable != null) {
|
||||
AndroidUtilities.CancelRunOnUIThread(openSecretPhotoRunnable);
|
||||
openSecretPhotoRunnable = null;
|
||||
} else {
|
||||
SecretPhotoViewer.getInstance().closePhoto();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -3693,7 +3726,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
|
||||
checkImage.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
} else if (message.isSent()) {
|
||||
if (!message.messageOwner.unread) {
|
||||
if (!message.isUnread()) {
|
||||
halfCheckImage.setVisibility(View.VISIBLE);
|
||||
checkImage.setVisibility(View.VISIBLE);
|
||||
halfCheckImage.setImageResource(R.drawable.msg_halfcheck);
|
||||
|
@ -836,6 +836,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
PhotoViewer.getInstance().destroyPhotoViewer();
|
||||
SecretPhotoViewer.getInstance().destroyPhotoViewer();
|
||||
super.onDestroy();
|
||||
onFinish();
|
||||
}
|
||||
|
@ -0,0 +1,279 @@
|
||||
/*
|
||||
* This is the source code of Telegram for Android v. 1.7.x.
|
||||
* It is licensed under GNU GPL v. 2 or later.
|
||||
* You should have received a copy of the license in this archive (see LICENSE).
|
||||
*
|
||||
* Copyright Nikolai Kudashov, 2013-2014.
|
||||
*/
|
||||
|
||||
package org.telegram.ui;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.RectF;
|
||||
import android.text.Layout;
|
||||
import android.text.StaticLayout;
|
||||
import android.text.TextPaint;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import org.telegram.android.AndroidUtilities;
|
||||
import org.telegram.android.ImageReceiver;
|
||||
import org.telegram.android.MessageObject;
|
||||
import org.telegram.android.NotificationCenter;
|
||||
import org.telegram.messenger.ConnectionsManager;
|
||||
import org.telegram.messenger.FileLoader;
|
||||
import org.telegram.messenger.FileLog;
|
||||
import org.telegram.messenger.TLRPC;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class SecretPhotoViewer implements NotificationCenter.NotificationCenterDelegate {
|
||||
|
||||
private class FrameLayoutDrawer extends FrameLayout {
|
||||
public FrameLayoutDrawer(Context context) {
|
||||
super(context);
|
||||
setWillNotDraw(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
getInstance().onDraw(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
private class SecretDeleteTimer extends FrameLayout {
|
||||
private String currentInfoString;
|
||||
private int infoWidth;
|
||||
private TextPaint infoPaint = null;
|
||||
private StaticLayout infoLayout = null;
|
||||
private Paint deleteProgressPaint;
|
||||
private RectF deleteProgressRect = new RectF();
|
||||
|
||||
public SecretDeleteTimer(Context context) {
|
||||
super(context);
|
||||
setWillNotDraw(false);
|
||||
|
||||
infoPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
|
||||
infoPaint.setTextSize(AndroidUtilities.dp(15));
|
||||
infoPaint.setColor(0xffffffff);
|
||||
|
||||
deleteProgressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
deleteProgressPaint.setColor(0xffe6e6e6);
|
||||
}
|
||||
|
||||
private void updateSecretTimeText() {
|
||||
if (currentMessageObject == null) {
|
||||
return;
|
||||
}
|
||||
String str = currentMessageObject.getSecretTimeString();
|
||||
if (str == null) {
|
||||
return;
|
||||
}
|
||||
if (currentInfoString == null || !currentInfoString.equals(str)) {
|
||||
currentInfoString = str;
|
||||
infoWidth = (int)Math.ceil(infoPaint.measureText(currentInfoString));
|
||||
CharSequence str2 = TextUtils.ellipsize(currentInfoString, infoPaint, infoWidth, TextUtils.TruncateAt.END);
|
||||
infoLayout = new StaticLayout(str2, infoPaint, infoWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
deleteProgressRect.set(getMeasuredWidth() - AndroidUtilities.dp(27), 0, getMeasuredWidth(), AndroidUtilities.dp(27));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
if (currentMessageObject == null) {
|
||||
return;
|
||||
}
|
||||
long msTime = System.currentTimeMillis() + ConnectionsManager.getInstance().getTimeDifference() * 1000;
|
||||
float progress = Math.max(0, (long)currentMessageObject.messageOwner.destroyTime * 1000 - msTime) / (currentMessageObject.messageOwner.ttl * 1000.0f);
|
||||
canvas.drawArc(deleteProgressRect, -90, -360 * progress, true, deleteProgressPaint);
|
||||
if (progress != 0) {
|
||||
int offset = AndroidUtilities.dp(2);
|
||||
invalidate((int)deleteProgressRect.left - offset, (int)deleteProgressRect.top - offset, (int)deleteProgressRect.right + offset * 2, (int)deleteProgressRect.bottom + offset * 2);
|
||||
}
|
||||
updateSecretTimeText();
|
||||
|
||||
if (infoLayout != null) {
|
||||
canvas.save();
|
||||
canvas.translate(getMeasuredWidth() - AndroidUtilities.dp(34) - infoWidth, AndroidUtilities.dp(5));
|
||||
infoLayout.draw(canvas);
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Activity parentActivity;
|
||||
private WindowManager.LayoutParams windowLayoutParams;
|
||||
private FrameLayout windowView;
|
||||
private FrameLayoutDrawer containerView;
|
||||
private ImageReceiver centerImage = new ImageReceiver();
|
||||
private SecretDeleteTimer secretDeleteTimer;
|
||||
|
||||
private MessageObject currentMessageObject = null;
|
||||
|
||||
private static volatile SecretPhotoViewer Instance = null;
|
||||
public static SecretPhotoViewer getInstance() {
|
||||
SecretPhotoViewer localInstance = Instance;
|
||||
if (localInstance == null) {
|
||||
synchronized (PhotoViewer.class) {
|
||||
localInstance = Instance;
|
||||
if (localInstance == null) {
|
||||
Instance = localInstance = new SecretPhotoViewer();
|
||||
}
|
||||
}
|
||||
}
|
||||
return localInstance;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void didReceivedNotification(int id, Object... args) {
|
||||
if (id == NotificationCenter.messagesDeleted) {
|
||||
if (currentMessageObject == null) {
|
||||
return;
|
||||
}
|
||||
ArrayList<Integer> markAsDeletedMessages = (ArrayList<Integer>)args[0];
|
||||
if (markAsDeletedMessages.contains(currentMessageObject.messageOwner.id)) {
|
||||
closePhoto();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setParentActivity(Activity activity) {
|
||||
if (parentActivity == activity) {
|
||||
return;
|
||||
}
|
||||
parentActivity = activity;
|
||||
|
||||
windowView = new FrameLayout(activity);
|
||||
windowView.setBackgroundColor(0xff000000);
|
||||
windowView.setFocusable(false);
|
||||
|
||||
containerView = new FrameLayoutDrawer(activity);
|
||||
containerView.setFocusable(false);
|
||||
windowView.addView(containerView);
|
||||
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams)containerView.getLayoutParams();
|
||||
layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT;
|
||||
layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT;
|
||||
layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
|
||||
containerView.setLayoutParams(layoutParams);
|
||||
|
||||
secretDeleteTimer = new SecretDeleteTimer(activity);
|
||||
containerView.addView(secretDeleteTimer);
|
||||
layoutParams = (FrameLayout.LayoutParams)secretDeleteTimer.getLayoutParams();
|
||||
layoutParams.gravity = Gravity.TOP | Gravity.RIGHT;
|
||||
layoutParams.width = AndroidUtilities.dp(100);
|
||||
layoutParams.height = AndroidUtilities.dp(27);
|
||||
layoutParams.rightMargin = AndroidUtilities.dp(19);
|
||||
layoutParams.topMargin = AndroidUtilities.dp(19);
|
||||
secretDeleteTimer.setLayoutParams(layoutParams);
|
||||
|
||||
windowLayoutParams = new WindowManager.LayoutParams();
|
||||
windowLayoutParams.height = WindowManager.LayoutParams.MATCH_PARENT;
|
||||
windowLayoutParams.format = PixelFormat.TRANSLUCENT;
|
||||
windowLayoutParams.width = WindowManager.LayoutParams.MATCH_PARENT;
|
||||
windowLayoutParams.gravity = Gravity.TOP;
|
||||
windowLayoutParams.type = WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
|
||||
windowLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
|
||||
|
||||
centerImage.setParentView(containerView);
|
||||
}
|
||||
|
||||
public void openPhoto(MessageObject messageObject) {
|
||||
if (parentActivity == null || messageObject == null || messageObject.messageOwner.media == null || messageObject.messageOwner.media.photo == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
NotificationCenter.getInstance().addObserver(this, NotificationCenter.messagesDeleted);
|
||||
|
||||
TLRPC.PhotoSize sizeFull = FileLoader.getClosestPhotoSizeWithSize(messageObject.messageOwner.media.photo.sizes, AndroidUtilities.getPhotoSize());
|
||||
int size = sizeFull.size;
|
||||
if (size == 0) {
|
||||
size = -1;
|
||||
}
|
||||
centerImage.setImage(sizeFull.location, null, null, size, false);
|
||||
currentMessageObject = messageObject;
|
||||
|
||||
AndroidUtilities.lockOrientation(parentActivity);
|
||||
|
||||
try {
|
||||
if (windowView.getParent() != null) {
|
||||
WindowManager wm = (WindowManager) parentActivity.getSystemService(Context.WINDOW_SERVICE);
|
||||
wm.removeView(windowView);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
|
||||
WindowManager wm = (WindowManager) parentActivity.getSystemService(Context.WINDOW_SERVICE);
|
||||
wm.addView(windowView, windowLayoutParams);
|
||||
secretDeleteTimer.invalidate();
|
||||
}
|
||||
|
||||
public void closePhoto() {
|
||||
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.messagesDeleted);
|
||||
if (parentActivity == null) {
|
||||
return;
|
||||
}
|
||||
currentMessageObject = null;
|
||||
AndroidUtilities.unlockOrientation(parentActivity);
|
||||
centerImage.setImageBitmap((Bitmap)null);
|
||||
try {
|
||||
if (windowView.getParent() != null) {
|
||||
WindowManager wm = (WindowManager) parentActivity.getSystemService(Context.WINDOW_SERVICE);
|
||||
wm.removeView(windowView);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void destroyPhotoViewer() {
|
||||
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.messagesDeleted);
|
||||
if (parentActivity == null || windowView == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (windowView.getParent() != null) {
|
||||
WindowManager wm = (WindowManager) parentActivity.getSystemService(Context.WINDOW_SERVICE);
|
||||
wm.removeViewImmediate(windowView);
|
||||
}
|
||||
windowView = null;
|
||||
} catch (Exception e) {
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
Instance = null;
|
||||
}
|
||||
|
||||
private void onDraw(Canvas canvas) {
|
||||
canvas.save();
|
||||
canvas.translate(containerView.getWidth() / 2, containerView.getHeight() / 2);
|
||||
Bitmap bitmap = centerImage.getBitmap();
|
||||
if (bitmap != null) {
|
||||
int bitmapWidth = bitmap.getWidth();
|
||||
int bitmapHeight = bitmap.getHeight();
|
||||
|
||||
float scaleX = (float) containerView.getWidth() / (float) bitmapWidth;
|
||||
float scaleY = (float) containerView.getHeight() / (float) bitmapHeight;
|
||||
float scale = scaleX > scaleY ? scaleY : scaleX;
|
||||
int width = (int) (bitmapWidth * scale);
|
||||
int height = (int) (bitmapHeight * scale);
|
||||
|
||||
centerImage.setImageCoords(-width / 2, -height / 2, width, height);
|
||||
centerImage.draw(canvas, -width / 2, -height / 2, width, height);
|
||||
}
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
@ -318,7 +318,7 @@ public class UserProfileActivity extends BaseFragment implements NotificationCen
|
||||
return fragmentView;
|
||||
}
|
||||
|
||||
public void didReceivedNotification(int id, Object... args) {
|
||||
public void didReceivedNotification(int id, final Object... args) {
|
||||
if (id == NotificationCenter.updateInterfaces) {
|
||||
int mask = (Integer)args[0];
|
||||
if ((mask & MessagesController.UPDATE_MASK_AVATAR) != 0 || (mask & MessagesController.UPDATE_MASK_NAME) != 0) {
|
||||
@ -338,11 +338,16 @@ public class UserProfileActivity extends BaseFragment implements NotificationCen
|
||||
}
|
||||
} else if (id == NotificationCenter.encryptedChatCreated) {
|
||||
if (creatingChat) {
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats);
|
||||
TLRPC.EncryptedChat encryptedChat = (TLRPC.EncryptedChat)args[0];
|
||||
Bundle args2 = new Bundle();
|
||||
args2.putInt("enc_id", encryptedChat.id);
|
||||
presentFragment(new ChatActivity(args2), true);
|
||||
AndroidUtilities.RunOnUIThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
NotificationCenter.getInstance().postNotificationName(NotificationCenter.closeChats);
|
||||
TLRPC.EncryptedChat encryptedChat = (TLRPC.EncryptedChat)args[0];
|
||||
Bundle args2 = new Bundle();
|
||||
args2.putInt("enc_id", encryptedChat.id);
|
||||
presentFragment(new ChatActivity(args2), true);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (id == NotificationCenter.encryptedChatUpdated) {
|
||||
TLRPC.EncryptedChat chat = (TLRPC.EncryptedChat)args[0];
|
||||
|
@ -276,22 +276,27 @@ public class VideoEditorActivity extends BaseFragment implements TextureView.Sur
|
||||
});
|
||||
|
||||
if (Build.VERSION.SDK_INT < 18) {
|
||||
MediaCodecInfo codecInfo = MediaController.selectCodec(MediaController.MIME_TYPE);
|
||||
if (codecInfo == null) {
|
||||
compressVideo.setVisibility(View.GONE);
|
||||
} else {
|
||||
String name = codecInfo.getName();
|
||||
if (name.equals("OMX.google.h264.encoder") ||
|
||||
name.equals("OMX.ST.VFM.H264Enc") ||
|
||||
name.equals("OMX.Exynos.avc.enc") ||
|
||||
name.equals("OMX.MARVELL.VIDEO.HW.CODA7542ENCODER") ||
|
||||
name.equals("OMX.MARVELL.VIDEO.H264ENCODER")) {
|
||||
try {
|
||||
MediaCodecInfo codecInfo = MediaController.selectCodec(MediaController.MIME_TYPE);
|
||||
if (codecInfo == null) {
|
||||
compressVideo.setVisibility(View.GONE);
|
||||
} else {
|
||||
if (MediaController.selectColorFormat(codecInfo, MediaController.MIME_TYPE) == 0) {
|
||||
String name = codecInfo.getName();
|
||||
if (name.equals("OMX.google.h264.encoder") ||
|
||||
name.equals("OMX.ST.VFM.H264Enc") ||
|
||||
name.equals("OMX.Exynos.avc.enc") ||
|
||||
name.equals("OMX.MARVELL.VIDEO.HW.CODA7542ENCODER") ||
|
||||
name.equals("OMX.MARVELL.VIDEO.H264ENCODER")) {
|
||||
compressVideo.setVisibility(View.GONE);
|
||||
} else {
|
||||
if (MediaController.selectColorFormat(codecInfo, MediaController.MIME_TYPE) == 0) {
|
||||
compressVideo.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
compressVideo.setVisibility(View.GONE);
|
||||
FileLog.e("tmessages", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.9 KiB |
BIN
TMessagesProj/src/main/res/drawable-hdpi/circle.png
Executable file
After Width: | Height: | Size: 1.8 KiB |
BIN
TMessagesProj/src/main/res/drawable-hdpi/photocheck.png
Executable file
After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.9 KiB |
BIN
TMessagesProj/src/main/res/drawable-ldpi/circle.png
Executable file
After Width: | Height: | Size: 1.3 KiB |
BIN
TMessagesProj/src/main/res/drawable-ldpi/photocheck.png
Executable file
After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.2 KiB |
BIN
TMessagesProj/src/main/res/drawable-mdpi/circle.png
Executable file
After Width: | Height: | Size: 1.5 KiB |
BIN
TMessagesProj/src/main/res/drawable-mdpi/photocheck.png
Executable file
After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.8 KiB |
BIN
TMessagesProj/src/main/res/drawable-xhdpi/circle.png
Executable file
After Width: | Height: | Size: 2.5 KiB |
BIN
TMessagesProj/src/main/res/drawable-xhdpi/photocheck.png
Executable file
After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.4 KiB |
BIN
TMessagesProj/src/main/res/drawable-xxhdpi/circle.png
Executable file
After Width: | Height: | Size: 3.1 KiB |
BIN
TMessagesProj/src/main/res/drawable-xxhdpi/photocheck.png
Executable file
After Width: | Height: | Size: 4.1 KiB |