Update to 2.8.1.3 (523)

This commit is contained in:
rafalense 2015-05-06 16:17:18 +02:00
parent d0d035cda2
commit 8713d46f1b
368 changed files with 19591 additions and 18044 deletions

View File

@ -13,11 +13,10 @@ repositories {
}
dependencies {
compile 'com.android.support:support-v4:22.0.+'
compile 'com.android.support:support-v4:22.1.+'
compile 'com.google.android.gms:play-services:3.2.+'
compile 'net.hockeyapp.android:HockeySDK:3.5.+'
compile 'com.googlecode.mp4parser:isoparser:1.0.+'
compile 'com.android.support:recyclerview-v7:+'
}
android {
@ -89,7 +88,7 @@ android {
applicationId "org.telegram.plus"
minSdkVersion 8
targetSdkVersion 22
versionCode 492
versionName "2.7.0.1"
versionCode 524
versionName "2.8.1.4"
}
}

View File

@ -15,13 +15,11 @@
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!--
<uses-permission android:name="org.telegram.plus.beta.android.provider.ACCESS" />-->
<permission android:name="org.telegram.plus.beta.permission.MAPS_RECEIVE" android:protectionLevel="signature"/>
<permission android:name="org.telegram.plus.beta.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<!--
<permission android:name="org.telegram.plus.beta.android.provider.ACCESS" android:protectionLevel="signature"/>-->
<permission android:name="org.telegram.plus.beta.android.provider.ACCESS" android:protectionLevel="signature"/>
<application
android:allowBackup="false"
@ -49,6 +47,14 @@
<uses-library android:name="com.google.android.maps" android:required="false"/>
<provider
android:authorities="org.telegram.plus.beta.android.provider.content"
android:name="org.telegram.android.ModuleContentProvider"
android:label="Plus beta"
tools:replace="label"
android:exported="true"
android:permission="org.telegram.plus.beta.android.provider.ACCESS" />
</application>
</manifest>

View File

@ -14,12 +14,12 @@
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!--
<uses-permission android:name="org.telegram.plus.android.provider.ACCESS" />-->
<permission android:name="org.telegram.plus.permission.MAPS_RECEIVE" android:protectionLevel="signature"/>
<permission android:name="org.telegram.plus.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<permission android:name="org.telegram.plus.android.provider.ACCESS" android:protectionLevel="signature"/>
<application
android:allowBackup="false"
android:icon="@drawable/ic_launcher"
@ -45,6 +45,13 @@
<uses-library android:name="com.google.android.maps" android:required="false"/>
<provider
android:authorities="org.telegram.plus.android.provider.content"
android:name="org.telegram.android.ModuleContentProvider"
android:label="@string/AppName"
android:exported="true"
android:permission="org.telegram.plus.android.provider.ACCESS" />
</application>
</manifest>

View File

@ -104,7 +104,7 @@ include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false
LOCAL_STATIC_LIBRARIES := webp sqlite
LOCAL_MODULE := tmessages.7
LOCAL_MODULE := tmessages.8
LOCAL_CFLAGS := -w -std=gnu99 -O2 -DNULL=0 -DSOCKLEN_T=socklen_t -DLOCALE_NOT_USED -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64
LOCAL_CFLAGS += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DFIXED_POINT -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -fno-math-errno
LOCAL_CFLAGS += -DANDROID_NDK -DDISABLE_IMPORTGL -fno-strict-aliasing -fprefetch-loop-arrays -DAVOID_TABLES -DANDROID_TILE_BASED_DECODE -DANDROID_ARMV6_IDCT -ffast-math

View File

@ -288,7 +288,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, int radius) {
JNIEXPORT void Java_org_telegram_messenger_Utilities_blurBitmap(JNIEnv *env, jclass class, jobject bitmap, int radius, int unpin) {
if (!bitmap) {
return;
}
@ -312,7 +312,9 @@ JNIEXPORT void Java_org_telegram_messenger_Utilities_blurBitmap(JNIEnv *env, jcl
} else {
fastBlurMore(info.width, info.height, info.stride, pixels, radius);
}
if (unpin) {
AndroidBitmap_unlockPixels(env, bitmap);
}
}
JNIEXPORT void Java_org_telegram_messenger_Utilities_calcCDT(JNIEnv *env, jclass class, jobject hsvBuffer, int width, int height, jobject buffer) {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 237 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 270 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

View File

@ -42,16 +42,16 @@ import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import org.telegram.android.AnimationCompat.AnimatorListenerAdapterProxy;
import org.telegram.android.AnimationCompat.AnimatorSetProxy;
import org.telegram.android.AnimationCompat.ObjectAnimatorProxy;
import org.telegram.android.AnimationCompat.ViewProxy;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.messenger.TLRPC;
import org.telegram.messenger.UserConfig;
import org.telegram.ui.AnimationCompat.AnimatorListenerAdapterProxy;
import org.telegram.ui.AnimationCompat.AnimatorSetProxy;
import org.telegram.ui.AnimationCompat.ObjectAnimatorProxy;
import org.telegram.ui.AnimationCompat.ViewProxy;
import org.telegram.ui.Components.ForegroundDetector;
import org.telegram.ui.Components.NumberPicker;
import org.telegram.ui.Components.TypefaceSpan;
@ -75,10 +75,11 @@ public class AndroidUtilities {
public static Integer photoSize = null;
public static DisplayMetrics displayMetrics = new DisplayMetrics();
public static int leftBaseline;
public static boolean usingHardwareInput;
private static Boolean isTablet = null;
public static final String THEME_PREFS = "theme";
public static final int THEME_PREFS_MODE = Activity.MODE_WORLD_READABLE;
public static final int THEME_PREFS_MODE = Activity.MODE_PRIVATE;
public static final int defColor = 0xff009688;//0xff58BCD5;//0xff43C3DB;//0xff2f8cc9;58BCD5//0xff55abd2
public static int themeColor = getIntColor("themeColor");
@ -238,21 +239,38 @@ public class AndroidUtilities {
}
public static int dp(float value) {
if (value == 0) {
return 0;
}
return (int)Math.ceil(density * value);
}
public static int compare(int lhs, int rhs) {
if (lhs == rhs) {
return 0;
} else if (lhs > rhs) {
return 1;
}
return -1;
}
public static float dpf2(float value) {
if (value == 0) {
return 0;
}
return density * value;
}
public static void checkDisplaySize() {
try {
WindowManager manager = (WindowManager)ApplicationLoader.applicationContext.getSystemService(Context.WINDOW_SERVICE);
Configuration configuration = ApplicationLoader.applicationContext.getResources().getConfiguration();
usingHardwareInput = configuration.keyboard != Configuration.KEYBOARD_NOKEYS && configuration.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO;
WindowManager manager = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Context.WINDOW_SERVICE);
if (manager != null) {
Display display = manager.getDefaultDisplay();
if (display != null) {
display.getMetrics(displayMetrics);
if(android.os.Build.VERSION.SDK_INT < 13) {
if (android.os.Build.VERSION.SDK_INT < 13) {
displaySize.set(display.getWidth(), display.getHeight());
} else {
display.getSize(displaySize);
@ -263,6 +281,38 @@ public class AndroidUtilities {
} catch (Exception e) {
FileLog.e("tmessages", e);
}
/*
keyboardHidden
public static final int KEYBOARDHIDDEN_NO = 1
Constant for keyboardHidden, value corresponding to the keysexposed resource qualifier.
public static final int KEYBOARDHIDDEN_UNDEFINED = 0
Constant for keyboardHidden: a value indicating that no value has been set.
public static final int KEYBOARDHIDDEN_YES = 2
Constant for keyboardHidden, value corresponding to the keyshidden resource qualifier.
hardKeyboardHidden
public static final int HARDKEYBOARDHIDDEN_NO = 1
Constant for hardKeyboardHidden, value corresponding to the physical keyboard being exposed.
public static final int HARDKEYBOARDHIDDEN_UNDEFINED = 0
Constant for hardKeyboardHidden: a value indicating that no value has been set.
public static final int HARDKEYBOARDHIDDEN_YES = 2
Constant for hardKeyboardHidden, value corresponding to the physical keyboard being hidden.
keyboard
public static final int KEYBOARD_12KEY = 3
Constant for keyboard, value corresponding to the 12key resource qualifier.
public static final int KEYBOARD_NOKEYS = 1
Constant for keyboard, value corresponding to the nokeys resource qualifier.
public static final int KEYBOARD_QWERTY = 2
Constant for keyboard, value corresponding to the qwerty resource qualifier.
*/
}
public static float getPixelsInCM(float cm, boolean isX) {
@ -573,6 +623,9 @@ public class AndroidUtilities {
if (start != -1) {
stringBuilder.replace(start, start + 3, "");
end = stringBuilder.indexOf("</b>");
if (end == -1) {
end = stringBuilder.indexOf("<b>");
}
stringBuilder.replace(end, end + 4, "");
bolds.add(start);
bolds.add(end);

View File

@ -14,6 +14,7 @@ import android.app.Activity;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.Uri;
@ -37,7 +38,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;
public class ContactsController {
@ -168,7 +168,7 @@ public class ContactsController {
if (!updatingInviteText && (inviteText == null || time + 86400 < (int)(System.currentTimeMillis() / 1000))) {
updatingInviteText = true;
TLRPC.TL_help_getInviteText req = new TLRPC.TL_help_getInviteText();
req.lang_code = LocaleController.getLocaleString(Locale.getDefault());
req.lang_code = LocaleController.getLocaleString(LocaleController.getInstance().getSystemDefaultLocale());
if (req.lang_code == null || req.lang_code.length() == 0) {
req.lang_code = "en";
}
@ -203,7 +203,19 @@ public class ContactsController {
public void checkAppAccount() {
AccountManager am = AccountManager.get(ApplicationLoader.applicationContext);
Account[] accounts = am.getAccountsByType("org.telegram.account");
Account[] accounts;
try {
accounts = am.getAccountsByType("org.telegram.account");
if (accounts != null && accounts.length > 0) {
for (Account c : accounts) {
am.removeAccount(c, null, null);
}
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
accounts = am.getAccountsByType("org.telegram.messenger");
boolean recreateAccount = false;
if (UserConfig.isClientActivated()) {
if (accounts.length == 1) {
@ -228,7 +240,7 @@ public class ContactsController {
}
if (UserConfig.isClientActivated()) {
try {
currentAccount = new Account(UserConfig.getCurrentUser().phone, "org.telegram.account");
currentAccount = new Account(UserConfig.getCurrentUser().phone, "org.telegram.messenger");
am.addAccountExplicitly(currentAccount, "", null);
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -240,7 +252,7 @@ public class ContactsController {
public void deleteAllAppAccounts() {
try {
AccountManager am = AccountManager.get(ApplicationLoader.applicationContext);
Account[] accounts = am.getAccountsByType("org.telegram.account");
Account[] accounts = am.getAccountsByType("org.telegram.messenger");
for (Account c : accounts) {
am.removeAccount(c, null, null);
}
@ -1247,7 +1259,7 @@ public class ContactsController {
private void performWriteContactsToPhoneBook() {
final ArrayList<TLRPC.TL_contact> contactsArray = new ArrayList<>();
contactsArray.addAll(contacts);
Utilities.photoBookQueue.postRunnable(new Runnable() {
Utilities.phoneBookQueue.postRunnable(new Runnable() {
@Override
public void run() {
performWriteContactsToPhoneBookInternal(contactsArray);
@ -1304,7 +1316,7 @@ public class ContactsController {
}
for (final Integer uid : contactsTD) {
Utilities.photoBookQueue.postRunnable(new Runnable() {
Utilities.phoneBookQueue.postRunnable(new Runnable() {
@Override
public void run() {
deleteContactFromPhoneBook(uid);
@ -1464,7 +1476,7 @@ public class ContactsController {
builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
builder.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0);
builder.withValue(ContactsContract.Data.MIMETYPE, "vnd.android.cursor.item/vnd.org.telegram.messenger.android.profile");
builder.withValue(ContactsContract.Data.DATA1, "+" + user.phone);
builder.withValue(ContactsContract.Data.DATA1, user.id);
builder.withValue(ContactsContract.Data.DATA2, "Telegram Profile");
builder.withValue(ContactsContract.Data.DATA3, "+" + user.phone);
builder.withValue(ContactsContract.Data.DATA4, user.id);
@ -1497,6 +1509,22 @@ public class ContactsController {
}
}
protected void markAsContacted(final String contactId) {
if (contactId == null) {
return;
}
Utilities.phoneBookQueue.postRunnable(new Runnable() {
@Override
public void run() {
Uri uri = Uri.parse(contactId);
ContentValues values = new ContentValues();
values.put(ContactsContract.Contacts.LAST_TIME_CONTACTED, System.currentTimeMillis());
ContentResolver cr = ApplicationLoader.applicationContext.getContentResolver();
cr.update(uri, values, null, null);
}
});
}
public void addContact(TLRPC.User user) {
if (user == null || user.phone == null) {
return;
@ -1534,7 +1562,7 @@ public class ContactsController {
// }
for (final TLRPC.User u : res.users) {
Utilities.photoBookQueue.postRunnable(new Runnable() {
Utilities.phoneBookQueue.postRunnable(new Runnable() {
@Override
public void run() {
addContactToPhoneBook(u, true);
@ -1547,7 +1575,7 @@ public class ContactsController {
MessagesStorage.getInstance().putContacts(arrayList, false);
if (u.phone != null && u.phone.length() > 0) {
String name = formatName(u.first_name, u.last_name);
CharSequence name = formatName(u.first_name, u.last_name);
MessagesStorage.getInstance().applyPhoneBookUpdates(u.phone, "");
Contact contact = contactsBookSPhones.get(u.phone);
if (contact != null) {
@ -1600,7 +1628,7 @@ public class ContactsController {
return;
}
MessagesStorage.getInstance().deleteContacts(uids);
Utilities.photoBookQueue.postRunnable(new Runnable() {
Utilities.phoneBookQueue.postRunnable(new Runnable() {
@Override
public void run() {
for (TLRPC.User user : users) {
@ -1611,7 +1639,7 @@ public class ContactsController {
for (TLRPC.User user : users) {
if (user.phone != null && user.phone.length() > 0) {
String name = ContactsController.formatName(user.first_name, user.last_name);
CharSequence name = ContactsController.formatName(user.first_name, user.last_name);
MessagesStorage.getInstance().applyPhoneBookUpdates(user.phone, "");
Contact contact = contactsBookSPhones.get(user.phone);
if (contact != null) {
@ -1773,22 +1801,37 @@ public class ContactsController {
}
public static String formatName(String firstName, String lastName) {
String result = "";
/*if ((firstName == null || firstName.length() == 0) && (lastName == null || lastName.length() == 0)) {
return LocaleController.getString("HiddenName", R.string.HiddenName);
}*/
if (firstName != null) {
firstName = firstName.trim();
}
if (lastName != null) {
lastName = lastName.trim();
}
StringBuilder result = new StringBuilder((firstName != null ? firstName.length() : 0) + (lastName != null ? lastName.length() : 0) + 1);
if (LocaleController.nameDisplayOrder == 1) {
result = firstName;
if (result == null || result.length() == 0) {
result = lastName;
} else if (result.length() != 0 && lastName != null && lastName.length() != 0) {
result += " " + lastName;
if (firstName != null && firstName.length() > 0) {
result.append(firstName);
if (lastName != null && lastName.length() > 0) {
result.append(" ");
result.append(lastName);
}
} else if (lastName != null && lastName.length() > 0) {
result.append(lastName);
}
} else {
result = lastName;
if (result == null || result.length() == 0) {
result = firstName;
} else if (result.length() != 0 && firstName != null && firstName.length() != 0) {
result += " " + firstName;
if (lastName != null && lastName.length() > 0) {
result.append(lastName);
if (firstName != null && firstName.length() > 0) {
result.append(" ");
result.append(firstName);
}
} else if (firstName != null && firstName.length() > 0) {
result.append(firstName);
}
}
return result.trim();
return result.toString();
}
}

View File

@ -33,7 +33,8 @@ import java.util.Locale;
public class Emoji {
private static HashMap<Long, DrawableInfo> rects = new HashMap<>();
private static int drawImgSize, bigImgSize;
private static int drawImgSize;
private static int bigImgSize;
private static boolean inited = false;
private static Paint placeholderPaint;
private static Bitmap emojiBmp[] = new Bitmap[5];
@ -193,19 +194,19 @@ public class Emoji {
static {
int emojiFullSize;
if (AndroidUtilities.density <= 1.0f) {
emojiFullSize = 30;
emojiFullSize = 32;
} else if (AndroidUtilities.density <= 1.5f) {
emojiFullSize = 45;
emojiFullSize = 48;
} else if (AndroidUtilities.density <= 2.0f) {
emojiFullSize = 60;
emojiFullSize = 64;
} else {
emojiFullSize = 90;
emojiFullSize = 96;
}
drawImgSize = AndroidUtilities.dp(20);
if (AndroidUtilities.isTablet()) {
bigImgSize = AndroidUtilities.dp(40);
} else {
bigImgSize = AndroidUtilities.dp(30);
bigImgSize = AndroidUtilities.dp(32);
}
for (int j = 1; j < data.length; j++) {
@ -234,8 +235,26 @@ public class Emoji {
scale = 3.0f;
}
String imageName = String.format(Locale.US, "emoji%.01fx_%d.jpg", scale, page);
File imageFile = ApplicationLoader.applicationContext.getFileStreamPath(imageName);
String imageName;
File imageFile;
try {
imageName = String.format(Locale.US, "emoji%.01fx_%d.jpg", scale, page);
imageFile = ApplicationLoader.applicationContext.getFileStreamPath(imageName);
if (imageFile.exists()) {
imageFile.delete();
}
imageName = String.format(Locale.US, "emoji%.01fx_a_%d.jpg", scale, page);
imageFile = ApplicationLoader.applicationContext.getFileStreamPath(imageName);
if (imageFile.exists()) {
imageFile.delete();
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
imageName = String.format(Locale.US, "v4_emoji%.01fx_%d.jpg", scale, page);
imageFile = ApplicationLoader.applicationContext.getFileStreamPath(imageName);
if (!imageFile.exists()) {
InputStream is = ApplicationLoader.applicationContext.getAssets().open("emoji/" + imageName);
Utilities.copyFile(is, imageFile);
@ -253,7 +272,7 @@ public class Emoji {
final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Utilities.loadBitmap(imageFile.getAbsolutePath(), bitmap, imageResize, width, height, stride);
imageName = String.format(Locale.US, "emoji%.01fx_a_%d.jpg", scale, page);
imageName = String.format(Locale.US, "v4_emoji%.01fx_a_%d.jpg", scale, page);
imageFile = ApplicationLoader.applicationContext.getFileStreamPath(imageName);
if (!imageFile.exists()) {
InputStream is = ApplicationLoader.applicationContext.getAssets().open("emoji/" + imageName);
@ -401,7 +420,6 @@ public class Emoji {
if (cs == null || cs.length() == 0) {
return cs;
}
Spannable s;
if (cs instanceof Spannable) {
s = (Spannable)cs;

View File

@ -70,6 +70,8 @@ public class ImageLoader {
private DispatchQueue recycleQueue = new DispatchQueue("recycleQueue");
private ConcurrentHashMap<String, Float> fileProgresses = new ConcurrentHashMap<>();
private HashMap<String, ThumbGenerateTask> thumbGenerateTasks = new HashMap<>();
private static byte[] bytes;
private static byte[] bytesThumb;
private int currentHttpTasksCount = 0;
private LinkedList<HttpFileTask> httpFileLoadTasks = new LinkedList<>();
@ -507,6 +509,7 @@ public class ImageLoader {
}
Long mediaId = null;
boolean mediaIsVideo = false;
Bitmap image = null;
File cacheFileFinal = cacheImage.finalFilePath;
boolean canDeleteFile = true;
@ -537,18 +540,35 @@ public class ImageLoader {
}
}
if (image == null) {
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 1;
if (!isWebp && Build.VERSION.SDK_INT > 10 && Build.VERSION.SDK_INT < 21) {
opts.inPurgeable = true;
}
if (isWebp) {
RandomAccessFile file = new RandomAccessFile(cacheFileFinal, "r");
ByteBuffer buffer = file.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, cacheFileFinal.length());
image = Utilities.loadWebpImage(buffer, buffer.limit(), null);
file.close();
} else {
if (opts.inPurgeable) {
RandomAccessFile f = new RandomAccessFile(cacheFileFinal, "r");
int len = (int) f.length();
byte[] data = bytesThumb != null && bytesThumb.length >= len ? bytesThumb : null;
if (data == null) {
bytesThumb = data = new byte[len];
}
f.readFully(data, 0, len);
image = BitmapFactory.decodeByteArray(data, 0, len, opts);
} else {
FileInputStream is = new FileInputStream(cacheFileFinal);
image = BitmapFactory.decodeStream(is, null, null);
image = BitmapFactory.decodeStream(is, null, opts);
is.close();
}
}
if (image == null) {
if (canDeleteFile && (cacheFileFinal.length() == 0 || cacheImage.filter == null)) {
cacheFileFinal.delete();
@ -556,15 +576,18 @@ public class ImageLoader {
} else {
if (image != null) {
if (blurType == 1) {
Utilities.blurBitmap(image, 3);
Utilities.blurBitmap(image, 3, opts.inPurgeable ? 0 : 1);
} else if (blurType == 2) {
Utilities.blurBitmap(image, 1);
Utilities.blurBitmap(image, 1, opts.inPurgeable ? 0 : 1);
} else if (blurType == 3) {
Utilities.blurBitmap(image, 7);
Utilities.blurBitmap(image, 7);
Utilities.blurBitmap(image, 7);
Utilities.blurBitmap(image, 7, opts.inPurgeable ? 0 : 1);
Utilities.blurBitmap(image, 7, opts.inPurgeable ? 0 : 1);
Utilities.blurBitmap(image, 7, opts.inPurgeable ? 0 : 1);
}
}
if (blurType == 0 && opts.inPurgeable) {
Utilities.pinBitmap(image);
}
if (runtimeHack != null) {
runtimeHack.trackFree(image.getRowBytes() * image.getHeight());
}
@ -579,6 +602,14 @@ public class ImageLoader {
int idx = cacheImage.httpUrl.indexOf(":", 8);
if (idx >= 0) {
mediaId = Long.parseLong(cacheImage.httpUrl.substring(8, idx));
mediaIsVideo = false;
}
canDeleteFile = false;
} else if (cacheImage.httpUrl.startsWith("vthumb://")) {
int idx = cacheImage.httpUrl.indexOf(":", 9);
if (idx >= 0) {
mediaId = Long.parseLong(cacheImage.httpUrl.substring(9, idx));
mediaIsVideo = true;
}
canDeleteFile = false;
} else if (!cacheImage.httpUrl.startsWith("http")) {
@ -604,21 +635,29 @@ public class ImageLoader {
}
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 1;
float w_filter = 0;
float h_filter = 0;
boolean blur = false;
if (cacheImage.filter != null) {
String args[] = cacheImage.filter.split("_");
if (args.length >= 2) {
w_filter = Float.parseFloat(args[0]) * AndroidUtilities.density;
h_filter = Float.parseFloat(args[1]) * AndroidUtilities.density;
if (args.length > 2) {
}
if (cacheImage.filter.contains("b")) {
blur = true;
}
if (w_filter != 0 && h_filter != 0) {
opts.inJustDecodeBounds = true;
if (mediaId != null) {
if (mediaIsVideo) {
MediaStore.Video.Thumbnails.getThumbnail(ApplicationLoader.applicationContext.getContentResolver(), mediaId, MediaStore.Video.Thumbnails.MINI_KIND, opts);
} else {
MediaStore.Images.Thumbnails.getThumbnail(ApplicationLoader.applicationContext.getContentResolver(), mediaId, MediaStore.Images.Thumbnails.MINI_KIND, opts);
}
} else {
FileInputStream is = new FileInputStream(cacheFileFinal);
image = BitmapFactory.decodeStream(is, null, opts);
@ -632,7 +671,8 @@ public class ImageLoader {
scaleFactor = 1;
}
opts.inJustDecodeBounds = false;
opts.inSampleSize = (int)scaleFactor;
opts.inSampleSize = (int) scaleFactor;
}
}
synchronized (sync) {
if (isCancelled) {
@ -645,37 +685,53 @@ public class ImageLoader {
} else {
opts.inPreferredConfig = Bitmap.Config.RGB_565;
}
//if (Build.VERSION.SDK_INT < 21) {
// opts.inPurgeable = true;
//}
if (!isWebp && Build.VERSION.SDK_INT > 10 && Build.VERSION.SDK_INT < 21) {
opts.inPurgeable = true;
}
opts.inDither = false;
if (mediaId != null) {
if (mediaIsVideo) {
image = MediaStore.Video.Thumbnails.getThumbnail(ApplicationLoader.applicationContext.getContentResolver(), mediaId, MediaStore.Video.Thumbnails.MINI_KIND, opts);
} else {
image = MediaStore.Images.Thumbnails.getThumbnail(ApplicationLoader.applicationContext.getContentResolver(), mediaId, MediaStore.Images.Thumbnails.MINI_KIND, opts);
}
}
if (image == null) {
if (isWebp) {
RandomAccessFile file = new RandomAccessFile(cacheFileFinal, "r");
ByteBuffer buffer = file.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, cacheFileFinal.length());
image = Utilities.loadWebpImage(buffer, buffer.limit(), null);
file.close();
} else {
if (opts.inPurgeable) {
RandomAccessFile f = new RandomAccessFile(cacheFileFinal, "r");
int len = (int) f.length();
byte[] data = bytes != null && bytes.length >= len ? bytes : null;
if (data == null) {
bytes = data = new byte[len];
}
f.readFully(data, 0, len);
image = BitmapFactory.decodeByteArray(data, 0, len, opts);
} else {
FileInputStream is = new FileInputStream(cacheFileFinal);
image = BitmapFactory.decodeStream(is, null, opts);
is.close();
}
}
}
if (image == null) {
if (canDeleteFile && (cacheFileFinal.length() == 0 || cacheImage.filter == null)) {
cacheFileFinal.delete();
}
} else {
boolean blured = false;
if (cacheImage.filter != null) {
float bitmapW = image.getWidth();
float bitmapH = image.getHeight();
if (bitmapW != w_filter && bitmapW > w_filter) {
if (!opts.inPurgeable && w_filter != 0 && bitmapW != w_filter && bitmapW > w_filter + 20) {
float scaleFactor = bitmapW / w_filter;
Bitmap scaledBitmap = Bitmap.createScaledBitmap(image, (int)w_filter, (int)(bitmapH / scaleFactor), true);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(image, (int) w_filter, (int) (bitmapH / scaleFactor), true);
if (image != scaledBitmap) {
image.recycle();
callGC();
@ -683,9 +739,13 @@ public class ImageLoader {
}
}
if (image != null && blur && bitmapH < 100 && bitmapW < 100) {
Utilities.blurBitmap(image, 3);
Utilities.blurBitmap(image, 3, opts.inPurgeable ? 0 : 1);
blured = true;
}
}
if (!blured && opts.inPurgeable) {
Utilities.pinBitmap(image);
}
if (runtimeHack != null) {
runtimeHack.trackFree(image.getRowBytes() * image.getHeight());
}
@ -753,7 +813,7 @@ public class ImageLoader {
}
try {
Object res = trackAllocation.invoke(runtime, size);
return (res instanceof Boolean) ? (Boolean)res : true;
return (res instanceof Boolean) ? (Boolean) res : true;
} catch (Exception e) {
return false;
}
@ -765,7 +825,7 @@ public class ImageLoader {
}
try {
Object res = trackFree.invoke(runtime, size);
return (res instanceof Boolean) ? (Boolean)res : true;
return (res instanceof Boolean) ? (Boolean) res : true;
} catch (Exception e) {
return false;
}
@ -778,8 +838,8 @@ public class ImageLoader {
Method getRt = cl.getMethod("getRuntime", new Class[0]);
Object[] objects = new Object[0];
runtime = getRt.invoke(null, objects);
trackAllocation = cl.getMethod("trackExternalAllocation", new Class[] {long.class});
trackFree = cl.getMethod("trackExternalFree", new Class[] {long.class});
trackAllocation = cl.getMethod("trackExternalAllocation", new Class[]{long.class});
trackFree = cl.getMethod("trackExternalFree", new Class[]{long.class});
} catch (Exception e) {
FileLog.e("tmessages", e);
runtime = null;
@ -872,7 +932,7 @@ public class ImageLoader {
@Override
public void run() {
for (ImageReceiver imgView : finalImageReceiverArray) {
imgView.setImageBitmapByKey(image, key, thumb);
imgView.setImageBitmapByKey(image, key, thumb, false);
}
}
});
@ -891,6 +951,7 @@ public class ImageLoader {
}
private static volatile ImageLoader Instance = null;
public static ImageLoader getInstance() {
ImageLoader localInstance = Instance;
if (localInstance == null) {
@ -915,12 +976,13 @@ public class ImageLoader {
@Override
protected int sizeOf(String key, BitmapDrawable bitmap) {
Bitmap b = bitmap.getBitmap();
if(Build.VERSION.SDK_INT < 12) {
if (Build.VERSION.SDK_INT < 12) {
return b.getRowBytes() * b.getHeight();
} else {
return b.getByteCount();
}
}
@Override
protected void entryRemoved(boolean evicted, String key, final BitmapDrawable oldBitmap, BitmapDrawable newBitmap) {
if (ignoreRemoval != null && key != null && ignoreRemoval.equals(key)) {
@ -1206,7 +1268,7 @@ public class ImageLoader {
recycleQueue.postRunnable(new Runnable() {
@Override
public void run() {
System.gc();
//System.gc();
}
});
}
@ -1309,17 +1371,21 @@ public class ImageLoader {
return memCache.get(key);
}
public void replaceImageInCache(final String oldKey, final String newKey) {
public void replaceImageInCache(final String oldKey, final String newKey, final TLRPC.FileLocation newLocation) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
ArrayList<String> arr = memCache.getFilterKeys(oldKey);
if (arr != null) {
for (String filter : arr) {
performReplace(oldKey + "@" + filter, newKey + "@" + filter);
String oldK = oldKey + "@" + filter;
String newK = newKey + "@" + filter;
performReplace(oldK, newK);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.didReplacedPhotoInMemCache, oldK, newK, newLocation);
}
} else {
performReplace(oldKey, newKey);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.didReplacedPhotoInMemCache, oldKey, newKey, newLocation);
}
}
});
@ -1397,6 +1463,11 @@ public class ImageLoader {
if (idx >= 0) {
cacheFile = new File(httpLocation.substring(idx + 1));
}
} else if (httpLocation.startsWith("vthumb://")) {
int idx = httpLocation.indexOf(":", 9);
if (idx >= 0) {
cacheFile = new File(httpLocation.substring(idx + 1));
}
} else {
cacheFile = new File(httpLocation);
}
@ -1500,7 +1571,7 @@ public class ImageLoader {
if (bitmapDrawable != null) {
cancelLoadingForImageReceiver(imageReceiver, 0);
if (!imageReceiver.isForcePreview()) {
imageReceiver.setImageBitmapByKey(bitmapDrawable, key, false);
imageReceiver.setImageBitmapByKey(bitmapDrawable, key, false, true);
return;
}
}
@ -1510,7 +1581,7 @@ public class ImageLoader {
if (thumbKey != null) {
BitmapDrawable bitmapDrawable = memCache.get(thumbKey);
if (bitmapDrawable != null) {
imageReceiver.setImageBitmapByKey(bitmapDrawable, thumbKey, true);
imageReceiver.setImageBitmapByKey(bitmapDrawable, thumbKey, true, true);
cancelLoadingForImageReceiver(imageReceiver, 1);
thumbSet = true;
}
@ -1797,7 +1868,7 @@ public class ImageLoader {
scaleFactor = 1;
}
bmOptions.inJustDecodeBounds = false;
bmOptions.inSampleSize = (int)scaleFactor;
bmOptions.inSampleSize = (int) scaleFactor;
String exifPath = null;
if (path != null) {
@ -1913,7 +1984,7 @@ public class ImageLoader {
size.size = size.bytes.length;
stream2.close();
} else {
size.size = (int)stream.getChannel().size();
size.size = (int) stream.getChannel().size();
}
stream.close();
if (scaledBitmap != bitmap) {
@ -1939,11 +2010,17 @@ public class ImageLoader {
boolean scaleAnyway = false;
float scaleFactor = Math.max(photoW / maxWidth, photoH / maxHeight);
if (minWidth != 0 && minHeight != 0 && (photoW < minWidth || photoH < minHeight)) {
if (photoW < minWidth && photoH > minHeight) {
scaleFactor = photoW / minWidth;
} else if (photoW > minWidth && photoH < minHeight) {
scaleFactor = photoH / minHeight;
} else {
scaleFactor = Math.max(photoW / minWidth, photoH / minHeight);
}
scaleAnyway = true;
}
int w = (int)(photoW / scaleFactor);
int h = (int)(photoH / scaleFactor);
int w = (int) (photoW / scaleFactor);
int h = (int) (photoH / scaleFactor);
if (h == 0 || w == 0) {
return null;
}

View File

@ -11,6 +11,7 @@ package org.telegram.android;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
@ -33,12 +34,25 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
void didSetImage(ImageReceiver imageReceiver, boolean set, boolean thumb);
}
private class SetImageBackup {
public TLObject fileLocation;
public String httpUrl;
public String filter;
public Drawable thumb;
public TLRPC.FileLocation thumbLocation;
public String thumbFilter;
public int size;
public boolean cacheOnly;
}
private View parentView;
private Integer tag;
private Integer thumbTag;
private MessageObject parentMessageObject;
private boolean canceledLoading;
private SetImageBackup setImageBackup;
private TLObject currentImageLocation;
private String currentKey;
private String currentThumbKey;
@ -66,12 +80,16 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
private RectF roundRect;
private RectF bitmapRect;
private Matrix shaderMatrix;
private int alpha = 255;
private float overrideAlpha = 1.0f;
private boolean isPressed;
private boolean disableRecycle;
private int orientation;
private boolean centerRotation;
private ImageReceiverDelegate delegate;
private float currentAlpha;
private long lastUpdateAlphaTime;
private byte crossfadeAlpha = 1;
private boolean crossfadeWithThumb;
private ColorFilter colorFilter;
public ImageReceiver() {
@ -107,6 +125,13 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
public void setImage(TLObject fileLocation, String httpUrl, String filter, Drawable thumb, TLRPC.FileLocation thumbLocation, String thumbFilter, int size, boolean cacheOnly) {
if (setImageBackup != null) {
setImageBackup.fileLocation = null;
setImageBackup.httpUrl = null;
setImageBackup.thumbLocation = null;
setImageBackup.thumb = null;
}
if ((fileLocation == null && httpUrl == null && thumbLocation == null)
|| (fileLocation != null && !(fileLocation instanceof TLRPC.TL_fileLocation)
&& !(fileLocation instanceof TLRPC.TL_fileEncryptedLocation)
@ -121,13 +146,14 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
currentFilter = null;
currentCacheOnly = false;
staticThumb = thumb;
currentAlpha = 1;
currentThumbLocation = null;
currentSize = 0;
currentImage = null;
bitmapShader = null;
ImageLoader.getInstance().cancelLoadingForImageReceiver(this, 0);
if (parentView != null) {
parentView.invalidate();
parentView.invalidate(imageX, imageY, imageX + imageW, imageY + imageH);
}
if (delegate != null) {
delegate.didSetImage(this, currentImage != null || currentThumb != null || staticThumb != null, currentImage == null);
@ -135,6 +161,8 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
return;
}
if (!(thumbLocation instanceof TLRPC.TL_fileLocation)) {
thumbLocation = null;
}
@ -188,6 +216,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
currentThumbLocation = thumbLocation;
staticThumb = thumb;
bitmapShader = null;
currentAlpha = 1.0f;
if (delegate != null) {
delegate.didSetImage(this, currentImage != null || currentThumb != null || staticThumb != null, currentImage == null);
@ -195,10 +224,14 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
ImageLoader.getInstance().loadImageForImageReceiver(this);
if (parentView != null) {
parentView.invalidate();
parentView.invalidate(imageX, imageY, imageX + imageW, imageY + imageH);
}
}
public void setColorFilter(ColorFilter filter) {
colorFilter = filter;
}
public void setDelegate(ImageReceiverDelegate delegate) {
this.delegate = delegate;
}
@ -240,11 +273,18 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
currentSize = 0;
currentCacheOnly = false;
bitmapShader = null;
if (setImageBackup != null) {
setImageBackup.fileLocation = null;
setImageBackup.httpUrl = null;
setImageBackup.thumbLocation = null;
setImageBackup.thumb = null;
}
currentAlpha = 1;
if (delegate != null) {
delegate.didSetImage(this, currentImage != null || currentThumb != null || staticThumb != null, currentImage == null);
}
if (parentView != null) {
parentView.invalidate();
parentView.invalidate(imageX, imageY, imageX + imageW, imageY + imageH);
}
}
@ -257,17 +297,37 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
}
public boolean draw(Canvas canvas) {
try {
BitmapDrawable bitmapDrawable = null;
if (!forcePreview && currentImage != null) {
bitmapDrawable = currentImage;
} else if (staticThumb instanceof BitmapDrawable) {
bitmapDrawable = (BitmapDrawable) staticThumb;
} else if (currentThumb != null) {
bitmapDrawable = currentThumb;
public void onDetachedFromWindow() {
if (currentImageLocation != null || currentHttpUrl != null || currentThumbLocation != null || staticThumb != null) {
if (setImageBackup == null) {
setImageBackup = new SetImageBackup();
}
if (bitmapDrawable != null) {
setImageBackup.fileLocation = currentImageLocation;
setImageBackup.httpUrl = currentHttpUrl;
setImageBackup.filter = currentFilter;
setImageBackup.thumb = staticThumb;
setImageBackup.thumbLocation = currentThumbLocation;
setImageBackup.thumbFilter = currentThumbFilter;
setImageBackup.size = currentSize;
setImageBackup.cacheOnly = currentCacheOnly;
}
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.didReplacedPhotoInMemCache);
clearImage();
}
public boolean onAttachedToWindow() {
NotificationCenter.getInstance().addObserver(this, NotificationCenter.didReplacedPhotoInMemCache);
if (setImageBackup != null && (setImageBackup.fileLocation != null || setImageBackup.httpUrl != null || setImageBackup.thumbLocation != null || setImageBackup.thumb != null)) {
setImage(setImageBackup.fileLocation, setImageBackup.httpUrl, setImageBackup.filter, setImageBackup.thumb, setImageBackup.thumbLocation, setImageBackup.thumbFilter, setImageBackup.size, setImageBackup.cacheOnly);
return true;
}
return false;
}
private void drawDrawable(Canvas canvas, Drawable drawable, int alpha) {
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
Paint paint = bitmapDrawable.getPaint();
boolean hasFilter = paint != null && paint.getColorFilter() != null;
if (hasFilter && !isPressed) {
@ -277,6 +337,9 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
bitmapDrawable.setColorFilter(new PorterDuffColorFilter(0xffdddddd, PorterDuff.Mode.MULTIPLY));
hasFilter = true;
}
if (colorFilter != null) {
bitmapDrawable.setColorFilter(colorFilter);
}
if (bitmapShader != null) {
drawRegion.set(imageX, imageY, imageX + imageW, imageY + imageH);
if (isVisible) {
@ -284,6 +347,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
shaderMatrix.reset();
shaderMatrix.setRectToRect(bitmapRect, roundRect, Matrix.ScaleToFit.FILL);
bitmapShader.setLocalMatrix(shaderMatrix);
roundPaint.setAlpha(alpha);
canvas.drawRoundRect(roundRect, roundRadius, roundRadius, roundPaint);
}
} else {
@ -411,18 +475,73 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
}
}
return true;
} else if (staticThumb != null) {
} else {
drawRegion.set(imageX, imageY, imageX + imageW, imageY + imageH);
staticThumb.setBounds(drawRegion);
drawable.setBounds(drawRegion);
if (isVisible) {
try {
staticThumb.setAlpha(alpha);
staticThumb.draw(canvas);
drawable.setAlpha(alpha);
drawable.draw(canvas);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
}
}
private void checkAlphaAnimation() {
if (currentAlpha != 1) {
long currentTime = System.currentTimeMillis();
currentAlpha += (currentTime - lastUpdateAlphaTime) / 150.0f;
if (currentAlpha > 1) {
currentAlpha = 1;
}
lastUpdateAlphaTime = System.currentTimeMillis();
if (parentView != null) {
parentView.invalidate(imageX, imageY, imageX + imageW, imageY + imageH);
}
}
}
public boolean draw(Canvas canvas) {
try {
BitmapDrawable bitmapDrawable = null;
if (!forcePreview && currentImage != null) {
bitmapDrawable = currentImage;
} else if (staticThumb instanceof BitmapDrawable) {
bitmapDrawable = (BitmapDrawable) staticThumb;
} else if (currentThumb != null) {
bitmapDrawable = currentThumb;
}
if (bitmapDrawable != null) {
if (crossfadeAlpha != 0) {
if (crossfadeWithThumb && currentAlpha != 1.0f) {
Drawable thumbDrawable = null;
if (bitmapDrawable == currentImage) {
if (staticThumb != null) {
thumbDrawable = staticThumb;
} else if (currentThumb != null) {
thumbDrawable = currentThumb;
}
} else if (bitmapDrawable == currentThumb) {
if (staticThumb != null) {
thumbDrawable = staticThumb;
}
}
if (thumbDrawable != null) {
drawDrawable(canvas, thumbDrawable, (int) (overrideAlpha * 255));
}
}
drawDrawable(canvas, bitmapDrawable, (int) (overrideAlpha * currentAlpha * 255));
} else {
drawDrawable(canvas, bitmapDrawable, (int) (overrideAlpha * 255));
}
checkAlphaAnimation();
return true;
} else if (staticThumb != null) {
drawDrawable(canvas, staticThumb, 255);
checkAlphaAnimation();
return true;
}
} catch (Exception e) {
@ -458,7 +577,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
isVisible = value;
if (invalidate && parentView != null) {
parentView.invalidate();
parentView.invalidate(imageX, imageY, imageX + imageW, imageY + imageH);
}
}
@ -467,7 +586,11 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
public void setAlpha(float value) {
alpha = (int)(value * 255.0f);
overrideAlpha = value;
}
public void setCrossfadeAlpha(byte value) {
crossfadeAlpha = value;
}
public boolean hasImage() {
@ -631,7 +754,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
}
protected void setImageBitmapByKey(BitmapDrawable bitmap, String key, boolean thumb) {
protected void setImageBitmapByKey(BitmapDrawable bitmap, String key, boolean thumb, boolean memCache) {
if (bitmap == null || key == null) {
return;
}
@ -647,17 +770,38 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
roundPaint.setShader(bitmapShader);
bitmapRect.set(0, 0, object.getWidth(), object.getHeight());
}
if (!memCache && !forcePreview) {
if (currentThumb == null && staticThumb == null || currentAlpha == 1.0f) {
currentAlpha = 0.0f;
lastUpdateAlphaTime = System.currentTimeMillis();
crossfadeWithThumb = currentThumb != null || staticThumb != null;
}
} else {
currentAlpha = 1.0f;
}
if (parentView != null) {
parentView.invalidate();
parentView.invalidate(imageX, imageY, imageX + imageW, imageY + imageH);
}
} else if (currentThumb == null && (currentImage == null || forcePreview)) {
if (currentThumbKey == null || !key.equals(currentThumbKey)) {
return;
}
ImageLoader.getInstance().incrementUseCount(currentThumbKey);
currentThumb = bitmap;
if (!memCache && crossfadeAlpha != 2) {
currentAlpha = 0.0f;
lastUpdateAlphaTime = System.currentTimeMillis();
crossfadeWithThumb = staticThumb != null && currentKey == null;
} else {
currentAlpha = 1.0f;
}
if (!(staticThumb instanceof BitmapDrawable) && parentView != null) {
parentView.invalidate();
parentView.invalidate(imageX, imageY, imageX + imageW, imageY + imageH);
}
}
@ -722,7 +866,27 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
staticThumb = null;
}
if (parentView != null) {
parentView.invalidate();
parentView.invalidate(imageX, imageY, imageX + imageW, imageY + imageH);
}
}
} else if (id == NotificationCenter.didReplacedPhotoInMemCache) {
String oldKey = (String) args[0];
if (currentKey != null && currentKey.equals(oldKey)) {
currentKey = (String) args[1];
currentImageLocation = (TLRPC.FileLocation) args[2];
}
if (currentThumbKey != null && currentThumbKey.equals(oldKey)) {
currentThumbKey = (String) args[1];
currentThumbLocation = (TLRPC.FileLocation) args[2];
}
if (setImageBackup != null) {
if (currentKey != null && currentKey.equals(oldKey)) {
currentKey = (String) args[1];
currentImageLocation = (TLRPC.FileLocation) args[2];
}
if (currentThumbKey != null && currentThumbKey.equals(oldKey)) {
currentThumbKey = (String) args[1];
currentThumbLocation = (TLRPC.FileLocation) args[2];
}
}
}

View File

@ -378,6 +378,10 @@ public class LocaleController {
}
}
public Locale getSystemDefaultLocale() {
return systemDefaultLocale;
}
public static String getLocaleString(Locale locale) {
if (locale == null) {
return "en";
@ -676,11 +680,12 @@ public class LocaleController {
}
public static String formatString(String key, int res, Object... args) {
try {
String value = getInstance().localeValues.get(key);
if (value == null) {
value = ApplicationLoader.applicationContext.getString(res);
}
try {
if (getInstance().currentLocale != null) {
return String.format(getInstance().currentLocale, value, args);
} else {

View File

@ -87,6 +87,8 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
public static int[] readArgs = new int[3];
public static String iFilter = "*";
public interface FileDownloadProgressListener {
void onFailedDownload(String fileName);
void onSuccessDownload(String fileName);
@ -117,17 +119,27 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
MediaStore.Images.Media.ORIENTATION
};
private static final String[] projectionVideo = {
MediaStore.Video.Media._ID,
MediaStore.Video.Media.BUCKET_ID,
MediaStore.Video.Media.BUCKET_DISPLAY_NAME,
MediaStore.Video.Media.DATA,
MediaStore.Video.Media.DATE_TAKEN
};
public static class AlbumEntry {
public int bucketId;
public String bucketName;
public PhotoEntry coverPhoto;
public ArrayList<PhotoEntry> photos = new ArrayList<>();
public HashMap<Integer, PhotoEntry> photosByIds = new HashMap<>();
public boolean isVideo;
public AlbumEntry(int bucketId, String bucketName, PhotoEntry coverPhoto) {
public AlbumEntry(int bucketId, String bucketName, PhotoEntry coverPhoto, boolean isVideo) {
this.bucketId = bucketId;
this.bucketName = bucketName;
this.coverPhoto = coverPhoto;
this.isVideo = isVideo;
}
public void addPhoto(PhotoEntry photoEntry) {
@ -144,13 +156,16 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
public int orientation;
public String thumbPath;
public String imagePath;
public boolean isVideo;
public CharSequence caption;
public PhotoEntry(int bucketId, int imageId, long dateTaken, String path, int orientation) {
public PhotoEntry(int bucketId, int imageId, long dateTaken, String path, int orientation, boolean isVideo) {
this.bucketId = bucketId;
this.imageId = imageId;
this.dateTaken = dateTaken;
this.path = path;
this.orientation = orientation;
this.isVideo = isVideo;
}
}
@ -167,6 +182,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
public int date;
public String thumbPath;
public String imagePath;
public CharSequence caption;
}
public final static String MIME_TYPE = "video/avc";
@ -178,6 +194,8 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
private final static int PROCESSOR_TYPE_TI = 5;
private final Object videoConvertSync = new Object();
private HashMap<Long, Long> typingTimes = new HashMap<>();
private SensorManager sensorManager;
private Sensor proximitySensor;
private boolean ignoreProximity;
@ -550,6 +568,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
videoDownloadQueue.clear();
downloadQueueKeys.clear();
videoConvertQueue.clear();
typingTimes.clear();
cancelVideoConvert(null);
}
@ -975,6 +994,29 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
}
listenerInProgress = false;
processLaterArrays();
try {
ArrayList<SendMessagesHelper.DelayedMessage> delayedMessages = SendMessagesHelper.getInstance().getDelayedMessages(fileName);
if (delayedMessages != null) {
for (SendMessagesHelper.DelayedMessage delayedMessage : delayedMessages) {
if (delayedMessage.encryptedChat == null) {
long dialog_id = delayedMessage.obj.getDialogId();
Long lastTime = typingTimes.get(dialog_id);
if (lastTime == null || lastTime + 4000 < System.currentTimeMillis()) {
if (delayedMessage.videoLocation != null) {
MessagesController.getInstance().sendTyping(dialog_id, 5, 0);
} else if (delayedMessage.documentLocation != null) {
MessagesController.getInstance().sendTyping(dialog_id, 3, 0);
} else if (delayedMessage.location != null) {
MessagesController.getInstance().sendTyping(dialog_id, 4, 0);
}
typingTimes.put(dialog_id, System.currentTimeMillis());
}
}
}
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
} else if (id == NotificationCenter.messagesDeleted) {
if (playingMessageObject != null) {
ArrayList<Integer> markAsDeletedMessages = (ArrayList<Integer>)args[0];
@ -1970,10 +2012,12 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
@Override
public void run() {
final ArrayList<AlbumEntry> albumsSorted = new ArrayList<>();
final ArrayList<AlbumEntry> videoAlbumsSorted = new ArrayList<>();
HashMap<Integer, AlbumEntry> albums = new HashMap<>();
AlbumEntry allPhotosAlbum = null;
String cameraFolder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath() + "/" + "Camera/";
Integer cameraAlbumId = null;
Integer cameraAlbumVideoId = null;
Cursor cursor = null;
try {
@ -1993,15 +2037,15 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
String path = cursor.getString(dataColumn);
long dateTaken = cursor.getLong(dateColumn);
int orientation = cursor.getInt(orientationColumn);
if (path == null || path.length() == 0) {
//Plus
if (path == null || path.length() == 0 || !iFilter.equals("*") && !path.toLowerCase().endsWith(iFilter)) {//|| !path.contains(".webp")
continue;
}
PhotoEntry photoEntry = new PhotoEntry(bucketId, imageId, dateTaken, path, orientation);
PhotoEntry photoEntry = new PhotoEntry(bucketId, imageId, dateTaken, path, orientation, false);
if (allPhotosAlbum == null) {
allPhotosAlbum = new AlbumEntry(0, LocaleController.getString("AllPhotos", R.string.AllPhotos), photoEntry);
allPhotosAlbum = new AlbumEntry(0, LocaleController.getString("AllPhotos", R.string.AllPhotos), photoEntry, false);
albumsSorted.add(0, allPhotosAlbum);
}
if (allPhotosAlbum != null) {
@ -2010,7 +2054,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
AlbumEntry albumEntry = albums.get(bucketId);
if (albumEntry == null) {
albumEntry = new AlbumEntry(bucketId, bucketName, photoEntry);
albumEntry = new AlbumEntry(bucketId, bucketName, photoEntry, false);
albums.put(bucketId, albumEntry);
if (cameraAlbumId == null && cameraFolder != null && path != null && path.startsWith(cameraFolder)) {
albumsSorted.add(0, albumEntry);
@ -2034,11 +2078,72 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
}
}
}
try {
albums.clear();
allPhotosAlbum = null;
cursor = MediaStore.Images.Media.query(ApplicationLoader.applicationContext.getContentResolver(), MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projectionVideo, "", null, MediaStore.Video.Media.DATE_TAKEN + " DESC");
if (cursor != null) {
int imageIdColumn = cursor.getColumnIndex(MediaStore.Video.Media._ID);
int bucketIdColumn = cursor.getColumnIndex(MediaStore.Video.Media.BUCKET_ID);
int bucketNameColumn = cursor.getColumnIndex(MediaStore.Video.Media.BUCKET_DISPLAY_NAME);
int dataColumn = cursor.getColumnIndex(MediaStore.Video.Media.DATA);
int dateColumn = cursor.getColumnIndex(MediaStore.Video.Media.DATE_TAKEN);
while (cursor.moveToNext()) {
int imageId = cursor.getInt(imageIdColumn);
int bucketId = cursor.getInt(bucketIdColumn);
String bucketName = cursor.getString(bucketNameColumn);
String path = cursor.getString(dataColumn);
long dateTaken = cursor.getLong(dateColumn);
if (path == null || path.length() == 0) {
continue;
}
PhotoEntry photoEntry = new PhotoEntry(bucketId, imageId, dateTaken, path, 0, true);
if (allPhotosAlbum == null) {
allPhotosAlbum = new AlbumEntry(0, LocaleController.getString("AllVideo", R.string.AllVideo), photoEntry, true);
videoAlbumsSorted.add(0, allPhotosAlbum);
}
if (allPhotosAlbum != null) {
allPhotosAlbum.addPhoto(photoEntry);
}
AlbumEntry albumEntry = albums.get(bucketId);
if (albumEntry == null) {
albumEntry = new AlbumEntry(bucketId, bucketName, photoEntry, true);
albums.put(bucketId, albumEntry);
if (cameraAlbumVideoId == null && cameraFolder != null && path != null && path.startsWith(cameraFolder)) {
videoAlbumsSorted.add(0, albumEntry);
cameraAlbumVideoId = bucketId;
} else {
videoAlbumsSorted.add(albumEntry);
}
}
albumEntry.addPhoto(photoEntry);
}
}
} catch (Exception e) {
FileLog.e("tmessages", e);
} finally {
if (cursor != null) {
try {
cursor.close();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
}
final Integer cameraAlbumIdFinal = cameraAlbumId;
final Integer cameraAlbumVideoIdFinal = cameraAlbumVideoId;
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.albumsDidLoaded, guid, albumsSorted, cameraAlbumIdFinal);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.albumsDidLoaded, guid, albumsSorted, cameraAlbumIdFinal, videoAlbumsSorted, cameraAlbumVideoIdFinal);
}
});
}

View File

@ -44,6 +44,7 @@ public class MessageObject {
public TLRPC.Message messageOwner;
public CharSequence messageText;
public CharSequence linkDescription;
public CharSequence caption;
public MessageObject replyMessageObject;
public int type;
public int contentType;
@ -54,7 +55,7 @@ public class MessageObject {
public int audioProgressSec;
public ArrayList<TLRPC.PhotoSize> photoThumbs;
private static TextPaint textPaint;
public static TextPaint textPaint;
private static TextPaint textPaintRight = new TextPaint(Paint.ANTI_ALIAS_FLAG);
private static TextPaint textPaintLeft = new TextPaint(Paint.ANTI_ALIAS_FLAG);
public int lastLineWidth;
@ -163,6 +164,13 @@ public class MessageObject {
whoUser = MessagesController.getInstance().getUser(message.action.user_id);
}
if (whoUser != null && fromUser != null) {
if (whoUser.id == fromUser.id) {
if (isOut()) {
messageText = LocaleController.getString("ActionAddUserSelf", R.string.ActionAddUserSelf).replace("un1", LocaleController.getString("FromYou", R.string.FromYou));
} else {
messageText = replaceWithLink(LocaleController.getString("ActionAddUserSelf", R.string.ActionAddUserSelf), "un1", fromUser);
}
} else {
if (isOut()) {
messageText = replaceWithLink(LocaleController.getString("ActionYouAddUser", R.string.ActionYouAddUser), "un2", whoUser);
} else if (message.action.user_id == UserConfig.getClientUserId()) {
@ -171,9 +179,20 @@ public class MessageObject {
messageText = replaceWithLink(LocaleController.getString("ActionAddUser", R.string.ActionAddUser), "un2", whoUser);
messageText = replaceWithLink(messageText, "un1", fromUser);
}
}
} else {
messageText = LocaleController.getString("ActionAddUser", R.string.ActionAddUser).replace("un2", "").replace("un1", "");
}
} else if (message.action instanceof TLRPC.TL_messageActionChatJoinedByLink) {
if (fromUser != null) {
if (isOut()) {
messageText = LocaleController.getString("ActionInviteYou", R.string.ActionInviteYou);
} else {
messageText = replaceWithLink(LocaleController.getString("ActionInviteUser", R.string.ActionInviteUser), "un1", fromUser);
}
} else {
messageText = LocaleController.getString("ActionInviteUser", R.string.ActionInviteUser).replace("un1", "");
}
} else if (message.action instanceof TLRPC.TL_messageActionChatEditPhoto) {
if (isOut()) {
messageText = LocaleController.getString("ActionYouChangedPhoto", R.string.ActionYouChangedPhoto);
@ -298,7 +317,7 @@ public class MessageObject {
messageText = LocaleController.getString("AttachPhoto", R.string.AttachPhoto);
} else if (message.media instanceof TLRPC.TL_messageMediaVideo) {
messageText = LocaleController.getString("AttachVideo", R.string.AttachVideo);
} else if (message.media instanceof TLRPC.TL_messageMediaGeo) {
} else if (message.media instanceof TLRPC.TL_messageMediaGeo || message.media instanceof TLRPC.TL_messageMediaVenue) {
messageText = LocaleController.getString("AttachLocation", R.string.AttachLocation);
} else if (message.media instanceof TLRPC.TL_messageMediaContact) {
messageText = LocaleController.getString("AttachContact", R.string.AttachContact);
@ -333,7 +352,7 @@ public class MessageObject {
contentType = type = 0;
} else if (message.media instanceof TLRPC.TL_messageMediaPhoto) {
contentType = type = 1;
} else if (message.media instanceof TLRPC.TL_messageMediaGeo) {
} else if (message.media instanceof TLRPC.TL_messageMediaGeo || message.media instanceof TLRPC.TL_messageMediaVenue) {
contentType = 1;
type = 4;
} else if (message.media instanceof TLRPC.TL_messageMediaVideo) {
@ -393,6 +412,7 @@ public class MessageObject {
monthKey = String.format("%d_%02d", dateYear, dateMonth);
}
generateCaption();
if (generateLayout) {
generateLayout();
}
@ -588,6 +608,41 @@ public class MessageObject {
}
}
public void generateCaption() {
if (caption != null) {
return;
}
if (messageOwner.media != null && messageOwner.media.caption != null && messageOwner.media.caption.length() > 0) {
caption = Emoji.replaceEmoji(messageOwner.media.caption, textPaint.getFontMetricsInt(), AndroidUtilities.dp(20));
if (containsUrls(caption)) {
try {
Linkify.addLinks((Spannable) caption, Linkify.WEB_URLS);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
addUsernamesAndHashtags(caption);
}
}
}
private void addUsernamesAndHashtags(CharSequence charSequence) {
try {
Pattern pattern = Pattern.compile("(^|\\s)@[a-zA-Z\\d_]{5,32}|(^|\\s)#[\\w\\.]+");
Matcher matcher = pattern.matcher(charSequence);
while (matcher.find()) {
int start = matcher.start();
int end = matcher.end();
if (charSequence.charAt(start) != '@' && charSequence.charAt(start) != '#') {
start++;
}
URLSpanNoUnderline url = new URLSpanNoUnderline(charSequence.subSequence(start, end).toString());
((Spannable) charSequence).setSpan(url, start, end, 0);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
private void generateLayout() {
if (type != 0 || messageOwner.to_id == null || messageText == null || messageText.length() == 0) {
return;
@ -598,26 +653,19 @@ public class MessageObject {
if (messageText instanceof Spannable && containsUrls(messageText)) {
if (messageText.length() < 100) {
Linkify.addLinks((Spannable) messageText, Linkify.WEB_URLS | Linkify.PHONE_NUMBERS);
} else {
Linkify.addLinks((Spannable) messageText, Linkify.WEB_URLS);
}
try {
Pattern pattern = Pattern.compile("(^|\\s)@[a-zA-Z\\d_]{5,32}|(^|\\s)#[\\w\\.]+");
Matcher matcher = pattern.matcher(messageText);
while (matcher.find()) {
int start = matcher.start();
int end = matcher.end();
if (messageText.charAt(start) != '@' && messageText.charAt(start) != '#') {
start++;
}
URLSpanNoUnderline url = new URLSpanNoUnderline(messageText.subSequence(start, end).toString());
((Spannable) messageText).setSpan(url, start, end, 0);
}
Linkify.addLinks((Spannable) messageText, Linkify.WEB_URLS | Linkify.PHONE_NUMBERS);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
} else {
try {
Linkify.addLinks((Spannable) messageText, Linkify.WEB_URLS);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
addUsernamesAndHashtags(messageText);
}
int maxWidth;
@ -782,10 +830,33 @@ public class MessageObject {
return (messageOwner.flags & TLRPC.MESSAGE_FLAG_UNREAD) != 0;
}
public boolean isContentUnread() {
return (messageOwner.flags & TLRPC.MESSAGE_FLAG_CONTENT_UNREAD) != 0;
}
public void setIsRead() {
messageOwner.flags &= ~TLRPC.MESSAGE_FLAG_UNREAD;
}
public int getUnradFlags() {
return getUnreadFlags(messageOwner);
}
public static int getUnreadFlags(TLRPC.Message message) {
int flags = 0;
if ((message.flags & TLRPC.MESSAGE_FLAG_UNREAD) == 0) {
flags |= 1;
}
if ((message.flags & TLRPC.MESSAGE_FLAG_CONTENT_UNREAD) == 0) {
flags |= 2;
}
return flags;
}
public void setContentIsRead() {
messageOwner.flags &= ~TLRPC.MESSAGE_FLAG_CONTENT_UNREAD;
}
public int getId() {
return messageOwner.id;
}
@ -801,18 +872,27 @@ public class MessageObject {
messageOwner.media instanceof TLRPC.TL_messageMediaVideo);
}
public static void setIsUnread(TLRPC.Message message, boolean unread) {
if (unread) {
public static void setUnreadFlags(TLRPC.Message message, int flag) {
if ((flag & 1) == 0) {
message.flags |= TLRPC.MESSAGE_FLAG_UNREAD;
} else {
message.flags &= ~TLRPC.MESSAGE_FLAG_UNREAD;
}
if ((flag & 2) == 0) {
message.flags |= TLRPC.MESSAGE_FLAG_CONTENT_UNREAD;
} else {
message.flags &= ~TLRPC.MESSAGE_FLAG_CONTENT_UNREAD;
}
}
public static boolean isUnread(TLRPC.Message message) {
return (message.flags & TLRPC.MESSAGE_FLAG_UNREAD) != 0;
}
public static boolean isContentUnread(TLRPC.Message message) {
return (message.flags & TLRPC.MESSAGE_FLAG_CONTENT_UNREAD) != 0;
}
public static boolean isOut(TLRPC.Message message) {
return (message.flags & TLRPC.MESSAGE_FLAG_OUT) != 0;
}

View File

@ -23,7 +23,6 @@ import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.messenger.RPCRequest;
import org.telegram.messenger.SerializedData;
import org.telegram.messenger.TLClassStore;
import org.telegram.messenger.TLObject;
import org.telegram.messenger.TLRPC;
import org.telegram.messenger.UserConfig;
@ -34,7 +33,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Semaphore;
@ -45,13 +43,16 @@ public class MessagesController implements NotificationCenter.NotificationCenter
private ConcurrentHashMap<Integer, TLRPC.User> users = new ConcurrentHashMap<>(100, 1.0f, 2);
private ConcurrentHashMap<String, TLRPC.User> usersByUsernames = new ConcurrentHashMap<>(100, 1.0f, 2);
private HashMap<Integer, TLRPC.ExportedChatInvite> exportedChats = new HashMap<>();
public ArrayList<TLRPC.TL_dialog> dialogs = new ArrayList<>();
public ArrayList<TLRPC.TL_dialog> dialogsServerOnly = new ArrayList<>();
public ConcurrentHashMap<Long, TLRPC.TL_dialog> dialogs_dict = new ConcurrentHashMap<>(100, 1.0f, 2);
public HashMap<Integer, MessageObject> dialogMessage = new HashMap<>();
public ConcurrentHashMap<Long, ArrayList<PrintingUser>> printingUsers = new ConcurrentHashMap<>(20, 1.0f, 2);
public HashMap<Long, CharSequence> printingStrings = new HashMap<>();
public HashMap<Long, Boolean> sendingTypings = new HashMap<>();
public HashMap<Long, Integer> printingStringsTypes = new HashMap<>();
public HashMap<Integer, HashMap<Long, Boolean>> sendingTypings = new HashMap<>();
public ConcurrentHashMap<Integer, Integer> onlinePrivacy = new ConcurrentHashMap<>(20, 1.0f, 2);
private int lastPrintingStringCount = 0;
@ -124,6 +125,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
public static class PrintingUser {
public long lastTime;
public int userId;
public TLRPC.SendMessageAction action;
}
private static volatile MessagesController Instance = null;
@ -163,9 +165,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter
byte[] bytes = Base64.decode(disabledFeaturesString, Base64.DEFAULT);
if (bytes != null) {
SerializedData data = new SerializedData(bytes);
int count = data.readInt32();
int count = data.readInt32(false);
for (int a = 0; a < count; a++) {
TLRPC.TL_disabledFeature feature = (TLRPC.TL_disabledFeature) TLClassStore.Instance().TLdeserialize(data, data.readInt32());
TLRPC.TL_disabledFeature feature = TLRPC.TL_disabledFeature.TLdeserialize(data, data.readInt32(false), false);
if (feature != null && feature.feature != null && feature.description != null) {
disabledFeatures.add(feature);
}
@ -372,6 +374,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
SecretChatHelper.getInstance().cleanUp();
dialogs_dict.clear();
exportedChats.clear();
dialogs.clear();
dialogsServerOnly.clear();
users.clear();
@ -380,6 +383,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
dialogMessage.clear();
printingUsers.clear();
printingStrings.clear();
printingStringsTypes.clear();
onlinePrivacy.clear();
totalDialogsCount = 0;
lastPrintingStringCount = 0;
@ -463,6 +467,14 @@ public class MessagesController implements NotificationCenter.NotificationCenter
return chat;
}
public TLRPC.ExportedChatInvite getExportedInvite(int chat_id) {
return exportedChats.get(chat_id);
}
public void putExportedInvite(int chat_id, TLRPC.TL_chatInviteExported invite) {
exportedChats.put(chat_id, invite);
}
public boolean putUser(TLRPC.User user, boolean fromCache) {
if (user == null) {
return false;
@ -564,7 +576,11 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
public void loadFullChat(final int chat_id, final int classGuid) {
if (loadingFullChats.contains(chat_id) || loadedFullChats.contains(chat_id)) {
loadFullChat(chat_id, classGuid, false);
}
public void loadFullChat(final int chat_id, final int classGuid, boolean force) {
if (loadingFullChats.contains(chat_id) || !force && loadedFullChats.contains(chat_id)) {
return;
}
loadingFullChats.add(chat_id);
@ -580,12 +596,13 @@ public class MessagesController implements NotificationCenter.NotificationCenter
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
loadingFullChats.remove((Integer)chat_id);
exportedChats.put(chat_id, res.full_chat.exported_invite);
loadingFullChats.remove((Integer) chat_id);
loadedFullChats.add(chat_id);
putUsers(res.users, false);
putChats(res.chats, false);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatInfoDidLoaded, chat_id, res.full_chat.participants);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatInfoDidLoaded, chat_id, res.full_chat.participants, classGuid);
}
});
} else {
@ -617,7 +634,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
loadingFullUsers.remove((Integer)user.id);
loadingFullUsers.remove((Integer) user.id);
loadedFullUsers.add(user.id);
String names = user.first_name + user.last_name + user.username;
TLRPC.TL_userFull userFull = (TLRPC.TL_userFull)response;
@ -1275,15 +1292,72 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
}
public void updatePrintingStrings() {
private String getUserNameForTyping(TLRPC.User user) {
if (user == null) {
return "";
}
if (user.first_name != null && user.first_name.length() > 0) {
return user.first_name;
} else if (user.last_name != null && user.last_name.length() > 0) {
return user.last_name;
}
return "";
}
private void updatePrintingStrings() {
final HashMap<Long, CharSequence> newPrintingStrings = new HashMap<>();
final HashMap<Long, Integer> newPrintingStringsTypes = new HashMap<>();
ArrayList<Long> keys = new ArrayList<>(printingUsers.keySet());
for (Long key : keys) {
if (key > 0 || key.intValue() == 0) {
newPrintingStrings.put(key, LocaleController.getString("Typing", R.string.Typing));
for (HashMap.Entry<Long, ArrayList<PrintingUser>> entry : printingUsers.entrySet()) {
long key = entry.getKey();
ArrayList<PrintingUser> arr = entry.getValue();
int lower_id = (int) key;
if (lower_id > 0 || lower_id == 0 || arr.size() == 1) {
PrintingUser pu = arr.get(0);
TLRPC.User user = getUser(pu.userId);
if (user == null) {
return;
}
if (pu.action instanceof TLRPC.TL_sendMessageUploadAudioAction || pu.action instanceof TLRPC.TL_sendMessageRecordAudioAction) {
if (lower_id < 0) {
newPrintingStrings.put(key, LocaleController.formatString("IsRecordingAudio", R.string.IsRecordingAudio, getUserNameForTyping(user)));
} else {
newPrintingStrings.put(key, LocaleController.getString("RecordingAudio", R.string.RecordingAudio));
}
newPrintingStringsTypes.put(key, 1);
} else if (pu.action instanceof TLRPC.TL_sendMessageUploadVideoAction || pu.action instanceof TLRPC.TL_sendMessageRecordVideoAction) {
if (lower_id < 0) {
newPrintingStrings.put(key, LocaleController.formatString("IsSendingVideo", R.string.IsSendingVideo, getUserNameForTyping(user)));
} else {
newPrintingStrings.put(key, LocaleController.getString("SendingVideoStatus", R.string.SendingVideoStatus));
}
newPrintingStringsTypes.put(key, 2);
} else if (pu.action instanceof TLRPC.TL_sendMessageUploadDocumentAction) {
if (lower_id < 0) {
newPrintingStrings.put(key, LocaleController.formatString("IsSendingFile", R.string.IsSendingFile, getUserNameForTyping(user)));
} else {
newPrintingStrings.put(key, LocaleController.getString("SendingFile", R.string.SendingFile));
}
newPrintingStringsTypes.put(key, 2);
} else if (pu.action instanceof TLRPC.TL_sendMessageUploadPhotoAction) {
if (lower_id < 0) {
newPrintingStrings.put(key, LocaleController.formatString("IsSendingPhoto", R.string.IsSendingPhoto, getUserNameForTyping(user)));
} else {
newPrintingStrings.put(key, LocaleController.getString("SendingPhoto", R.string.SendingPhoto));
}
newPrintingStringsTypes.put(key, 2);
} else {
if (lower_id < 0) {
newPrintingStrings.put(key, String.format("%s %s", getUserNameForTyping(user), LocaleController.getString("IsTyping", R.string.IsTyping)));
} else {
newPrintingStrings.put(key, LocaleController.getString("Typing", R.string.Typing));
}
newPrintingStringsTypes.put(key, 0);
}
} else {
ArrayList<PrintingUser> arr = printingUsers.get(key);
int count = 0;
String label = "";
for (PrintingUser pu : arr) {
@ -1292,11 +1366,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
if (label.length() != 0) {
label += ", ";
}
if (user.first_name != null && user.first_name.length() > 0) {
label += user.first_name;
} else if (user.last_name != null && user.last_name.length() > 0) {
label += user.last_name;
}
label += getUserNameForTyping(user);
count++;
}
if (count == 2) {
@ -1304,15 +1374,12 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
}
if (label.length() != 0) {
if (count > 1) {
if (arr.size() > 2) {
newPrintingStrings.put(key, String.format("%s %s", label, LocaleController.formatPluralString("AndMoreTyping", arr.size() - 2)));
} else {
newPrintingStrings.put(key, String.format("%s %s", label, LocaleController.getString("AreTyping", R.string.AreTyping)));
}
} else {
newPrintingStrings.put(key, String.format("%s %s", label, LocaleController.getString("IsTyping", R.string.IsTyping)));
}
newPrintingStringsTypes.put(key, 0);
}
}
}
@ -1323,21 +1390,30 @@ public class MessagesController implements NotificationCenter.NotificationCenter
@Override
public void run() {
printingStrings = newPrintingStrings;
printingStringsTypes = newPrintingStringsTypes;
}
});
}
public void cancelTyping(long dialog_id) {
sendingTypings.remove(dialog_id);
public void cancelTyping(int action, long dialog_id) {
HashMap<Long, Boolean> typings = sendingTypings.get(action);
if (typings != null) {
typings.remove(dialog_id);
}
}
public void sendTyping(final long dialog_id, int classGuid) {
public void sendTyping(final long dialog_id, final int action, int classGuid) {
if (dialog_id == 0) {
return;
}
if (sendingTypings.get(dialog_id) != null) {
HashMap<Long, Boolean> typings = sendingTypings.get(action);
if (typings != null && typings.get(dialog_id) != null) {
return;
}
if (typings == null) {
typings = new HashMap<>();
sendingTypings.put(action, typings);
}
int lower_part = (int)dialog_id;
int high_id = (int)(dialog_id >> 32);
if (lower_part != 0) {
@ -1364,21 +1440,41 @@ public class MessagesController implements NotificationCenter.NotificationCenter
return;
}
}
if (action == 0) {
req.action = new TLRPC.TL_sendMessageTypingAction();
sendingTypings.put(dialog_id, true);
} else if (action == 1) {
req.action = new TLRPC.TL_sendMessageRecordAudioAction();
} else if (action == 2) {
req.action = new TLRPC.TL_sendMessageCancelAction();
} else if (action == 3) {
req.action = new TLRPC.TL_sendMessageUploadDocumentAction();
} else if (action == 4) {
req.action = new TLRPC.TL_sendMessageUploadPhotoAction();
} else if (action == 5) {
req.action = new TLRPC.TL_sendMessageUploadVideoAction();
}
typings.put(dialog_id, true);
long reqId = ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() {
@Override
public void run(TLObject response, TLRPC.TL_error error) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
sendingTypings.remove(dialog_id);
HashMap<Long, Boolean> typings = sendingTypings.get(action);
if (typings != null) {
typings.remove(dialog_id);
}
}
});
}
}, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors);
if (classGuid != 0) {
ConnectionsManager.getInstance().bindRequestToGuid(reqId, classGuid);
}
} else {
if (action != 0) {
return;
}
TLRPC.EncryptedChat chat = getEncryptedChat(high_id);
if (chat.auth_key != null && chat.auth_key.length > 1 && chat instanceof TLRPC.TL_encryptedChat) {
TLRPC.TL_messages_setEncryptedTyping req = new TLRPC.TL_messages_setEncryptedTyping();
@ -1386,17 +1482,27 @@ public class MessagesController implements NotificationCenter.NotificationCenter
req.peer.chat_id = chat.id;
req.peer.access_hash = chat.access_hash;
req.typing = true;
sendingTypings.put(dialog_id, true);
typings.put(dialog_id, true);
long reqId = ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() {
@Override
public void run(TLObject response, TLRPC.TL_error error) {
sendingTypings.remove(dialog_id);
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
HashMap<Long, Boolean> typings = sendingTypings.get(action);
if (typings != null) {
typings.remove(dialog_id);
}
}
});
}
}, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors);
if (classGuid != 0) {
ConnectionsManager.getInstance().bindRequestToGuid(reqId, classGuid);
}
}
}
}
public void loadMessages(final long dialog_id, final int count, final int max_id, boolean fromCache, int midDate, final int classGuid, final int load_type, final int last_message_id, final int first_message_id, final boolean allowCache) {
int lower_part = (int)dialog_id;
@ -1567,7 +1673,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
currentDialog.unread_count = entry.getValue();
}
}
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_READ_DIALOG_MESSAGE);
NotificationsController.getInstance().processDialogsUpdateRead(dialogsToUpdate);
}
});
@ -1803,12 +1909,29 @@ public class MessagesController implements NotificationCenter.NotificationCenter
dialogsEndReached = (dialogsRes.dialogs.size() == 0 || dialogsRes.dialogs.size() != count) && !isCache;
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
generateUpdateMessage();
}
});
}
});
}
public void markMessageContentAsRead(int mid) {
TLRPC.TL_messages_readMessageContents req = new TLRPC.TL_messages_readMessageContents();
req.id.add(mid);
MessagesStorage.getInstance().markMessagesContentAsRead(req.id);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messagesReadContent, req.id);
ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() {
@Override
public void run(TLObject response, TLRPC.TL_error error) {
if (error == null) {
TLRPC.TL_messages_affectedMessages res = (TLRPC.TL_messages_affectedMessages) response;
processNewDifferenceParams(-1, res.pts, -1, res.pts_count);
}
}
});
}
public void markMessageAsRead(final long dialog_id, final long random_id, int ttl) {
if (random_id == 0 || dialog_id == 0 || ttl <= 0) {
return;
@ -2030,7 +2153,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
public void run() {
putUsers(updates.users, false);
putChats(updates.chats, false);
TLRPC.Chat chat = null;
if (updates.chats != null && !updates.chats.isEmpty()) {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatDidCreated, updates.chats.get(0).id);
} else {
@ -2213,6 +2335,35 @@ public class MessagesController implements NotificationCenter.NotificationCenter
});
}
public void generateUpdateMessage() {
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
try {
String build = LocaleController.getString("updateBuild", R.string.updateBuild);
if (build != null) {
int version = Utilities.parseInt(build);
if (version <= UserConfig.lastUpdateVersion) {
return;
}
UserConfig.lastUpdateVersion = version;
UserConfig.saveConfig(false);
}
TLRPC.TL_updateServiceNotification update = new TLRPC.TL_updateServiceNotification();
update.message = LocaleController.getString("updateText", R.string.updateText) + LocaleController.getString("updatePlusText", R.string.updatePlusText);
update.media = new TLRPC.TL_messageMediaEmpty();
update.type = "update";
update.popup = false;
ArrayList<TLRPC.Update> updates = new ArrayList<>();
updates.add(update);
processUpdateArray(updates, null, null);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
}
public void registerForPush(final String regid) {
if (regid == null || regid.length() == 0 || registeringForPush || UserConfig.getClientUserId() == 0) {
return;
@ -2226,7 +2377,10 @@ public class MessagesController implements NotificationCenter.NotificationCenter
req.token = regid;
req.app_sandbox = false;
try {
req.lang_code = LocaleController.getLocaleString(Locale.getDefault());
req.lang_code = LocaleController.getLocaleString(LocaleController.getInstance().getSystemDefaultLocale());
if (req.lang_code == null || req.lang_code.length() == 0) {
req.lang_code = "en";
}
req.device_model = Build.MANUFACTURER + Build.MODEL;
if (req.device_model == null) {
req.device_model = "Android unknown";
@ -2359,7 +2513,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
} else if (type == 2) {
if (updates.qts <= MessagesStorage.lastQtsValue) {
return 2;
} else if (MessagesStorage.lastQtsValue + 1 == updates.qts) {
} else if (MessagesStorage.lastQtsValue + updates.updates.size() == updates.qts) {
return 0;
} else {
return 1;
@ -2375,14 +2529,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
Collections.sort(updatesQueue, new Comparator<TLRPC.Updates>() {
@Override
public int compare(TLRPC.Updates updates, TLRPC.Updates updates2) {
int seq1 = getUpdateSeq(updates);
int seq2 = getUpdateSeq(updates2);
if (seq1 == seq2) {
return 0;
} else if (seq1 > seq2) {
return 1;
}
return -1;
return AndroidUtilities.compare(getUpdateSeq(updates), getUpdateSeq(updates2));
}
});
} else if (type == 1) {
@ -2390,12 +2537,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
Collections.sort(updatesQueue, new Comparator<TLRPC.Updates>() {
@Override
public int compare(TLRPC.Updates updates, TLRPC.Updates updates2) {
if (updates.pts == updates2.pts) {
return 0;
} else if (updates.pts > updates2.pts) {
return 1;
}
return -1;
return AndroidUtilities.compare(updates.pts, updates2.pts);
}
});
} else if (type == 2) {
@ -2403,12 +2545,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
Collections.sort(updatesQueue, new Comparator<TLRPC.Updates>() {
@Override
public int compare(TLRPC.Updates updates, TLRPC.Updates updates2) {
if (updates.qts == updates2.qts) {
return 0;
} else if (updates.qts > updates2.qts) {
return 1;
}
return -1;
return AndroidUtilities.compare(updates.qts, updates2.qts);
}
});
}
@ -2710,6 +2847,17 @@ public class MessagesController implements NotificationCenter.NotificationCenter
});
}
private int getUpdateType(TLRPC.Update update) {
if (update instanceof TLRPC.TL_updateNewMessage || update instanceof TLRPC.TL_updateReadMessagesContents || update instanceof TLRPC.TL_updateReadHistoryInbox ||
update instanceof TLRPC.TL_updateReadHistoryOutbox || update instanceof TLRPC.TL_updateDeleteMessages) {
return 0;
} else if (update instanceof TLRPC.TL_updateNewEncryptedMessage) {
return 1;
} else {
return 2;
}
}
public void processUpdates(final TLRPC.Updates updates, boolean fromQueue) {
boolean needGetDiff = false;
boolean needReceivedQueue = false;
@ -2719,11 +2867,12 @@ public class MessagesController implements NotificationCenter.NotificationCenter
arr.add(updates.update);
processUpdateArray(arr, null, null);
} else if (updates instanceof TLRPC.TL_updateShortChatMessage || updates instanceof TLRPC.TL_updateShortMessage) {
TLRPC.User user = getUser(updates.user_id);
final int user_id = updates instanceof TLRPC.TL_updateShortChatMessage ? updates.from_id : updates.user_id;
TLRPC.User user = getUser(user_id);
TLRPC.User user2 = null;
if (user == null) {
user = MessagesStorage.getInstance().getUserSync(updates.user_id);
user = MessagesStorage.getInstance().getUserSync(user_id);
putUser(user, true);
}
@ -2763,13 +2912,13 @@ public class MessagesController implements NotificationCenter.NotificationCenter
if ((updates.flags & TLRPC.MESSAGE_FLAG_OUT) != 0) {
message.from_id = UserConfig.getClientUserId();
} else {
message.from_id = updates.user_id;
message.from_id = user_id;
}
message.to_id = new TLRPC.TL_peerUser();
message.to_id.user_id = updates.user_id;
message.dialog_id = updates.user_id;
message.to_id.user_id = user_id;
message.dialog_id = user_id;
} else {
message.from_id = updates.user_id;
message.from_id = user_id;
message.to_id = new TLRPC.TL_peerChat();
message.to_id.chat_id = updates.chat_id;
message.dialog_id = -updates.chat_id;
@ -2798,7 +2947,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
if (printUpdate) {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_USER_PRINT);
}
updateInterfaceWithMessages(updates.user_id, objArr);
updateInterfaceWithMessages(user_id, objArr);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
}
});
@ -2840,7 +2989,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
if (updatesStartWaitTimePts == 0) {
updatesStartWaitTimePts = System.currentTimeMillis();
}
FileLog.e("tmessages", "add short message to queue");
FileLog.e("tmessages", "add to queue");
updatesQueuePts.add(updates);
} else {
needGetDiff = true;
@ -2849,56 +2998,92 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
} else if (updates instanceof TLRPC.TL_updatesCombined || updates instanceof TLRPC.TL_updates) {
MessagesStorage.getInstance().putUsersAndChats(updates.users, updates.chats, true, true);
int lastQtsValue = MessagesStorage.lastQtsValue;
Collections.sort(updates.updates, new Comparator<TLRPC.Update>() {
@Override
public int compare(TLRPC.Update lhs, TLRPC.Update rhs) {
int ltype = getUpdateType(lhs);
int rtype = getUpdateType(rhs);
if (ltype != rtype) {
return AndroidUtilities.compare(ltype, rtype);
} else if (ltype == 0) {
return AndroidUtilities.compare(lhs.pts, rhs.pts);
} else if (ltype == 1) {
return AndroidUtilities.compare(lhs.qts, rhs.qts);
}
return 0;
}
});
for (int a = 0; a < updates.updates.size(); a++) {
TLRPC.Update update = updates.updates.get(a);
if (update instanceof TLRPC.TL_updateNewMessage || update instanceof TLRPC.TL_updateReadMessages || update instanceof TLRPC.TL_updateReadHistoryInbox ||
update instanceof TLRPC.TL_updateReadHistoryOutbox || update instanceof TLRPC.TL_updateDeleteMessages) {
if (getUpdateType(update) == 0) {
TLRPC.TL_updates updatesNew = new TLRPC.TL_updates();
updatesNew.updates.add(update);
updatesNew.pts = update.pts;
updatesNew.pts_count = update.pts_count;
if (MessagesStorage.lastPtsValue + update.pts_count == update.pts) {
for (int b = a + 1; b < updates.updates.size(); b++) {
TLRPC.Update update2 = updates.updates.get(b);
if (getUpdateType(update2) == 0 && updatesNew.pts + update2.pts_count == update2.pts) {
updatesNew.updates.add(update2);
updatesNew.pts = update2.pts;
updatesNew.pts_count += update2.pts_count;
updates.updates.remove(b);
b--;
} else {
break;
}
}
if (MessagesStorage.lastPtsValue + updatesNew.pts_count == updatesNew.pts) {
if (!processUpdateArray(updatesNew.updates, updates.users, updates.chats)) {
FileLog.e("tmessages", "need get diff inner TL_updates, seq: " + MessagesStorage.lastSeqValue + " " + updates.seq);
needGetDiff = true;
} else {
MessagesStorage.lastPtsValue = update.pts;
MessagesStorage.lastPtsValue = updatesNew.pts;
}
} else if (MessagesStorage.lastPtsValue != update.pts) {
FileLog.e("tmessages", update + " need get diff, pts: " + MessagesStorage.lastPtsValue + " " + update.pts + " count = " + update.pts_count);
} else if (MessagesStorage.lastPtsValue != updatesNew.pts) {
FileLog.e("tmessages", update + " need get diff, pts: " + MessagesStorage.lastPtsValue + " " + updatesNew.pts + " count = " + updatesNew.pts_count);
if (gettingDifference || updatesStartWaitTimePts == 0 || updatesStartWaitTimePts != 0 && updatesStartWaitTimePts + 1500 > System.currentTimeMillis()) {
if (updatesStartWaitTimePts == 0) {
updatesStartWaitTimePts = System.currentTimeMillis();
}
FileLog.e("tmessages", "add short message to queue");
FileLog.e("tmessages", "add to queue");
updatesQueuePts.add(updatesNew);
} else {
needGetDiff = true;
}
}
} else if (update instanceof TLRPC.TL_updateNewEncryptedMessage) {
} else if (getUpdateType(update) == 1) {
TLRPC.TL_updates updatesNew = new TLRPC.TL_updates();
updatesNew.updates.add(update);
updatesNew.qts = update.qts;
if (MessagesStorage.lastQtsValue == 0 || MessagesStorage.lastQtsValue + 1 == update.qts) {
for (int b = a + 1; b < updates.updates.size(); b++) {
TLRPC.Update update2 = updates.updates.get(b);
if (getUpdateType(update2) == 1 && updatesNew.qts + 1 == update2.qts) {
updatesNew.updates.add(update2);
updatesNew.qts = update2.qts;
updates.updates.remove(b);
b--;
} else {
break;
}
}
if (MessagesStorage.lastQtsValue == 0 || MessagesStorage.lastQtsValue + updatesNew.updates.size() == updatesNew.qts) {
processUpdateArray(updatesNew.updates, updates.users, updates.chats);
MessagesStorage.lastQtsValue = update.qts;
MessagesStorage.lastQtsValue = updatesNew.qts;
needReceivedQueue = true;
} else if (MessagesStorage.lastPtsValue != update.qts) {
FileLog.e("tmessages", update + " need get diff, qts: " + MessagesStorage.lastQtsValue + " " + update.qts);
} else if (MessagesStorage.lastPtsValue != updatesNew.qts) {
FileLog.e("tmessages", update + " need get diff, qts: " + MessagesStorage.lastQtsValue + " " + updatesNew.qts);
if (gettingDifference || updatesStartWaitTimeQts == 0 || updatesStartWaitTimeQts != 0 && updatesStartWaitTimeQts + 1500 > System.currentTimeMillis()) {
if (updatesStartWaitTimeQts == 0) {
updatesStartWaitTimeQts = System.currentTimeMillis();
}
FileLog.e("tmessages", "add short message to queue");
FileLog.e("tmessages", "add to queue");
updatesQueueQts.add(updatesNew);
} else {
needGetDiff = true;
}
}
} else {
continue;
break;
}
updates.updates.remove(a);
a--;
@ -2996,6 +3181,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
final ArrayList<TLRPC.Message> messagesArr = new ArrayList<>();
final HashMap<Integer, Integer> markAsReadMessagesInbox = new HashMap<>();
final HashMap<Integer, Integer> markAsReadMessagesOutbox = new HashMap<>();
final ArrayList<Integer> markAsReadMessages = new ArrayList<>();
final HashMap<Integer, Integer> markAsReadEncrypted = new HashMap<>();
final ArrayList<Integer> deletedMessages = new ArrayList<>();
boolean printChanged = false;
@ -3078,8 +3264,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter
if (!obj.isOut() && obj.isUnread()) {
pushMessages.add(obj);
}
} else if (update instanceof TLRPC.TL_updateReadMessages) {
//markAsReadMessages.addAll(update.messages); disabled for now
} else if (update instanceof TLRPC.TL_updateReadMessagesContents) {
markAsReadMessages.addAll(update.messages);
} else if (update instanceof TLRPC.TL_updateReadHistoryInbox) {
TLRPC.Peer peer = ((TLRPC.TL_updateReadHistoryInbox) update).peer;
if (peer.chat_id != 0) {
@ -3097,12 +3283,27 @@ public class MessagesController implements NotificationCenter.NotificationCenter
} else if (update instanceof TLRPC.TL_updateDeleteMessages) {
deletedMessages.addAll(update.messages);
} else if (update instanceof TLRPC.TL_updateUserTyping || update instanceof TLRPC.TL_updateChatUserTyping) {
if (update.action instanceof TLRPC.TL_sendMessageTypingAction && update.user_id != UserConfig.getClientUserId()) {
if (update.user_id != UserConfig.getClientUserId()) {
long uid = -update.chat_id;
if (uid == 0) {
uid = update.user_id;
}
ArrayList<PrintingUser> arr = printingUsers.get(uid);
if (update.action instanceof TLRPC.TL_sendMessageCancelAction) {
if (arr != null) {
for (int a = 0; a < arr.size(); a++) {
PrintingUser pu = arr.get(a);
if (pu.userId == update.user_id) {
arr.remove(a);
printChanged = true;
break;
}
}
if (arr.isEmpty()) {
printingUsers.remove(uid);
}
}
} else {
if (arr == null) {
arr = new ArrayList<>();
printingUsers.put(uid, arr);
@ -3112,6 +3313,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
if (u.userId == update.user_id) {
exist = true;
u.lastTime = currentTime;
u.action = update.action;
break;
}
}
@ -3119,9 +3321,11 @@ public class MessagesController implements NotificationCenter.NotificationCenter
PrintingUser newUser = new PrintingUser();
newUser.userId = update.user_id;
newUser.lastTime = currentTime;
newUser.action = update.action;
arr.add(newUser);
printChanged = true;
}
}
onlinePrivacy.put(update.user_id, ConnectionsManager.getInstance().getCurrentTime());
}
} else if (update instanceof TLRPC.TL_updateChatParticipants) {
@ -3181,8 +3385,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
contactsIds.add(-update.user_id);
}
}
} else if (update instanceof TLRPC.TL_updateActivation) {
//DEPRECATED
} else if (update instanceof TLRPC.TL_updateNewAuthorization) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
@ -3247,6 +3449,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
if (u.userId == update.user_id) {
exist = true;
u.lastTime = currentTime;
u.action = new TLRPC.TL_sendMessageTypingAction();
break;
}
}
@ -3254,6 +3457,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
PrintingUser newUser = new PrintingUser();
newUser.userId = update.user_id;
newUser.lastTime = currentTime;
newUser.action = new TLRPC.TL_sendMessageTypingAction();
arr.add(newUser);
printChanged = true;
}
@ -3304,7 +3508,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
newMessage.local_id = newMessage.id = UserConfig.getNewMessageId();
UserConfig.saveConfig(false);
newMessage.flags = TLRPC.MESSAGE_FLAG_UNREAD;
newMessage.date = update.date;
newMessage.date = ConnectionsManager.getInstance().getCurrentTime();
newMessage.from_id = 777000;
newMessage.to_id = new TLRPC.TL_peerUser();
newMessage.to_id.user_id = UserConfig.getClientUserId();
@ -3403,14 +3607,16 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
} else if (update instanceof TLRPC.TL_updateUserName) {
if (currentUser != null) {
if (!(currentUser instanceof TLRPC.TL_userContact)) {
currentUser.first_name = update.first_name;
currentUser.last_name = update.last_name;
}
if (currentUser.username != null && currentUser.username.length() > 0) {
usersByUsernames.remove(currentUser.username);
}
if (update.username != null && update.username.length() > 0) {
usersByUsernames.put(update.username, currentUser);
}
currentUser.first_name = update.first_name;
currentUser.last_name = update.last_name;
currentUser.username = update.username;
}
toDbUser.first_name = update.first_name;
@ -3427,7 +3633,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
} else if (update instanceof TLRPC.TL_updateUserPhone) {
if (currentUser != null) {
currentUser.phone = update.phone;
Utilities.photoBookQueue.postRunnable(new Runnable() {
Utilities.phoneBookQueue.postRunnable(new Runnable() {
@Override
public void run() {
ContactsController.getInstance().addContactToPhoneBook(currentUser, true);
@ -3470,13 +3676,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
if (dialog != null) {
dialog.notify_settings.mute_until = 0;
}
//editor.remove("notify2_" + dialog_id);
//Smart Notifications
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE);
if (preferences.getInt("notify2_" + dialog_id, 0) != 4) {
editor.remove("notify2_" + dialog_id);
}
//
MessagesStorage.getInstance().setDialogFlags(dialog_id, 0);
}
@ -3569,7 +3769,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
if (!markAsReadEncrypted.isEmpty()) {
for (HashMap.Entry<Integer, Integer> entry : markAsReadEncrypted.entrySet()) {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messagesReadedEncrypted, entry.getKey(), entry.getValue());
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messagesReadEncrypted, entry.getKey(), entry.getValue());
long dialog_id = (long) (entry.getKey()) << 32;
TLRPC.TL_dialog dialog = dialogs_dict.get(dialog_id);
if (dialog != null) {
@ -3581,6 +3781,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
}
}
if (!markAsReadMessages.isEmpty()) {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messagesReadContent, markAsReadMessages);
}
if (!deletedMessages.isEmpty()) {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messagesDeleted, deletedMessages);
for (Integer id : deletedMessages) {
@ -3607,6 +3810,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
MessagesStorage.getInstance().markMessagesAsRead(markAsReadMessagesInbox, markAsReadMessagesOutbox, markAsReadEncrypted, true);
}
if (!markAsReadMessages.isEmpty()) {
MessagesStorage.getInstance().markMessagesContentAsRead(markAsReadMessages);
}
if (!deletedMessages.isEmpty()) {
MessagesStorage.getInstance().markMessagesAsDeleted(deletedMessages, true);
}
@ -3690,7 +3896,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
NotificationCenter.getInstance().postNotificationName(NotificationCenter.didReceivedNewMessages, uid, messages);
for (MessageObject message : messages) {
if (lastMessage == null || (!isEncryptedChat && message.getId() > lastMessage.getId() || isEncryptedChat && message.getId() < lastMessage.getId()) || message.messageOwner.date > lastMessage.messageOwner.date) {
if (lastMessage == null || (!isEncryptedChat && message.getId() > lastMessage.getId() || (isEncryptedChat || message.getId() < 0 && lastMessage.getId() < 0) && message.getId() < lastMessage.getId()) || message.messageOwner.date > lastMessage.messageOwner.date) {
lastMessage = message;
}
}

View File

@ -106,7 +106,7 @@ public class MessagesStorage {
database.executeFast("CREATE TABLE messages(mid INTEGER PRIMARY KEY, uid INTEGER, read_state INTEGER, send_state INTEGER, date INTEGER, data BLOB, out INTEGER, ttl INTEGER, media INTEGER, replydata BLOB)").stepThis().dispose();
database.executeFast("CREATE TABLE chats(uid INTEGER PRIMARY KEY, name TEXT, data BLOB)").stepThis().dispose();
database.executeFast("CREATE TABLE enc_chats(uid INTEGER PRIMARY KEY, user INTEGER, name TEXT, data BLOB, g BLOB, authkey BLOB, ttl INTEGER, layer INTEGER, seq_in INTEGER, seq_out INTEGER, use_count INTEGER, exchange_id INTEGER, key_date INTEGER, fprint INTEGER, fauthkey BLOB, khash BLOB)").stepThis().dispose();
database.executeFast("CREATE TABLE dialogs(did INTEGER PRIMARY KEY, date INTEGER, unread_count INTEGER, last_mid INTEGER)").stepThis().dispose();
database.executeFast("CREATE TABLE dialogs(did INTEGER PRIMARY KEY, date INTEGER, unread_count INTEGER, last_mid INTEGER, inbox_max INTEGER, outbox_max INTEGER)").stepThis().dispose();
database.executeFast("CREATE TABLE chat_settings(uid INTEGER PRIMARY KEY, participants BLOB)").stepThis().dispose();
database.executeFast("CREATE TABLE contacts(uid INTEGER PRIMARY KEY, mutual INTEGER)").stepThis().dispose();
database.executeFast("CREATE TABLE pending_read(uid INTEGER PRIMARY KEY, max_id INTEGER)").stepThis().dispose();
@ -164,7 +164,7 @@ public class MessagesStorage {
database.executeFast("CREATE TABLE keyvalue(id TEXT PRIMARY KEY, value TEXT)").stepThis().dispose();
//version
database.executeFast("PRAGMA user_version = 16").stepThis().dispose();
database.executeFast("PRAGMA user_version = 17").stepThis().dispose();
} else {
try {
SQLiteCursor cursor = database.queryFinalized("SELECT seq, pts, date, qts, lsv, sg, pbytes FROM params WHERE id = 1");
@ -195,7 +195,7 @@ public class MessagesStorage {
}
}
int version = database.executeInt("PRAGMA user_version");
if (version < 16) {
if (version < 17) {
updateDbToLastVersion(version);
}
}
@ -295,7 +295,7 @@ public class MessagesStorage {
if ((length = cursor.byteBufferValue(1, data.buffer)) != 0) {
for (int a = 0; a < length / 4; a++) {
state.requery();
state.bindInteger(1, data.readInt32());
state.bindInteger(1, data.readInt32(false));
state.bindInteger(2, date);
state.step();
}
@ -385,6 +385,12 @@ public class MessagesStorage {
database.executeFast("PRAGMA user_version = 16").stepThis().dispose();
version = 16;
}
if (version == 16 && version < 17) {
database.executeFast("ALTER TABLE dialogs ADD COLUMN inbox_max INTEGER default 0").stepThis().dispose();
database.executeFast("ALTER TABLE dialogs ADD COLUMN outbox_max INTEGER default 0").stepThis().dispose();
database.executeFast("PRAGMA user_version = 17").stepThis().dispose();
version = 17;
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
@ -523,12 +529,12 @@ public class MessagesStorage {
ArrayList<Integer> chatIds = new ArrayList<>();
ArrayList<Integer> encryptedChatIds = new ArrayList<>();
cursor = database.queryFinalized("SELECT read_state, data, send_state, mid, date, uid FROM messages WHERE uid IN (" + ids.toString() + ") AND out = 0 AND read_state = 0 ORDER BY date DESC LIMIT 50");
cursor = database.queryFinalized("SELECT read_state, data, send_state, mid, date, uid FROM messages WHERE uid IN (" + ids.toString() + ") AND out = 0 AND read_state IN(0,2) ORDER BY date DESC LIMIT 50");
while (cursor.next()) {
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());
MessageObject.setIsUnread(message, cursor.intValue(0) != 1);
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
MessageObject.setUnreadFlags(message, cursor.intValue(0));
message.id = cursor.intValue(3);
message.date = cursor.intValue(4);
message.dialog_id = cursor.longValue(5);
@ -762,7 +768,7 @@ public class MessagesStorage {
while (cursor.next()) {
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
TLRPC.WallPaper wallPaper = (TLRPC.WallPaper) TLClassStore.Instance().TLdeserialize(data, data.readInt32());
TLRPC.WallPaper wallPaper = TLRPC.WallPaper.TLdeserialize(data, data.readInt32(false), false);
wallPapers.add(wallPaper);
}
buffersStorage.reuseFreeBuffer(data);
@ -876,7 +882,7 @@ public class MessagesStorage {
while (cursor.next()) {
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
TLRPC.Message message = (TLRPC.Message) TLClassStore.Instance().TLdeserialize(data, data.readInt32());
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
if (message == null || message.media == null) {
continue;
}
@ -950,7 +956,7 @@ public class MessagesStorage {
while (cursor.next()) {
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
TLRPC.Photo photo = (TLRPC.Photo)TLClassStore.Instance().TLdeserialize(data, data.readInt32());
TLRPC.Photo photo = TLRPC.Photo.TLdeserialize(data, data.readInt32(false), false);
res.photos.add(photo);
}
buffersStorage.reuseFreeBuffer(data);
@ -1065,7 +1071,7 @@ public class MessagesStorage {
StringBuilder mids = new StringBuilder();
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));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT mid, ttl FROM messages WHERE uid = %d AND out = %d AND read_state != 0 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));
@ -1147,7 +1153,7 @@ public class MessagesStorage {
cursor.dispose();
} else if (inbox != null && !inbox.isEmpty()) {
for (HashMap.Entry<Integer, Integer> entry : inbox.entrySet()) {
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT COUNT(mid) FROM messages WHERE uid = %d AND mid <= %d AND read_state = 0 AND out = 0", entry.getKey(), entry.getValue()));
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT COUNT(mid) FROM messages WHERE uid = %d AND mid <= %d AND read_state IN(0,2) AND out = 0", entry.getKey(), entry.getValue()));
if (cursor.next()) {
int count = cursor.intValue(0);
if (count == 0) {
@ -1255,7 +1261,7 @@ public class MessagesStorage {
if (cursor.next()) {
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
info = (TLRPC.ChatParticipants)TLClassStore.Instance().TLdeserialize(data, data.readInt32());
info = TLRPC.ChatParticipants.TLdeserialize(data, data.readInt32(false), false);
}
buffersStorage.reuseFreeBuffer(data);
}
@ -1318,7 +1324,7 @@ public class MessagesStorage {
if (cursor.next()) {
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
info = (TLRPC.ChatParticipants)TLClassStore.Instance().TLdeserialize(data, data.readInt32());
info = TLRPC.ChatParticipants.TLdeserialize(data, data.readInt32(false), false);
}
buffersStorage.reuseFreeBuffer(data);
}
@ -1383,14 +1389,14 @@ public class MessagesStorage {
int lower_id = (int)dialog_id;
if (lower_id != 0) {
state = database.executeFast("UPDATE messages SET read_state = 1 WHERE uid = ? AND mid <= ? AND read_state = 0 AND out = 0");
state = database.executeFast("UPDATE messages SET read_state = read_state | 1 WHERE uid = ? AND mid <= ? AND read_state IN(0,2) AND out = 0");
state.requery();
state.bindLong(1, dialog_id);
state.bindInteger(2, max_id);
state.step();
state.dispose();
} else {
state = database.executeFast("UPDATE messages SET read_state = 1 WHERE uid = ? AND date <= ? AND read_state = 0 AND out = 0");
state = database.executeFast("UPDATE messages SET read_state = read_state | 1 WHERE uid = ? AND date <= ? AND read_state IN(0,2) AND out = 0");
state.requery();
state.bindLong(1, dialog_id);
state.bindInteger(2, max_date);
@ -1613,9 +1619,9 @@ public class MessagesStorage {
while (cursor.next()) {
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());
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
if (!messageHashMap.containsKey(message.id)) {
MessageObject.setIsUnread(message, cursor.intValue(0) != 1);
MessageObject.setUnreadFlags(message, cursor.intValue(0));
message.id = cursor.intValue(3);
message.date = cursor.intValue(4);
if (!cursor.isNull(5)) {
@ -1798,14 +1804,14 @@ public class MessagesStorage {
}
cursor.dispose();
cursor = database.queryFinalized(String.format(Locale.US, "SELECT min(mid), max(date) FROM messages WHERE uid = %d AND out = 0 AND read_state = 0 AND mid > 0", dialog_id));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT min(mid), max(date) FROM messages WHERE uid = %d AND out = 0 AND read_state IN(0,2) AND mid > 0", dialog_id));
if (cursor.next()) {
min_unread_id = cursor.intValue(0);
max_unread_date = cursor.intValue(1);
}
cursor.dispose();
if (min_unread_id != 0) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT COUNT(*) FROM messages WHERE uid = %d AND mid >= %d AND out = 0 AND read_state = 0", dialog_id, min_unread_id));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT COUNT(*) FROM messages WHERE uid = %d AND mid >= %d AND out = 0 AND read_state IN(0,2)", dialog_id, min_unread_id));
if (cursor.next()) {
count_unread = cursor.intValue(0);
}
@ -1843,14 +1849,14 @@ public class MessagesStorage {
}
cursor.dispose();
cursor = database.queryFinalized(String.format(Locale.US, "SELECT max(mid), max(date) FROM messages WHERE uid = %d AND out = 0 AND read_state = 0 AND mid < 0", dialog_id));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT max(mid), max(date) FROM messages WHERE uid = %d AND out = 0 AND read_state IN(0,2) AND mid < 0", dialog_id));
if (cursor.next()) {
min_unread_id = cursor.intValue(0);
max_unread_date = cursor.intValue(1);
}
cursor.dispose();
if (min_unread_id != 0) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT COUNT(*) FROM messages WHERE uid = %d AND mid <= %d AND out = 0 AND read_state = 0", dialog_id, min_unread_id));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT COUNT(*) FROM messages WHERE uid = %d AND mid <= %d AND out = 0 AND read_state IN(0,2)", dialog_id, min_unread_id));
if (cursor.next()) {
count_unread = cursor.intValue(0);
}
@ -1876,8 +1882,8 @@ public class MessagesStorage {
while (cursor.next()) {
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());
MessageObject.setIsUnread(message, cursor.intValue(0) != 1);
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
MessageObject.setUnreadFlags(message, cursor.intValue(0));
message.id = cursor.intValue(3);
message.date = cursor.intValue(4);
message.dialog_id = dialog_id;
@ -1900,7 +1906,7 @@ public class MessagesStorage {
if (!cursor.isNull(6)) {
ByteBufferDesc data2 = buffersStorage.getFreeBuffer(cursor.byteArrayLength(6));
if (data2 != null && cursor.byteBufferValue(6, data2.buffer) != 0) {
message.replyMessage = (TLRPC.Message) TLClassStore.Instance().TLdeserialize(data2, data2.readInt32());
message.replyMessage = TLRPC.Message.TLdeserialize(data2, data2.readInt32(false), false);
if (message.replyMessage != null) {
fromUser.add(message.replyMessage.from_id);
if (message.replyMessage.action != null && message.replyMessage.action.user_id != 0) {
@ -1987,7 +1993,7 @@ public class MessagesStorage {
while (cursor.next()) {
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
TLRPC.Message message = (TLRPC.Message) TLClassStore.Instance().TLdeserialize(data, data.readInt32());
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
message.id = cursor.intValue(1);
message.date = cursor.intValue(2);
message.dialog_id = dialog_id;
@ -2091,7 +2097,7 @@ public class MessagesStorage {
if (cursor.next()) {
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
TLObject file = TLClassStore.Instance().TLdeserialize(data, data.readInt32());
TLObject file = TLClassStore.Instance().TLdeserialize(data, data.readInt32(false), false);
if (file != null) {
result.add(file);
}
@ -2374,11 +2380,13 @@ public class MessagesStorage {
buffersStorage.reuseFreeBuffer(data5);
if (dialog != null) {
state = database.executeFast("REPLACE INTO dialogs(did, date, unread_count, last_mid) VALUES(?, ?, ?, ?)");
state = database.executeFast("REPLACE INTO dialogs(did, date, unread_count, last_mid, inbox_max, outbox_max) VALUES(?, ?, ?, ?, ?, ?)");
state.bindLong(1, dialog.id);
state.bindInteger(2, dialog.last_message_date);
state.bindInteger(3, dialog.unread_count);
state.bindInteger(4, dialog.top_message);
state.bindInteger(5, dialog.read_inbox_max_id);
state.bindInteger(6, 0);
state.step();
state.dispose();
}
@ -2469,7 +2477,7 @@ public class MessagesStorage {
try {
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
TLRPC.User user = (TLRPC.User)TLClassStore.Instance().TLdeserialize(data, data.readInt32());
TLRPC.User user = TLRPC.User.TLdeserialize(data, data.readInt32(false), false);
if (user != null) {
if (user.status != null) {
user.status.expires = cursor.intValue(1);
@ -2494,7 +2502,7 @@ public class MessagesStorage {
try {
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
TLRPC.Chat chat = (TLRPC.Chat)TLClassStore.Instance().TLdeserialize(data, data.readInt32());
TLRPC.Chat chat = TLRPC.Chat.TLdeserialize(data, data.readInt32(false), false);
if (chat != null) {
result.add(chat);
}
@ -2511,13 +2519,12 @@ public class MessagesStorage {
if (chatsToLoad == null || chatsToLoad.length() == 0 || result == null) {
return;
}
//use_count INTEGER, exchange_id INTEGER, key_date INTEGER, fprint INTEGER, fauthkey BLOB
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, user, g, authkey, ttl, layer, seq_in, seq_out, use_count, exchange_id, key_date, fprint, fauthkey, khash FROM enc_chats WHERE uid IN(%s)", chatsToLoad));
while (cursor.next()) {
try {
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
TLRPC.EncryptedChat chat = (TLRPC.EncryptedChat)TLClassStore.Instance().TLdeserialize(data, data.readInt32());
TLRPC.EncryptedChat chat = TLRPC.EncryptedChat.TLdeserialize(data, data.readInt32(false), false);
if (chat != null) {
chat.user_id = cursor.intValue(1);
if (usersToLoad != null && !usersToLoad.contains(chat.user_id)) {
@ -2634,7 +2641,7 @@ public class MessagesStorage {
downloadObject.id = cursor.longValue(0);
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(2));
if (data != null && cursor.byteBufferValue(2, data.buffer) != 0) {
downloadObject.object = TLClassStore.Instance().TLdeserialize(data, data.readInt32());
downloadObject.object = TLClassStore.Instance().TLdeserialize(data, data.readInt32(false), false);
}
buffersStorage.reuseFreeBuffer(data);
objects.add(downloadObject);
@ -2691,7 +2698,7 @@ public class MessagesStorage {
int mid = cursor.intValue(0);
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());
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
message.id = mid;
message.media.webpage = webPages.get(message.media.webpage.id);
@ -2865,7 +2872,7 @@ public class MessagesStorage {
state.bindInteger(1, messageId);
state.bindLong(2, dialog_id);
state.bindInteger(3, (MessageObject.isUnread(message) ? 0 : 1));
state.bindInteger(3, MessageObject.getUnreadFlags(message));
state.bindInteger(4, message.send_state);
state.bindInteger(5, message.date);
state.bindByteBuffer(6, data.buffer);
@ -2954,7 +2961,7 @@ public class MessagesStorage {
state4.dispose();
state5.dispose();
state = database.executeFast("REPLACE INTO dialogs(did, date, unread_count, last_mid) VALUES(?, ?, ?, ?)");
state = database.executeFast("REPLACE INTO dialogs(did, date, unread_count, last_mid, inbox_max, outbox_max) VALUES(?, ?, ?, ?, ?, ?)");
for (HashMap.Entry<Long, TLRPC.Message> pair : messagesMap.entrySet()) {
Long key = pair.getKey();
@ -2987,6 +2994,8 @@ public class MessagesStorage {
}
state.bindInteger(3, old_unread_count + unread_count);
state.bindInteger(4, messageId);
state.bindInteger(5, 0);
state.bindInteger(6, 0);
state.step();
}
state.dispose();
@ -3294,8 +3303,10 @@ public class MessagesStorage {
TLRPC.User updateUser = usersDict.get(user.id);
if (updateUser != null) {
if (updateUser.first_name != null && updateUser.last_name != null) {
if (!(user instanceof TLRPC.TL_userContact)) {
user.first_name = updateUser.first_name;
user.last_name = updateUser.last_name;
}
user.username = updateUser.username;
} else if (updateUser.photo != null) {
user.photo = updateUser.photo;
@ -3337,25 +3348,22 @@ public class MessagesStorage {
}
private void markMessagesAsReadInternal(HashMap<Integer, Integer> inbox, HashMap<Integer, Integer> outbox, HashMap<Integer, Integer> encryptedMessages) {
if (Thread.currentThread().getId() != storageQueue.getId()) {
throw new RuntimeException("wrong db thread");
}
try {
if (inbox != null) {
for (HashMap.Entry<Integer, Integer> entry : inbox.entrySet()) {
database.executeFast(String.format(Locale.US, "UPDATE messages SET read_state = 1 WHERE uid = %d AND mid <= %d AND read_state = 0 AND out = 0", entry.getKey(), entry.getValue())).stepThis().dispose();
database.executeFast(String.format(Locale.US, "UPDATE messages SET read_state = read_state | 1 WHERE uid = %d AND mid <= %d AND read_state IN(0,2) AND out = 0", entry.getKey(), entry.getValue())).stepThis().dispose();
}
}
if (outbox != null) {
for (HashMap.Entry<Integer, Integer> entry : outbox.entrySet()) {
database.executeFast(String.format(Locale.US, "UPDATE messages SET read_state = 1 WHERE uid = %d AND mid <= %d AND read_state = 0 AND out = 1", entry.getKey(), entry.getValue())).stepThis().dispose();
database.executeFast(String.format(Locale.US, "UPDATE messages SET read_state = read_state | 1 WHERE uid = %d AND mid <= %d AND read_state IN(0,2) AND out = 1", entry.getKey(), entry.getValue())).stepThis().dispose();
}
}
if (encryptedMessages != null && !encryptedMessages.isEmpty()) {
for (HashMap.Entry<Integer, Integer> entry : encryptedMessages.entrySet()) {
long dialog_id = ((long)entry.getKey()) << 32;
int max_date = entry.getValue();
SQLitePreparedStatement state = database.executeFast("UPDATE messages SET read_state = 1 WHERE uid = ? AND date <= ? AND read_state = 0 AND out = 1");
SQLitePreparedStatement state = database.executeFast("UPDATE messages SET read_state = read_state | 1 WHERE uid = ? AND date <= ? AND read_state IN(0,2) AND out = 1");
state.requery();
state.bindLong(1, dialog_id);
state.bindInteger(2, max_date);
@ -3368,6 +3376,22 @@ public class MessagesStorage {
}
}
public void markMessagesContentAsRead(final ArrayList<Integer> mids) {
if (mids == null || mids.isEmpty()) {
return;
}
storageQueue.postRunnable(new Runnable() {
@Override
public void run() {
try {
database.executeFast(String.format(Locale.US, "UPDATE messages SET read_state = read_state | 2 WHERE mid IN (%s)", TextUtils.join(",", mids))).stepThis().dispose();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
}
public void markMessagesAsRead(final HashMap<Integer, Integer> inbox, final HashMap<Integer, Integer> outbox, final HashMap<Integer, Integer> encryptedMessages, boolean useQueue) {
if (useQueue) {
storageQueue.postRunnable(new Runnable() {
@ -3433,7 +3457,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());
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
if (message == null || message.media == null) {
continue;
}
@ -3527,8 +3551,8 @@ 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());
MessageObject.setIsUnread(message, cursor.intValue(5) != 1);
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
MessageObject.setUnreadFlags(message, cursor.intValue(5));
message.id = cursor.intValue(6);
message.send_state = cursor.intValue(7);
int date = cursor.intValue(8);
@ -3667,7 +3691,7 @@ public class MessagesStorage {
message.serializeToStream(data);
state.bindInteger(1, message.id);
state.bindLong(2, dialog_id);
state.bindInteger(3, (MessageObject.isUnread(message) ? 0 : 1));
state.bindInteger(3, MessageObject.getUnreadFlags(message));
state.bindInteger(4, message.send_state);
state.bindInteger(5, message.date);
state.bindByteBuffer(6, data.buffer);
@ -3732,9 +3756,9 @@ 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());
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
if (message != null) {
MessageObject.setIsUnread(message, cursor.intValue(5) != 1);
MessageObject.setUnreadFlags(message, cursor.intValue(5));
message.id = cursor.intValue(6);
int date = cursor.intValue(9);
if (date != 0) {
@ -3831,7 +3855,7 @@ public class MessagesStorage {
if (!dialogs.dialogs.isEmpty()) {
SQLitePreparedStatement state = database.executeFast("REPLACE INTO messages VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, NULL)");
SQLitePreparedStatement state2 = database.executeFast("REPLACE INTO dialogs(did, date, unread_count, last_mid) VALUES(?, ?, ?, ?)");
SQLitePreparedStatement state2 = database.executeFast("REPLACE INTO dialogs(did, date, unread_count, last_mid, inbox_max, outbox_max) VALUES(?, ?, ?, ?, ?, ?)");
SQLitePreparedStatement state3 = database.executeFast("REPLACE INTO media_v2 VALUES(?, ?, ?, ?, ?)");
SQLitePreparedStatement state4 = database.executeFast("REPLACE INTO dialog_settings VALUES(?, ?)");
@ -3850,7 +3874,7 @@ public class MessagesStorage {
state.bindInteger(1, message.id);
state.bindInteger(2, uid);
state.bindInteger(3, (MessageObject.isUnread(message) ? 0 : 1));
state.bindInteger(3, MessageObject.getUnreadFlags(message));
state.bindInteger(4, message.send_state);
state.bindInteger(5, message.date);
state.bindByteBuffer(6, data.buffer);
@ -3863,6 +3887,8 @@ public class MessagesStorage {
state2.bindInteger(2, message.date);
state2.bindInteger(3, dialog.unread_count);
state2.bindInteger(4, dialog.top_message);
state2.bindInteger(5, dialog.read_inbox_max_id);
state2.bindInteger(6, 0);
state2.step();
state4.bindLong(1, uid);

View File

@ -23,7 +23,7 @@ import java.util.zip.ZipFile;
public class NativeLoader {
private final static int LIB_VERSION = 7;
private final static int LIB_VERSION = 8;
private final static String LIB_NAME = "tmessages." + LIB_VERSION;
private final static String LIB_SO_NAME = "lib" + LIB_NAME + ".so";
private final static String LOCALE_LIB_SO_NAME = "lib" + LIB_NAME + "loc.so";

View File

@ -32,7 +32,7 @@ public class NotificationCenter {
public static final int mediaDidLoaded = totalEvents++;
public static final int mediaCountDidLoaded = totalEvents++;
public static final int encryptedChatUpdated = totalEvents++;
public static final int messagesReadedEncrypted = totalEvents++;
public static final int messagesReadEncrypted = totalEvents++;
public static final int encryptedChatCreated = totalEvents++;
public static final int userPhotosLoaded = totalEvents++;
public static final int removeAllMessagesFromDialog = totalEvents++;
@ -56,6 +56,9 @@ public class NotificationCenter {
public static final int newSessionReceived = totalEvents++;
public static final int didReceivedWebpages = totalEvents++;
public static final int didReceivedWebpagesInUpdates = totalEvents++;
public static final int stickersDidLoaded = totalEvents++;
public static final int didReplacedPhotoInMemCache = totalEvents++;
public static final int messagesReadContent = totalEvents++;
public static final int httpFileDidLoaded = totalEvents++;
public static final int httpFileDidFailedLoad = totalEvents++;

View File

@ -17,10 +17,10 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.AssetFileDescriptor;
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.SoundPool;
import android.net.Uri;
import android.os.Build;
import android.os.SystemClock;
@ -45,9 +45,7 @@ import org.telegram.ui.PopupNotificationActivity;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
public class NotificationsController {
@ -56,7 +54,9 @@ public class NotificationsController {
private DispatchQueue notificationsQueue = new DispatchQueue("notificationsQueue");
private ArrayList<MessageObject> pushMessages = new ArrayList<>();
private ArrayList<MessageObject> delayedPushMessages = new ArrayList<>();
private HashMap<Integer, MessageObject> pushMessagesDict = new HashMap<>();
private HashMap<Long, Point> smartNotificationsDialogs = new HashMap<>();
private NotificationManagerCompat notificationManager = null;
private HashMap<Long, Integer> pushDialogs = new HashMap<>();
private HashMap<Long, Integer> wearNoticationsIds = new HashMap<>();
@ -69,10 +69,14 @@ public class NotificationsController {
private boolean notifyCheck = false;
private int lastOnlineFromOtherDevice = 0;
private boolean inChatSoundEnabled = true;
private int lastBadgeCount;
private long lastSoundPlay;
private MediaPlayer mediaPlayerIn;
private MediaPlayer mediaPlayerOut;
//private MediaPlayer mediaPlayerIn;
//private MediaPlayer mediaPlayerOut;
private SoundPool soundPool;
private int soundIn;
private int soundOut;
protected AudioManager audioManager;
private static volatile NotificationsController Instance = null;
@ -112,6 +116,7 @@ public class NotificationsController {
popupMessages.clear();
wearNoticationsIds.clear();
notifyCheck = false;
lastBadgeCount = 0;
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.clear();
@ -189,7 +194,7 @@ public class NotificationsController {
msg = LocaleController.formatString("NotificationMessageVideo", R.string.NotificationMessageVideo, ContactsController.formatName(user.first_name, user.last_name));
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaContact) {
msg = LocaleController.formatString("NotificationMessageContact", R.string.NotificationMessageContact, ContactsController.formatName(user.first_name, user.last_name));
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGeo) {
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGeo || messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaVenue) {
msg = LocaleController.formatString("NotificationMessageMap", R.string.NotificationMessageMap, ContactsController.formatName(user.first_name, user.last_name));
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument) {
if (messageObject.isSticker()) {
@ -216,8 +221,14 @@ public class NotificationsController {
if (u2 == null) {
return null;
}
if (user.id == u2.id) {
msg = LocaleController.formatString("NotificationGroupAddSelf", R.string.NotificationGroupAddSelf, ContactsController.formatName(user.first_name, user.last_name), chat.title);
} else {
msg = LocaleController.formatString("NotificationGroupAddMember", R.string.NotificationGroupAddMember, ContactsController.formatName(user.first_name, user.last_name), chat.title, ContactsController.formatName(u2.first_name, u2.last_name));
}
}
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatJoinedByLink) {
msg = LocaleController.formatString("NotificationInvitedToGroupByLink", R.string.NotificationInvitedToGroupByLink, ContactsController.formatName(user.first_name, user.last_name), chat.title);
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatEditTitle) {
msg = LocaleController.formatString("NotificationEditedGroupName", R.string.NotificationEditedGroupName, ContactsController.formatName(user.first_name, user.last_name), messageObject.messageOwner.action.title);
} else if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatEditPhoto || messageObject.messageOwner.action instanceof TLRPC.TL_messageActionChatDeletePhoto) {
@ -250,7 +261,7 @@ public class NotificationsController {
msg = LocaleController.formatString("NotificationMessageGroupVideo", R.string.NotificationMessageGroupVideo, ContactsController.formatName(user.first_name, user.last_name), chat.title);
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaContact) {
msg = LocaleController.formatString("NotificationMessageGroupContact", R.string.NotificationMessageGroupContact, ContactsController.formatName(user.first_name, user.last_name), chat.title);
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGeo) {
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGeo || messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaVenue) {
msg = LocaleController.formatString("NotificationMessageGroupMap", R.string.NotificationMessageGroupMap, ContactsController.formatName(user.first_name, user.last_name), chat.title);
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument) {
if (messageObject.isSticker()) {
@ -288,14 +299,14 @@ public class NotificationsController {
private void scheduleNotificationDelay(boolean onlineReason) {
try {
FileLog.e("tmessages", "delay notification start");
FileLog.e("tmessages", "delay notification start, onlineReason = " + onlineReason);
AlarmManager alarm = (AlarmManager) ApplicationLoader.applicationContext.getSystemService(Context.ALARM_SERVICE);
PendingIntent pintent = PendingIntent.getService(ApplicationLoader.applicationContext, 0, new Intent(ApplicationLoader.applicationContext, NotificationDelay.class), 0);
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE);
if (onlineReason) {
alarm.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 3 * 1000, pintent);
} else {
alarm.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 500, pintent);
alarm.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 1000, pintent);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -304,7 +315,10 @@ public class NotificationsController {
protected void notificationDelayReached() {
FileLog.e("tmessages", "delay reached");
if (!delayedPushMessages.isEmpty()) {
showOrUpdateNotification(true);
delayedPushMessages.clear();
}
}
protected void repeatNotificationMaybe() {
@ -321,6 +335,7 @@ public class NotificationsController {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
FileLog.e("tmessages", "set last online from other device = " + time);
lastOnlineFromOtherDevice = time;
}
});
@ -366,54 +381,47 @@ public class NotificationsController {
boolean inAppPreview = false;
boolean inAppPriority = false;
int priority = 0;
int priority_override = 0;
int vibrate_override = 0;
int priorityOverride = 0;
int vibrateOverride = 0;
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Context.MODE_PRIVATE);
int notify_override = preferences.getInt("notify2_" + override_dialog_id, 0);
if (notify_override == 3) {
int mute_until = preferences.getInt("notifyuntil_" + override_dialog_id, 0);
if (mute_until >= ConnectionsManager.getInstance().getCurrentTime()) {
notify_override = 2;
}
}
if (!notifyAboutLast || notify_override == 2 || (!preferences.getBoolean("EnableAll", true) || chat_id != 0 && !preferences.getBoolean("EnableGroup", true)) && notify_override == 0) {
int notifyOverride = getNotifyOverride(preferences, override_dialog_id);
if (!notifyAboutLast || notifyOverride == 2 || (!preferences.getBoolean("EnableAll", true) || chat_id != 0 && !preferences.getBoolean("EnableGroup", true)) && notifyOverride == 0) {
notifyDisabled = true;
}
//Smart notifications
boolean use_smart_notify = preferences.getBoolean("smart_notify_" + dialog_id, false);
Long smart_notify_timeframe = preferences.getLong("smart_notify_timeframe_" + dialog_id, 1);
int smart_notify_max_count = preferences.getInt("smart_notify_max_count_" + dialog_id, 1);
if (chat_id != 0 && use_smart_notify)
{
if (chat.sound_timestamps == null)
chat.sound_timestamps = new LinkedList<>();
boolean shouldAdd = true;
Date firstNotification = chat.sound_timestamps.peek();
Date currentDate = new Date();
if (firstNotification != null) {
if (currentDate.getTime() - firstNotification.getTime() < smart_notify_timeframe * 1000 && chat.sound_timestamps.size () >= smart_notify_max_count) {
shouldAdd = false;
}
}
if (!shouldAdd) {
if (!notifyDisabled && dialog_id == override_dialog_id && chat != null) {
int notifyMaxCount = preferences.getInt("smart_max_count_" + dialog_id, 2);
int notifyDelay = preferences.getInt("smart_delay_" + dialog_id, 3 * 60);
if (notifyMaxCount != 0) {
Point dialogInfo = smartNotificationsDialogs.get(dialog_id);
if (dialogInfo == null) {
dialogInfo = new Point(1, (int) (System.currentTimeMillis() / 1000));
smartNotificationsDialogs.put(dialog_id, dialogInfo);
} else {
int lastTime = dialogInfo.y;
if (lastTime + notifyDelay < System.currentTimeMillis() / 1000) {
dialogInfo.set(1, (int) (System.currentTimeMillis() / 1000));
} else {
int count = dialogInfo.x;
if (count < notifyMaxCount) {
dialogInfo.set(count + 1, (int) (System.currentTimeMillis() / 1000));
} else {
notifyDisabled = true;
}
else {
if (chat.sound_timestamps.size() >= smart_notify_max_count)
chat.sound_timestamps.poll();
chat.sound_timestamps.add(currentDate);
}
}
//
}
}
String defaultPath = Settings.System.DEFAULT_NOTIFICATION_URI.getPath();
if (!notifyDisabled) {
inAppSounds = preferences.getBoolean("EnableInAppSounds", true);
inAppVibrate = preferences.getBoolean("EnableInAppVibrate", true);
inAppPreview = preferences.getBoolean("EnableInAppPreview", true);
inAppPriority = preferences.getBoolean("EnableInAppPriority", false);
vibrate_override = preferences.getInt("vibrate_" + dialog_id, 0);
priority_override = preferences.getInt("priority_" + dialog_id, 3);
vibrateOverride = preferences.getInt("vibrate_" + dialog_id, 0);
priorityOverride = preferences.getInt("priority_" + dialog_id, 3);
boolean vibrateOnlyIfSilent = false;
choosenSoundPath = preferences.getString("sound_path_" + dialog_id, null);
@ -440,16 +448,16 @@ public class NotificationsController {
ledColor = preferences.getInt("color_" + dialog_id, 0);
}
if (priority_override != 3) {
priority = priority_override;
if (priorityOverride != 3) {
priority = priorityOverride;
}
if (needVibrate == 4) {
vibrateOnlyIfSilent = true;
needVibrate = 0;
}
if (needVibrate == 2 && (vibrate_override == 1 || vibrate_override == 3 || vibrate_override == 5) || needVibrate != 2 && vibrate_override == 2 || vibrate_override != 0) {
needVibrate = vibrate_override;
if (needVibrate == 2 && (vibrateOverride == 1 || vibrateOverride == 3 || vibrateOverride == 5) || needVibrate != 2 && vibrateOverride == 2 || vibrateOverride != 0) {
needVibrate = vibrateOverride;
}
if (!ApplicationLoader.mainInterfacePaused) {
if (!inAppSounds) {
@ -538,7 +546,7 @@ public class NotificationsController {
.setGroup("messages")
.setGroupSummary(true)
//.setColor(0xff2ca5e0);
.setColor(AndroidUtilities.getIntColor("themeColor"));
.setColor(AndroidUtilities.getIntColor("themeColor")); //Plus
if (priority == 0) {
mBuilder.setPriority(NotificationCompat.PRIORITY_DEFAULT);
@ -552,9 +560,6 @@ public class NotificationsController {
if (chat == null && user != null && user.phone != null && user.phone.length() > 0) {
mBuilder.addPerson("tel:+" + user.phone);
}
/*Bundle bundle = new Bundle();
bundle.putString(NotificationCompat.EXTRA_PEOPLE, );
mBuilder.setExtras()*/
String lastMessage = null;
String lastMessageFull = null;
@ -586,7 +591,6 @@ public class NotificationsController {
}
if (i == 0) {
lastMessageFull = message;
//lastMessage = getStringForMessage(pushMessages.get(i), true);
lastMessage = lastMessageFull;
}
if (pushDialogs.size() == 1) {
@ -818,6 +822,7 @@ public class NotificationsController {
}
popupMessages.remove(messageObject);
pushMessagesDict.remove(messageObject.getId());
delayedPushMessages.remove(messageObject);
pushMessages.remove(a);
a--;
}
@ -849,6 +854,7 @@ public class NotificationsController {
personal_count--;
}
pushMessages.remove(a);
delayedPushMessages.remove(messageObject);
popupMessages.remove(messageObject);
pushMessagesDict.remove(messageObject.getId());
a--;
@ -875,14 +881,8 @@ public class NotificationsController {
try {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Context.MODE_PRIVATE);
int notify_override = preferences.getInt("notify2_" + openned_dialog_id, 0);
if (notify_override == 3) {
int mute_until = preferences.getInt("notifyuntil_" + openned_dialog_id, 0);
if (mute_until >= ConnectionsManager.getInstance().getCurrentTime()) {
notify_override = 2;
}
}
if (notify_override == 2) {
int notifyOverride = getNotifyOverride(preferences, openned_dialog_id);
if (notifyOverride == 2) {
return;
}
notificationsQueue.postRunnable(new Runnable() {
@ -892,7 +892,14 @@ public class NotificationsController {
return;
}
try {
if (mediaPlayerIn == null) {
if (soundPool == null) {
soundPool = new SoundPool(4, AudioManager.STREAM_SYSTEM, 0);
}
if (soundIn == 0) {
soundIn = soundPool.load(ApplicationLoader.applicationContext, R.raw.sound_in, 1);
}
soundPool.play(soundIn, 1.0f, 1.0f, 1, 0, 1.0f);
/*if (mediaPlayerIn == null) {
AssetFileDescriptor assetFileDescriptor = ApplicationLoader.applicationContext.getResources().openRawResourceFd(R.raw.sound_in);
if (assetFileDescriptor != null) {
mediaPlayerIn = new MediaPlayer();
@ -903,45 +910,18 @@ public class NotificationsController {
mediaPlayerIn.prepare();
}
}
mediaPlayerIn.start();
try {
mediaPlayerIn.pause();
mediaPlayerIn.seekTo(0);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
mediaPlayerIn.start();*/
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
/*String choosenSoundPath = null;
String defaultPath = Settings.System.DEFAULT_NOTIFICATION_URI.getPath();
choosenSoundPath = preferences.getString("sound_path_" + openned_dialog_id, null);
boolean isChat = (int)(openned_dialog_id) < 0;
if (isChat) {
if (choosenSoundPath != null && choosenSoundPath.equals(defaultPath)) {
choosenSoundPath = null;
} else if (choosenSoundPath == null) {
choosenSoundPath = preferences.getString("GroupSoundPath", defaultPath);
}
} else {
if (choosenSoundPath != null && choosenSoundPath.equals(defaultPath)) {
choosenSoundPath = null;
} else if (choosenSoundPath == null) {
choosenSoundPath = preferences.getString("GlobalSoundPath", defaultPath);
}
}
if (choosenSoundPath != null && !choosenSoundPath.equals("NoSound")) {
if (lastMediaPlayerUri == null || !choosenSoundPath.equals(lastMediaPlayerUri)) {
lastMediaPlayerUri = choosenSoundPath;
mediaPlayer.reset();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);
if (choosenSoundPath.equals(defaultPath)) {
mediaPlayer.setDataSource(ApplicationLoader.applicationContext, Settings.System.DEFAULT_NOTIFICATION_URI);
} else {
mediaPlayer.setDataSource(ApplicationLoader.applicationContext, Uri.parse(choosenSoundPath));
}
mediaPlayer.prepare();
}
mediaPlayer.start();
}*/
} catch (Exception e) {
FileLog.e("tmessages", e);
}
@ -962,7 +942,14 @@ public class NotificationsController {
@Override
public void run() {
try {
if (mediaPlayerOut == null) {
if (soundPool == null) {
soundPool = new SoundPool(4, AudioManager.STREAM_SYSTEM, 0);
}
if (soundOut == 0) {
soundOut = soundPool.load(ApplicationLoader.applicationContext, R.raw.sound_out, 1);
}
soundPool.play(soundOut, 1.0f, 1.0f, 1, 0, 1.0f);
/*if (mediaPlayerOut == null) {
AssetFileDescriptor assetFileDescriptor = ApplicationLoader.applicationContext.getResources().openRawResourceFd(R.raw.sound_out);
if (assetFileDescriptor != null) {
mediaPlayerOut = new MediaPlayer();
@ -973,7 +960,13 @@ public class NotificationsController {
mediaPlayerOut.prepare();
}
}
mediaPlayerOut.start();
try {
mediaPlayerOut.pause();
mediaPlayerOut.seekTo(0);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
mediaPlayerOut.start();*/
} catch (Exception e) {
FileLog.e("tmessages", e);
}
@ -981,6 +974,17 @@ public class NotificationsController {
});
}
private int getNotifyOverride(SharedPreferences preferences, long dialog_id) {
int notifyOverride = preferences.getInt("notify2_" + dialog_id, 0);
if (notifyOverride == 3) {
int muteUntil = preferences.getInt("notifyuntil_" + dialog_id, 0);
if (muteUntil >= ConnectionsManager.getInstance().getCurrentTime()) {
notifyOverride = 2;
}
}
return notifyOverride;
}
public void processNewMessages(ArrayList<MessageObject> messageObjects, boolean isLast) {
if (messageObjects.isEmpty()) {
return;
@ -1014,20 +1018,15 @@ public class NotificationsController {
boolean isChat = (int)dialog_id < 0;
popup = (int)dialog_id == 0 ? 0 : preferences.getInt(isChat ? "popupGroup" : "popupAll", 0);
if (value == null) {
int notify_override = preferences.getInt("notify2_" + dialog_id, 0);
if (notify_override == 3) {
int mute_until = preferences.getInt("notifyuntil_" + dialog_id, 0);
if (mute_until >= ConnectionsManager.getInstance().getCurrentTime()) {
notify_override = 2;
}
}
value = !(notify_override == 2 || (!preferences.getBoolean("EnableAll", true) || isChat && !preferences.getBoolean("EnableGroup", true)) && notify_override == 0);
int notifyOverride = getNotifyOverride(preferences, dialog_id);
value = !(notifyOverride == 2 || (!preferences.getBoolean("EnableAll", true) || isChat && !preferences.getBoolean("EnableGroup", true)) && notifyOverride == 0);
settingsCache.put(dialog_id, value);
}
if (value) {
if (popup != 0) {
popupMessages.add(0, messageObject);
}
delayedPushMessages.add(messageObject);
pushMessages.add(0, messageObject);
pushMessagesDict.put(messageObject.getId(), messageObject);
if (original_dialog_id != dialog_id) {
@ -1058,24 +1057,22 @@ public class NotificationsController {
for (HashMap.Entry<Long, Integer> entry : dialogsToUpdate.entrySet()) {
long dialog_id = entry.getKey();
int notify_override = preferences.getInt("notify2_" + dialog_id, 0);
if (notify_override == 3) {
int mute_until = preferences.getInt("notifyuntil_" + dialog_id, 0);
if (mute_until >= ConnectionsManager.getInstance().getCurrentTime()) {
notify_override = 2;
}
}
int notifyOverride = getNotifyOverride(preferences, dialog_id);
if (notifyCheck) {
Integer override = pushDialogsOverrideMention.get(dialog_id);
if (override != null && override == 1) {
pushDialogsOverrideMention.put(dialog_id, 0);
notify_override = 1;
notifyOverride = 1;
}
}
boolean canAddValue = !(notify_override == 2 || (!preferences.getBoolean("EnableAll", true) || ((int)dialog_id < 0) && !preferences.getBoolean("EnableGroup", true)) && notify_override == 0);
boolean canAddValue = !(notifyOverride == 2 || (!preferences.getBoolean("EnableAll", true) || ((int)dialog_id < 0) && !preferences.getBoolean("EnableGroup", true)) && notifyOverride == 0);
Integer currentCount = pushDialogs.get(dialog_id);
Integer newCount = entry.getValue();
if (newCount == 0) {
smartNotificationsDialogs.remove(dialog_id);
}
if (newCount < 0) {
if (currentCount == null) {
continue;
@ -1098,6 +1095,7 @@ public class NotificationsController {
}
pushMessages.remove(a);
a--;
delayedPushMessages.remove(messageObject);
pushMessagesDict.remove(messageObject.getId());
popupMessages.remove(messageObject);
}
@ -1107,17 +1105,18 @@ public class NotificationsController {
pushDialogs.put(dialog_id, newCount);
}
}
/*if (old_unread_count != total_unread_count) { TODO
if (lastOnlineFromOtherDevice > ConnectionsManager.getInstance().getCurrentTime()) {
showOrUpdateNotification(false);
scheduleNotificationDelay(true);
} else {
showOrUpdateNotification(notifyCheck);
}
}*/
if (old_unread_count != total_unread_count) {
if (!notifyCheck) {
delayedPushMessages.clear();
showOrUpdateNotification(notifyCheck);
} else {
showOrUpdateNotification(false);
scheduleNotificationDelay(lastOnlineFromOtherDevice > ConnectionsManager.getInstance().getCurrentTime());
}
}
/*if (old_unread_count != total_unread_count) {
showOrUpdateNotification(notifyCheck);
}*/
notifyCheck = false;
if (preferences.getBoolean("badgeNumber", true)) {
setBadge(ApplicationLoader.applicationContext, total_unread_count);
@ -1153,14 +1152,8 @@ public class NotificationsController {
}
Boolean value = settingsCache.get(dialog_id);
if (value == null) {
int notify_override = preferences.getInt("notify2_" + dialog_id, 0);
if (notify_override == 3) {
int mute_until = preferences.getInt("notifyuntil_" + dialog_id, 0);
if (mute_until >= ConnectionsManager.getInstance().getCurrentTime()) {
notify_override = 2;
}
}
value = !(notify_override == 2 || (!preferences.getBoolean("EnableAll", true) || ((int) dialog_id < 0) && !preferences.getBoolean("EnableGroup", true)) && notify_override == 0);
int notifyOverride = getNotifyOverride(preferences, dialog_id);
value = !(notifyOverride == 2 || (!preferences.getBoolean("EnableAll", true) || ((int) dialog_id < 0) && !preferences.getBoolean("EnableGroup", true)) && notifyOverride == 0);
settingsCache.put(dialog_id, value);
}
if (!value || dialog_id == openned_dialog_id && ApplicationLoader.isScreenOn) {
@ -1177,19 +1170,13 @@ public class NotificationsController {
long dialog_id = entry.getKey();
Boolean value = settingsCache.get(dialog_id);
if (value == null) {
int notify_override = preferences.getInt("notify2_" + dialog_id, 0);
if (notify_override == 3) {
int mute_until = preferences.getInt("notifyuntil_" + dialog_id, 0);
if (mute_until >= ConnectionsManager.getInstance().getCurrentTime()) {
notify_override = 2;
}
}
int notifyOverride = getNotifyOverride(preferences, dialog_id);
Integer override = pushDialogsOverrideMention.get(dialog_id);
if (override != null && override == 1) {
pushDialogsOverrideMention.put(dialog_id, 0);
notify_override = 1;
notifyOverride = 1;
}
value = !(notify_override == 2 || (!preferences.getBoolean("EnableAll", true) || ((int) dialog_id < 0) && !preferences.getBoolean("EnableGroup", true)) && notify_override == 0);
value = !(notifyOverride == 2 || (!preferences.getBoolean("EnableAll", true) || ((int) dialog_id < 0) && !preferences.getBoolean("EnableGroup", true)) && notifyOverride == 0);
settingsCache.put(dialog_id, value);
}
if (!value) {
@ -1218,10 +1205,14 @@ public class NotificationsController {
notificationsQueue.postRunnable(new Runnable() {
@Override
public void run() {
if (lastBadgeCount == count) {
return;
}
lastBadgeCount = count;
try {
ContentValues cv = new ContentValues();
//cv.put("tag", "org.telegram.messenger/org.telegram.ui.LaunchActivity");
cv.put("tag", context.getPackageName() + "/org.telegram.ui.LaunchActivity");
cv.put("tag", context.getPackageName() + "/org.telegram.ui.LaunchActivity"); //Plus
cv.put("count", count);
context.getContentResolver().insert(Uri.parse("content://com.teslacoilsw.notifier/unread_count"), cv);
} catch (Throwable e) {

View File

@ -542,7 +542,7 @@ public class SecretChatHelper {
File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName + ".jpg");
File cacheFile2 = FileLoader.getPathToAttach(size);
cacheFile.renameTo(cacheFile2);
ImageLoader.getInstance().replaceImageInCache(fileName, fileName2);
ImageLoader.getInstance().replaceImageInCache(fileName, fileName2, size.location);
ArrayList<TLRPC.Message> arr = new ArrayList<>();
arr.add(newMsg);
MessagesStorage.getInstance().putMessages(arr, false, true, false, 0);
@ -557,7 +557,7 @@ public class SecretChatHelper {
newMsg.media.video.w = video.w;
newMsg.media.video.h = video.h;
newMsg.media.video.date = video.date;
newMsg.media.video.caption = "";
newMsg.media.caption = video.caption != null ? video.caption : "";
newMsg.media.video.user_id = video.user_id;
newMsg.media.video.size = file.size;
newMsg.media.video.id = file.id;
@ -565,6 +565,7 @@ public class SecretChatHelper {
newMsg.media.video.key = decryptedMessage.media.key;
newMsg.media.video.iv = decryptedMessage.media.iv;
newMsg.media.video.mime_type = video.mime_type;
newMsg.media.video.caption = video.caption != null ? video.caption : "";
if (newMsg.attachPath != null && newMsg.attachPath.startsWith(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE).getAbsolutePath())) {
File cacheFile = new File(newMsg.attachPath);
@ -893,10 +894,10 @@ public class SecretChatHelper {
return null;
}
newMessage.media = new TLRPC.TL_messageMediaPhoto();
newMessage.media.caption = "";
newMessage.media.photo = new TLRPC.TL_photo();
newMessage.media.photo.user_id = newMessage.from_id;
newMessage.media.photo.date = newMessage.date;
newMessage.media.photo.caption = "";
newMessage.media.photo.geo = new TLRPC.TL_geoPointEmpty();
if (decryptedMessage.media.thumb.length != 0 && decryptedMessage.media.thumb.length <= 6000 && decryptedMessage.media.thumb_w <= 100 && decryptedMessage.media.thumb_h <= 100) {
TLRPC.TL_photoCachedSize small = new TLRPC.TL_photoCachedSize();
@ -926,6 +927,7 @@ public class SecretChatHelper {
return null;
}
newMessage.media = new TLRPC.TL_messageMediaVideo();
newMessage.media.caption = "";
newMessage.media.video = new TLRPC.TL_videoEncrypted();
if (decryptedMessage.media.thumb.length != 0 && decryptedMessage.media.thumb.length <= 6000 && decryptedMessage.media.thumb_w <= 100 && decryptedMessage.media.thumb_h <= 100) {
newMessage.media.video.thumb = new TLRPC.TL_photoCachedSize();
@ -943,7 +945,6 @@ public class SecretChatHelper {
newMessage.media.video.w = decryptedMessage.media.w;
newMessage.media.video.h = decryptedMessage.media.h;
newMessage.media.video.date = date;
newMessage.media.video.caption = "";
newMessage.media.video.user_id = from_id;
newMessage.media.video.size = file.size;
newMessage.media.video.id = file.id;
@ -951,6 +952,7 @@ public class SecretChatHelper {
newMessage.media.video.key = decryptedMessage.media.key;
newMessage.media.video.iv = decryptedMessage.media.iv;
newMessage.media.video.mime_type = decryptedMessage.media.mime_type;
newMessage.media.video.caption = "";
if (newMessage.ttl != 0) {
newMessage.ttl = Math.max(newMessage.media.video.duration + 1, newMessage.ttl);
}
@ -1300,7 +1302,7 @@ public class SecretChatHelper {
ByteBufferDesc is = BuffersStorage.getInstance().getFreeBuffer(message.bytes.length);
is.writeRaw(message.bytes);
is.position(0);
long fingerprint = is.readInt64();
long fingerprint = is.readInt64(false);
byte[] keyToDecrypt = null;
boolean new_key_used = false;
if (chat.key_fingerprint == fingerprint) {
@ -1311,12 +1313,12 @@ public class SecretChatHelper {
}
if (keyToDecrypt != null) {
byte[] messageKey = is.readData(16);
byte[] messageKey = is.readData(16, false);
MessageKeyData keyData = Utilities.generateMessageKeyData(keyToDecrypt, messageKey, false);
Utilities.aesIgeEncryption(is.buffer, keyData.aesKey, keyData.aesIv, false, false, 24, is.limit() - 24);
int len = is.readInt32();
int len = is.readInt32(false);
if (len < 0 || len > is.limit() - 28) {
return null;
}
@ -1325,7 +1327,13 @@ public class SecretChatHelper {
return null;
}
TLObject object = TLClassStore.Instance().TLdeserialize(is, is.readInt32());
TLObject object = null;
try {
object = TLClassStore.Instance().TLdeserialize(is, is.readInt32(true), true);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
BuffersStorage.getInstance().reuseFreeBuffer(is);
if (!new_key_used && AndroidUtilities.getPeerLayerVersion(chat.layer) >= 20) {
chat.key_use_count_in++;

View File

@ -44,7 +44,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
private HashMap<Integer, MessageObject> unsentMessages = new HashMap<>();
private HashMap<Integer, TLRPC.Message> sendingMessages = new HashMap<>();
private class DelayedMessage {
protected class DelayedMessage {
public TLObject sendRequest;
public TLRPC.TL_decryptedMessage sendEncryptedRequest;
public int type;
@ -458,8 +458,8 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
sendMessage(video, null, messageObject.messageOwner.attachPath, did, messageObject.replyMessageObject);
} else if (messageObject.messageOwner.media.document instanceof TLRPC.TL_document) {
sendMessage((TLRPC.TL_document) messageObject.messageOwner.media.document, null, messageObject.messageOwner.attachPath, did, messageObject.replyMessageObject);
} else if (messageObject.messageOwner.media.geo instanceof TLRPC.TL_geoPoint) {
sendMessage(messageObject.messageOwner.media.geo.lat, messageObject.messageOwner.media.geo._long, did, messageObject.replyMessageObject);
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaVenue || messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGeo) {
sendMessage(messageObject.messageOwner.media, did, messageObject.replyMessageObject);
} else if (messageObject.messageOwner.media.phone_number != null) {
TLRPC.User user = new TLRPC.TL_userContact();
user.phone = messageObject.messageOwner.media.phone_number;
@ -481,8 +481,53 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
}
public void sendSticker(TLRPC.Document document, long peer, MessageObject replyingMessageObject) {
if (document == null) {
return;
}
if (((int) peer) == 0 && document.thumb instanceof TLRPC.TL_photoSize) {
File file = FileLoader.getPathToAttach(document.thumb, true);
if (file.exists()) {
try {
int len = (int) file.length();
byte[] arr = new byte[(int) file.length()];
RandomAccessFile reader = new RandomAccessFile(file, "r");
reader.readFully(arr);
TLRPC.TL_document newDocument = new TLRPC.TL_document();
newDocument.thumb = new TLRPC.TL_photoCachedSize();
newDocument.thumb.location = document.thumb.location;
newDocument.thumb.size = document.thumb.size;
newDocument.thumb.w = document.thumb.w;
newDocument.thumb.h = document.thumb.h;
newDocument.thumb.type = document.thumb.type;
newDocument.thumb.bytes = arr;
newDocument.id = document.id;
newDocument.access_hash = document.access_hash;
newDocument.date = document.date;
newDocument.mime_type = document.mime_type;
newDocument.size = document.size;
newDocument.dc_id = document.dc_id;
newDocument.attributes = document.attributes;
document = newDocument;
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
}
for (int a = 0; a < document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeSticker) {
document.attributes.remove(a);
document.attributes.add(new TLRPC.TL_documentAttributeSticker_old());
break;
}
}
SendMessagesHelper.getInstance().sendMessage((TLRPC.TL_document) document, null, null, peer, replyingMessageObject);
}
public void sendMessage(TLRPC.User user, long peer, MessageObject reply_to_msg) {
sendMessage(null, null, null, null, null, null, user, null, null, null, peer, false, null, reply_to_msg, null, true);
sendMessage(null, null, null, null, null, user, null, null, null, peer, false, null, reply_to_msg, null, true);
}
public void sendMessage(ArrayList<MessageObject> messages, long peer) {
@ -550,6 +595,9 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
ids.add(newMsg.fwd_msg_id);
newMsg.date = ConnectionsManager.getInstance().getCurrentTime();
newMsg.flags |= TLRPC.MESSAGE_FLAG_UNREAD;
if (newMsg.media instanceof TLRPC.TL_messageMediaAudio) {
newMsg.flags |= TLRPC.MESSAGE_FLAG_CONTENT_UNREAD;
}
newMsg.dialog_id = peer;
newMsg.to_id = to_id;
MessageObject newMsgObj = new MessageObject(newMsg, null, true);
@ -560,7 +608,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
putToSendingMessages(newMsg);
if (arr.size() == 100 || a == messages.size() - 1) {
MessagesStorage.getInstance().putMessages(arr, false, true, false, 0);
MessagesStorage.getInstance().putMessages(new ArrayList<>(arr), false, true, false, 0);
MessagesController.getInstance().updateInterfaceWithMessages(peer, objArr);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
UserConfig.saveConfig(false);
@ -655,38 +703,38 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
public void sendMessage(MessageObject message) {
sendMessage(null, null, null, null, null, message, null, null, null, null, message.getDialogId(), true, message.messageOwner.attachPath, null, null, true);
sendMessage(null, null, null, null, message, null, null, null, null, message.getDialogId(), true, message.messageOwner.attachPath, null, null, true);
}
public void sendMessage(MessageObject message, long peer) {
sendMessage(null, null, null, null, null, message, null, null, null, null, peer, false, message.messageOwner.attachPath, null, null, true);
sendMessage(null, null, null, null, message, null, null, null, null, peer, false, message.messageOwner.attachPath, null, null, true);
}
public void sendMessage(TLRPC.TL_document document, String originalPath, String path, long peer, MessageObject reply_to_msg) {
sendMessage(null, null, null, null, null, null, null, document, null, originalPath, peer, false, path, reply_to_msg, null, true);
sendMessage(null, null, null, null, null, null, document, null, originalPath, peer, false, path, reply_to_msg, null, true);
}
public void sendMessage(String message, long peer, MessageObject reply_to_msg, TLRPC.WebPage webPage, boolean searchLinks) {
sendMessage(message, null, null, null, null, null, null, null, null, null, peer, false, null, reply_to_msg, webPage, searchLinks);
sendMessage(message, null, null, null, null, null, null, null, null, peer, false, null, reply_to_msg, webPage, searchLinks);
}
public void sendMessage(double lat, double lon, long peer, MessageObject reply_to_msg) {
sendMessage(null, lat, lon, null, null, null, null, null, null, null, peer, false, null, reply_to_msg, null, true);
public void sendMessage(TLRPC.MessageMedia location, long peer, MessageObject reply_to_msg) {
sendMessage(null, location, null, null, null, null, null, null, null, peer, false, null, reply_to_msg, null, true);
}
public void sendMessage(TLRPC.TL_photo photo, String originalPath, String path, long peer, MessageObject reply_to_msg) {
sendMessage(null, null, null, photo, null, null, null, null, null, originalPath, peer, false, path, reply_to_msg, null, true);
sendMessage(null, null, photo, null, null, null, null, null, originalPath, peer, false, path, reply_to_msg, null, true);
}
public void sendMessage(TLRPC.TL_video video, String originalPath, String path, long peer, MessageObject reply_to_msg) {
sendMessage(null, null, null, null, video, null, null, null, null, originalPath, peer, false, path, reply_to_msg, null, true);
sendMessage(null, null, null, video, null, null, null, null, originalPath, peer, false, path, reply_to_msg, null, true);
}
public void sendMessage(TLRPC.TL_audio audio, String path, long peer, MessageObject reply_to_msg) {
sendMessage(null, null, null, null, null, null, null, null, audio, null, peer, false, path, reply_to_msg, null, true);
sendMessage(null, null, null, null, null, null, null, audio, null, peer, false, path, reply_to_msg, null, true);
}
private void 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, MessageObject reply_to_msg, TLRPC.WebPage webPage, boolean searchLinks) {
private void sendMessage(String message, TLRPC.MessageMedia location, 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, MessageObject reply_to_msg, TLRPC.WebPage webPage, boolean searchLinks) {
if (peer == 0) {
return;
}
@ -713,8 +761,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
type = 0;
}
} else if (msgObj.type == 4) {
lat = newMsg.media.geo.lat;
lon = newMsg.media.geo._long;
location = newMsg.media;
type = 1;
} else if (msgObj.type == 1) {
if (msgObj.isForwarded()) {
@ -760,16 +807,13 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
type = 0;
newMsg.message = message;
} else if (lat != null && lon != null) {
} else if (location != null) {
if (encryptedChat != null && AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
newMsg = new TLRPC.TL_message_secret();
} else {
newMsg = new TLRPC.TL_message();
}
newMsg.media = new TLRPC.TL_messageMediaGeo();
newMsg.media.geo = new TLRPC.TL_geoPoint();
newMsg.media.geo.lat = lat;
newMsg.media.geo._long = lon;
newMsg.media = location;
newMsg.message = "";
type = 1;
} else if (photo != null) {
@ -779,6 +823,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
newMsg = new TLRPC.TL_message();
}
newMsg.media = new TLRPC.TL_messageMediaPhoto();
newMsg.media.caption = photo.caption != null ? photo.caption : "";
newMsg.media.photo = photo;
type = 2;
newMsg.message = "-1";
@ -795,6 +840,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
newMsg = new TLRPC.TL_message();
}
newMsg.media = new TLRPC.TL_messageMediaVideo();
newMsg.media.caption = video.caption != null ? video.caption : "";
newMsg.media.video = video;
newMsg.videoEditedInfo = video.videoEditedInfo;
type = 3;
@ -868,6 +914,9 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
newMsg.date = ConnectionsManager.getInstance().getCurrentTime();
newMsg.flags |= TLRPC.MESSAGE_FLAG_UNREAD;
if (encryptedChat == null && high_id != 1 && newMsg.media instanceof TLRPC.TL_messageMediaAudio) {
newMsg.flags |= TLRPC.MESSAGE_FLAG_CONTENT_UNREAD;
}
newMsg.dialog_id = peer;
if (reply_to_msg != null) {
newMsg.flags |= TLRPC.MESSAGE_FLAG_REPLY;
@ -993,13 +1042,22 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
TLRPC.InputMedia inputMedia = null;
DelayedMessage delayedMessage = null;
if (type == 1) {
if (location instanceof TLRPC.TL_messageMediaVenue) {
inputMedia = new TLRPC.TL_inputMediaVenue();
inputMedia.address = location.address;
inputMedia.title = location.title;
inputMedia.provider = location.provider;
inputMedia.venue_id = location.venue_id;
} else {
inputMedia = new TLRPC.TL_inputMediaGeoPoint();
}
inputMedia.geo_point = new TLRPC.TL_inputGeoPoint();
inputMedia.geo_point.lat = lat;
inputMedia.geo_point._long = lon;
inputMedia.geo_point.lat = location.geo.lat;
inputMedia.geo_point._long = location.geo._long;
} else if (type == 2) {
if (photo.access_hash == 0) {
inputMedia = new TLRPC.TL_inputMediaUploadedPhoto();
inputMedia.caption = photo.caption != null ? photo.caption : "";
delayedMessage = new DelayedMessage();
delayedMessage.originalPath = originalPath;
delayedMessage.type = 0;
@ -1012,6 +1070,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
} else {
TLRPC.TL_inputMediaPhoto media = new TLRPC.TL_inputMediaPhoto();
media.id = new TLRPC.TL_inputPhoto();
media.caption = photo.caption != null ? photo.caption : "";
media.id.id = photo.id;
media.id.access_hash = photo.access_hash;
inputMedia = media;
@ -1023,6 +1082,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
} else {
inputMedia = new TLRPC.TL_inputMediaUploadedVideo();
}
inputMedia.caption = video.caption != null ? video.caption : "";
inputMedia.duration = video.duration;
inputMedia.w = video.w;
inputMedia.h = video.h;
@ -1036,6 +1096,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
} else {
TLRPC.TL_inputMediaVideo media = new TLRPC.TL_inputMediaVideo();
media.id = new TLRPC.TL_inputVideo();
media.caption = video.caption != null ? video.caption : "";
media.id.id = video.id;
media.id.access_hash = video.access_hash;
inputMedia = media;
@ -1161,8 +1222,8 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
reqSend.message = "";
if (type == 1) {
reqSend.media = new TLRPC.TL_decryptedMessageMediaGeoPoint();
reqSend.media.lat = lat;
reqSend.media._long = lon;
reqSend.media.lat = location.geo.lat;
reqSend.media._long = location.geo._long;
SecretChatHelper.getInstance().performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, null, null);
} else if (type == 2) {
TLRPC.PhotoSize small = photo.sizes.get(0);
@ -1589,7 +1650,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
cacheFile2 = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName2 + ".jpg");
}
cacheFile.renameTo(cacheFile2);
ImageLoader.getInstance().replaceImageInCache(fileName, fileName2);
ImageLoader.getInstance().replaceImageInCache(fileName, fileName2, size.location);
size2.location = size.location;
break;
}
@ -1611,7 +1672,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName + ".jpg");
File cacheFile2 = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName2 + ".jpg");
cacheFile.renameTo(cacheFile2);
ImageLoader.getInstance().replaceImageInCache(fileName, fileName2);
ImageLoader.getInstance().replaceImageInCache(fileName, fileName2, size.location);
size2.location = size.location;
}
}
@ -1642,7 +1703,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName + ".jpg");
File cacheFile2 = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName2 + ".jpg");
cacheFile.renameTo(cacheFile2);
ImageLoader.getInstance().replaceImageInCache(fileName, fileName2);
ImageLoader.getInstance().replaceImageInCache(fileName, fileName2, size.location);
size2.location = size.location;
}
} else if (MessageObject.isStickerMessage(sentMessage) && size2.location != null) {
@ -1697,6 +1758,10 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
arrayList.add(message);
}
protected ArrayList<DelayedMessage> getDelayedMessages(String location) {
return delayedMessages.get(location);
}
protected long getNextRandomId() {
long val = 0;
while (val == 0) {
@ -1749,7 +1814,6 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
photo.user_id = UserConfig.getClientUserId();
photo.date = ConnectionsManager.getInstance().getCurrentTime();
photo.sizes = sizes;
photo.caption = "";
photo.geo = new TLRPC.TL_geoPointEmpty();
return photo;
}
@ -1811,12 +1875,16 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
document.size = (int)f.length();
document.dc_id = 0;
if (ext.length() != 0) {
if (ext.toLowerCase().equals("webp")) {
document.mime_type = "image/webp";
} else {
String mimeType = myMime.getMimeTypeFromExtension(ext.toLowerCase());
if (mimeType != null) {
document.mime_type = mimeType;
} else {
document.mime_type = "application/octet-stream";
}
}
} else {
document.mime_type = "application/octet-stream";
}
@ -1929,9 +1997,10 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}).start();
}
public static void prepareSendingPhoto(String imageFilePath, Uri imageUri, long dialog_id, MessageObject reply_to_msg) {
public static void prepareSendingPhoto(String imageFilePath, Uri imageUri, long dialog_id, MessageObject reply_to_msg, CharSequence caption) {
ArrayList<String> paths = null;
ArrayList<Uri> uris = null;
ArrayList<String> captions = null;
if (imageFilePath != null && imageFilePath.length() != 0) {
paths = new ArrayList<>();
paths.add(imageFilePath);
@ -1940,7 +2009,11 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
uris = new ArrayList<>();
uris.add(imageUri);
}
prepareSendingPhotos(paths, uris, dialog_id, reply_to_msg);
if (caption != null) {
captions = new ArrayList<>();
captions.add(caption.toString());
}
prepareSendingPhotos(paths, uris, dialog_id, reply_to_msg, captions);
}
public static void prepareSendingPhotosSearch(final ArrayList<MediaController.SearchImage> photos, final long dialog_id, final MessageObject reply_to_msg) {
@ -1951,7 +2024,8 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
@Override
public void run() {
boolean isEncrypted = (int)dialog_id == 0;
for (final MediaController.SearchImage searchImage : photos) {
for (int a = 0; a < photos.size(); a++) {
final MediaController.SearchImage searchImage = photos.get(a);
if (searchImage.type == 1) {
TLRPC.TL_document document = null;
if (!isEncrypted) {
@ -2029,7 +2103,6 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
photo = new TLRPC.TL_photo();
photo.user_id = UserConfig.getClientUserId();
photo.date = ConnectionsManager.getInstance().getCurrentTime();
photo.caption = "";
photo.geo = new TLRPC.TL_geoPointEmpty();
TLRPC.TL_photoSize photoSize = new TLRPC.TL_photoSize();
photoSize.w = searchImage.width;
@ -2042,6 +2115,9 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
}
if (photo != null) {
if (searchImage.caption != null) {
photo.caption = searchImage.caption.toString();
}
final String originalPathFinal = searchImage.imageUrl;
final TLRPC.TL_photo photoFinal = photo;
final boolean needDownloadHttpFinal = needDownloadHttp;
@ -2058,7 +2134,32 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}).start();
}
public static void prepareSendingPhotos(ArrayList<String> paths, ArrayList<Uri> uris, final long dialog_id, final MessageObject reply_to_msg) {
private static String getTrimmedString(String src) {
String result = src.trim();
if (result.length() == 0) {
return result;
}
while (src.startsWith("\n")) {
src = src.substring(1);
}
while (src.endsWith("\n")) {
src = src.substring(0, src.length() - 1);
}
return src;
}
public static void prepareSendingText(String text, long dialog_id) {
text = getTrimmedString(text);
if (text.length() != 0) {
int count = (int) Math.ceil(text.length() / 4096.0f);
for (int a = 0; a < count; a++) {
String mess = text.substring(a * 4096, Math.min((a + 1) * 4096, text.length()));
SendMessagesHelper.getInstance().sendMessage(mess, dialog_id, null, null, true);
}
}
}
public static void prepareSendingPhotos(ArrayList<String> paths, ArrayList<Uri> uris, final long dialog_id, final MessageObject reply_to_msg, final ArrayList<String> captions) {
if (paths == null && uris == null || paths != null && paths.isEmpty() || uris != null && uris.isEmpty()) {
return;
}
@ -2080,6 +2181,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
int count = !pathsCopy.isEmpty() ? pathsCopy.size() : urisCopy.size();
String path = null;
Uri uri = null;
String extension = null;
for (int a = 0; a < count; a++) {
if (!pathsCopy.isEmpty()) {
path = pathsCopy.get(a);
@ -2096,16 +2198,23 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
boolean isDocument = false;
if (tempPath != null && (tempPath.endsWith(".gif") || tempPath.endsWith(".webp"))) {
if (tempPath.endsWith(".gif")) {
extension = "gif";
} else {
extension = "webp";
}
isDocument = true;
} else if (tempPath == null && uri != null) {
if (MediaController.isGif(uri)) {
isDocument = true;
originalPath = uri.toString();
tempPath = MediaController.copyDocumentToCache(uri, "gif");
extension = "gif";
} else if (MediaController.isWebp(uri)) {
isDocument = true;
originalPath = uri.toString();
tempPath = MediaController.copyDocumentToCache(uri, "webp");
extension = "webp";
}
}
@ -2134,6 +2243,9 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
photo = SendMessagesHelper.getInstance().generatePhotoSizes(path, uri);
}
if (photo != null) {
if (captions != null) {
photo.caption = captions.get(a);
}
final String originalPathFinal = originalPath;
final TLRPC.TL_photo photoFinal = photo;
AndroidUtilities.runOnUIThread(new Runnable() {
@ -2147,7 +2259,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
if (sendAsDocuments != null && !sendAsDocuments.isEmpty()) {
for (int a = 0; a < sendAsDocuments.size(); a++) {
prepareSendingDocumentInternal(sendAsDocuments.get(a), sendAsDocumentsOriginal.get(a), null, "gif", dialog_id, reply_to_msg);
prepareSendingDocumentInternal(sendAsDocuments.get(a), sendAsDocumentsOriginal.get(a), null, extension, dialog_id, reply_to_msg);
}
}
}
@ -2190,7 +2302,6 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
} else {
video.thumb.type = "s";
}
video.caption = "";
video.mime_type = "video/mp4";
video.id = 0;
UserConfig.saveConfig(false);

View File

@ -20,7 +20,6 @@ import org.telegram.messenger.ByteBufferDesc;
import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.RPCRequest;
import org.telegram.messenger.TLClassStore;
import org.telegram.messenger.TLObject;
import org.telegram.messenger.TLRPC;
@ -178,7 +177,7 @@ public class SharedMediaQuery {
}
final ArrayList<MessageObject> objects = new ArrayList<>();
for (TLRPC.Message message : res.messages) {
objects.add(new MessageObject(message, usersLocal, false));
objects.add(new MessageObject(message, usersLocal, true));
}
AndroidUtilities.runOnUIThread(new Runnable() {
@ -324,7 +323,7 @@ public class SharedMediaQuery {
while (cursor.next()) {
ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
TLRPC.Message message = (TLRPC.Message) TLClassStore.Instance().TLdeserialize(data, data.readInt32());
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
message.id = cursor.intValue(1);
message.dialog_id = uid;
if ((int)uid == 0) {

View File

@ -20,17 +20,19 @@ public abstract class AbsSerializedData {
public abstract void writeByteArray(byte[] b, int offset, int count);
public abstract void writeByteArray(byte[] b);
public abstract void writeDouble(double d);
public abstract int readInt32();
public abstract int readInt32(boolean[] error);
public abstract boolean readBool();
public abstract long readInt64();
public abstract long readInt64(boolean[] error);
public abstract void readRaw(byte[] b);
public abstract byte[] readData(int count);
public abstract String readString();
public abstract byte[] readByteArray();
public abstract ByteBufferDesc readByteBuffer();
public abstract void writeByteBuffer(ByteBufferDesc buffer);
public abstract double readDouble();
public abstract int readInt32(boolean exception);
public abstract boolean readBool(boolean exception);
public abstract long readInt64(boolean exception);
public abstract void readRaw(byte[] b, boolean exception);
public abstract byte[] readData(int count, boolean exception);
public abstract String readString(boolean exception);
public abstract byte[] readByteArray(boolean exception);
public abstract ByteBufferDesc readByteBuffer(boolean exception);
public abstract double readDouble(boolean exception);
public abstract int length();
public abstract void skip(int count);
public abstract int getPosition();
}

View File

@ -17,8 +17,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
@ -67,6 +65,7 @@ public class ApplicationLoader extends Application {
public static volatile boolean mainInterfacePaused = true;
public static boolean SHOW_ANDROID_EMOJI;
public static boolean KEEP_ORIGINAL_FILENAME;
public static boolean isCustomTheme() {
return isCustomTheme;
@ -197,7 +196,7 @@ public class ApplicationLoader extends Application {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
SHOW_ANDROID_EMOJI = preferences.getBoolean("showAndroidEmoji", false);
KEEP_ORIGINAL_FILENAME = preferences.getBoolean("keepOriginalFilename", false);
startPushService();
}
@ -278,8 +277,7 @@ public class ApplicationLoader extends Application {
return "";
}
int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
int currentVersion = getAppVersion();
if (registeredVersion != currentVersion) {
if (registeredVersion != BuildVars.BUILD_VERSION) {
FileLog.d("tmessages", "App version changed.");
return "";
}
@ -290,15 +288,6 @@ public class ApplicationLoader extends Application {
return getSharedPreferences(ApplicationLoader.class.getSimpleName(), Context.MODE_PRIVATE);
}
public static int getAppVersion() {
try {
PackageInfo packageInfo = applicationContext.getPackageManager().getPackageInfo(applicationContext.getPackageName(), 0);
return packageInfo.versionCode;
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException("Could not get package name: " + e);
}
}
private void registerInBackground() {
AsyncTask<String, String, Boolean> task = new AsyncTask<String, String, Boolean>() {
@Override
@ -359,7 +348,7 @@ public class ApplicationLoader extends Application {
private void storeRegistrationId(Context context, String regId) {
final SharedPreferences prefs = getGCMPreferences(context);
int appVersion = getAppVersion();
int appVersion = BuildVars.BUILD_VERSION;
FileLog.e("tmessages", "Saving regId on app version " + appVersion);
SharedPreferences.Editor editor = prefs.edit();
editor.putString(PROPERTY_REG_ID, regId);

View File

@ -10,10 +10,14 @@ package org.telegram.messenger;
public class BuildVars {
public static boolean DEBUG_VERSION = false;
public static int APP_ID = 0; //obtain your own APP_ID at https://core.telegram.org/api/obtaining_api_id
public static String APP_HASH = ""; //obtain your own APP_HASH at https://core.telegram.org/api/obtaining_api_id
public static String HOCKEY_APP_HASH = "your-hockeyapp-api-key-here";
public static String GCM_SENDER_ID = "760348033672";
public static String SEND_LOGS_EMAIL = "email@gmail.com";
public static String BING_SEARCH_KEY = ""; //obtain your own KEY at https://www.bing.com/dev/en-us/dev-center
public static int BUILD_VERSION = 521;
public static int APP_ID = 16623; //obtain your own APP_ID at https://core.telegram.org/api/obtaining_api_id
public static String APP_HASH = "8c9dbfe58437d1739540f5d53c72ae4b"; //obtain your own APP_HASH at https://core.telegram.org/api/obtaining_api_id
public static String HOCKEY_APP_HASH = "9602f502a85552c90543497e91a071f0";//"a5b5c4f551dadedc9918d9766a22ca7c";
public static String GCM_SENDER_ID = "326898382893";
public static String SEND_LOGS_EMAIL = "androiddeveloperplus@gmail.com";
public static String BING_SEARCH_KEY = "dKYt6BjhkmFnJABZI/nWs++mx7owYEKZLcdA3DTOO1s"; //obtain your own KEY at https://www.bing.com/dev/en-us/dev-center
public static String FOURSQUARE_API_KEY = "AYVLOEUWYPLCHN113NI41GHUE2NVHO4NHA5XLZWJU152N3ZP"; //obtain your own KEY at https://developer.foursquare.com/
public static String FOURSQUARE_API_ID = "CRY3VMYDJYBKQQDCZ4YY3ZAACTIITLVMBUUEDSPRXNZVZZA1"; //obtain your own API_ID at https://developer.foursquare.com/
public static String FOURSQUARE_API_VERSION = "20150326";
}

View File

@ -109,7 +109,7 @@ public class ByteBufferDesc extends AbsSerializedData {
} else {
len += b.length;
}
} catch (Exception x) {
} catch (Exception e) {
FileLog.e("tmessages", "write raw error");
}
}
@ -121,7 +121,7 @@ public class ByteBufferDesc extends AbsSerializedData {
} else {
len += count;
}
} catch (Exception x) {
} catch (Exception e) {
FileLog.e("tmessages", "write raw error");
}
}
@ -145,7 +145,7 @@ public class ByteBufferDesc extends AbsSerializedData {
public void writeString(String s) {
try {
writeByteArray(s.getBytes("UTF-8"));
} catch(Exception x) {
} catch(Exception e) {
FileLog.e("tmessages", "write string error");
}
}
@ -182,7 +182,7 @@ public class ByteBufferDesc extends AbsSerializedData {
}
i++;
}
} catch (Exception x) {
} catch (Exception e) {
FileLog.e("tmessages", "write byte array error");
}
}
@ -219,7 +219,7 @@ public class ByteBufferDesc extends AbsSerializedData {
}
i++;
}
} catch (Exception x) {
} catch (Exception e) {
FileLog.e("tmessages", "write byte array error");
}
}
@ -227,7 +227,7 @@ public class ByteBufferDesc extends AbsSerializedData {
public void writeDouble(double d) {
try {
writeInt64(Double.doubleToRawLongBits(d));
} catch(Exception x) {
} catch(Exception e) {
FileLog.e("tmessages", "write double error");
}
}
@ -280,72 +280,92 @@ public class ByteBufferDesc extends AbsSerializedData {
}
}
public int readInt32() {
return readInt32(null);
public int getIntFromByte(byte b) {
return b >= 0 ? b : ((int)b) + 256;
}
public int readInt32(boolean[] error) {
public int length() {
if (!justCalc) {
return buffer.position();
}
return len;
}
public void skip(int count) {
if (count == 0) {
return;
}
if (!justCalc) {
buffer.position(buffer.position() + count);
} else {
len += count;
}
}
public int getPosition() {
return buffer.position();
}
public int readInt32(boolean exception) {
try {
int i = buffer.getInt();
if (error != null) {
error[0] = false;
}
return i;
} catch (Exception x) {
if (error != null) {
error[0] = true;
}
return buffer.getInt();
} catch (Exception e) {
if (exception) {
throw new RuntimeException("read int32 error", e);
} else {
FileLog.e("tmessages", "read int32 error");
}
}
return 0;
}
public boolean readBool() {
int consructor = readInt32();
public boolean readBool(boolean exception) {
int consructor = readInt32(exception);
if (consructor == 0x997275b5) {
return true;
} else if (consructor == 0xbc799737) {
return false;
}
if (exception) {
throw new RuntimeException("Not bool value!");
} else {
FileLog.e("tmessages", "Not bool value!");
}
return false;
}
public long readInt64() {
return readInt64(null);
}
public long readInt64(boolean[] error) {
public long readInt64(boolean exception) {
try {
long i = buffer.getLong();
if (error != null) {
error[0] = false;
}
return i;
} catch (Exception x) {
if (error != null) {
error[0] = true;
}
return buffer.getLong();
} catch (Exception e) {
if (exception) {
throw new RuntimeException("read int64 error", e);
} else {
FileLog.e("tmessages", "read int64 error");
}
}
return 0;
}
public void readRaw(byte[] b) {
public void readRaw(byte[] b, boolean exception) {
try {
buffer.get(b);
} catch (Exception x) {
} catch (Exception e) {
if (exception) {
throw new RuntimeException("read raw error", e);
} else {
FileLog.e("tmessages", "read raw error");
}
}
}
public byte[] readData(int count) {
public byte[] readData(int count, boolean exception) {
byte[] arr = new byte[count];
readRaw(arr);
readRaw(arr, exception);
return arr;
}
public String readString() {
public String readString(boolean exception) {
try {
int sl = 1;
int l = getIntFromByte(buffer.get());
@ -361,17 +381,17 @@ public class ByteBufferDesc extends AbsSerializedData {
i++;
}
return new String(b, "UTF-8");
} catch (Exception x) {
} catch (Exception e) {
if (exception) {
throw new RuntimeException("read string error", e);
} else {
FileLog.e("tmessages", "read string error");
}
}
return null;
}
public int getIntFromByte(byte b) {
return b >= 0 ? b : ((int)b) + 256;
}
public byte[] readByteArray() {
public byte[] readByteArray(boolean exception) {
try {
int sl = 1;
int l = getIntFromByte(buffer.get());
@ -387,13 +407,17 @@ public class ByteBufferDesc extends AbsSerializedData {
i++;
}
return b;
} catch (Exception x) {
} catch (Exception e) {
if (exception) {
throw new RuntimeException("read byte array error", e);
} else {
FileLog.e("tmessages", "read byte array error");
}
}
return null;
}
public ByteBufferDesc readByteBuffer() {
public ByteBufferDesc readByteBuffer(boolean exception) {
try {
int sl = 1;
int l = getIntFromByte(buffer.get());
@ -415,25 +439,26 @@ public class ByteBufferDesc extends AbsSerializedData {
i++;
}
return b;
} catch (Exception x) {
} catch (Exception e) {
if (exception) {
throw new RuntimeException("read byte array error", e);
} else {
FileLog.e("tmessages", "read byte array error");
}
}
return null;
}
public double readDouble() {
public double readDouble(boolean exception) {
try {
return Double.longBitsToDouble(readInt64());
} catch(Exception x) {
return Double.longBitsToDouble(readInt64(exception));
} catch(Exception e) {
if (exception) {
throw new RuntimeException("read double error", e);
} else {
FileLog.e("tmessages", "read double error");
}
}
return 0;
}
public int length() {
if (!justCalc) {
return buffer.position();
}
return len;
}
}

View File

@ -65,7 +65,6 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
private boolean updatingDcSettings = false;
private int updatingDcStartTime = 0;
private int lastDcUpdateTime = 0;
private int currentAppVersion = 0;
private long pushSessionId;
private boolean registeringForPush = false;
@ -85,6 +84,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
private PowerManager.WakeLock wakeLock = null;
private static volatile ConnectionsManager Instance = null;
public static ConnectionsManager getInstance() {
ConnectionsManager localInstance = Instance;
if (localInstance == null) {
@ -185,7 +185,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
boolean notFound = true;
for (Action actor : actionQueue) {
if (actor instanceof HandshakeAction) {
HandshakeAction eactor = (HandshakeAction)actor;
HandshakeAction eactor = (HandshakeAction) actor;
if (eactor.datacenter.datacenterId == datacenter.datacenterId) {
notFound = false;
break;
@ -206,7 +206,6 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
};
public ConnectionsManager() {
currentAppVersion = ApplicationLoader.getAppVersion();
lastOutgoingMessageId = 0;
movingToDatacenterId = DEFAULT_DATACENTER_ID;
loadSession();
@ -218,7 +217,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
Utilities.stageQueue.postRunnable(stageRunnable, 1000);
try {
PowerManager pm = (PowerManager)ApplicationLoader.applicationContext.getSystemService(Context.POWER_SERVICE);
PowerManager pm = (PowerManager) ApplicationLoader.applicationContext.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "lock");
wakeLock.setReferenceCounted(false);
} catch (Exception e) {
@ -352,20 +351,20 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
if (configFile.exists()) {
try {
SerializedData data = new SerializedData(configFile);
isTestBackend = data.readInt32();
int version = data.readInt32();
isTestBackend = data.readInt32(false);
int version = data.readInt32(false);
sessionsToDestroy.clear();
int count = data.readInt32();
int count = data.readInt32(false);
for (int a = 0; a < count; a++) {
sessionsToDestroy.add(data.readInt64());
sessionsToDestroy.add(data.readInt64(false));
}
timeDifference = data.readInt32();
count = data.readInt32();
timeDifference = data.readInt32(false);
count = data.readInt32(false);
for (int a = 0; a < count; a++) {
Datacenter datacenter = new Datacenter(data, 0);
datacenters.put(datacenter.datacenterId, datacenter);
}
currentDatacenterId = data.readInt32();
currentDatacenterId = data.readInt32(false);
data.cleanup();
} catch (Exception e) {
UserConfig.clearConfig();
@ -385,9 +384,9 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
byte[] sessionsBytes = Base64.decode(sessionsString, Base64.DEFAULT);
if (sessionsBytes != null) {
SerializedData data = new SerializedData(sessionsBytes);
int count = data.readInt32();
int count = data.readInt32(false);
for (int a = 0; a < count; a++) {
sessionsToDestroy.add(data.readInt64());
sessionsToDestroy.add(data.readInt64(false));
}
data.cleanup();
}
@ -402,7 +401,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
byte[] datacentersBytes = Base64.decode(datacentersString, Base64.DEFAULT);
if (datacentersBytes != null) {
SerializedData data = new SerializedData(datacentersBytes);
int count = data.readInt32();
int count = data.readInt32(false);
for (int a = 0; a < count; a++) {
Datacenter datacenter = new Datacenter(data, 1);
datacenters.put(datacenter.datacenterId, datacenter);
@ -625,7 +624,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
}
long generateMessageId() {
long messageId = (long)((((double)System.currentTimeMillis() + ((double)timeDifference) * 1000) * 4294967296.0) / 1000.0);
long messageId = (long) ((((double) System.currentTimeMillis() + ((double) timeDifference) * 1000) * 4294967296.0) / 1000.0);
if (messageId <= lastOutgoingMessageId) {
messageId = lastOutgoingMessageId + 1;
}
@ -637,13 +636,14 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
}
long getTimeFromMsgId(long messageId) {
return (long)(messageId / 4294967296.0 * 1000);
return (long) (messageId / 4294967296.0 * 1000);
}
//================================================================================
// Requests manage
//================================================================================
int lastClassGuid = 1;
public int generateClassGuid() {
int guid = lastClassGuid++;
requestsByGuids.put(guid, new ArrayList<Long>());
@ -756,7 +756,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
if (updatingDcSettings) {
return;
}
updatingDcStartTime = (int)(System.currentTimeMillis() / 1000);
updatingDcStartTime = (int) (System.currentTimeMillis() / 1000);
updatingDcSettings = true;
TLRPC.TL_help_getConfig getConfig = new TLRPC.TL_help_getConfig();
@ -767,12 +767,12 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
return;
}
if (error == null) {
TLRPC.TL_config config = (TLRPC.TL_config)response;
TLRPC.TL_config config = (TLRPC.TL_config) response;
int updateIn = config.expires - getCurrentTime();
if (updateIn <= 0) {
updateIn = 120;
}
lastDcUpdateTime = (int)(System.currentTimeMillis() / 1000) - DC_UPDATE_TIME + updateIn;
lastDcUpdateTime = (int) (System.currentTimeMillis() / 1000) - DC_UPDATE_TIME + updateIn;
ArrayList<Datacenter> datacentersArr = new ArrayList<>();
HashMap<Integer, Datacenter> datacenterMap = new HashMap<>();
for (TLRPC.TL_dcOption datacenterDesc : config.dc_options) {
@ -813,14 +813,17 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
private TLObject wrapInLayer(TLObject object, int datacenterId, RPCRequest request) {
if (object.layer() > 0) {
Datacenter datacenter = datacenterWithId(datacenterId);
if (datacenter == null || datacenter.lastInitVersion != currentAppVersion) {
if (datacenter == null || datacenter.lastInitVersion != BuildVars.BUILD_VERSION) {
registerForPush();
request.initRequest = true;
TLRPC.initConnection invoke = new TLRPC.initConnection();
invoke.query = object;
invoke.api_id = BuildVars.APP_ID;
try {
invoke.lang_code = LocaleController.getLocaleString(Locale.getDefault());
invoke.lang_code = LocaleController.getLocaleString(LocaleController.getInstance().getSystemDefaultLocale());
if (invoke.lang_code == null || invoke.lang_code.length() == 0) {
invoke.lang_code = "en";
}
invoke.device_model = Build.MANUFACTURER + Build.MODEL;
if (invoke.device_model == null) {
invoke.device_model = "Android unknown";
@ -962,7 +965,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
public static boolean isNetworkOnline() {
try {
ConnectivityManager cm = (ConnectivityManager)ApplicationLoader.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE);
ConnectivityManager cm = (ConnectivityManager) ApplicationLoader.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && (netInfo.isConnectedOrConnecting() || netInfo.isAvailable())) {
return true;
@ -974,11 +977,11 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
return true;
} else {
netInfo = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if(netInfo != null && netInfo.isConnectedOrConnecting()) {
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
}
}
} catch(Exception e) {
} catch (Exception e) {
FileLog.e("tmessages", e);
return true;
}
@ -987,12 +990,12 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
public static boolean isRoaming() {
try {
ConnectivityManager cm = (ConnectivityManager)ApplicationLoader.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE);
ConnectivityManager cm = (ConnectivityManager) ApplicationLoader.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null) {
return netInfo.isRoaming();
}
} catch(Exception e) {
} catch (Exception e) {
FileLog.e("tmessages", e);
}
return false;
@ -1000,19 +1003,19 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
public static boolean isConnectedToWiFi() {
try {
ConnectivityManager cm = (ConnectivityManager)ApplicationLoader.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE);
ConnectivityManager cm = (ConnectivityManager) ApplicationLoader.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (netInfo != null && netInfo.getState() == NetworkInfo.State.CONNECTED) {
return true;
}
} catch(Exception e) {
} catch (Exception e) {
FileLog.e("tmessages", e);
}
return false;
}
public int getCurrentTime() {
return (int)(System.currentTimeMillis() / 1000) + timeDifference;
return (int) (System.currentTimeMillis() / 1000) + timeDifference;
}
public int getTimeDifference() {
@ -1033,7 +1036,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
genericConnection = defaultDatacenter.getGenericConnection(this);
}
int currentTime = (int)(System.currentTimeMillis() / 1000);
int currentTime = (int) (System.currentTimeMillis() / 1000);
for (int i = 0; i < runningRequests.size(); i++) {
RPCRequest request = runningRequests.get(i);
@ -1062,7 +1065,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
}
Datacenter requestDatacenter = datacenterWithId(datacenterId);
if (!request.initRequest && requestDatacenter.lastInitVersion != currentAppVersion) {
if (!request.initRequest && requestDatacenter.lastInitVersion != BuildVars.BUILD_VERSION) {
request.rpcRequest = wrapInLayer(request.rawRequest, requestDatacenter.datacenterId, request);
ByteBufferDesc os = new ByteBufferDesc(true);
request.rpcRequest.serializeToStream(os);
@ -1093,7 +1096,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
connection = requestDatacenter.getGenericConnection(this);
} else if ((request.flags & RPCRequest.RPCRequestClassDownloadMedia) != 0) {
connection = requestDatacenter.getDownloadConnection(this);
} else if ((request.flags & RPCRequest.RPCRequestClassUploadMedia) != 0 ) {
} else if ((request.flags & RPCRequest.RPCRequestClassUploadMedia) != 0) {
connection = requestDatacenter.getUploadConnection(this);
}
@ -1203,7 +1206,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
continue;
}
if (System.currentTimeMillis() / 1000 - lastDestroySessionRequestTime > 2.0) {
lastDestroySessionRequestTime = (int)(System.currentTimeMillis() / 1000);
lastDestroySessionRequestTime = (int) (System.currentTimeMillis() / 1000);
TLRPC.TL_destroy_session destroySession = new TLRPC.TL_destroy_session();
destroySession.session_id = it;
destroyingSessions.add(it);
@ -1277,7 +1280,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
}
Datacenter requestDatacenter = datacenterWithId(datacenterId);
if (!request.initRequest && requestDatacenter.lastInitVersion != currentAppVersion) {
if (!request.initRequest && requestDatacenter.lastInitVersion != BuildVars.BUILD_VERSION) {
request.rpcRequest = wrapInLayer(request.rawRequest, requestDatacenter.datacenterId, request);
}
@ -1363,7 +1366,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
request.runningMessageId = messageId;
request.runningMessageSeqNo = networkMessage.protoMessage.seqno;
request.serializedLength = requestLength;
request.runningStartTime = (int)(System.currentTimeMillis() / 1000);
request.runningStartTime = (int) (System.currentTimeMillis() / 1000);
request.transportChannelToken = connection.channelToken;
if (request.requiresCompletion) {
runningRequests.add(request);
@ -1486,7 +1489,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
boolean notFound = true;
for (Action actor : actionQueue) {
if (actor instanceof HandshakeAction) {
HandshakeAction eactor = (HandshakeAction)actor;
HandshakeAction eactor = (HandshakeAction) actor;
if (eactor.datacenter.datacenterId == num) {
notFound = false;
break;
@ -1506,7 +1509,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
boolean notFound = true;
for (Action actor : actionQueue) {
if (actor instanceof ExportAuthorizationAction) {
ExportAuthorizationAction eactor = (ExportAuthorizationAction)actor;
ExportAuthorizationAction eactor = (ExportAuthorizationAction) actor;
if (eactor.datacenter.datacenterId == num) {
notFound = false;
break;
@ -1554,7 +1557,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
}
ArrayList<NetworkMessage> messages = new ArrayList<>();
if(messageList != null) {
if (messageList != null) {
messages.addAll(messageList);
}
@ -1638,11 +1641,11 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
if (BuildVars.DEBUG_VERSION) {
if (message.body instanceof TLRPC.invokeWithLayer) {
FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer)message.body).query);
FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer) message.body).query);
} else if (message.body instanceof TLRPC.initConnection) {
TLRPC.initConnection r = (TLRPC.initConnection)message.body;
TLRPC.initConnection r = (TLRPC.initConnection) message.body;
if (r.query instanceof TLRPC.invokeWithLayer) {
FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer)r.query).query);
FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer) r.query).query);
} else {
FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + r.query);
}
@ -1652,7 +1655,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
}
long msg_time = getTimeFromMsgId(message.msg_id);
long currentTime = System.currentTimeMillis() + ((long)timeDifference) * 1000;
long currentTime = System.currentTimeMillis() + ((long) timeDifference) * 1000;
if (msg_time < currentTime - 30000 || msg_time > currentTime + 25000) {
FileLog.d("tmessages", "wrap in messages continaer");
@ -1678,11 +1681,11 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
containerMessages.add(message);
if (BuildVars.DEBUG_VERSION) {
if (message.body instanceof TLRPC.invokeWithLayer) {
FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer)message.body).query);
FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer) message.body).query);
} else if (message.body instanceof TLRPC.initConnection) {
TLRPC.initConnection r = (TLRPC.initConnection)message.body;
TLRPC.initConnection r = (TLRPC.initConnection) message.body;
if (r.query instanceof TLRPC.invokeWithLayer) {
FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer)r.query).query);
FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer) r.query).query);
} else {
FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + r.query);
}
@ -1722,7 +1725,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
if (quickAckId != null) {
SerializedData data = new SerializedData(messageKeyFull);
quickAckId.add(data.readInt32() & 0x7fffffff);
quickAckId.add(data.readInt32(false) & 0x7fffffff);
data.cleanup();
}
@ -1782,7 +1785,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
performRpc(getFutureSalts, new RPCRequest.RPCRequestDelegate() {
@Override
public void run(TLObject response, TLRPC.TL_error error) {
TLRPC.TL_futuresalts res = (TLRPC.TL_futuresalts)response;
TLRPC.TL_futuresalts res = (TLRPC.TL_futuresalts) response;
if (error == null) {
int currentTime = getCurrentTime();
datacenter.mergeServerSalts(currentTime, res.salts);
@ -1837,7 +1840,10 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
req.token = "" + pushSessionId;
req.app_sandbox = false;
try {
req.lang_code = LocaleController.getLocaleString(Locale.getDefault());
req.lang_code = LocaleController.getLocaleString(LocaleController.getInstance().getSystemDefaultLocale());
if (req.lang_code == null || req.lang_code.length() == 0) {
req.lang_code = "en";
}
req.device_model = Build.MANUFACTURER + Build.MODEL;
if (req.device_model == null) {
req.device_model = "Android unknown";
@ -1896,7 +1902,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
Datacenter datacenter = datacenterWithId(connection.getDatacenterId());
if (message instanceof TLRPC.TL_new_session_created) {
TLRPC.TL_new_session_created newSession = (TLRPC.TL_new_session_created)message;
TLRPC.TL_new_session_created newSession = (TLRPC.TL_new_session_created) message;
if (!connection.isSessionProcessed(newSession.unique_id)) {
FileLog.d("tmessages", "New session:");
@ -1941,7 +1947,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
timeDifference = (int)((time - currentTime) / 1000 - currentPingTime / 2.0);
}*/
TLRPC.TL_msg_container messageContainer = (TLRPC.TL_msg_container)message;
TLRPC.TL_msg_container messageContainer = (TLRPC.TL_msg_container) message;
for (TLRPC.TL_protoMessage innerMessage : messageContainer.messages) {
long innerMessageId = innerMessage.msg_id;
if (innerMessage.seqno % 2 != 0) {
@ -1989,7 +1995,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
sendingPushPing = false;
}
} else if (message instanceof TLRPC.TL_futuresalts) {
TLRPC.TL_futuresalts futureSalts = (TLRPC.TL_futuresalts)message;
TLRPC.TL_futuresalts futureSalts = (TLRPC.TL_futuresalts) message;
long requestMid = futureSalts.req_msg_id;
for (RPCRequest request : runningRequests) {
if (request.respondsToMessageId(requestMid)) {
@ -2007,7 +2013,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
}
}
} else if (message instanceof TLRPC.DestroySessionRes) {
TLRPC.DestroySessionRes res = (TLRPC.DestroySessionRes)message;
TLRPC.DestroySessionRes res = (TLRPC.DestroySessionRes) message;
ArrayList<Long> lst = new ArrayList<>();
lst.addAll(sessionsToDestroy);
destroyingSessions.remove(res.session_id);
@ -2019,18 +2025,18 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
}
}
} else if (message instanceof TLRPC.TL_rpc_result) {
TLRPC.TL_rpc_result resultContainer = (TLRPC.TL_rpc_result)message;
TLRPC.TL_rpc_result resultContainer = (TLRPC.TL_rpc_result) message;
long resultMid = resultContainer.req_msg_id;
boolean ignoreResult = false;
FileLog.d("tmessages", "object in rpc_result is " + resultContainer.result);
if (resultContainer.result instanceof TLRPC.RpcError) {
String errorMessage = ((TLRPC.RpcError)resultContainer.result).error_message;
FileLog.e("tmessages", String.format("***** RPC error %d: %s", ((TLRPC.RpcError)resultContainer.result).error_code, errorMessage));
String errorMessage = ((TLRPC.RpcError) resultContainer.result).error_message;
FileLog.e("tmessages", String.format("***** RPC error %d: %s", ((TLRPC.RpcError) resultContainer.result).error_code, errorMessage));
int migrateToDatacenterId = DEFAULT_DATACENTER_ID;
if (((TLRPC.RpcError)resultContainer.result).error_code == 303) {
if (((TLRPC.RpcError) resultContainer.result).error_code == 303) {
ArrayList<String> migrateErrors = new ArrayList<>();
migrateErrors.add("NETWORK_MIGRATE_");
migrateErrors.add("PHONE_MIGRATE_");
@ -2079,21 +2085,16 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
boolean discardResponse = false;
boolean isError = false;
boolean allowInitConnection = true;
if (request.completionBlock != null) {
TLRPC.TL_error implicitError = null;
if (resultContainer.result instanceof TLRPC.TL_gzip_packed) {
TLRPC.TL_gzip_packed packet = (TLRPC.TL_gzip_packed)resultContainer.result;
TLObject uncomressed = Utilities.decompress(packet.packed_data, request.rawRequest);
if (uncomressed == null) {
System.gc();
uncomressed = Utilities.decompress(packet.packed_data, request.rawRequest);
}
if (uncomressed == null) {
throw new RuntimeException("failed to decomress responce for " + request.rawRequest);
}
resultContainer.result = uncomressed;
TLRPC.TL_gzip_packed packet = (TLRPC.TL_gzip_packed) resultContainer.result;
resultContainer.result = Utilities.decompress(packet.packed_data, request.rawRequest, true);
}
if (resultContainer.result instanceof TLRPC.RpcError) {
allowInitConnection = false;
String errorMessage = ((TLRPC.RpcError) resultContainer.result).error_message;
FileLog.e("tmessages", String.format("***** RPC error %d: %s", ((TLRPC.RpcError) resultContainer.result).error_code, errorMessage));
@ -2106,6 +2107,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
request.runningMinStartTime = request.runningStartTime + delay;
request.confirmed = false;
}
request.serverFailureCount++;
} else if (errorCode == 420) {
if ((request.flags & RPCRequest.RPCRequestClassFailOnServerErrors) == 0) {
@ -2135,20 +2137,21 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
discardResponse = true;
request.wait = true;
request.runningMinStartTime = (int)(System.currentTimeMillis() / 1000 + waitTime);
request.runningMinStartTime = (int) (System.currentTimeMillis() / 1000 + waitTime);
request.confirmed = false;
}
}
implicitError = new TLRPC.TL_error();
implicitError.code = ((TLRPC.RpcError)resultContainer.result).error_code;
implicitError.text = ((TLRPC.RpcError)resultContainer.result).error_message;
implicitError.code = ((TLRPC.RpcError) resultContainer.result).error_code;
implicitError.text = ((TLRPC.RpcError) resultContainer.result).error_message;
} else if (!(resultContainer.result instanceof TLRPC.TL_error)) {
if (request.rawRequest == null || resultContainer.result == null || !request.rawRequest.responseClass().isAssignableFrom(resultContainer.result.getClass())) {
if (request.rawRequest == null || resultContainer.result == null) {
allowInitConnection = false;
if (request.rawRequest == null) {
FileLog.e("tmessages", "rawRequest is null");
} else {
FileLog.e("tmessages", "***** RPC error: invalid response class " + resultContainer.result + " (" + request.rawRequest.responseClass() + " expected)");
FileLog.e("tmessages", "***** RPC error: invalid response class " + resultContainer.result + " (for request " + request.rawRequest + ")");
}
implicitError = new TLRPC.TL_error();
implicitError.code = -1000;
@ -2161,6 +2164,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
isError = true;
request.completionBlock.run(null, implicitError != null ? implicitError : (TLRPC.TL_error) resultContainer.result);
} else {
request.completionBlock.run(resultContainer.result, null);
if (resultContainer.result instanceof TLRPC.updates_Difference) {
pushMessagesReceived = true;
AndroidUtilities.runOnUIThread(new Runnable() {
@ -2173,24 +2177,14 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
}
});
}
request.completionBlock.run(resultContainer.result, null);
}
}
if (implicitError != null && implicitError.code == 401) {
allowInitConnection = false;
isError = true;
if (implicitError.text != null && implicitError.text.contains("SESSION_PASSWORD_NEEDED")) {
/*UserConfig.setWaitingForPasswordEnter(true); TODO
UserConfig.saveConfig(false);
if (UserConfig.isClientActivated()) {
discardResponse = true;
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.needPasswordEnter);
}
});
}*/
//ignore this error
} else if (datacenter.datacenterId == currentDatacenterId || datacenter.datacenterId == movingToDatacenterId) {
if ((request.flags & RPCRequest.RPCRequestClassGeneric) != 0 && UserConfig.isClientActivated()) {
UserConfig.clearConfig();
@ -2214,9 +2208,9 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
}
if (!discardResponse) {
if (request.initRequest && !isError) {
if (datacenter.lastInitVersion != currentAppVersion) {
datacenter.lastInitVersion = currentAppVersion;
if (allowInitConnection && request.initRequest && !isError) {
if (datacenter.lastInitVersion != BuildVars.BUILD_VERSION) {
datacenter.lastInitVersion = BuildVars.BUILD_VERSION;
saveSession();
FileLog.e("tmessages", "init connection completed");
} else {
@ -2254,7 +2248,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
} else if (message instanceof TLRPC.TL_ping) {
} else if (message instanceof TLRPC.TL_bad_msg_notification) {
TLRPC.TL_bad_msg_notification badMsgNotification = (TLRPC.TL_bad_msg_notification)message;
TLRPC.TL_bad_msg_notification badMsgNotification = (TLRPC.TL_bad_msg_notification) message;
FileLog.e("tmessages", String.format("***** Bad message: %d", badMsgNotification.error_code));
@ -2267,7 +2261,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
if (realId != 0) {
long time = getTimeFromMsgId(messageId);
long currentTime = System.currentTimeMillis();
timeDifference = (int)((time - currentTime) / 1000 - currentPingTime / 2.0);
timeDifference = (int) ((time - currentTime) / 1000 - currentPingTime / 2.0);
}
datacenter.recreateSessions();
@ -2283,7 +2277,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
if (messageId != 0) {
long time = getTimeFromMsgId(messageId);
long currentTime = System.currentTimeMillis();
timeDifference = (int)((time - currentTime) / 1000 - currentPingTime / 2.0);
timeDifference = (int) ((time - currentTime) / 1000 - currentPingTime / 2.0);
lastOutgoingMessageId = Math.max(messageId, lastOutgoingMessageId);
}
@ -2316,7 +2310,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
processRequestQueue(RPCRequest.RPCRequestClassTransportMask, datacenter.datacenterId);
}
} else if (message instanceof TLRPC.MsgDetailedInfo) {
TLRPC.MsgDetailedInfo detailedInfo = (TLRPC.MsgDetailedInfo)message;
TLRPC.MsgDetailedInfo detailedInfo = (TLRPC.MsgDetailedInfo) message;
boolean requestResend = false;
boolean confirm = true;
@ -2327,8 +2321,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
if (request.completed) {
break;
}
if (request.lastResendTime == 0 || request.lastResendTime + 60 < (int)(System.currentTimeMillis() / 1000)) {
request.lastResendTime = (int)(System.currentTimeMillis() / 1000);
if (request.lastResendTime == 0 || request.lastResendTime + 60 < (int) (System.currentTimeMillis() / 1000)) {
request.lastResendTime = (int) (System.currentTimeMillis() / 1000);
requestResend = true;
} else {
confirm = false;
@ -2356,9 +2350,11 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
connection.addMessageToConfirm(detailedInfo.answer_msg_id);
}
} else if (message instanceof TLRPC.TL_gzip_packed) {
TLRPC.TL_gzip_packed packet = (TLRPC.TL_gzip_packed)message;
TLObject result = Utilities.decompress(packet.packed_data, getRequestWithMessageId(messageId));
TLRPC.TL_gzip_packed packet = (TLRPC.TL_gzip_packed) message;
TLObject result = Utilities.decompress(packet.packed_data, getRequestWithMessageId(messageId), true);
if (result != null) {
processMessage(result, messageId, messageSeqNo, messageSalt, connection, innerMsgId, containerMessageId);
}
} else if (message instanceof TLRPC.Updates) {
if ((connection.transportRequestClass & RPCRequest.RPCRequestClassPush) != 0) {
FileLog.e("tmessages", "received internal push");
@ -2375,6 +2371,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
resumeNetworkInternal();
} else {
pushMessagesReceived = true;
MessagesController.getInstance().processUpdates((TLRPC.Updates) message, false);
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
@ -2384,7 +2381,6 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
}
}
});
MessagesController.getInstance().processUpdates((TLRPC.Updates) message, false);
}
} else {
FileLog.e("tmessages", "***** Error: unknown message class " + message);
@ -2464,7 +2460,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
}
if (BuildVars.DEBUG_VERSION) {
try {
ConnectivityManager cm = (ConnectivityManager)ApplicationLoader.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE);
ConnectivityManager cm = (ConnectivityManager) ApplicationLoader.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo[] networkInfos = cm.getAllNetworkInfo();
for (int a = 0; a < 2; a++) {
if (a >= networkInfos.length) {
@ -2491,7 +2487,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
FileLog.e("tmessages", "push connection closed");
if (BuildVars.DEBUG_VERSION) {
try {
ConnectivityManager cm = (ConnectivityManager)ApplicationLoader.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE);
ConnectivityManager cm = (ConnectivityManager) ApplicationLoader.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo[] networkInfos = cm.getAllNetworkInfo();
for (int a = 0; a < 2; a++) {
if (a >= networkInfos.length) {
@ -2577,7 +2573,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
}
}
if (length == 4) {
int error = data.readInt32();
int error = data.readInt32(false);
FileLog.e("tmessages", "mtproto error = " + error);
connection.suspendConnection(true);
connection.connect();
@ -2585,22 +2581,20 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
}
Datacenter datacenter = datacenterWithId(connection.getDatacenterId());
long keyId = data.readInt64();
long keyId = data.readInt64(false);
if (keyId == 0) {
long messageId = data.readInt64();
long messageId = data.readInt64(false);
if (connection.isMessageIdProcessed(messageId)) {
finishUpdatingState(connection);
return;
}
int messageLength = data.readInt32();
int constructor = data.readInt32();
int messageLength = data.readInt32(false);
TLObject object = TLClassStore.Instance().TLdeserialize(data, constructor, getRequestWithMessageId(messageId));
TLObject message = deserialize(getRequestWithMessageId(messageId), data, true);
processMessage(object, messageId, 0, 0, connection, 0, 0);
if (object != null) {
if (message != null) {
processMessage(message, messageId, 0, 0, connection, 0, 0);
connection.addProcessedMessageId(messageId);
}
} else {
@ -2612,13 +2606,13 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
return;
}
byte[] messageKey = data.readData(16);
byte[] messageKey = data.readData(16, false);
MessageKeyData keyData = Utilities.generateMessageKeyData(datacenter.authKey, messageKey, true);
Utilities.aesIgeEncryption(data.buffer, keyData.aesKey, keyData.aesIv, false, false, data.position(), length - 24);
long messageServerSalt = data.readInt64();
long messageSessionId = data.readInt64();
long messageServerSalt = data.readInt64(false);
long messageSessionId = data.readInt64(false);
if (messageSessionId != connection.getSissionId()) {
FileLog.e("tmessages", String.format("***** Error: invalid message session ID (%d instead of %d)", messageSessionId, connection.getSissionId()));
@ -2628,9 +2622,9 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
boolean doNotProcess = false;
long messageId = data.readInt64();
int messageSeqNo = data.readInt32();
int messageLength = data.readInt32();
long messageId = data.readInt64(false);
int messageSeqNo = data.readInt32(false);
int messageLength = data.readInt32(false);
if (connection.isMessageIdProcessed(messageId)) {
doNotProcess = true;
@ -2654,12 +2648,8 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
}
if (!doNotProcess) {
int constructor = data.readInt32();
TLObject message = TLClassStore.Instance().TLdeserialize(data, constructor, getRequestWithMessageId(messageId));
if (message == null) {
FileLog.e("tmessages", "***** Error parsing message: " + constructor);
} else {
TLObject message = deserialize(getRequestWithMessageId(messageId), data, true);
if (message != null) {
FileLog.d("tmessages", "received object " + message);
processMessage(message, messageId, messageSeqNo, messageServerSalt, connection, 0, 0);
connection.addProcessedMessageId(messageId);
@ -2680,6 +2670,33 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
}
}
protected TLObject deserialize(TLObject request, AbsSerializedData data, boolean exception) {
int constructor = data.readInt32(exception);
TLObject message = null;
try {
message = TLClassStore.Instance().TLdeserialize(data, constructor, request, exception);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
if (message == null) {
if (request != null) {
try {
message = request.deserializeResponse(data, constructor, exception);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
if (message == null) {
FileLog.e("tmessages", String.format(Locale.US, "***** Error parsing message: %x", constructor));
}
} else {
FileLog.d("tmessages", String.format(Locale.US, "***** Not found request to parse message: %x", constructor));
}
} else if (message instanceof TLRPC.TL_rpc_result && ((TLRPC.TL_rpc_result) message).result == null) {
message = null;
}
return message;
}
public TLObject getRequestWithMessageId(long msgId) {
for (RPCRequest request : runningRequests) {
if (msgId == request.runningMessageId) {
@ -2712,7 +2729,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
@Override
public void run(TLObject response, TLRPC.TL_error error) {
if (error == null) {
movingAuthorization = (TLRPC.TL_auth_exportedAuthorization)response;
movingAuthorization = (TLRPC.TL_auth_exportedAuthorization) response;
authorizeOnMovingDatacenter();
} else {
Utilities.stageQueue.postRunnable(new Runnable() {
@ -2797,12 +2814,12 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
@Override
public void ActionDidFinishExecution(final Action action, HashMap<String, Object> params) {
if (action instanceof HandshakeAction) {
HandshakeAction eactor = (HandshakeAction)action;
HandshakeAction eactor = (HandshakeAction) action;
eactor.datacenter.connection.delegate = this;
saveSession();
if (eactor.datacenter.datacenterId == currentDatacenterId || eactor.datacenter.datacenterId == movingToDatacenterId) {
timeDifference = (Integer)params.get("timeDifference");
timeDifference = (Integer) params.get("timeDifference");
eactor.datacenter.recreateSessions();
clearRequestsForRequestClass(RPCRequest.RPCRequestClassGeneric, eactor.datacenter);
@ -2811,7 +2828,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
}
processRequestQueue(RPCRequest.RPCRequestClassTransportMask, eactor.datacenter.datacenterId);
} else if (action instanceof ExportAuthorizationAction) {
ExportAuthorizationAction eactor = (ExportAuthorizationAction)action;
ExportAuthorizationAction eactor = (ExportAuthorizationAction) action;
Datacenter datacenter = eactor.datacenter;
datacenter.authorized = true;

View File

@ -45,64 +45,64 @@ public class Datacenter {
public Datacenter(SerializedData data, int version) {
if (version == 0) {
datacenterId = data.readInt32();
String address = data.readString();
datacenterId = data.readInt32(false);
String address = data.readString(false);
addresses.add(address);
int port = data.readInt32();
int port = data.readInt32(false);
ports.put(address, port);
int len = data.readInt32();
int len = data.readInt32(false);
if (len != 0) {
authKey = data.readData(len);
authKey = data.readData(len, false);
}
len = data.readInt32();
len = data.readInt32(false);
if (len != 0) {
authKeyId = data.readInt64();
authKeyId = data.readInt64(false);
}
authorized = data.readInt32() != 0;
len = data.readInt32();
authorized = data.readInt32(false) != 0;
len = data.readInt32(false);
for (int a = 0; a < len; a++) {
ServerSalt salt = new ServerSalt();
salt.validSince = data.readInt32();
salt.validUntil = data.readInt32();
salt.value = data.readInt64();
salt.validSince = data.readInt32(false);
salt.validUntil = data.readInt32(false);
salt.value = data.readInt64(false);
if (authServerSaltSet == null) {
authServerSaltSet = new ArrayList<>();
}
authServerSaltSet.add(salt);
}
} else if (version == 1) {
int currentVersion = data.readInt32();
int currentVersion = data.readInt32(false);
if (currentVersion == 2 || currentVersion == 3 || currentVersion == 4) {
datacenterId = data.readInt32();
datacenterId = data.readInt32(false);
if (currentVersion >= 3) {
lastInitVersion = data.readInt32();
lastInitVersion = data.readInt32(false);
}
int len = data.readInt32();
int len = data.readInt32(false);
for (int a = 0; a < len; a++) {
String address = data.readString();
String address = data.readString(false);
addresses.add(address);
ports.put(address, data.readInt32());
ports.put(address, data.readInt32(false));
}
len = data.readInt32();
len = data.readInt32(false);
if (len != 0) {
authKey = data.readData(len);
authKey = data.readData(len, false);
}
if (currentVersion == 4) {
authKeyId = data.readInt64();
authKeyId = data.readInt64(false);
} else {
len = data.readInt32();
len = data.readInt32(false);
if (len != 0) {
authKeyId = data.readInt64();
authKeyId = data.readInt64(false);
}
}
authorized = data.readInt32() != 0;
len = data.readInt32();
authorized = data.readInt32(false) != 0;
len = data.readInt32(false);
for (int a = 0; a < len; a++) {
ServerSalt salt = new ServerSalt();
salt.validSince = data.readInt32();
salt.validUntil = data.readInt32();
salt.value = data.readInt64();
salt.validSince = data.readInt32(false);
salt.validUntil = data.readInt32(false);
salt.value = data.readInt64(false);
if (authServerSaltSet == null) {
authServerSaltSet = new ArrayList<>();
}

View File

@ -8,8 +8,8 @@
package org.telegram.messenger;
import java.io.RandomAccessFile;
import java.io.File;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Scanner;
@ -54,6 +54,8 @@ public class FileLoadOperation {
private File tempPath = null;
private boolean isForceRequest = false;
private static String orgName = null;
public interface FileLoadOperationDelegate {
void didFinishLoadingFile(FileLoadOperation operation, File finalFile);
void didFailedLoadingFile(FileLoadOperation operation, int state);
@ -83,6 +85,7 @@ public class FileLoadOperation {
if (ext == null) {
ext = "jpg";
}
orgName = null;
}
public FileLoadOperation(TLRPC.Video videoLocation) {
@ -149,6 +152,9 @@ public class FileLoadOperation {
ext = "";
}
}
if(ApplicationLoader.KEEP_ORIGINAL_FILENAME && !ext.contains("webp")){
orgName = FileLoader.getDocName(documentLocation);
}
}
public void setForceRequest(boolean forceRequest) {
@ -215,9 +221,19 @@ public class FileLoadOperation {
return;
}
}
//
if(ApplicationLoader.KEEP_ORIGINAL_FILENAME && orgName != null){
fileNameFinal = orgName;
}
//
cacheFileFinal = new File(storePath, fileNameFinal);
boolean exist = cacheFileFinal.exists();
//
if(exist && orgName != null && ApplicationLoader.KEEP_ORIGINAL_FILENAME){
exist = false;
cacheFileFinal.delete();
}
//
if (exist && totalBytesCount != 0 && totalBytesCount != cacheFileFinal.length()) {
exist = false;
cacheFileFinal.delete();

View File

@ -11,9 +11,12 @@ package org.telegram.messenger;
import org.telegram.android.AndroidUtilities;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Semaphore;
@ -632,6 +635,10 @@ public class FileLoader {
}
public static TLRPC.PhotoSize getClosestPhotoSizeWithSize(ArrayList<TLRPC.PhotoSize> sizes, int side) {
return getClosestPhotoSizeWithSize(sizes, side, false);
}
public static TLRPC.PhotoSize getClosestPhotoSizeWithSize(ArrayList<TLRPC.PhotoSize> sizes, int side, boolean byMinSide) {
if (sizes == null || sizes.isEmpty()) {
return null;
}
@ -641,12 +648,20 @@ public class FileLoader {
if (obj == null) {
continue;
}
if (byMinSide) {
int currentSide = obj.h >= obj.w ? obj.w : obj.h;
if (closestObject == null || side > 100 && closestObject.location != null && closestObject.location.dc_id == Integer.MIN_VALUE || obj instanceof TLRPC.TL_photoCachedSize || side > lastSide && lastSide < currentSide) {
closestObject = obj;
lastSide = currentSide;
}
} else {
int currentSide = obj.w >= obj.h ? obj.w : obj.h;
if (closestObject == null || side > 100 && closestObject.location != null && closestObject.location.dc_id == Integer.MIN_VALUE || obj instanceof TLRPC.TL_photoCachedSize || currentSide <= side && lastSide < currentSide) {
closestObject = obj;
lastSide = currentSide;
}
}
}
return closestObject;
}
@ -675,6 +690,7 @@ public class FileLoader {
ext = ext.substring(idx);
}
if (ext.length() > 1) {
if(ApplicationLoader.KEEP_ORIGINAL_FILENAME && !ext.contains("webp"))return getDocName(document); //Plus
return document.dc_id + "_" + document.id + ext;
} else {
return document.dc_id + "_" + document.id;
@ -694,6 +710,64 @@ public class FileLoader {
}
return "";
}
//Plus
public static String getAttachFileName(TLObject attach, boolean out) {
if (attach instanceof TLRPC.Video) {
TLRPC.Video video = (TLRPC.Video)attach;
return video.dc_id + "_" + video.id + ".mp4";
} else if (attach instanceof TLRPC.Document) {
TLRPC.Document document = (TLRPC.Document)attach;
String ext = getDocumentFileName(document);
int idx = -1;
if (ext == null || (idx = ext.lastIndexOf(".")) == -1) {
ext = "";
} else {
ext = ext.substring(idx);
}
if (ext.length() > 1) {
if(!out && ApplicationLoader.KEEP_ORIGINAL_FILENAME && !ext.contains("webp"))return getDocName(document);
return document.dc_id + "_" + document.id + ext;
} else {
return document.dc_id + "_" + document.id;
}
} else if (attach instanceof TLRPC.PhotoSize) {
TLRPC.PhotoSize photo = (TLRPC.PhotoSize)attach;
if (photo.location == null) {
return "";
}
return photo.location.volume_id + "_" + photo.location.local_id + "." + (photo.location.ext != null ? photo.location.ext : "jpg");
} else if (attach instanceof TLRPC.Audio) {
TLRPC.Audio audio = (TLRPC.Audio)attach;
return audio.dc_id + "_" + audio.id + ".ogg";
} else if (attach instanceof TLRPC.FileLocation) {
TLRPC.FileLocation location = (TLRPC.FileLocation)attach;
return location.volume_id + "_" + location.local_id + "." + (location.ext != null ? location.ext : "jpg");
}
return "";
}
//Plus
public static String getDocName(TLRPC.Document document) {
String name = getDocumentFileName(document);
//boolean org = false;
//if(org)return name;
String date = document.date +"";
String ext = name;
int idx = -1;
if (ext == null || (idx = ext.lastIndexOf(".")) == -1) {
ext = "";
} else {
ext = ext.substring(idx);
}
int pos = name.lastIndexOf(".");
SimpleDateFormat formatter = new SimpleDateFormat("ddMMyyHHmmss", Locale.US);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(document.date * 1000L);
date = formatter.format(calendar.getTime());
if (pos > 0) {
name = name.substring(0, pos) + "_" + date + ext;
}
return name;
}
public void deleteFiles(final ArrayList<File> files) {
if (files == null || files.isEmpty()) {

View File

@ -340,7 +340,7 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
Utilities.aesIgeEncryption(answerWithHash.buffer, tmpAesKey.toByteArray(), tmpAesIv.toByteArray(), false, false, 0, serverDhParams.encrypted_answer.length);
byte[] answerHash = new byte[20];
answerWithHash.readRaw(answerHash);
answerWithHash.readRaw(answerHash, false);
boolean hashVerified = false;
for (int i = 0; i < 16; i++) {
@ -358,8 +358,8 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
return;
}
int constructor = answerWithHash.readInt32();
TLRPC.TL_server_DH_inner_data dhInnerData = (TLRPC.TL_server_DH_inner_data)TLClassStore.Instance().TLdeserialize(answerWithHash, constructor);
int constructor = answerWithHash.readInt32(false);
TLRPC.TL_server_DH_inner_data dhInnerData = TLRPC.TL_server_DH_inner_data.TLdeserialize(answerWithHash, constructor, false);
BuffersStorage.getInstance().reuseFreeBuffer(answerWithHash);
if (!(dhInnerData instanceof TLRPC.TL_server_DH_inner_data)) {
@ -627,17 +627,17 @@ public class HandshakeAction extends Action implements TcpConnection.TcpConnecti
@Override
public void tcpConnectionReceivedData(TcpConnection connection, ByteBufferDesc data, int length) {
long keyId = data.readInt64();
long keyId = data.readInt64(false);
if (keyId == 0) {
long messageId = data.readInt64();
long messageId = data.readInt64(false);
if (processedMessageIds.contains(messageId)) {
FileLog.d("tmessages", String.format("===== Duplicate message id %d received, ignoring", messageId));
return;
}
int messageLength = data.readInt32();
int messageLength = data.readInt32(false);
int constructor = data.readInt32();
TLObject object = TLClassStore.Instance().TLdeserialize(data, constructor);
int constructor = data.readInt32(false);
TLObject object = TLClassStore.Instance().TLdeserialize(data, constructor, false);
if (object != null) {
processedMessageIds.add(messageId);

View File

@ -47,6 +47,7 @@ public class SerializedData extends AbsSerializedData {
isOut = false;
inbuf = new ByteArrayInputStream(data);
in = new DataInputStream(inbuf);
len = 0;
}
public void cleanup() {
@ -131,17 +132,6 @@ public class SerializedData extends AbsSerializedData {
}
}
public boolean readBool() {
int consructor = readInt32();
if (consructor == 0x997275b5) {
return true;
} else if (consructor == 0xbc799737) {
return false;
}
FileLog.e("tmessages", "Not bool value!");
return false;
}
public void writeBool(boolean value) {
if (!justCalc) {
if (value) {
@ -173,52 +163,6 @@ public class SerializedData extends AbsSerializedData {
}
}
public int readInt32() {
return readInt32(null);
}
public int readInt32(boolean[] error) {
try {
int i = 0;
for(int j = 0; j < 4; j++) {
i |= (in.read() << (j * 8));
}
if (error != null) {
error[0] = false;
}
return i;
} catch(Exception x) {
if (error != null) {
error[0] = true;
}
FileLog.e("tmessages", "read int32 error");
}
return 0;
}
public long readInt64() {
return readInt64(null);
}
public long readInt64(boolean[] error) {
try {
long i = 0;
for(int j = 0; j < 8; j++) {
i |= ((long)in.read() << (j * 8));
}
if (error != null) {
error[0] = false;
}
return i;
} catch (Exception x) {
if (error != null) {
error[0] = true;
}
FileLog.e("tmessages", "read int64 error");
}
return 0;
}
public void writeRaw(byte[] b) {
try {
if (!justCalc) {
@ -226,7 +170,7 @@ public class SerializedData extends AbsSerializedData {
} else {
len += b.length;
}
} catch (Exception x) {
} catch (Exception e) {
FileLog.e("tmessages", "write raw error");
}
}
@ -238,7 +182,7 @@ public class SerializedData extends AbsSerializedData {
} else {
len += count;
}
} catch (Exception x) {
} catch (Exception e) {
FileLog.e("tmessages", "write raw error");
}
}
@ -246,7 +190,7 @@ public class SerializedData extends AbsSerializedData {
public void writeByte(int i) {
try {
if (!justCalc) {
out.writeByte((byte)i);
out.writeByte((byte) i);
} else {
len += 1;
}
@ -267,68 +211,6 @@ public class SerializedData extends AbsSerializedData {
}
}
public void readRaw(byte[] b) {
try {
in.read(b);
} catch (Exception x) {
FileLog.e("tmessages", "read raw error");
}
}
public byte[] readData(int count) {
byte[] arr = new byte[count];
readRaw(arr);
return arr;
}
public String readString() {
try {
int sl = 1;
int l = in.read();
if(l >= 254) {
l = in.read() | (in.read() << 8) | (in.read() << 16);
sl = 4;
}
byte[] b = new byte[l];
in.read(b);
int i=sl;
while((l + i) % 4 != 0) {
in.read();
i++;
}
return new String(b, "UTF-8");
} catch (Exception x) {
FileLog.e("tmessages", "read string error");
}
return null;
}
public byte[] readByteArray() {
try {
int sl = 1;
int l = in.read();
if (l >= 254) {
l = in.read() | (in.read() << 8) | (in.read() << 16);
sl = 4;
}
byte[] b = new byte[l];
in.read(b);
int i = sl;
while((l + i) % 4 != 0) {
in.read();
i++;
}
return b;
} catch (Exception x) {
FileLog.e("tmessages", "read byte array error");
}
return null;
}
public ByteBufferDesc readByteBuffer() {
throw new RuntimeException("SerializedData don't support readByteBuffer");
}
public void writeByteArray(byte[] b) {
try {
if (b.length <= 253) {
@ -361,7 +243,7 @@ public class SerializedData extends AbsSerializedData {
}
i++;
}
} catch (Exception x) {
} catch (Exception e) {
FileLog.e("tmessages", "write byte array error");
}
}
@ -369,7 +251,7 @@ public class SerializedData extends AbsSerializedData {
public void writeString(String s) {
try {
writeByteArray(s.getBytes("UTF-8"));
} catch(Exception x) {
} catch(Exception e) {
FileLog.e("tmessages", "write string error");
}
}
@ -406,24 +288,15 @@ public class SerializedData extends AbsSerializedData {
}
i++;
}
} catch (Exception x) {
} catch (Exception e) {
FileLog.e("tmessages", "write byte array error");
}
}
public double readDouble() {
try {
return Double.longBitsToDouble(readInt64());
} catch(Exception x) {
FileLog.e("tmessages", "read double error");
}
return 0;
}
public void writeDouble(double d) {
try {
writeInt64(Double.doubleToRawLongBits(d));
} catch(Exception x) {
} catch(Exception e) {
FileLog.e("tmessages", "write double error");
}
}
@ -444,4 +317,172 @@ public class SerializedData extends AbsSerializedData {
public byte[] toByteArray() {
return outbuf.toByteArray();
}
public void skip(int count) {
if (count == 0) {
return;
}
if (!justCalc) {
if (in != null) {
try {
in.skipBytes(count);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
} else {
len += count;
}
}
public int getPosition() {
return len;
}
public boolean readBool(boolean exception) {
int consructor = readInt32(exception);
if (consructor == 0x997275b5) {
return true;
} else if (consructor == 0xbc799737) {
return false;
}
if (exception) {
throw new RuntimeException("Not bool value!");
} else {
FileLog.e("tmessages", "Not bool value!");
}
return false;
}
public void readRaw(byte[] b, boolean exception) {
try {
in.read(b);
len += b.length;
} catch (Exception e) {
if (exception) {
throw new RuntimeException("read raw error", e);
} else {
FileLog.e("tmessages", "read raw error");
}
}
}
public byte[] readData(int count, boolean exception) {
byte[] arr = new byte[count];
readRaw(arr, exception);
return arr;
}
public String readString(boolean exception) {
try {
int sl = 1;
int l = in.read();
len++;
if(l >= 254) {
l = in.read() | (in.read() << 8) | (in.read() << 16);
len += 3;
sl = 4;
}
byte[] b = new byte[l];
in.read(b);
len++;
int i=sl;
while((l + i) % 4 != 0) {
in.read();
len++;
i++;
}
return new String(b, "UTF-8");
} catch (Exception e) {
if (exception) {
throw new RuntimeException("read string error", e);
} else {
FileLog.e("tmessages", "read string error");
}
}
return null;
}
public byte[] readByteArray(boolean exception) {
try {
int sl = 1;
int l = in.read();
len++;
if (l >= 254) {
l = in.read() | (in.read() << 8) | (in.read() << 16);
len += 3;
sl = 4;
}
byte[] b = new byte[l];
in.read(b);
len++;
int i = sl;
while((l + i) % 4 != 0) {
in.read();
len++;
i++;
}
return b;
} catch (Exception e) {
if (exception) {
throw new RuntimeException("read byte array error", e);
} else {
FileLog.e("tmessages", "read byte array error");
}
}
return null;
}
public ByteBufferDesc readByteBuffer(boolean exception) {
throw new RuntimeException("SerializedData don't support readByteBuffer");
}
public double readDouble(boolean exception) {
try {
return Double.longBitsToDouble(readInt64(exception));
} catch(Exception e) {
if (exception) {
throw new RuntimeException("read double error", e);
} else {
FileLog.e("tmessages", "read double error");
}
}
return 0;
}
public int readInt32(boolean exception) {
try {
int i = 0;
for(int j = 0; j < 4; j++) {
i |= (in.read() << (j * 8));
len++;
}
return i;
} catch(Exception e) {
if (exception) {
throw new RuntimeException("read int32 error", e);
} else {
FileLog.e("tmessages", "read int32 error");
}
}
return 0;
}
public long readInt64(boolean exception) {
try {
long i = 0;
for(int j = 0; j < 8; j++) {
i |= ((long)in.read() << (j * 8));
len++;
}
return i;
} catch (Exception e) {
if (exception) {
throw new RuntimeException("read int64 error", e);
} else {
FileLog.e("tmessages", "read int64 error");
}
}
return 0;
}
}

View File

@ -16,415 +16,86 @@ public class TLClassStore {
public TLClassStore () {
classStore = new HashMap<>();
classStore.put(TLRPC.TL_chatPhotoEmpty.constructor, TLRPC.TL_chatPhotoEmpty.class);
classStore.put(TLRPC.TL_chatPhoto.constructor, TLRPC.TL_chatPhoto.class);
classStore.put(TLRPC.TL_futuresalts.constructor, TLRPC.TL_futuresalts.class);
classStore.put(TLRPC.TL_bad_msg_notification.constructor, TLRPC.TL_bad_msg_notification.class);
classStore.put(TLRPC.TL_bad_server_salt.constructor, TLRPC.TL_bad_server_salt.class);
classStore.put(TLRPC.TL_msg_new_detailed_info.constructor, TLRPC.TL_msg_new_detailed_info.class);
classStore.put(TLRPC.TL_msg_detailed_info.constructor, TLRPC.TL_msg_detailed_info.class);
classStore.put(TLRPC.TL_error.constructor, TLRPC.TL_error.class);
classStore.put(TLRPC.TL_messages_sentEncryptedMessage.constructor, TLRPC.TL_messages_sentEncryptedMessage.class);
classStore.put(TLRPC.TL_messages_sentEncryptedFile.constructor, TLRPC.TL_messages_sentEncryptedFile.class);
classStore.put(TLRPC.TL_notifyAll.constructor, TLRPC.TL_notifyAll.class);
classStore.put(TLRPC.TL_notifyChats.constructor, TLRPC.TL_notifyChats.class);
classStore.put(TLRPC.TL_notifyUsers.constructor, TLRPC.TL_notifyUsers.class);
classStore.put(TLRPC.TL_notifyPeer.constructor, TLRPC.TL_notifyPeer.class);
classStore.put(TLRPC.TL_auth_checkedPhone.constructor, TLRPC.TL_auth_checkedPhone.class);
classStore.put(TLRPC.TL_msgs_ack.constructor, TLRPC.TL_msgs_ack.class);
classStore.put(TLRPC.TL_messages_chatFull.constructor, TLRPC.TL_messages_chatFull.class);
classStore.put(TLRPC.TL_documentAttributeAnimated.constructor, TLRPC.TL_documentAttributeAnimated.class);
classStore.put(TLRPC.TL_documentAttributeAudio.constructor, TLRPC.TL_documentAttributeAudio.class);
classStore.put(TLRPC.TL_documentAttributeFilename.constructor, TLRPC.TL_documentAttributeFilename.class);
classStore.put(TLRPC.TL_documentAttributeVideo.constructor, TLRPC.TL_documentAttributeVideo.class);
classStore.put(TLRPC.TL_documentAttributeSticker.constructor, TLRPC.TL_documentAttributeSticker.class);
classStore.put(TLRPC.TL_documentAttributeImageSize.constructor, TLRPC.TL_documentAttributeImageSize.class);
classStore.put(TLRPC.TL_rpc_result.constructor, TLRPC.TL_rpc_result.class);
classStore.put(TLRPC.TL_contactStatus.constructor, TLRPC.TL_contactStatus.class);
classStore.put(TLRPC.TL_auth_authorization.constructor, TLRPC.TL_auth_authorization.class);
classStore.put(TLRPC.TL_messages_messages.constructor, TLRPC.TL_messages_messages.class);
classStore.put(TLRPC.TL_messages_messagesSlice.constructor, TLRPC.TL_messages_messagesSlice.class);
classStore.put(TLRPC.TL_rpc_answer_unknown.constructor, TLRPC.TL_rpc_answer_unknown.class);
classStore.put(TLRPC.TL_rpc_answer_dropped.constructor, TLRPC.TL_rpc_answer_dropped.class);
classStore.put(TLRPC.TL_rpc_answer_dropped_running.constructor, TLRPC.TL_rpc_answer_dropped_running.class);
classStore.put(TLRPC.TL_contacts_link.constructor, TLRPC.TL_contacts_link.class);
classStore.put(TLRPC.TL_peerUser.constructor, TLRPC.TL_peerUser.class);
classStore.put(TLRPC.TL_peerChat.constructor, TLRPC.TL_peerChat.class);
classStore.put(TLRPC.TL_encryptedFile.constructor, TLRPC.TL_encryptedFile.class);
classStore.put(TLRPC.TL_encryptedFileEmpty.constructor, TLRPC.TL_encryptedFileEmpty.class);
classStore.put(TLRPC.TL_destroy_session_ok.constructor, TLRPC.TL_destroy_session_ok.class);
classStore.put(TLRPC.TL_destroy_session_none.constructor, TLRPC.TL_destroy_session_none.class);
classStore.put(TLRPC.TL_updates_differenceEmpty.constructor, TLRPC.TL_updates_differenceEmpty.class);
classStore.put(TLRPC.TL_updates_differenceSlice.constructor, TLRPC.TL_updates_differenceSlice.class);
classStore.put(TLRPC.TL_updates_difference.constructor, TLRPC.TL_updates_difference.class);
classStore.put(TLRPC.TL_geoPointEmpty.constructor, TLRPC.TL_geoPointEmpty.class);
classStore.put(TLRPC.TL_geoPoint.constructor, TLRPC.TL_geoPoint.class);
classStore.put(TLRPC.TL_privacyKeyStatusTimestamp.constructor, TLRPC.TL_privacyKeyStatusTimestamp.class);
classStore.put(TLRPC.TL_account_privacyRules.constructor, TLRPC.TL_account_privacyRules.class);
classStore.put(TLRPC.TL_help_appUpdate.constructor, TLRPC.TL_help_appUpdate.class);
classStore.put(TLRPC.TL_help_noAppUpdate.constructor, TLRPC.TL_help_noAppUpdate.class);
classStore.put(TLRPC.TL_messageEmpty.constructor, TLRPC.TL_messageEmpty.class);
classStore.put(TLRPC.TL_message.constructor, TLRPC.TL_message.class);
classStore.put(TLRPC.TL_messageService.constructor, TLRPC.TL_messageService.class);
classStore.put(TLRPC.TL_inputPhoneContact.constructor, TLRPC.TL_inputPhoneContact.class);
classStore.put(TLRPC.TL_sendMessageGeoLocationAction.constructor, TLRPC.TL_sendMessageGeoLocationAction.class);
classStore.put(TLRPC.TL_sendMessageChooseContactAction.constructor, TLRPC.TL_sendMessageChooseContactAction.class);
classStore.put(TLRPC.TL_sendMessageTypingAction.constructor, TLRPC.TL_sendMessageTypingAction.class);
classStore.put(TLRPC.TL_sendMessageUploadDocumentAction.constructor, TLRPC.TL_sendMessageUploadDocumentAction.class);
classStore.put(TLRPC.TL_sendMessageRecordVideoAction.constructor, TLRPC.TL_sendMessageRecordVideoAction.class);
classStore.put(TLRPC.TL_sendMessageUploadPhotoAction.constructor, TLRPC.TL_sendMessageUploadPhotoAction.class);
classStore.put(TLRPC.TL_sendMessageUploadVideoAction.constructor, TLRPC.TL_sendMessageUploadVideoAction.class);
classStore.put(TLRPC.TL_sendMessageUploadAudioAction.constructor, TLRPC.TL_sendMessageUploadAudioAction.class);
classStore.put(TLRPC.TL_sendMessageCancelAction.constructor, TLRPC.TL_sendMessageCancelAction.class);
classStore.put(TLRPC.TL_sendMessageRecordAudioAction.constructor, TLRPC.TL_sendMessageRecordAudioAction.class);
classStore.put(TLRPC.TL_invokeAfterMsg.constructor, TLRPC.TL_invokeAfterMsg.class);
classStore.put(TLRPC.TL_messageMediaVideo.constructor, TLRPC.TL_messageMediaVideo.class);
classStore.put(TLRPC.TL_messageMediaPhoto.constructor, TLRPC.TL_messageMediaPhoto.class);
classStore.put(TLRPC.TL_messageMediaDocument.constructor, TLRPC.TL_messageMediaDocument.class);
classStore.put(TLRPC.TL_messageMediaGeo.constructor, TLRPC.TL_messageMediaGeo.class);
classStore.put(TLRPC.TL_messageMediaEmpty.constructor, TLRPC.TL_messageMediaEmpty.class);
classStore.put(TLRPC.TL_messageMediaAudio.constructor, TLRPC.TL_messageMediaAudio.class);
classStore.put(TLRPC.TL_messageMediaContact.constructor, TLRPC.TL_messageMediaContact.class);
classStore.put(TLRPC.TL_messageMediaUnsupported.constructor, TLRPC.TL_messageMediaUnsupported.class);
classStore.put(TLRPC.TL_auth_sentAppCode.constructor, TLRPC.TL_auth_sentAppCode.class);
classStore.put(TLRPC.TL_auth_sentCode.constructor, TLRPC.TL_auth_sentCode.class);
classStore.put(TLRPC.TL_peerNotifySettingsEmpty.constructor, TLRPC.TL_peerNotifySettingsEmpty.class);
classStore.put(TLRPC.TL_peerNotifySettings.constructor, TLRPC.TL_peerNotifySettings.class);
classStore.put(TLRPC.TL_msg_resend_req.constructor, TLRPC.TL_msg_resend_req.class);
classStore.put(TLRPC.TL_http_wait.constructor, TLRPC.TL_http_wait.class);
classStore.put(TLRPC.TL_contacts_blocked.constructor, TLRPC.TL_contacts_blocked.class);
classStore.put(TLRPC.TL_contacts_blockedSlice.constructor, TLRPC.TL_contacts_blockedSlice.class);
classStore.put(TLRPC.TL_inputGeoPoint.constructor, TLRPC.TL_inputGeoPoint.class);
classStore.put(TLRPC.TL_inputGeoPointEmpty.constructor, TLRPC.TL_inputGeoPointEmpty.class);
classStore.put(TLRPC.TL_help_inviteText.constructor, TLRPC.TL_help_inviteText.class);
classStore.put(TLRPC.TL_messages_dhConfigNotModified.constructor, TLRPC.TL_messages_dhConfigNotModified.class);
classStore.put(TLRPC.TL_messages_dhConfig.constructor, TLRPC.TL_messages_dhConfig.class);
classStore.put(TLRPC.TL_audioEmpty.constructor, TLRPC.TL_audioEmpty.class);
classStore.put(TLRPC.TL_audio.constructor, TLRPC.TL_audio.class);
classStore.put(TLRPC.TL_destroy_sessions_res.constructor, TLRPC.TL_destroy_sessions_res.class);
classStore.put(TLRPC.TL_privacyValueAllowUsers.constructor, TLRPC.TL_privacyValueAllowUsers.class);
classStore.put(TLRPC.TL_privacyValueDisallowAll.constructor, TLRPC.TL_privacyValueDisallowAll.class);
classStore.put(TLRPC.TL_privacyValueAllowContacts.constructor, TLRPC.TL_privacyValueAllowContacts.class);
classStore.put(TLRPC.TL_privacyValueDisallowContacts.constructor, TLRPC.TL_privacyValueDisallowContacts.class);
classStore.put(TLRPC.TL_privacyValueAllowAll.constructor, TLRPC.TL_privacyValueAllowAll.class);
classStore.put(TLRPC.TL_privacyValueDisallowUsers.constructor, TLRPC.TL_privacyValueDisallowUsers.class);
classStore.put(TLRPC.TL_contacts_contacts.constructor, TLRPC.TL_contacts_contacts.class);
classStore.put(TLRPC.TL_contacts_contactsNotModified.constructor, TLRPC.TL_contacts_contactsNotModified.class);
classStore.put(TLRPC.TL_inputPrivacyKeyStatusTimestamp.constructor, TLRPC.TL_inputPrivacyKeyStatusTimestamp.class);
classStore.put(TLRPC.TL_photos_photos.constructor, TLRPC.TL_photos_photos.class);
classStore.put(TLRPC.TL_photos_photosSlice.constructor, TLRPC.TL_photos_photosSlice.class);
classStore.put(TLRPC.TL_chatFull.constructor, TLRPC.TL_chatFull.class);
classStore.put(TLRPC.TL_msgs_all_info.constructor, TLRPC.TL_msgs_all_info.class);
classStore.put(TLRPC.TL_inputPeerNotifySettings.constructor, TLRPC.TL_inputPeerNotifySettings.class);
classStore.put(TLRPC.TL_null.constructor, TLRPC.TL_null.class);
classStore.put(TLRPC.TL_inputUserSelf.constructor, TLRPC.TL_inputUserSelf.class);
classStore.put(TLRPC.TL_inputUserForeign.constructor, TLRPC.TL_inputUserForeign.class);
classStore.put(TLRPC.TL_inputUserEmpty.constructor, TLRPC.TL_inputUserEmpty.class);
classStore.put(TLRPC.TL_inputUserContact.constructor, TLRPC.TL_inputUserContact.class);
classStore.put(TLRPC.TL_p_q_inner_data.constructor, TLRPC.TL_p_q_inner_data.class);
classStore.put(TLRPC.TL_msgs_state_req.constructor, TLRPC.TL_msgs_state_req.class);
classStore.put(TLRPC.TL_boolTrue.constructor, TLRPC.TL_boolTrue.class);
classStore.put(TLRPC.TL_boolFalse.constructor, TLRPC.TL_boolFalse.class);
classStore.put(TLRPC.TL_auth_exportedAuthorization.constructor, TLRPC.TL_auth_exportedAuthorization.class);
classStore.put(TLRPC.TL_inputNotifyChats.constructor, TLRPC.TL_inputNotifyChats.class);
classStore.put(TLRPC.TL_inputNotifyPeer.constructor, TLRPC.TL_inputNotifyPeer.class);
classStore.put(TLRPC.TL_inputNotifyUsers.constructor, TLRPC.TL_inputNotifyUsers.class);
classStore.put(TLRPC.TL_inputNotifyGeoChatPeer.constructor, TLRPC.TL_inputNotifyGeoChatPeer.class);
classStore.put(TLRPC.TL_inputNotifyAll.constructor, TLRPC.TL_inputNotifyAll.class);
classStore.put(TLRPC.TL_inputAudioFileLocation.constructor, TLRPC.TL_inputAudioFileLocation.class);
classStore.put(TLRPC.TL_inputEncryptedFileLocation.constructor, TLRPC.TL_inputEncryptedFileLocation.class);
classStore.put(TLRPC.TL_inputVideoFileLocation.constructor, TLRPC.TL_inputVideoFileLocation.class);
classStore.put(TLRPC.TL_inputDocumentFileLocation.constructor, TLRPC.TL_inputDocumentFileLocation.class);
classStore.put(TLRPC.TL_inputFileLocation.constructor, TLRPC.TL_inputFileLocation.class);
classStore.put(TLRPC.TL_photos_photo.constructor, TLRPC.TL_photos_photo.class);
classStore.put(TLRPC.TL_userContact.constructor, TLRPC.TL_userContact.class);
classStore.put(TLRPC.TL_userRequest.constructor, TLRPC.TL_userRequest.class);
classStore.put(TLRPC.TL_userForeign.constructor, TLRPC.TL_userForeign.class);
classStore.put(TLRPC.TL_userDeleted.constructor, TLRPC.TL_userDeleted.class);
classStore.put(TLRPC.TL_userSelf.constructor, TLRPC.TL_userSelf.class);
classStore.put(TLRPC.TL_userEmpty.constructor, TLRPC.TL_userEmpty.class);
classStore.put(TLRPC.TL_geoChatMessage.constructor, TLRPC.TL_geoChatMessage.class);
classStore.put(TLRPC.TL_geoChatMessageService.constructor, TLRPC.TL_geoChatMessageService.class);
classStore.put(TLRPC.TL_geoChatMessageEmpty.constructor, TLRPC.TL_geoChatMessageEmpty.class);
classStore.put(TLRPC.TL_pong.constructor, TLRPC.TL_pong.class);
classStore.put(TLRPC.TL_messageActionChatEditPhoto.constructor, TLRPC.TL_messageActionChatEditPhoto.class);
classStore.put(TLRPC.TL_messageActionChatDeleteUser.constructor, TLRPC.TL_messageActionChatDeleteUser.class);
classStore.put(TLRPC.TL_messageActionChatDeletePhoto.constructor, TLRPC.TL_messageActionChatDeletePhoto.class);
classStore.put(TLRPC.TL_messageActionChatAddUser.constructor, TLRPC.TL_messageActionChatAddUser.class);
classStore.put(TLRPC.TL_messageActionChatCreate.constructor, TLRPC.TL_messageActionChatCreate.class);
classStore.put(TLRPC.TL_messageActionEmpty.constructor, TLRPC.TL_messageActionEmpty.class);
classStore.put(TLRPC.TL_messageActionChatEditTitle.constructor, TLRPC.TL_messageActionChatEditTitle.class);
classStore.put(TLRPC.TL_messageActionGeoChatCreate.constructor, TLRPC.TL_messageActionGeoChatCreate.class);
classStore.put(TLRPC.TL_messageActionGeoChatCheckin.constructor, TLRPC.TL_messageActionGeoChatCheckin.class);
classStore.put(TLRPC.TL_dh_gen_retry.constructor, TLRPC.TL_dh_gen_retry.class);
classStore.put(TLRPC.TL_dh_gen_fail.constructor, TLRPC.TL_dh_gen_fail.class);
classStore.put(TLRPC.TL_dh_gen_ok.constructor, TLRPC.TL_dh_gen_ok.class);
classStore.put(TLRPC.TL_peerNotifyEventsEmpty.constructor, TLRPC.TL_peerNotifyEventsEmpty.class);
classStore.put(TLRPC.TL_peerNotifyEventsAll.constructor, TLRPC.TL_peerNotifyEventsAll.class);
classStore.put(TLRPC.TL_chatLocated.constructor, TLRPC.TL_chatLocated.class);
classStore.put(TLRPC.TL_decryptedMessageService.constructor, TLRPC.TL_decryptedMessageService.class);
classStore.put(TLRPC.TL_decryptedMessage.constructor, TLRPC.TL_decryptedMessage.class);
classStore.put(TLRPC.TL_inputPeerNotifyEventsAll.constructor, TLRPC.TL_inputPeerNotifyEventsAll.class);
classStore.put(TLRPC.TL_inputPeerNotifyEventsEmpty.constructor, TLRPC.TL_inputPeerNotifyEventsEmpty.class);
classStore.put(TLRPC.TL_client_DH_inner_data.constructor, TLRPC.TL_client_DH_inner_data.class);
classStore.put(TLRPC.TL_video.constructor, TLRPC.TL_video.class);
classStore.put(TLRPC.TL_videoEmpty.constructor, TLRPC.TL_videoEmpty.class);
classStore.put(TLRPC.TL_contactBlocked.constructor, TLRPC.TL_contactBlocked.class);
classStore.put(TLRPC.TL_inputDocumentEmpty.constructor, TLRPC.TL_inputDocumentEmpty.class);
classStore.put(TLRPC.TL_inputDocument.constructor, TLRPC.TL_inputDocument.class);
classStore.put(TLRPC.TL_inputAppEvent.constructor, TLRPC.TL_inputAppEvent.class);
classStore.put(TLRPC.TL_messages_affectedHistory.constructor, TLRPC.TL_messages_affectedHistory.class);
classStore.put(TLRPC.TL_documentEmpty.constructor, TLRPC.TL_documentEmpty.class);
classStore.put(TLRPC.TL_document.constructor, TLRPC.TL_document.class);
classStore.put(TLRPC.TL_inputPrivacyValueDisallowUsers.constructor, TLRPC.TL_inputPrivacyValueDisallowUsers.class);
classStore.put(TLRPC.TL_inputPrivacyValueDisallowAll.constructor, TLRPC.TL_inputPrivacyValueDisallowAll.class);
classStore.put(TLRPC.TL_inputPrivacyValueDisallowContacts.constructor, TLRPC.TL_inputPrivacyValueDisallowContacts.class);
classStore.put(TLRPC.TL_inputPrivacyValueAllowAll.constructor, TLRPC.TL_inputPrivacyValueAllowAll.class);
classStore.put(TLRPC.TL_inputPrivacyValueAllowContacts.constructor, TLRPC.TL_inputPrivacyValueAllowContacts.class);
classStore.put(TLRPC.TL_inputPrivacyValueAllowUsers.constructor, TLRPC.TL_inputPrivacyValueAllowUsers.class);
classStore.put(TLRPC.TL_inputMediaContact.constructor, TLRPC.TL_inputMediaContact.class);
classStore.put(TLRPC.TL_inputMediaUploadedThumbDocument.constructor, TLRPC.TL_inputMediaUploadedThumbDocument.class);
classStore.put(TLRPC.TL_inputMediaAudio.constructor, TLRPC.TL_inputMediaAudio.class);
classStore.put(TLRPC.TL_inputMediaDocument.constructor, TLRPC.TL_inputMediaDocument.class);
classStore.put(TLRPC.TL_inputMediaVideo.constructor, TLRPC.TL_inputMediaVideo.class);
classStore.put(TLRPC.TL_inputMediaGeoPoint.constructor, TLRPC.TL_inputMediaGeoPoint.class);
classStore.put(TLRPC.TL_inputMediaEmpty.constructor, TLRPC.TL_inputMediaEmpty.class);
classStore.put(TLRPC.TL_inputMediaUploadedThumbVideo.constructor, TLRPC.TL_inputMediaUploadedThumbVideo.class);
classStore.put(TLRPC.TL_inputMediaUploadedPhoto.constructor, TLRPC.TL_inputMediaUploadedPhoto.class);
classStore.put(TLRPC.TL_inputMediaUploadedAudio.constructor, TLRPC.TL_inputMediaUploadedAudio.class);
classStore.put(TLRPC.TL_inputMediaUploadedVideo.constructor, TLRPC.TL_inputMediaUploadedVideo.class);
classStore.put(TLRPC.TL_inputMediaUploadedDocument.constructor, TLRPC.TL_inputMediaUploadedDocument.class);
classStore.put(TLRPC.TL_inputMediaPhoto.constructor, TLRPC.TL_inputMediaPhoto.class);
classStore.put(TLRPC.TL_geochats_messagesSlice.constructor, TLRPC.TL_geochats_messagesSlice.class);
classStore.put(TLRPC.TL_geochats_messages.constructor, TLRPC.TL_geochats_messages.class);
classStore.put(TLRPC.TL_messages_sentMessage.constructor, TLRPC.TL_messages_sentMessage.class);
classStore.put(TLRPC.TL_messages_sentMessageLink.constructor, TLRPC.TL_messages_sentMessageLink.class);
classStore.put(TLRPC.TL_encryptedMessageService.constructor, TLRPC.TL_encryptedMessageService.class);
classStore.put(TLRPC.TL_encryptedMessage.constructor, TLRPC.TL_encryptedMessage.class);
classStore.put(TLRPC.TL_contactSuggested.constructor, TLRPC.TL_contactSuggested.class);
classStore.put(TLRPC.TL_server_DH_params_fail.constructor, TLRPC.TL_server_DH_params_fail.class);
classStore.put(TLRPC.TL_server_DH_params_ok.constructor, TLRPC.TL_server_DH_params_ok.class);
classStore.put(TLRPC.TL_userStatusOffline.constructor, TLRPC.TL_userStatusOffline.class);
classStore.put(TLRPC.TL_userStatusLastWeek.constructor, TLRPC.TL_userStatusLastWeek.class);
classStore.put(TLRPC.TL_userStatusEmpty.constructor, TLRPC.TL_userStatusEmpty.class);
classStore.put(TLRPC.TL_userStatusLastMonth.constructor, TLRPC.TL_userStatusLastMonth.class);
classStore.put(TLRPC.TL_userStatusOnline.constructor, TLRPC.TL_userStatusOnline.class);
classStore.put(TLRPC.TL_userStatusRecently.constructor, TLRPC.TL_userStatusRecently.class);
classStore.put(TLRPC.TL_msg_copy.constructor, TLRPC.TL_msg_copy.class);
classStore.put(TLRPC.TL_contacts_importedContacts.constructor, TLRPC.TL_contacts_importedContacts.class);
classStore.put(TLRPC.TL_disabledFeature.constructor, TLRPC.TL_disabledFeature.class);
classStore.put(TLRPC.TL_server_DH_inner_data.constructor, TLRPC.TL_server_DH_inner_data.class);
classStore.put(TLRPC.TL_msgs_ack.constructor, TLRPC.TL_msgs_ack.class);
classStore.put(TLRPC.TL_futureSalt.constructor, TLRPC.TL_futureSalt.class);
classStore.put(TLRPC.TL_updateEncryptedMessagesRead.constructor, TLRPC.TL_updateEncryptedMessagesRead.class);
classStore.put(TLRPC.TL_updateContactLink.constructor, TLRPC.TL_updateContactLink.class);
classStore.put(TLRPC.TL_updateReadMessages.constructor, TLRPC.TL_updateReadMessages.class);
classStore.put(TLRPC.TL_updateChatParticipantDelete.constructor, TLRPC.TL_updateChatParticipantDelete.class);
classStore.put(TLRPC.TL_updateServiceNotification.constructor, TLRPC.TL_updateServiceNotification.class);
classStore.put(TLRPC.TL_updateNotifySettings.constructor, TLRPC.TL_updateNotifySettings.class);
classStore.put(TLRPC.TL_updateUserTyping.constructor, TLRPC.TL_updateUserTyping.class);
classStore.put(TLRPC.TL_updateChatUserTyping.constructor, TLRPC.TL_updateChatUserTyping.class);
classStore.put(TLRPC.TL_updateUserName.constructor, TLRPC.TL_updateUserName.class);
classStore.put(TLRPC.TL_updateNewEncryptedMessage.constructor, TLRPC.TL_updateNewEncryptedMessage.class);
classStore.put(TLRPC.TL_updateNewMessage.constructor, TLRPC.TL_updateNewMessage.class);
classStore.put(TLRPC.TL_updateMessageID.constructor, TLRPC.TL_updateMessageID.class);
classStore.put(TLRPC.TL_updateDeleteMessages.constructor, TLRPC.TL_updateDeleteMessages.class);
classStore.put(TLRPC.TL_updateEncryptedChatTyping.constructor, TLRPC.TL_updateEncryptedChatTyping.class);
classStore.put(TLRPC.TL_updateDcOptions.constructor, TLRPC.TL_updateDcOptions.class);
classStore.put(TLRPC.TL_updateChatParticipants.constructor, TLRPC.TL_updateChatParticipants.class);
classStore.put(TLRPC.TL_updatePrivacy.constructor, TLRPC.TL_updatePrivacy.class);
classStore.put(TLRPC.TL_updateEncryption.constructor, TLRPC.TL_updateEncryption.class);
classStore.put(TLRPC.TL_updateUserBlocked.constructor, TLRPC.TL_updateUserBlocked.class);
classStore.put(TLRPC.TL_updateActivation.constructor, TLRPC.TL_updateActivation.class);
classStore.put(TLRPC.TL_updateNewAuthorization.constructor, TLRPC.TL_updateNewAuthorization.class);
classStore.put(TLRPC.TL_updateNewGeoChatMessage.constructor, TLRPC.TL_updateNewGeoChatMessage.class);
classStore.put(TLRPC.TL_updateUserPhoto.constructor, TLRPC.TL_updateUserPhoto.class);
classStore.put(TLRPC.TL_updateContactRegistered.constructor, TLRPC.TL_updateContactRegistered.class);
classStore.put(TLRPC.TL_updateChatParticipantAdd.constructor, TLRPC.TL_updateChatParticipantAdd.class);
classStore.put(TLRPC.TL_updateUserStatus.constructor, TLRPC.TL_updateUserStatus.class);
classStore.put(TLRPC.TL_contacts_suggested.constructor, TLRPC.TL_contacts_suggested.class);
classStore.put(TLRPC.TL_msg_resend_req.constructor, TLRPC.TL_msg_resend_req.class);
classStore.put(TLRPC.TL_rpc_error.constructor, TLRPC.TL_rpc_error.class);
classStore.put(TLRPC.TL_rpc_req_error.constructor, TLRPC.TL_rpc_req_error.class);
classStore.put(TLRPC.TL_inputEncryptedFile.constructor, TLRPC.TL_inputEncryptedFile.class);
classStore.put(TLRPC.TL_inputEncryptedFileBigUploaded.constructor, TLRPC.TL_inputEncryptedFileBigUploaded.class);
classStore.put(TLRPC.TL_inputEncryptedFileEmpty.constructor, TLRPC.TL_inputEncryptedFileEmpty.class);
classStore.put(TLRPC.TL_inputEncryptedFileUploaded.constructor, TLRPC.TL_inputEncryptedFileUploaded.class);
classStore.put(TLRPC.TL_decryptedMessageActionFlushHistory.constructor, TLRPC.TL_decryptedMessageActionFlushHistory.class);
classStore.put(TLRPC.TL_decryptedMessageActionResend.constructor, TLRPC.TL_decryptedMessageActionResend.class);
classStore.put(TLRPC.TL_decryptedMessageActionNotifyLayer.constructor, TLRPC.TL_decryptedMessageActionNotifyLayer.class);
classStore.put(TLRPC.TL_decryptedMessageActionSetMessageTTL.constructor, TLRPC.TL_decryptedMessageActionSetMessageTTL.class);
classStore.put(TLRPC.TL_decryptedMessageActionDeleteMessages.constructor, TLRPC.TL_decryptedMessageActionDeleteMessages.class);
classStore.put(TLRPC.TL_decryptedMessageActionTyping.constructor, TLRPC.TL_decryptedMessageActionTyping.class);
classStore.put(TLRPC.TL_decryptedMessageActionReadMessages.constructor, TLRPC.TL_decryptedMessageActionReadMessages.class);
classStore.put(TLRPC.TL_decryptedMessageActionScreenshotMessages.constructor, TLRPC.TL_decryptedMessageActionScreenshotMessages.class);
classStore.put(TLRPC.TL_server_DH_inner_data.constructor, TLRPC.TL_server_DH_inner_data.class);
classStore.put(TLRPC.TL_decryptedMessageService.constructor, TLRPC.TL_decryptedMessageService.class);
classStore.put(TLRPC.TL_decryptedMessage.constructor, TLRPC.TL_decryptedMessage.class);
classStore.put(TLRPC.TL_bad_msg_notification.constructor, TLRPC.TL_bad_msg_notification.class);
classStore.put(TLRPC.TL_bad_server_salt.constructor, TLRPC.TL_bad_server_salt.class);
classStore.put(TLRPC.TL_new_session_created.constructor, TLRPC.TL_new_session_created.class);
classStore.put(TLRPC.TL_account_password.constructor, TLRPC.TL_account_password.class);
classStore.put(TLRPC.TL_account_noPassword.constructor, TLRPC.TL_account_noPassword.class);
classStore.put(TLRPC.TL_userProfilePhotoEmpty.constructor, TLRPC.TL_userProfilePhotoEmpty.class);
classStore.put(TLRPC.TL_userProfilePhoto.constructor, TLRPC.TL_userProfilePhoto.class);
classStore.put(TLRPC.TL_photo.constructor, TLRPC.TL_photo.class);
classStore.put(TLRPC.TL_photoEmpty.constructor, TLRPC.TL_photoEmpty.class);
classStore.put(TLRPC.TL_encryptedChatWaiting.constructor, TLRPC.TL_encryptedChatWaiting.class);
classStore.put(TLRPC.TL_encryptedChatEmpty.constructor, TLRPC.TL_encryptedChatEmpty.class);
classStore.put(TLRPC.TL_encryptedChatDiscarded.constructor, TLRPC.TL_encryptedChatDiscarded.class);
classStore.put(TLRPC.TL_encryptedChat.constructor, TLRPC.TL_encryptedChat.class);
classStore.put(TLRPC.TL_encryptedChatRequested.constructor, TLRPC.TL_encryptedChatRequested.class);
classStore.put(TLRPC.TL_geochats_statedMessage.constructor, TLRPC.TL_geochats_statedMessage.class);
classStore.put(TLRPC.TL_contact.constructor, TLRPC.TL_contact.class);
classStore.put(TLRPC.TL_config.constructor, TLRPC.TL_config.class);
classStore.put(TLRPC.TL_inputAudio.constructor, TLRPC.TL_inputAudio.class);
classStore.put(TLRPC.TL_inputAudioEmpty.constructor, TLRPC.TL_inputAudioEmpty.class);
classStore.put(TLRPC.TL_help_support.constructor, TLRPC.TL_help_support.class);
classStore.put(TLRPC.TL_messages_chats.constructor, TLRPC.TL_messages_chats.class);
classStore.put(TLRPC.TL_contacts_found.constructor, TLRPC.TL_contacts_found.class);
classStore.put(TLRPC.TL_chatParticipants.constructor, TLRPC.TL_chatParticipants.class);
classStore.put(TLRPC.TL_chatParticipantsForbidden.constructor, TLRPC.TL_chatParticipantsForbidden.class);
classStore.put(TLRPC.TL_decryptedMessageMediaDocument.constructor, TLRPC.TL_decryptedMessageMediaDocument.class);
classStore.put(TLRPC.TL_decryptedMessageMediaGeoPoint.constructor, TLRPC.TL_decryptedMessageMediaGeoPoint.class);
classStore.put(TLRPC.TL_decryptedMessageMediaAudio.constructor, TLRPC.TL_decryptedMessageMediaAudio.class);
classStore.put(TLRPC.TL_decryptedMessageMediaVideo.constructor, TLRPC.TL_decryptedMessageMediaVideo.class);
classStore.put(TLRPC.TL_decryptedMessageMediaContact.constructor, TLRPC.TL_decryptedMessageMediaContact.class);
classStore.put(TLRPC.TL_decryptedMessageMediaEmpty.constructor, TLRPC.TL_decryptedMessageMediaEmpty.class);
classStore.put(TLRPC.TL_decryptedMessageMediaPhoto.constructor, TLRPC.TL_decryptedMessageMediaPhoto.class);
classStore.put(TLRPC.TL_chatParticipant.constructor, TLRPC.TL_chatParticipant.class);
classStore.put(TLRPC.TL_chatForbidden.constructor, TLRPC.TL_chatForbidden.class);
classStore.put(TLRPC.TL_geoChat.constructor, TLRPC.TL_geoChat.class);
classStore.put(TLRPC.TL_chatEmpty.constructor, TLRPC.TL_chatEmpty.class);
classStore.put(TLRPC.TL_chat.constructor, TLRPC.TL_chat.class);
classStore.put(TLRPC.TL_storage_fileUnknown.constructor, TLRPC.TL_storage_fileUnknown.class);
classStore.put(TLRPC.TL_storage_fileMp4.constructor, TLRPC.TL_storage_fileMp4.class);
classStore.put(TLRPC.TL_storage_fileWebp.constructor, TLRPC.TL_storage_fileWebp.class);
classStore.put(TLRPC.TL_storage_filePng.constructor, TLRPC.TL_storage_filePng.class);
classStore.put(TLRPC.TL_storage_fileGif.constructor, TLRPC.TL_storage_fileGif.class);
classStore.put(TLRPC.TL_storage_filePdf.constructor, TLRPC.TL_storage_filePdf.class);
classStore.put(TLRPC.TL_storage_fileMp3.constructor, TLRPC.TL_storage_fileMp3.class);
classStore.put(TLRPC.TL_storage_fileJpeg.constructor, TLRPC.TL_storage_fileJpeg.class);
classStore.put(TLRPC.TL_storage_fileMov.constructor, TLRPC.TL_storage_fileMov.class);
classStore.put(TLRPC.TL_storage_filePartial.constructor, TLRPC.TL_storage_filePartial.class);
classStore.put(TLRPC.TL_inputMessagesFilterVideo.constructor, TLRPC.TL_inputMessagesFilterVideo.class);
classStore.put(TLRPC.TL_inputMessagesFilterEmpty.constructor, TLRPC.TL_inputMessagesFilterEmpty.class);
classStore.put(TLRPC.TL_inputMessagesFilterPhotos.constructor, TLRPC.TL_inputMessagesFilterPhotos.class);
classStore.put(TLRPC.TL_inputMessagesFilterPhotoVideo.constructor, TLRPC.TL_inputMessagesFilterPhotoVideo.class);
classStore.put(TLRPC.TL_inputMessagesFilterDocument.constructor, TLRPC.TL_inputMessagesFilterDocument.class);
classStore.put(TLRPC.TL_inputMessagesFilterAudio.constructor, TLRPC.TL_inputMessagesFilterAudio.class);
classStore.put(TLRPC.TL_msgs_state_info.constructor, TLRPC.TL_msgs_state_info.class);
classStore.put(TLRPC.TL_upload_file.constructor, TLRPC.TL_upload_file.class);
classStore.put(TLRPC.TL_dialog.constructor, TLRPC.TL_dialog.class);
classStore.put(TLRPC.TL_fileLocation.constructor, TLRPC.TL_fileLocation.class);
classStore.put(TLRPC.TL_fileLocationUnavailable.constructor, TLRPC.TL_fileLocationUnavailable.class);
classStore.put(TLRPC.TL_messages_messageEmpty.constructor, TLRPC.TL_messages_messageEmpty.class);
classStore.put(TLRPC.TL_messages_message.constructor, TLRPC.TL_messages_message.class);
classStore.put(TLRPC.TL_geochats_located.constructor, TLRPC.TL_geochats_located.class);
classStore.put(TLRPC.TL_inputGeoChat.constructor, TLRPC.TL_inputGeoChat.class);
classStore.put(TLRPC.TL_protoMessage.constructor, TLRPC.TL_protoMessage.class);
classStore.put(TLRPC.TL_photoSize.constructor, TLRPC.TL_photoSize.class);
classStore.put(TLRPC.TL_photoSizeEmpty.constructor, TLRPC.TL_photoSizeEmpty.class);
classStore.put(TLRPC.TL_photoCachedSize.constructor, TLRPC.TL_photoCachedSize.class);
classStore.put(TLRPC.TL_contactFound.constructor, TLRPC.TL_contactFound.class);
classStore.put(TLRPC.TL_inputFileBig.constructor, TLRPC.TL_inputFileBig.class);
classStore.put(TLRPC.TL_inputFile.constructor, TLRPC.TL_inputFile.class);
classStore.put(TLRPC.TL_userFull.constructor, TLRPC.TL_userFull.class);
classStore.put(TLRPC.TL_updates_state.constructor, TLRPC.TL_updates_state.class);
classStore.put(TLRPC.TL_resPQ.constructor, TLRPC.TL_resPQ.class);
classStore.put(TLRPC.TL_config.constructor, TLRPC.TL_config.class);
classStore.put(TLRPC.TL_msg_copy.constructor, TLRPC.TL_msg_copy.class);
classStore.put(TLRPC.TL_pong.constructor, TLRPC.TL_pong.class);
classStore.put(TLRPC.TL_rpc_answer_unknown.constructor, TLRPC.TL_rpc_answer_unknown.class);
classStore.put(TLRPC.TL_rpc_answer_dropped.constructor, TLRPC.TL_rpc_answer_dropped.class);
classStore.put(TLRPC.TL_rpc_answer_dropped_running.constructor, TLRPC.TL_rpc_answer_dropped_running.class);
classStore.put(TLRPC.TL_rpc_result.constructor, TLRPC.TL_rpc_result.class);
classStore.put(TLRPC.TL_auth_exportedAuthorization.constructor, TLRPC.TL_auth_exportedAuthorization.class);
classStore.put(TLRPC.TL_destroy_session_ok.constructor, TLRPC.TL_destroy_session_ok.class);
classStore.put(TLRPC.TL_destroy_session_none.constructor, TLRPC.TL_destroy_session_none.class);
classStore.put(TLRPC.TL_msgs_state_req.constructor, TLRPC.TL_msgs_state_req.class);
classStore.put(TLRPC.TL_server_DH_params_fail.constructor, TLRPC.TL_server_DH_params_fail.class);
classStore.put(TLRPC.TL_server_DH_params_ok.constructor, TLRPC.TL_server_DH_params_ok.class);
classStore.put(TLRPC.TL_protoMessage.constructor, TLRPC.TL_protoMessage.class);
classStore.put(TLRPC.TL_msgs_all_info.constructor, TLRPC.TL_msgs_all_info.class);
classStore.put(TLRPC.TL_p_q_inner_data.constructor, TLRPC.TL_p_q_inner_data.class);
classStore.put(TLRPC.TL_updateShortChatMessage.constructor, TLRPC.TL_updateShortChatMessage.class);
classStore.put(TLRPC.TL_updates.constructor, TLRPC.TL_updates.class);
classStore.put(TLRPC.TL_updateShortMessage.constructor, TLRPC.TL_updateShortMessage.class);
classStore.put(TLRPC.TL_updateShort.constructor, TLRPC.TL_updateShort.class);
classStore.put(TLRPC.TL_updatesCombined.constructor, TLRPC.TL_updatesCombined.class);
classStore.put(TLRPC.TL_updatesTooLong.constructor, TLRPC.TL_updatesTooLong.class);
classStore.put(TLRPC.TL_wallPaper.constructor, TLRPC.TL_wallPaper.class);
classStore.put(TLRPC.TL_wallPaperSolid.constructor, TLRPC.TL_wallPaperSolid.class);
classStore.put(TLRPC.TL_msg_new_detailed_info.constructor, TLRPC.TL_msg_new_detailed_info.class);
classStore.put(TLRPC.TL_msg_detailed_info.constructor, TLRPC.TL_msg_detailed_info.class);
classStore.put(TLRPC.TL_inputEncryptedChat.constructor, TLRPC.TL_inputEncryptedChat.class);
classStore.put(TLRPC.TL_inputChatPhoto.constructor, TLRPC.TL_inputChatPhoto.class);
classStore.put(TLRPC.TL_inputChatPhotoEmpty.constructor, TLRPC.TL_inputChatPhotoEmpty.class);
classStore.put(TLRPC.TL_inputChatUploadedPhoto.constructor, TLRPC.TL_inputChatUploadedPhoto.class);
classStore.put(TLRPC.TL_inputVideoEmpty.constructor, TLRPC.TL_inputVideoEmpty.class);
classStore.put(TLRPC.TL_inputVideo.constructor, TLRPC.TL_inputVideo.class);
classStore.put(TLRPC.TL_nearestDc.constructor, TLRPC.TL_nearestDc.class);
classStore.put(TLRPC.TL_inputPhotoEmpty.constructor, TLRPC.TL_inputPhotoEmpty.class);
classStore.put(TLRPC.TL_inputPhoto.constructor, TLRPC.TL_inputPhoto.class);
classStore.put(TLRPC.TL_importedContact.constructor, TLRPC.TL_importedContact.class);
classStore.put(TLRPC.TL_accountDaysTTL.constructor, TLRPC.TL_accountDaysTTL.class);
classStore.put(TLRPC.TL_stickerPack.constructor, TLRPC.TL_stickerPack.class);
classStore.put(TLRPC.TL_messages_allStickers.constructor, TLRPC.TL_messages_allStickers.class);
classStore.put(TLRPC.TL_messages_allStickersNotModified.constructor, TLRPC.TL_messages_allStickersNotModified.class);
classStore.put(TLRPC.TL_inputPeerContact.constructor, TLRPC.TL_inputPeerContact.class);
classStore.put(TLRPC.TL_inputPeerChat.constructor, TLRPC.TL_inputPeerChat.class);
classStore.put(TLRPC.TL_inputPeerEmpty.constructor, TLRPC.TL_inputPeerEmpty.class);
classStore.put(TLRPC.TL_inputPeerSelf.constructor, TLRPC.TL_inputPeerSelf.class);
classStore.put(TLRPC.TL_inputPeerForeign.constructor, TLRPC.TL_inputPeerForeign.class);
classStore.put(TLRPC.TL_dcOption.constructor, TLRPC.TL_dcOption.class);
classStore.put(TLRPC.TL_msgs_state_info.constructor, TLRPC.TL_msgs_state_info.class);
classStore.put(TLRPC.TL_decryptedMessageLayer.constructor, TLRPC.TL_decryptedMessageLayer.class);
classStore.put(TLRPC.TL_inputPhotoCropAuto.constructor, TLRPC.TL_inputPhotoCropAuto.class);
classStore.put(TLRPC.TL_inputPhotoCrop.constructor, TLRPC.TL_inputPhotoCrop.class);
classStore.put(TLRPC.TL_messages_dialogs.constructor, TLRPC.TL_messages_dialogs.class);
classStore.put(TLRPC.TL_messages_dialogsSlice.constructor, TLRPC.TL_messages_dialogsSlice.class);
classStore.put(TLRPC.TL_account_sentChangePhoneCode.constructor, TLRPC.TL_account_sentChangePhoneCode.class);
classStore.put(TLRPC.TL_updateUserPhone.constructor, TLRPC.TL_updateUserPhone.class);
classStore.put(TLRPC.TL_decryptedMessageActionRequestKey.constructor, TLRPC.TL_decryptedMessageActionRequestKey.class);
classStore.put(TLRPC.TL_decryptedMessageActionAcceptKey.constructor, TLRPC.TL_decryptedMessageActionAcceptKey.class);
classStore.put(TLRPC.TL_decryptedMessageActionCommitKey.constructor, TLRPC.TL_decryptedMessageActionCommitKey.class);
classStore.put(TLRPC.TL_decryptedMessageActionAbortKey.constructor, TLRPC.TL_decryptedMessageActionAbortKey.class);
classStore.put(TLRPC.TL_decryptedMessageActionNoop.constructor, TLRPC.TL_decryptedMessageActionNoop.class);
classStore.put(TLRPC.TL_decryptedMessageMediaExternalDocument.constructor, TLRPC.TL_decryptedMessageMediaExternalDocument.class);
classStore.put(TLRPC.TL_updateReadHistoryInbox.constructor, TLRPC.TL_updateReadHistoryInbox.class);
classStore.put(TLRPC.TL_updateReadHistoryOutbox.constructor, TLRPC.TL_updateReadHistoryOutbox.class);
classStore.put(TLRPC.TL_contactLinkUnknown.constructor, TLRPC.TL_contactLinkUnknown.class);
classStore.put(TLRPC.TL_contactLinkNone.constructor, TLRPC.TL_contactLinkNone.class);
classStore.put(TLRPC.TL_contactLinkHasPhone.constructor, TLRPC.TL_contactLinkHasPhone.class);
classStore.put(TLRPC.TL_contactLinkContact.constructor, TLRPC.TL_contactLinkContact.class);
classStore.put(TLRPC.TL_messages_affectedMessages.constructor, TLRPC.TL_messages_affectedMessages.class);
classStore.put(TLRPC.TL_updateWebPage.constructor, TLRPC.TL_updateWebPage.class);
classStore.put(TLRPC.TL_webPagePending.constructor, TLRPC.TL_webPagePending.class);
classStore.put(TLRPC.TL_webPageEmpty.constructor, TLRPC.TL_webPageEmpty.class);
classStore.put(TLRPC.TL_webPage.constructor, TLRPC.TL_webPage.class);
classStore.put(TLRPC.TL_messageMediaWebPage.constructor, TLRPC.TL_messageMediaWebPage.class);
classStore.put(TLRPC.TL_authorization.constructor, TLRPC.TL_authorization.class);
classStore.put(TLRPC.TL_account_authorizations.constructor, TLRPC.TL_account_authorizations.class);
classStore.put(TLRPC.TL_account_passwordSettings.constructor, TLRPC.TL_account_passwordSettings.class);
classStore.put(TLRPC.TL_account_passwordInputSettings.constructor, TLRPC.TL_account_passwordInputSettings.class);
classStore.put(TLRPC.TL_auth_passwordRecovery.constructor, TLRPC.TL_auth_passwordRecovery.class);
classStore.put(TLRPC.TL_messages_getWebPagePreview.constructor, TLRPC.TL_messages_getWebPagePreview.class);
classStore.put(TLRPC.TL_messageMediaUnsupported_old.constructor, TLRPC.TL_messageMediaUnsupported_old.class);
classStore.put(TLRPC.TL_userSelf_old2.constructor, TLRPC.TL_userSelf_old2.class);
classStore.put(TLRPC.TL_msg_container.constructor, TLRPC.TL_msg_container.class);
classStore.put(TLRPC.TL_fileEncryptedLocation.constructor, TLRPC.TL_fileEncryptedLocation.class);
classStore.put(TLRPC.TL_messageActionTTLChange.constructor, TLRPC.TL_messageActionTTLChange.class);
classStore.put(TLRPC.TL_videoEncrypted.constructor, TLRPC.TL_videoEncrypted.class);
classStore.put(TLRPC.TL_documentEncrypted.constructor, TLRPC.TL_documentEncrypted.class);
classStore.put(TLRPC.TL_audioEncrypted.constructor, TLRPC.TL_audioEncrypted.class);
classStore.put(TLRPC.TL_http_wait.constructor, TLRPC.TL_http_wait.class);
classStore.put(TLRPC.TL_gzip_packed.constructor, TLRPC.TL_gzip_packed.class);
classStore.put(TLRPC.Vector.constructor, TLRPC.Vector.class);
classStore.put(TLRPC.TL_userProfilePhotoOld.constructor, TLRPC.TL_userProfilePhotoOld.class);
classStore.put(TLRPC.TL_messageActionUserUpdatedPhoto.constructor, TLRPC.TL_messageActionUserUpdatedPhoto.class);
classStore.put(TLRPC.TL_messageActionUserJoined.constructor, TLRPC.TL_messageActionUserJoined.class);
classStore.put(TLRPC.TL_messageActionLoginUnknownLocation.constructor, TLRPC.TL_messageActionLoginUnknownLocation.class);
classStore.put(TLRPC.TL_encryptedChat_old.constructor, TLRPC.TL_encryptedChat_old.class);
classStore.put(TLRPC.TL_encryptedChatRequested_old.constructor, TLRPC.TL_encryptedChatRequested_old.class);
classStore.put(TLRPC.TL_decryptedMessageMediaVideo_old.constructor, TLRPC.TL_decryptedMessageMediaVideo_old.class);
classStore.put(TLRPC.TL_decryptedMessageMediaAudio_old.constructor, TLRPC.TL_decryptedMessageMediaAudio_old.class);
classStore.put(TLRPC.TL_audio_old.constructor, TLRPC.TL_audio_old.class);
classStore.put(TLRPC.TL_video_old.constructor, TLRPC.TL_video_old.class);
classStore.put(TLRPC.TL_messageActionCreatedBroadcastList.constructor, TLRPC.TL_messageActionCreatedBroadcastList.class);
classStore.put(TLRPC.TL_messageForwarded_old.constructor, TLRPC.TL_messageForwarded_old.class);
classStore.put(TLRPC.TL_message_old.constructor, TLRPC.TL_message_old.class);
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);
classStore.put(TLRPC.TL_userSelf_old.constructor, TLRPC.TL_userSelf_old.class);
classStore.put(TLRPC.TL_userContact_old.constructor, TLRPC.TL_userContact_old.class);
classStore.put(TLRPC.TL_userRequest_old.constructor, TLRPC.TL_userRequest_old.class);
classStore.put(TLRPC.TL_userForeign_old.constructor, TLRPC.TL_userForeign_old.class);
classStore.put(TLRPC.TL_userDeleted_old.constructor, TLRPC.TL_userDeleted_old.class);
classStore.put(TLRPC.TL_messageEncryptedAction.constructor, TLRPC.TL_messageEncryptedAction.class);
classStore.put(TLRPC.TL_decryptedMessageHolder.constructor, TLRPC.TL_decryptedMessageHolder.class);
classStore.put(TLRPC.TL_client_DH_inner_data.constructor, TLRPC.TL_client_DH_inner_data.class);
classStore.put(TLRPC.TL_null.constructor, TLRPC.TL_null.class);
classStore.put(TLRPC.TL_destroy_sessions_res.constructor, TLRPC.TL_destroy_sessions_res.class);
classStore.put(TLRPC.TL_msg_container.constructor, TLRPC.TL_msg_container.class);
classStore.put(TLRPC.TL_video.constructor, TLRPC.TL_video.class);
classStore.put(TLRPC.TL_videoEmpty.constructor, TLRPC.TL_videoEmpty.class);
classStore.put(TLRPC.TL_video_old2.constructor, TLRPC.TL_video_old2.class);
classStore.put(TLRPC.TL_video_old.constructor, TLRPC.TL_video_old.class);
classStore.put(TLRPC.TL_videoEncrypted.constructor, TLRPC.TL_videoEncrypted.class);
classStore.put(TLRPC.TL_audio.constructor, TLRPC.TL_audio.class);
classStore.put(TLRPC.TL_audioEncrypted.constructor, TLRPC.TL_audioEncrypted.class);
classStore.put(TLRPC.TL_audioEmpty.constructor, TLRPC.TL_audioEmpty.class);
classStore.put(TLRPC.TL_audio_old.constructor, TLRPC.TL_audio_old.class);
classStore.put(TLRPC.TL_document.constructor, TLRPC.TL_document.class);
classStore.put(TLRPC.TL_documentEmpty.constructor, TLRPC.TL_documentEmpty.class);
classStore.put(TLRPC.TL_documentEncrypted_old.constructor, TLRPC.TL_documentEncrypted_old.class);
classStore.put(TLRPC.TL_documentEncrypted.constructor, TLRPC.TL_documentEncrypted.class);
classStore.put(TLRPC.TL_document_old.constructor, TLRPC.TL_document_old.class);
classStore.put(TLRPC.TL_config_old.constructor, TLRPC.TL_config_old.class);
classStore.put(TLRPC.TL_messageForwarded_old2.constructor, TLRPC.TL_messageForwarded_old2.class);
classStore.put(TLRPC.TL_message_old2.constructor, TLRPC.TL_message_old2.class);
classStore.put(TLRPC.TL_documentAttributeSticker_old.constructor, TLRPC.TL_documentAttributeSticker_old.class);
classStore.put(TLRPC.TL_photo.constructor, TLRPC.TL_photo.class);
classStore.put(TLRPC.TL_photoEmpty.constructor, TLRPC.TL_photoEmpty.class);
classStore.put(TLRPC.TL_photoSize.constructor, TLRPC.TL_photoSize.class);
classStore.put(TLRPC.TL_photoSizeEmpty.constructor, TLRPC.TL_photoSizeEmpty.class);
classStore.put(TLRPC.TL_photoCachedSize.constructor, TLRPC.TL_photoCachedSize.class);
classStore.put(TLRPC.TL_photo_old.constructor, TLRPC.TL_photo_old.class);
}
static TLClassStore store = null;
@ -436,46 +107,27 @@ public class TLClassStore {
return store;
}
public TLObject TLdeserialize(AbsSerializedData stream, int constructor) {
public TLObject TLdeserialize(AbsSerializedData stream, int constructor, boolean exception) {
try {
return TLdeserialize(stream, constructor, null);
return TLdeserialize(stream, constructor, null, exception);
} catch (Exception e) {
return null;
}
}
public TLObject TLdeserialize(AbsSerializedData stream, int constructor, TLObject request) {
public TLObject TLdeserialize(AbsSerializedData stream, int constructor, TLObject request, boolean exception) {
Class objClass = classStore.get(constructor);
if (objClass != null) {
try {
TLObject response = (TLObject)objClass.newInstance();
if (response instanceof TLRPC.Vector) {
if (request != null) {
request.parseVector((TLRPC.Vector)response, stream);
} else {
int size = stream.readInt32();
for (int a = 0; a < size; a++) {
((TLRPC.Vector)response).objects.add(stream.readInt32());
}
}
} else {
response.readParams(stream);
}
response.readParams(stream, exception);
return response;
} catch (IllegalAccessException e) {
FileLog.e("tmessages", "can't create class");
return null;
} catch (InstantiationException e2) {
} catch (Throwable e) {
FileLog.e("tmessages", "can't create class");
return null;
}
} else {
FileLog.e("tmessages", String.format("unknown class %x", constructor));
if (BuildVars.DEBUG_VERSION) {
throw new RuntimeException(String.format("unknown class %x", constructor));
} else {
return null;
}
}
}
}

View File

@ -11,15 +11,15 @@ package org.telegram.messenger;
public class TLObject {
public boolean disableFree = false;
public TLObject () {
public TLObject() {
}
public void readParams(AbsSerializedData stream) {
public void readParams(AbsSerializedData stream, boolean exception) {
}
public byte[] serialize () {
public byte[] serialize() {
return null;
}
@ -27,18 +27,14 @@ public class TLObject {
}
public Class<? extends TLObject> responseClass () {
return this.getClass();
public TLObject deserializeResponse(AbsSerializedData stream, int constructor, boolean exception) {
return null;
}
public int layer () {
public int layer() {
return 11;
}
public void parseVector(TLRPC.Vector vector, AbsSerializedData data) {
}
public void freeResources() {
}

File diff suppressed because it is too large Load Diff

View File

@ -36,6 +36,7 @@ public class UserConfig {
public static int autoLockIn = 60 * 60;
public static int lastPauseTime = 0;
public static boolean isWaitingForPasscodeEnter = false;
public static int lastUpdateVersion;
public static int getNewMessageId() {
int id;
@ -71,6 +72,7 @@ public class UserConfig {
editor.putInt("passcodeType", passcodeType);
editor.putInt("autoLockIn", autoLockIn);
editor.putInt("lastPauseTime", lastPauseTime);
editor.putInt("lastUpdateVersion", lastUpdateVersion);
if (currentUser != null) {
if (withFile) {
@ -123,28 +125,28 @@ public class UserConfig {
if (configFile.exists()) {
try {
SerializedData data = new SerializedData(configFile);
int ver = data.readInt32();
int ver = data.readInt32(false);
if (ver == 1) {
int constructor = data.readInt32();
currentUser = (TLRPC.TL_userSelf)TLClassStore.Instance().TLdeserialize(data, constructor);
MessagesStorage.lastDateValue = data.readInt32();
MessagesStorage.lastPtsValue = data.readInt32();
MessagesStorage.lastSeqValue = data.readInt32();
registeredForPush = data.readBool();
pushString = data.readString();
lastSendMessageId = data.readInt32();
lastLocalId = data.readInt32();
contactsHash = data.readString();
importHash = data.readString();
saveIncomingPhotos = data.readBool();
int constructor = data.readInt32(false);
currentUser = TLRPC.TL_userSelf.TLdeserialize(data, constructor, false);
MessagesStorage.lastDateValue = data.readInt32(false);
MessagesStorage.lastPtsValue = data.readInt32(false);
MessagesStorage.lastSeqValue = data.readInt32(false);
registeredForPush = data.readBool(false);
pushString = data.readString(false);
lastSendMessageId = data.readInt32(false);
lastLocalId = data.readInt32(false);
contactsHash = data.readString(false);
importHash = data.readString(false);
saveIncomingPhotos = data.readBool(false);
contactsVersion = 0;
MessagesStorage.lastQtsValue = data.readInt32();
MessagesStorage.lastSecretVersion = data.readInt32();
int val = data.readInt32();
MessagesStorage.lastQtsValue = data.readInt32(false);
MessagesStorage.lastSecretVersion = data.readInt32(false);
int val = data.readInt32(false);
if (val == 1) {
MessagesStorage.secretPBytes = data.readByteArray();
MessagesStorage.secretPBytes = data.readByteArray(false);
}
MessagesStorage.secretG = data.readInt32();
MessagesStorage.secretG = data.readInt32(false);
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
@ -152,8 +154,8 @@ public class UserConfig {
}
});
} else if (ver == 2) {
int constructor = data.readInt32();
currentUser = (TLRPC.TL_userSelf)TLClassStore.Instance().TLdeserialize(data, constructor);
int constructor = data.readInt32(false);
currentUser = TLRPC.TL_userSelf.TLdeserialize(data, constructor, false);
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("userconfing", Context.MODE_PRIVATE);
registeredForPush = preferences.getBoolean("registeredForPush", false);
@ -199,12 +201,13 @@ public class UserConfig {
passcodeType = preferences.getInt("passcodeType", 0);
autoLockIn = preferences.getInt("autoLockIn", 60 * 60);
lastPauseTime = preferences.getInt("lastPauseTime", 0);
lastUpdateVersion = preferences.getInt("lastUpdateVersion", 511);
String user = preferences.getString("user", null);
if (user != null) {
byte[] userBytes = Base64.decode(user, Base64.DEFAULT);
if (userBytes != null) {
SerializedData data = new SerializedData(userBytes);
currentUser = (TLRPC.TL_userSelf)TLClassStore.Instance().TLdeserialize(data, data.readInt32());
currentUser = TLRPC.TL_userSelf.TLdeserialize(data, data.readInt32(false), false);
data.cleanup();
}
}
@ -229,6 +232,7 @@ public class UserConfig {
autoLockIn = 60 * 60;
lastPauseTime = 0;
isWaitingForPasscodeEnter = false;
lastUpdateVersion = BuildVars.BUILD_VERSION;
saveConfig(true);
}
}

View File

@ -23,7 +23,6 @@ import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.text.Html;
import android.text.SpannableStringBuilder;
import android.util.Base64;
import android.util.Log;
@ -69,6 +68,9 @@ public class Utilities {
public static Pattern pattern = Pattern.compile("[0-9]+");
public static SecureRandom random = new SecureRandom();
private static byte[] decompressBuffer;
private static ByteArrayOutputStreamExpand decompressStream;
public static ArrayList<String> goodPrimes = new ArrayList<>();
public static class TPFactorizedValue {
@ -78,7 +80,7 @@ public class Utilities {
public static volatile DispatchQueue stageQueue = new DispatchQueue("stageQueue");
public static volatile DispatchQueue globalQueue = new DispatchQueue("globalQueue");
public static volatile DispatchQueue searchQueue = new DispatchQueue("searchQueue");
public static volatile DispatchQueue photoBookQueue = new DispatchQueue("photoBookQueue");
public static volatile DispatchQueue phoneBookQueue = new DispatchQueue("photoBookQueue");
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
@ -103,9 +105,9 @@ public class Utilities {
byte[] bytes = Base64.decode(primes, Base64.DEFAULT);
if (bytes != null) {
SerializedData data = new SerializedData(bytes);
int count = data.readInt32();
int count = data.readInt32(false);
for (int a = 0; a < count; a++) {
goodPrimes.add(data.readString());
goodPrimes.add(data.readString(false));
}
data.cleanup();
}
@ -120,7 +122,7 @@ public class Utilities {
public native static long doPQNative(long _what);
public native static void loadBitmap(String path, Bitmap bitmap, int scale, int width, int height, int stride);
public native static int pinBitmap(Bitmap bitmap);
public native static void blurBitmap(Object bitmap, int radius);
public native static void blurBitmap(Object bitmap, int radius, int unpin);
public native static void calcCDT(ByteBuffer hsvBuffer, int width, int height, ByteBuffer buffer);
public native static Bitmap loadWebpImage(ByteBuffer buffer, int len, BitmapFactory.Options options);
public native static Bitmap loadBpgImage(ByteBuffer buffer, int len, BitmapFactory.Options options);
@ -422,17 +424,21 @@ public class Utilities {
return keyData;
}
public static TLObject decompress(byte[] data, TLObject parentObject) {
final int BUFFER_SIZE = 512;
public static TLObject decompress(byte[] data, TLObject parentObject, boolean exception) {
final int BUFFER_SIZE = 16384;
ByteArrayInputStream is = new ByteArrayInputStream(data);
GZIPInputStream gis;
SerializedData stream = null;
try {
if (decompressBuffer == null) {
decompressBuffer = new byte[BUFFER_SIZE];
decompressStream = new ByteArrayOutputStreamExpand(BUFFER_SIZE);
}
decompressStream.reset();
gis = new GZIPInputStream(is, BUFFER_SIZE);
ByteArrayOutputStream bytesOutput = new ByteArrayOutputStream();
data = new byte[BUFFER_SIZE];
int bytesRead;
while ((bytesRead = gis.read(data)) != -1) {
bytesOutput.write(data, 0, bytesRead);
while ((bytesRead = gis.read(decompressBuffer)) != -1) {
decompressStream.write(decompressBuffer, 0, bytesRead);
}
try {
gis.close();
@ -444,18 +450,15 @@ public class Utilities {
} catch (Exception e) {
FileLog.e("tmessages", e);
}
SerializedData stream = new SerializedData(bytesOutput.toByteArray());
try {
bytesOutput.close();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
TLObject object = TLClassStore.Instance().TLdeserialize(stream, stream.readInt32(), parentObject);
stream.cleanup();
return object;
stream = new SerializedData(decompressStream.toByteArray());
} catch (IOException e) {
FileLog.e("tmessages", e);
}
if (stream != null) {
TLObject object = ConnectionsManager.getInstance().deserialize(parentObject, stream, exception);
stream.cleanup();
return object;
}
return null;
}
@ -685,7 +688,7 @@ public class Utilities {
}
wholeString = wholeString.trim();
String lower = " " + wholeString.toLowerCase();
String hexDarkColor = String.format("#%06X", (0xFFFFFF & AndroidUtilities.getIntDarkerColor("themeColor", 0x15)));/*Search Name*/
String hexDarkColor = String.format("#%08X", (0xFFFFFFFF & AndroidUtilities.getIntDarkerColor("chatsNameColor", -0x40)));/*Search Name*/
int index = -1;
int lastIndex = 0;
while ((index = lower.indexOf(" " + q, lastIndex)) != -1) {
@ -702,9 +705,9 @@ public class Utilities {
if (query.startsWith(" ")) {
builder.append(" ");
}
query.trim();
builder.append(Html.fromHtml("<font color=" + hexDarkColor + ">" + query + "</font>"));
//builder.append(Html.fromHtml("<font color=\"#4d83b3\">" + query + "</font>"));
query = query.trim();
builder.append(AndroidUtilities.replaceTags("<c" + hexDarkColor + ">" + query + "</c>"));
//builder.append(AndroidUtilities.replaceTags("<c#ff4d83b3>" + query + "</c>"));
lastIndex = end;
}

View File

@ -24,6 +24,7 @@ import android.widget.TextView;
import org.telegram.android.AndroidUtilities;
import org.telegram.messenger.R;
import org.telegram.ui.Components.LayoutHelper;
public class ActionBar extends FrameLayout {
@ -62,8 +63,8 @@ public class ActionBar extends FrameLayout {
titleFrameLayout = new FrameLayout(context);
addView(titleFrameLayout);
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams)titleFrameLayout.getLayoutParams();
layoutParams.width = LayoutParams.WRAP_CONTENT;
layoutParams.height = LayoutParams.FILL_PARENT;
layoutParams.width = LayoutHelper.WRAP_CONTENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
titleFrameLayout.setLayoutParams(layoutParams);
titleFrameLayout.setPadding(0, 0, AndroidUtilities.dp(4), 0);
@ -97,8 +98,8 @@ public class ActionBar extends FrameLayout {
}
layoutParams = (LayoutParams) titleTextView.getLayoutParams();
layoutParams.width = LayoutParams.WRAP_CONTENT;
layoutParams.height = LayoutParams.WRAP_CONTENT;
layoutParams.width = LayoutHelper.WRAP_CONTENT;
layoutParams.height = LayoutHelper.WRAP_CONTENT;
layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
titleTextView.setLayoutParams(layoutParams);
titleTextView.measure(width, height);
@ -112,8 +113,8 @@ public class ActionBar extends FrameLayout {
}
layoutParams = (LayoutParams) subTitleTextView.getLayoutParams();
layoutParams.width = LayoutParams.WRAP_CONTENT;
layoutParams.height = LayoutParams.WRAP_CONTENT;
layoutParams.width = LayoutHelper.WRAP_CONTENT;
layoutParams.height = LayoutHelper.WRAP_CONTENT;
layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
subTitleTextView.setLayoutParams(layoutParams);
subTitleTextView.measure(width, height);
@ -133,7 +134,7 @@ public class ActionBar extends FrameLayout {
if (titleTextView != null && titleTextView.getVisibility() == VISIBLE) {
layoutParams = (LayoutParams) titleTextView.getLayoutParams();
layoutParams.width = LayoutParams.MATCH_PARENT;
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = titleTextView.getMeasuredHeight();
int y;
if (subTitleTextView != null && subTitleTextView.getVisibility() == VISIBLE) {
@ -146,7 +147,7 @@ public class ActionBar extends FrameLayout {
}
if (subTitleTextView != null && subTitleTextView.getVisibility() == VISIBLE) {
layoutParams = (LayoutParams) subTitleTextView.getLayoutParams();
layoutParams.width = LayoutParams.MATCH_PARENT;
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = subTitleTextView.getMeasuredHeight();
layoutParams.setMargins(x, height / 2 + (height / 2 - subTitleTextView.getMeasuredHeight()) / 2 - offset, 0, 0);
subTitleTextView.setLayoutParams(layoutParams);
@ -163,7 +164,7 @@ public class ActionBar extends FrameLayout {
return;
}
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams)menu.getLayoutParams();
layoutParams.width = isSearchFieldVisible ? LayoutParams.MATCH_PARENT : LayoutParams.WRAP_CONTENT;
layoutParams.width = isSearchFieldVisible ? LayoutHelper.MATCH_PARENT : LayoutHelper.WRAP_CONTENT;
layoutParams.height = height;
layoutParams.leftMargin = isSearchFieldVisible ? AndroidUtilities.dp(AndroidUtilities.isTablet() ? 74 : 66) : 0;
layoutParams.topMargin = occupyStatusBar ? AndroidUtilities.statusBarHeight : 0;
@ -277,14 +278,19 @@ public class ActionBar extends FrameLayout {
}
public void setTitle(CharSequence value) {
boolean created = false;
if (value != null && titleTextView == null) {
createTitleTextView();
created = true;
}
if (titleTextView != null) {
lastTitle = value;
titleTextView.setVisibility(value != null && !isSearchFieldVisible ? VISIBLE : INVISIBLE);
titleTextView.setText(value);
positionTitle(getMeasuredWidth(), getMeasuredHeight());
if (!created) {
titleTextView.setText(value);
}
}
}
@ -301,13 +307,13 @@ public class ActionBar extends FrameLayout {
return subTitleTextView.getCompoundDrawables()[0];
}
public CharSequence getTitle() {
public String getTitle() {
if (titleTextView == null) {
return null;
}
return titleTextView.getText();
return titleTextView.getText().toString();
}
//Plus
public void setTitleColor(int color) {
if (titleTextView == null) {
createTitleTextView();
@ -316,7 +322,6 @@ public class ActionBar extends FrameLayout {
titleTextView.setTextColor(color);
}
}
public ActionBarMenu createMenu() {
if (menu != null) {
return menu;
@ -324,8 +329,8 @@ public class ActionBar extends FrameLayout {
menu = new ActionBarMenu(getContext(), this);
addView(menu);
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams)menu.getLayoutParams();
layoutParams.height = LayoutParams.FILL_PARENT;
layoutParams.width = LayoutParams.WRAP_CONTENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
layoutParams.width = LayoutHelper.WRAP_CONTENT;
layoutParams.gravity = Gravity.RIGHT;
menu.setLayoutParams(layoutParams);
return menu;
@ -340,8 +345,8 @@ public class ActionBar extends FrameLayout {
View view = li.inflate(resourceId, null);
addView(view);
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams)view.getLayoutParams();
layoutParams.width = LayoutParams.FILL_PARENT;
layoutParams.height = LayoutParams.FILL_PARENT;
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
layoutParams.topMargin = occupyStatusBar ? AndroidUtilities.statusBarHeight : 0;
view.setLayoutParams(layoutParams);
}
@ -355,8 +360,8 @@ public class ActionBar extends FrameLayout {
addView(actionMode);
actionMode.setPadding(0, occupyStatusBar ? AndroidUtilities.statusBarHeight : 0, 0, 0);
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams)actionMode.getLayoutParams();
layoutParams.height = LayoutParams.FILL_PARENT;
layoutParams.width = LayoutParams.FILL_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.gravity = Gravity.RIGHT;
actionMode.setLayoutParams(layoutParams);
actionMode.setVisibility(INVISIBLE);
@ -367,7 +372,7 @@ public class ActionBar extends FrameLayout {
addView(actionModeTop);
layoutParams = (FrameLayout.LayoutParams)actionModeTop.getLayoutParams();
layoutParams.height = AndroidUtilities.statusBarHeight;
layoutParams.width = LayoutParams.FILL_PARENT;
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
actionModeTop.setLayoutParams(layoutParams);
actionModeTop.setVisibility(INVISIBLE);
@ -508,9 +513,7 @@ public class ActionBar extends FrameLayout {
if (backButtonImageView != null) {
backButtonImageView.setBackgroundResource(itemsBackgroundResourceId);
}
//
setBackgroundColor(AndroidUtilities.getIntColor("themeColor"));
//
setBackgroundColor(AndroidUtilities.getIntColor("themeColor")); //Plus
}
public void setCastShadows(boolean value) {

View File

@ -28,12 +28,13 @@ import android.widget.FrameLayout;
import android.widget.LinearLayout;
import org.telegram.android.AndroidUtilities;
import org.telegram.android.AnimationCompat.AnimatorListenerAdapterProxy;
import org.telegram.android.AnimationCompat.AnimatorSetProxy;
import org.telegram.android.AnimationCompat.ObjectAnimatorProxy;
import org.telegram.android.AnimationCompat.ViewProxy;
import org.telegram.android.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.ui.AnimationCompat.AnimatorListenerAdapterProxy;
import org.telegram.ui.AnimationCompat.AnimatorSetProxy;
import org.telegram.ui.AnimationCompat.ObjectAnimatorProxy;
import org.telegram.ui.AnimationCompat.ViewProxy;
import org.telegram.ui.Components.LayoutHelper;
import java.util.ArrayList;
@ -108,6 +109,8 @@ public class ActionBarLayout extends FrameLayout {
private ActionBar currentActionBar;
private AnimatorSetProxy currentAnimation;
private DecelerateInterpolator decelerateInterpolator = new DecelerateInterpolator(1.5f);
private AccelerateDecelerateInterpolator accelerateDecelerateInterpolator = new AccelerateDecelerateInterpolator();
public float innerTranslationX;
@ -128,6 +131,9 @@ public class ActionBarLayout extends FrameLayout {
private View backgroundView;
private boolean removeActionBarExtraHeight;
private float animationProgress = 0.0f;
private long lastFrameTime;
private String titleOverlayText;
private ActionBarLayoutDelegate delegate = null;
@ -151,16 +157,16 @@ public class ActionBarLayout extends FrameLayout {
containerViewBack = new LinearLayoutContainer(parentActivity);
addView(containerViewBack);
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) containerViewBack.getLayoutParams();
layoutParams.width = LayoutParams.MATCH_PARENT;
layoutParams.height = LayoutParams.MATCH_PARENT;
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
containerViewBack.setLayoutParams(layoutParams);
containerView = new LinearLayoutContainer(parentActivity);
addView(containerView);
layoutParams = (FrameLayout.LayoutParams) containerView.getLayoutParams();
layoutParams.width = LayoutParams.MATCH_PARENT;
layoutParams.height = LayoutParams.MATCH_PARENT;
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
containerView.setLayoutParams(layoutParams);
@ -347,8 +353,8 @@ public class ActionBarLayout extends FrameLayout {
}
containerViewBack.addView(fragmentView);
ViewGroup.LayoutParams layoutParams = fragmentView.getLayoutParams();
layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT;
layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT;
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
fragmentView.setLayoutParams(layoutParams);
if (!lastFragment.hasOwnBackground && fragmentView.getBackground() == null) {
fragmentView.setBackgroundColor(0xffffffff);
@ -380,7 +386,7 @@ public class ActionBarLayout extends FrameLayout {
int dx = Math.max(0, (int) (ev.getX() - startedTrackingX));
int dy = Math.abs((int) ev.getY() - startedTrackingY);
velocityTracker.addMovement(ev);
if (maybeStartTracking && !startedTracking && dx >= AndroidUtilities.getPixelsInCM(0.3f, true) && Math.abs(dx) / 3 > dy) {
if (maybeStartTracking && !startedTracking && dx >= AndroidUtilities.getPixelsInCM(0.4f, true) && Math.abs(dx) / 3 > dy) {
prepareForMoving(ev);
} else if (startedTracking) {
if (!beginTrackingSent) {
@ -399,10 +405,10 @@ public class ActionBarLayout extends FrameLayout {
velocityTracker = VelocityTracker.obtain();
}
velocityTracker.computeCurrentVelocity(1000);
if (!startedTracking) {
if (!startedTracking && fragmentsStack.get(fragmentsStack.size() - 1).swipeBackEnabled) {
float velX = velocityTracker.getXVelocity();
float velY = velocityTracker.getYVelocity();
if (velX >= 3500 && velX > velY) {
if (velX >= 3500 && velX > Math.abs(velY)) {
prepareForMoving(ev);
if (!beginTrackingSent) {
if (((Activity) getContext()).getCurrentFocus() != null) {
@ -550,6 +556,44 @@ public class ActionBarLayout extends FrameLayout {
return presentFragment(fragment, removeLast, false, true);
}
private void startLayoutAnimation(final boolean open, final boolean first) {
if (first) {
animationProgress = 0.0f;
lastFrameTime = System.nanoTime() / 1000000;
}
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
if (first) {
transitionAnimationStartTime = System.currentTimeMillis();
}
long newTime = System.nanoTime() / 1000000;
long dt = newTime - lastFrameTime;
if (dt > 18) {
dt = 18;
}
lastFrameTime = newTime;
animationProgress += dt / 150.0f;
if (animationProgress > 1.0f) {
animationProgress = 1.0f;
}
float interpolated = decelerateInterpolator.getInterpolation(animationProgress);
if (open) {
ViewProxy.setAlpha(containerView, interpolated);
ViewProxy.setTranslationX(containerView, AndroidUtilities.dp(48) * (1.0f - interpolated));
} else {
ViewProxy.setAlpha(containerViewBack, 1.0f - interpolated);
ViewProxy.setTranslationX(containerViewBack, AndroidUtilities.dp(48) * interpolated);
}
if (animationProgress < 1) {
startLayoutAnimation(open, false);
} else {
onAnimationEndCheck(false);
}
}
});
}
public boolean presentFragment(final BaseFragment fragment, final boolean removeLast, boolean forceWithoutAnimation, boolean check) {
if (checkTransitionAnimation() || delegate != null && check && !delegate.needPresentFragment(fragment, removeLast, forceWithoutAnimation, this) || !fragment.onFragmentCreate()) {
return false;
@ -586,8 +630,8 @@ public class ActionBarLayout extends FrameLayout {
containerViewBack.addView(fragmentView);
ViewGroup.LayoutParams layoutParams = fragmentView.getLayoutParams();
layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT;
layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT;
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
fragmentView.setLayoutParams(layoutParams);
fragmentsStack.add(fragment);
fragment.onResume();
@ -615,6 +659,14 @@ public class ActionBarLayout extends FrameLayout {
if (useAlphaAnimations && fragmentsStack.size() == 1) {
presentFragmentInternalRemoveOld(removeLast, currentFragment);
transitionAnimationStartTime = System.currentTimeMillis();
transitionAnimationInProgress = true;
onOpenAnimationEndRunnable = new Runnable() {
@Override
public void run() {
fragment.onOpenAnimationEnd();
}
};
ArrayList<Object> animators = new ArrayList<>();
animators.add(ObjectAnimatorProxy.ofFloat(this, "alpha", 0.0f, 1.0f));
if (backgroundView != null) {
@ -624,7 +676,7 @@ public class ActionBarLayout extends FrameLayout {
currentAnimation = new AnimatorSetProxy();
currentAnimation.playTogether(animators);
currentAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
currentAnimation.setInterpolator(accelerateDecelerateInterpolator);
currentAnimation.setDuration(200);
currentAnimation.addListener(new AnimatorListenerAdapterProxy() {
@Override
@ -651,11 +703,12 @@ public class ActionBarLayout extends FrameLayout {
};
ViewProxy.setAlpha(containerView, 0.0f);
ViewProxy.setTranslationX(containerView, 48.0f);
currentAnimation = new AnimatorSetProxy();
startLayoutAnimation(true, true);
/*currentAnimation = new AnimatorSetProxy();
currentAnimation.playTogether(
ObjectAnimatorProxy.ofFloat(containerView, "alpha", 0.0f, 1.0f),
ObjectAnimatorProxy.ofFloat(containerView, "translationX", AndroidUtilities.dp(48), 0));
currentAnimation.setInterpolator(new DecelerateInterpolator(1.5f));
currentAnimation.setInterpolator(decelerateInterpolator);
currentAnimation.setDuration(200);
currentAnimation.addListener(new AnimatorListenerAdapterProxy() {
@Override
@ -673,7 +726,7 @@ public class ActionBarLayout extends FrameLayout {
onAnimationEndCheck(false);
}
});
currentAnimation.start();
currentAnimation.start();*/
}
} else {
if (backgroundView != null) {
@ -771,8 +824,8 @@ public class ActionBarLayout extends FrameLayout {
}
containerView.addView(fragmentView);
ViewGroup.LayoutParams layoutParams = fragmentView.getLayoutParams();
layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT;
layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT;
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
fragmentView.setLayoutParams(layoutParams);
previousFragment.onResume();
currentActionBar = previousFragment.actionBar;
@ -794,12 +847,13 @@ public class ActionBarLayout extends FrameLayout {
ViewProxy.setTranslationX(containerViewBack, 0);
}
};
startLayoutAnimation(false, true);
currentAnimation = new AnimatorSetProxy();
/*currentAnimation = new AnimatorSetProxy();
currentAnimation.playTogether(
ObjectAnimatorProxy.ofFloat(containerViewBack, "alpha", 1.0f, 0.0f),
ObjectAnimatorProxy.ofFloat(containerViewBack, "translationX", 0, AndroidUtilities.dp(48)));
currentAnimation.setInterpolator(new DecelerateInterpolator(1.5f));
currentAnimation.setInterpolator(decelerateInterpolator);
currentAnimation.setDuration(200);
currentAnimation.addListener(new AnimatorListenerAdapterProxy() {
@Override
@ -817,7 +871,7 @@ public class ActionBarLayout extends FrameLayout {
onAnimationEndCheck(false);
}
});
currentAnimation.start();
currentAnimation.start();*/
}
} else {
if (useAlphaAnimations) {
@ -846,7 +900,7 @@ public class ActionBarLayout extends FrameLayout {
currentAnimation = new AnimatorSetProxy();
currentAnimation.playTogether(animators);
currentAnimation.setInterpolator(new AccelerateDecelerateInterpolator());
currentAnimation.setInterpolator(accelerateDecelerateInterpolator);
currentAnimation.setDuration(200);
currentAnimation.addListener(new AnimatorListenerAdapterProxy() {
@Override
@ -903,8 +957,8 @@ public class ActionBarLayout extends FrameLayout {
}
containerView.addView(fragmentView);
ViewGroup.LayoutParams layoutParams = fragmentView.getLayoutParams();
layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT;
layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT;
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
fragmentView.setLayoutParams(layoutParams);
previousFragment.onResume();
currentActionBar = previousFragment.actionBar;

View File

@ -13,10 +13,10 @@ import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import org.telegram.android.AndroidUtilities;
import org.telegram.ui.Components.LayoutHelper;
public class ActionBarMenu extends LinearLayout {
@ -46,7 +46,7 @@ public class ActionBarMenu extends LinearLayout {
view.setTag(id);
addView(view);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams)view.getLayoutParams();
layoutParams.height = FrameLayout.LayoutParams.FILL_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
view.setBackgroundResource(parentActionBar.itemsBackgroundResourceId);
view.setLayoutParams(layoutParams);
view.setOnClickListener(new OnClickListener() {
@ -84,7 +84,7 @@ public class ActionBarMenu extends LinearLayout {
}
addView(menuItem);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams)menuItem.getLayoutParams();
layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
layoutParams.width = width;
menuItem.setLayoutParams(layoutParams);
menuItem.setOnClickListener(new OnClickListener() {

View File

@ -9,7 +9,6 @@
package org.telegram.ui.ActionBar;
import android.content.Context;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
@ -33,10 +32,11 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import org.telegram.android.AndroidUtilities;
import org.telegram.android.AnimationCompat.ViewProxy;
import org.telegram.android.LocaleController;
import org.telegram.messenger.R;
import org.telegram.ui.AnimationCompat.ViewProxy;
import org.telegram.ui.Components.FrameLayoutFixed;
import org.telegram.ui.Components.LayoutHelper;
import java.lang.reflect.Field;
@ -76,8 +76,8 @@ public class ActionBarMenuItem extends FrameLayoutFixed {
iconView.setScaleType(ImageView.ScaleType.CENTER);
addView(iconView);
LayoutParams layoutParams = (LayoutParams) iconView.getLayoutParams();
layoutParams.width = LayoutParams.MATCH_PARENT;
layoutParams.height = LayoutParams.MATCH_PARENT;
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
iconView.setLayoutParams(layoutParams);
}
@ -218,7 +218,7 @@ public class ActionBarMenuItem extends FrameLayoutFixed {
if (LocaleController.isRTL) {
layoutParams.gravity = Gravity.RIGHT;
}
layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT;
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = AndroidUtilities.dp(48);
textView.setLayoutParams(layoutParams);
textView.setOnClickListener(new OnClickListener() {
@ -251,7 +251,7 @@ public class ActionBarMenuItem extends FrameLayoutFixed {
return;
}
if (popupWindow == null) {
popupWindow = new ActionBarPopupWindow(popupLayout, FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
popupWindow = new ActionBarPopupWindow(popupLayout, LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT);
//popupWindow.setBackgroundDrawable(new BitmapDrawable());
popupWindow.setAnimationStyle(R.style.PopupAnimation);
popupWindow.setOutsideTouchable(true);
@ -352,7 +352,7 @@ public class ActionBarMenuItem extends FrameLayoutFixed {
public void setIcon(int resId) {
iconView.setImageResource(resId);
}
//Plus
public void setIcon(Drawable drawable) {
iconView.setImageDrawable(drawable);
}
@ -368,7 +368,7 @@ public class ActionBarMenuItem extends FrameLayoutFixed {
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams)searchContainer.getLayoutParams();
layoutParams.weight = 1;
layoutParams.width = 0;
layoutParams.height = LinearLayout.LayoutParams.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
layoutParams.leftMargin = AndroidUtilities.dp(6);
searchContainer.setLayoutParams(layoutParams);
searchContainer.setVisibility(GONE);
@ -452,7 +452,7 @@ public class ActionBarMenuItem extends FrameLayoutFixed {
}
searchContainer.addView(searchField);
FrameLayout.LayoutParams layoutParams2 = (FrameLayout.LayoutParams) searchField.getLayoutParams();
layoutParams2.width = FrameLayout.LayoutParams.MATCH_PARENT;
layoutParams2.width = LayoutHelper.MATCH_PARENT;
layoutParams2.gravity = Gravity.CENTER_VERTICAL;
layoutParams2.height = AndroidUtilities.dp(36);
layoutParams2.rightMargin = AndroidUtilities.dp(48);
@ -472,7 +472,7 @@ public class ActionBarMenuItem extends FrameLayoutFixed {
layoutParams2 = (FrameLayout.LayoutParams) clearButton.getLayoutParams();
layoutParams2.width = AndroidUtilities.dp(48);
layoutParams2.gravity = Gravity.CENTER_VERTICAL | Gravity.RIGHT;
layoutParams2.height = FrameLayout.LayoutParams.MATCH_PARENT;
layoutParams2.height = LayoutHelper.MATCH_PARENT;
clearButton.setLayoutParams(layoutParams2);
}
isSearchField = value;
@ -502,11 +502,15 @@ public class ActionBarMenuItem extends FrameLayoutFixed {
popupWindow.update(this, -AndroidUtilities.dp(8), getOffsetY(), -1, -1);
}
}
if(clearButton!=null){
/*if(clearButton!=null){ //Plus
Drawable clear = getResources().getDrawable(R.drawable.ic_close_white);
clear.setColorFilter(AndroidUtilities.getIntDef("chatsHeaderIconsColor", 0xffffffff), PorterDuff.Mode.MULTIPLY);
clearButton.setImageDrawable(clear);
}*/
}
public ImageView getClearButton(){
return clearButton;
}
public void hideSubItem(int id) {

View File

@ -24,6 +24,7 @@ import org.telegram.android.AndroidUtilities;
import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.messenger.Utilities;
public class BaseFragment {
private boolean isFinished = false;
@ -82,7 +83,7 @@ public class BaseFragment {
actionBar = new ActionBar(parentLayout.getContext());
actionBar.parentFragment = this;
//actionBar.setBackgroundColor(0xff54759e);
actionBar.setBackgroundResource(R.color.header);
actionBar.setBackgroundResource(R.color.header); //Plus
actionBar.setItemsBackground(R.drawable.bar_selector);
}
}
@ -119,7 +120,10 @@ public class BaseFragment {
}
public void onResume() {
if(AndroidUtilities.needRestart){
AndroidUtilities.needRestart = false;
Utilities.restartApp();
}
}
public void onPause() {
@ -208,7 +212,7 @@ public class BaseFragment {
}
public AlertDialog showAlertDialog(AlertDialog.Builder builder) {
if (parentLayout == null || parentLayout.checkTransitionAnimation() || parentLayout.animationInProgress || parentLayout.startedTracking) {
if (parentLayout == null || parentLayout.animationInProgress || parentLayout.startedTracking || parentLayout.checkTransitionAnimation()) {
return null;
}
try {
@ -221,7 +225,7 @@ public class BaseFragment {
}
try {
visibleDialog = builder.show();
//
//Plus
int color = AndroidUtilities.getIntColor("themeColor");
int id = visibleDialog.getContext().getResources().getIdentifier("android:id/alertTitle", null, null);
TextView tv = (TextView) visibleDialog.findViewById(id);

View File

@ -25,10 +25,10 @@ import android.widget.FrameLayout;
import android.widget.ListView;
import org.telegram.android.AndroidUtilities;
import org.telegram.android.AnimationCompat.AnimatorListenerAdapterProxy;
import org.telegram.android.AnimationCompat.AnimatorSetProxy;
import org.telegram.android.AnimationCompat.ObjectAnimatorProxy;
import org.telegram.messenger.R;
import org.telegram.ui.AnimationCompat.AnimatorListenerAdapterProxy;
import org.telegram.ui.AnimationCompat.AnimatorSetProxy;
import org.telegram.ui.AnimationCompat.ObjectAnimatorProxy;
public class DrawerLayoutContainer extends FrameLayout {
@ -57,6 +57,7 @@ public class DrawerLayoutContainer extends FrameLayout {
private float drawerPosition = 0;
private boolean drawerOpened = false;
private boolean allowDrawContent = true;
public DrawerLayoutContainer(Context context) {
super(context);
@ -150,7 +151,7 @@ public class DrawerLayoutContainer extends FrameLayout {
if (drawerLayout.getVisibility() != newVisibility) {
drawerLayout.setVisibility(newVisibility);
}
setScrimOpacity(drawerPosition / (float)drawerLayout.getMeasuredWidth());
setScrimOpacity(drawerPosition / (float) drawerLayout.getMeasuredWidth());
}
public float getDrawerPosition() {
@ -276,6 +277,13 @@ public class DrawerLayoutContainer extends FrameLayout {
return drawerOpened;
}
public void setAllowDrawContent(boolean value) {
if (allowDrawContent != value) {
allowDrawContent = value;
invalidate();
}
}
public boolean onTouchEvent(MotionEvent ev) {
if (!parentActionBarLayout.checkTransitionAnimation()) {
if (drawerOpened && ev != null && ev.getX() > drawerPosition && !startedTracking) {
@ -301,7 +309,7 @@ public class DrawerLayoutContainer extends FrameLayout {
float dx = (int) (ev.getX() - startedTrackingX);
float dy = Math.abs((int) ev.getY() - startedTrackingY);
velocityTracker.addMovement(ev);
if (maybeStartTracking && !startedTracking && (dx > 0 && dx / 3.0f > Math.abs(dy) && Math.abs(dx) >= AndroidUtilities.getPixelsInCM(0.2f, true) || dx < 0 && Math.abs(dx) >= Math.abs(dy) && Math.abs(dx) >= AndroidUtilities.getPixelsInCM(0.3f, true))) {
if (maybeStartTracking && !startedTracking && (dx > 0 && dx / 3.0f > Math.abs(dy) && Math.abs(dx) >= AndroidUtilities.getPixelsInCM(0.2f, true) || dx < 0 && Math.abs(dx) >= Math.abs(dy) && Math.abs(dx) >= AndroidUtilities.getPixelsInCM(0.4f, true))) {
prepareForDrawerOpen(ev);
startedTrackingX = (int) ev.getX();
requestDisallowInterceptTouchEvent(true);
@ -441,11 +449,14 @@ public class DrawerLayoutContainer extends FrameLayout {
child.measure(drawerWidthSpec, drawerHeightSpec);
}
}
getDrawerLayout().setBackgroundColor(AndroidUtilities.getIntDef("drawerListColor",0xffffffff));
getDrawerLayout().setBackgroundColor(AndroidUtilities.getIntDef("drawerListColor",0xffffffff)); //Plus
}
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
if (!allowDrawContent) {
return false;
}
final int height = getHeight();
final boolean drawingContent = child != drawerLayout;
int clipLeft = 0, clipRight = getWidth();

View File

@ -87,11 +87,7 @@ public class MenuDrawable extends Drawable {
canvas.drawLine(startXDiff, -startYDiff, endXDiff, -endYDiff, paint);
canvas.drawLine(startXDiff, startYDiff, endXDiff, endYDiff, paint);
canvas.restore();
updateTheme();
}
private void updateTheme(){
paint.setColor(AndroidUtilities.getIntDef("chatsHeaderIconsColor", 0xffffffff));
paint.setColor(AndroidUtilities.getIntDef("chatsHeaderIconsColor", 0xffffffff)); //Plus
}
@Override

View File

@ -17,13 +17,13 @@ import android.view.View;
import android.view.ViewGroup;
import org.telegram.android.AndroidUtilities;
import org.telegram.android.AnimationCompat.ViewProxy;
import org.telegram.android.ContactsController;
import org.telegram.android.LocaleController;
import org.telegram.android.MessagesController;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.R;
import org.telegram.messenger.TLRPC;
import org.telegram.ui.AnimationCompat.ViewProxy;
import org.telegram.ui.Cells.DividerCell;
import org.telegram.ui.Cells.GreySectionCell;
import org.telegram.ui.Cells.LetterSectionCell;
@ -41,12 +41,14 @@ public class ContactsAdapter extends BaseSectionsAdapter {
private HashMap<Integer, TLRPC.User> ignoreUsers;
private HashMap<Integer, ?> checkedMap;
private boolean scrolling;
private boolean isAdmin;
public ContactsAdapter(Context context, boolean arg1, boolean arg2, HashMap<Integer, TLRPC.User> arg3) {
public ContactsAdapter(Context context, boolean arg1, boolean arg2, HashMap<Integer, TLRPC.User> arg3, boolean arg4) {
mContext = context;
onlyUsers = arg1;
needPhonebook = arg2;
ignoreUsers = arg3;
isAdmin = arg4;
}
public void setCheckedMap(HashMap<Integer, ?> map) {
@ -59,7 +61,7 @@ public class ContactsAdapter extends BaseSectionsAdapter {
@Override
public Object getItem(int section, int position) {
if (onlyUsers) {
if (onlyUsers && !isAdmin) {
if (section < ContactsController.getInstance().sortedUsersSectionsArray.size()) {
ArrayList<TLRPC.TL_contact> arr = ContactsController.getInstance().usersSectionsDict.get(ContactsController.getInstance().sortedUsersSectionsArray.get(section));
if (position < arr.size()) {
@ -88,12 +90,12 @@ public class ContactsAdapter extends BaseSectionsAdapter {
@Override
public boolean isRowEnabled(int section, int row) {
if (onlyUsers) {
if (onlyUsers && !isAdmin) {
ArrayList<TLRPC.TL_contact> arr = ContactsController.getInstance().usersSectionsDict.get(ContactsController.getInstance().sortedUsersSectionsArray.get(section));
return row < arr.size();
} else {
if (section == 0) {
if (needPhonebook) {
if (needPhonebook || isAdmin) {
if (row == 1) {
return false;
}
@ -117,6 +119,9 @@ public class ContactsAdapter extends BaseSectionsAdapter {
if (!onlyUsers) {
count++;
}
if (isAdmin) {
count++;
}
if (needPhonebook) {
count++;
}
@ -125,7 +130,7 @@ public class ContactsAdapter extends BaseSectionsAdapter {
@Override
public int getCountForSection(int section) {
if (onlyUsers) {
if (onlyUsers && !isAdmin) {
if (section < ContactsController.getInstance().sortedUsersSectionsArray.size()) {
ArrayList<TLRPC.TL_contact> arr = ContactsController.getInstance().usersSectionsDict.get(ContactsController.getInstance().sortedUsersSectionsArray.get(section));
int count = arr.size();
@ -136,7 +141,7 @@ public class ContactsAdapter extends BaseSectionsAdapter {
}
} else {
if (section == 0) {
if (needPhonebook) {
if (needPhonebook || isAdmin) {
return 2;
} else {
return 4;
@ -161,7 +166,7 @@ public class ContactsAdapter extends BaseSectionsAdapter {
if (convertView == null) {
convertView = new LetterSectionCell(mContext);
}
if (onlyUsers) {
if (onlyUsers && !isAdmin) {
if (section < ContactsController.getInstance().sortedUsersSectionsArray.size()) {
((LetterSectionCell) convertView).setLetter(ContactsController.getInstance().sortedUsersSectionsArray.get(section));
} else {
@ -176,7 +181,7 @@ public class ContactsAdapter extends BaseSectionsAdapter {
((LetterSectionCell) convertView).setLetter("");
}
}
((LetterSectionCell) convertView).setLetterColor(AndroidUtilities.getIntDef("contactsNameColor", 0xff808080));
((LetterSectionCell) convertView).setLetterColor(AndroidUtilities.getIntDef("contactsNameColor", 0xff808080)); //Plus
return convertView;
}
@ -190,7 +195,7 @@ public class ContactsAdapter extends BaseSectionsAdapter {
if (convertView == null) {
convertView = new DividerCell(mContext);
convertView.setPadding(AndroidUtilities.dp(LocaleController.isRTL ? 28 : 72), 0, AndroidUtilities.dp(LocaleController.isRTL ? 72 : 28), 0);
convertView.setTag("contactsRowColor");
convertView.setTag("contactsRowColor"); //Plus
}
} else if (type == 3) {
if (convertView == null) {
@ -211,6 +216,11 @@ public class ContactsAdapter extends BaseSectionsAdapter {
Drawable invite = mContext.getResources().getDrawable(R.drawable.menu_invite);
invite.setColorFilter(cColorGrey, PorterDuff.Mode.SRC_IN);
actionCell.setTextAndIcon(LocaleController.getString("InviteFriends", R.string.InviteFriends), invite);
} else if (isAdmin) {
//actionCell.setTextAndIcon(LocaleController.getString("InviteToGroupByLink", R.string.InviteToGroupByLink), R.drawable.menu_invite);
Drawable invite = mContext.getResources().getDrawable(R.drawable.menu_invite);
invite.setColorFilter(cColorGrey, PorterDuff.Mode.SRC_IN);
actionCell.setTextAndIcon(LocaleController.getString("InviteToGroupByLink", R.string.InviteToGroupByLink), invite);
} else {
if (position == 0) {
//actionCell.setTextAndIcon(LocaleController.getString("NewGroup", R.string.NewGroup), R.drawable.menu_newgroup);
@ -252,7 +262,7 @@ public class ContactsAdapter extends BaseSectionsAdapter {
((UserCell) convertView).setAvatarRadius(themePrefs.getInt("contactsAvatarRadius", 32));
}
ArrayList<TLRPC.TL_contact> arr = ContactsController.getInstance().usersSectionsDict.get(ContactsController.getInstance().sortedUsersSectionsArray.get(section - (onlyUsers ? 0 : 1)));
ArrayList<TLRPC.TL_contact> arr = ContactsController.getInstance().usersSectionsDict.get(ContactsController.getInstance().sortedUsersSectionsArray.get(section - (onlyUsers && !isAdmin ? 0 : 1)));
TLRPC.User user = MessagesController.getInstance().getUser(arr.get(position).user_id);
((UserCell)convertView).setData(user, null, null, 0);
if (checkedMap != null) {
@ -266,18 +276,18 @@ public class ContactsAdapter extends BaseSectionsAdapter {
}
}
}
parent.setBackgroundColor(themePrefs.getInt("contactsRowColor", 0xffffffff));
parent.setBackgroundColor(themePrefs.getInt("contactsRowColor", 0xffffffff)); //Plus
return convertView;
}
@Override
public int getItemViewType(int section, int position) {
if (onlyUsers) {
if (onlyUsers && !isAdmin) {
ArrayList<TLRPC.TL_contact> arr = ContactsController.getInstance().usersSectionsDict.get(ContactsController.getInstance().sortedUsersSectionsArray.get(section));
return position < arr.size() ? 0 : 4;
} else {
if (section == 0) {
if (needPhonebook) {
if (needPhonebook || isAdmin) {
if (position == 1) {
return 3;
}

View File

@ -8,17 +8,14 @@
package org.telegram.ui.Adapters;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.view.View;
import android.view.ViewGroup;
import org.telegram.android.AndroidUtilities;
import org.telegram.android.MessageObject;
import org.telegram.android.MessagesController;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.R;
import org.telegram.messenger.TLRPC;
import org.telegram.ui.Cells.DialogCell;
import org.telegram.ui.Cells.LoadingCell;

View File

@ -25,10 +25,8 @@ import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.messenger.RPCRequest;
import org.telegram.messenger.TLClassStore;
import org.telegram.messenger.TLObject;
import org.telegram.messenger.TLRPC;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities;
import org.telegram.ui.Cells.DialogCell;
import org.telegram.ui.Cells.GreySectionCell;
@ -242,8 +240,7 @@ public class DialogsSearchAdapter extends BaseSearchAdapter {
if (found != 0) {
ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
TLRPC.User user = (TLRPC.User) TLClassStore.Instance().TLdeserialize(data, data.readInt32());
if (user.id != UserConfig.getClientUserId()) {
TLRPC.User user = TLRPC.User.TLdeserialize(data, data.readInt32(false), false);
DialogSearchResult dialogSearchResult = dialogsResult.get((long) user.id);
if (user.status != null) {
user.status.expires = cursor.intValue(1);
@ -256,7 +253,6 @@ public class DialogsSearchAdapter extends BaseSearchAdapter {
dialogSearchResult.object = user;
resultCount++;
}
}
MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data);
break;
}
@ -277,7 +273,7 @@ public class DialogsSearchAdapter extends BaseSearchAdapter {
if (name.startsWith(q) || name.contains(" " + q) || tName != null && (tName.startsWith(q) || tName.contains(" " + q))) {
ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
TLRPC.Chat chat = (TLRPC.Chat) TLClassStore.Instance().TLdeserialize(data, data.readInt32());
TLRPC.Chat chat = TLRPC.Chat.TLdeserialize(data, data.readInt32(false), false);
long dialog_id;
if (chat.id > 0) {
dialog_id = -chat.id;
@ -323,7 +319,7 @@ public class DialogsSearchAdapter extends BaseSearchAdapter {
ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0));
ByteBufferDesc data2 = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(6));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0 && cursor.byteBufferValue(6, data2.buffer) != 0) {
TLRPC.EncryptedChat chat = (TLRPC.EncryptedChat) TLClassStore.Instance().TLdeserialize(data, data.readInt32());
TLRPC.EncryptedChat chat = TLRPC.EncryptedChat.TLdeserialize(data, data.readInt32(false), false);
DialogSearchResult dialogSearchResult = dialogsResult.get((long) chat.id << 32);
chat.user_id = cursor.intValue(2);
@ -342,7 +338,7 @@ public class DialogsSearchAdapter extends BaseSearchAdapter {
chat.future_auth_key = cursor.byteArrayValue(15);
chat.key_hash = cursor.byteArrayValue(16);
TLRPC.User user = (TLRPC.User) TLClassStore.Instance().TLdeserialize(data2, data2.readInt32());
TLRPC.User user = TLRPC.User.TLdeserialize(data2, data2.readInt32(false), false);
if (user.status != null) {
user.status.expires = cursor.intValue(7);
}
@ -417,8 +413,7 @@ public class DialogsSearchAdapter extends BaseSearchAdapter {
if (found != 0) {
ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
TLRPC.User user = (TLRPC.User) TLClassStore.Instance().TLdeserialize(data, data.readInt32());
if (user.id != UserConfig.getClientUserId()) {
TLRPC.User user = TLRPC.User.TLdeserialize(data, data.readInt32(false), false);
if (user.status != null) {
user.status.expires = cursor.intValue(1);
}
@ -429,7 +424,6 @@ public class DialogsSearchAdapter extends BaseSearchAdapter {
}
resultArray.add(user);
}
}
MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data);
break;
}

View File

@ -9,7 +9,6 @@
package org.telegram.ui.Adapters;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
@ -18,12 +17,12 @@ import org.telegram.SQLite.SQLitePreparedStatement;
import org.telegram.android.AndroidUtilities;
import org.telegram.android.MessagesStorage;
import org.telegram.android.NotificationCenter;
import org.telegram.android.support.widget.RecyclerView;
import org.telegram.messenger.ByteBufferDesc;
import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.RPCRequest;
import org.telegram.messenger.TLClassStore;
import org.telegram.messenger.TLObject;
import org.telegram.messenger.TLRPC;
import org.telegram.messenger.Utilities;
@ -109,7 +108,7 @@ public class StickersAdapter extends RecyclerView.Adapter implements Notificatio
if (cursor.next()) {
ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
result = (TLRPC.messages_AllStickers) TLClassStore.Instance().TLdeserialize(data, data.readInt32());
result = TLRPC.messages_AllStickers.TLdeserialize(data, data.readInt32(false), false);
}
date = cursor.intValue(1);
MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data);
@ -320,7 +319,6 @@ public class StickersAdapter extends RecyclerView.Adapter implements Notificatio
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) {
Holder holder = (Holder) viewHolder;
int side = 0;
if (i == 0) {
if (stickers.size() == 1) {
@ -331,6 +329,6 @@ public class StickersAdapter extends RecyclerView.Adapter implements Notificatio
} else if (i == stickers.size() - 1) {
side = 1;
}
((StickerCell) holder.itemView).setSticker(stickers.get(i), side);
((StickerCell) viewHolder.itemView).setSticker(stickers.get(i), side);
}
}

View File

@ -1,191 +0,0 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.ui.Animation;
import android.view.animation.Interpolator;
import java.util.ArrayList;
public abstract class Animator10 implements Cloneable {
ArrayList<AnimatorListener> mListeners = null;
ArrayList<AnimatorPauseListener> mPauseListeners = null;
boolean mPaused = false;
public abstract long getStartDelay();
public abstract void setStartDelay(long startDelay);
public abstract Animator10 setDuration(long duration);
public abstract long getDuration();
public abstract void setInterpolator(Interpolator value);
public abstract boolean isRunning();
public void start() {
}
public void cancel() {
}
public void end() {
}
@SuppressWarnings("unchecked")
public void pause() {
if (isStarted() && !mPaused) {
mPaused = true;
if (mPauseListeners != null) {
ArrayList<AnimatorPauseListener> tmpListeners = (ArrayList<AnimatorPauseListener>) mPauseListeners.clone();
int numListeners = tmpListeners.size();
for (AnimatorPauseListener tmpListener : tmpListeners) {
tmpListener.onAnimationPause(this);
}
}
}
}
@SuppressWarnings("unchecked")
public void resume() {
if (mPaused) {
mPaused = false;
if (mPauseListeners != null) {
ArrayList<AnimatorPauseListener> tmpListeners = (ArrayList<AnimatorPauseListener>) mPauseListeners.clone();
int numListeners = tmpListeners.size();
for (AnimatorPauseListener tmpListener : tmpListeners) {
tmpListener.onAnimationResume(this);
}
}
}
}
public boolean isPaused() {
return mPaused;
}
public boolean isStarted() {
return isRunning();
}
public Interpolator getInterpolator() {
return null;
}
public void addListener(AnimatorListener listener) {
if (mListeners == null) {
mListeners = new ArrayList<AnimatorListener>();
}
mListeners.add(listener);
}
public void removeListener(AnimatorListener listener) {
if (mListeners == null) {
return;
}
mListeners.remove(listener);
if (mListeners.size() == 0) {
mListeners = null;
}
}
public ArrayList<AnimatorListener> getListeners() {
return mListeners;
}
public void addPauseListener(AnimatorPauseListener listener) {
if (mPauseListeners == null) {
mPauseListeners = new ArrayList<AnimatorPauseListener>();
}
mPauseListeners.add(listener);
}
public void removePauseListener(AnimatorPauseListener listener) {
if (mPauseListeners == null) {
return;
}
mPauseListeners.remove(listener);
if (mPauseListeners.size() == 0) {
mPauseListeners = null;
}
}
public void removeAllListeners() {
if (mListeners != null) {
mListeners.clear();
mListeners = null;
}
if (mPauseListeners != null) {
mPauseListeners.clear();
mPauseListeners = null;
}
}
@Override
public Animator10 clone() {
try {
final Animator10 anim = (Animator10) super.clone();
if (mListeners != null) {
ArrayList<AnimatorListener> oldListeners = mListeners;
anim.mListeners = new ArrayList<AnimatorListener>();
int numListeners = oldListeners.size();
for (AnimatorListener oldListener : oldListeners) {
anim.mListeners.add(oldListener);
}
}
if (mPauseListeners != null) {
ArrayList<AnimatorPauseListener> oldListeners = mPauseListeners;
anim.mPauseListeners = new ArrayList<AnimatorPauseListener>();
int numListeners = oldListeners.size();
for (AnimatorPauseListener oldListener : oldListeners) {
anim.mPauseListeners.add(oldListener);
}
}
return anim;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
public void setupStartValues() {
}
public void setupEndValues() {
}
public void setTarget(Object target) {
}
public interface AnimatorListener {
void onAnimationStart(Animator10 animation);
void onAnimationEnd(Animator10 animation);
void onAnimationCancel(Animator10 animation);
void onAnimationRepeat(Animator10 animation);
}
public interface AnimatorPauseListener {
void onAnimationPause(Animator10 animation);
void onAnimationResume(Animator10 animation);
}
}

View File

@ -1,50 +0,0 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.ui.Animation;
public abstract class AnimatorListenerAdapter10 implements Animator10.AnimatorListener, Animator10.AnimatorPauseListener {
@Override
public void onAnimationCancel(Animator10 animation) {
}
@Override
public void onAnimationEnd(Animator10 animation) {
}
@Override
public void onAnimationRepeat(Animator10 animation) {
}
@Override
public void onAnimationStart(Animator10 animation) {
}
@Override
public void onAnimationPause(Animator10 animation) {
}
@Override
public void onAnimationResume(Animator10 animation) {
}
}

View File

@ -1,705 +0,0 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.ui.Animation;
import android.view.animation.Interpolator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
public final class AnimatorSet10 extends Animator10 {
private ArrayList<Animator10> mPlayingSet = new ArrayList<>();
private HashMap<Animator10, Node> mNodeMap = new HashMap<>();
private ArrayList<Node> mNodes = new ArrayList<>();
private ArrayList<Node> mSortedNodes = new ArrayList<>();
private boolean mNeedsSort = true;
private AnimatorSetListener mSetListener = null;
boolean mTerminated = false;
private boolean mStarted = false;
private long mStartDelay = 0;
private ValueAnimator mDelayAnim = null;
private long mDuration = -1;
private Interpolator mInterpolator = null;
public void playTogether(Animator10... items) {
if (items != null) {
mNeedsSort = true;
Builder builder = play(items[0]);
for (int i = 1; i < items.length; ++i) {
builder.with(items[i]);
}
}
}
public void playTogether(Collection<Animator10> items) {
if (items != null && items.size() > 0) {
mNeedsSort = true;
Builder builder = null;
for (Animator10 anim : items) {
if (builder == null) {
builder = play(anim);
} else {
builder.with(anim);
}
}
}
}
public void playSequentially(Animator10... items) {
if (items != null) {
mNeedsSort = true;
if (items.length == 1) {
play(items[0]);
} else {
for (int i = 0; i < items.length - 1; ++i) {
play(items[i]).before(items[i+1]);
}
}
}
}
public void playSequentially(List<Animator10> items) {
if (items != null && items.size() > 0) {
mNeedsSort = true;
if (items.size() == 1) {
play(items.get(0));
} else {
for (int i = 0; i < items.size() - 1; ++i) {
play(items.get(i)).before(items.get(i+1));
}
}
}
}
public ArrayList<Animator10> getChildAnimations() {
ArrayList<Animator10> childList = new ArrayList<>();
for (Node node : mNodes) {
childList.add(node.animation);
}
return childList;
}
@Override
public void setTarget(Object target) {
for (Node node : mNodes) {
Animator10 animation = node.animation;
if (animation instanceof AnimatorSet10) {
animation.setTarget(target);
} else if (animation instanceof ObjectAnimator10) {
animation.setTarget(target);
}
}
}
@Override
public void setInterpolator(Interpolator interpolator) {
mInterpolator = interpolator;
}
@Override
public Interpolator getInterpolator() {
return mInterpolator;
}
public Builder play(Animator10 anim) {
if (anim != null) {
mNeedsSort = true;
return new Builder(anim);
}
return null;
}
@SuppressWarnings("unchecked")
@Override
public void cancel() {
mTerminated = true;
if (isStarted()) {
ArrayList<AnimatorListener> tmpListeners = null;
if (mListeners != null) {
tmpListeners = (ArrayList<AnimatorListener>) mListeners.clone();
for (AnimatorListener listener : tmpListeners) {
listener.onAnimationCancel(this);
}
}
if (mDelayAnim != null && mDelayAnim.isRunning()) {
mDelayAnim.cancel();
} else if (mSortedNodes.size() > 0) {
for (Node node : mSortedNodes) {
node.animation.cancel();
}
}
if (tmpListeners != null) {
for (AnimatorListener listener : tmpListeners) {
listener.onAnimationEnd(this);
}
}
mStarted = false;
}
}
@SuppressWarnings("unchecked")
@Override
public void end() {
mTerminated = true;
if (isStarted()) {
if (mSortedNodes.size() != mNodes.size()) {
// hasn't been started yet - sort the nodes now, then end them
sortNodes();
for (Node node : mSortedNodes) {
if (mSetListener == null) {
mSetListener = new AnimatorSetListener(this);
}
node.animation.addListener(mSetListener);
}
}
if (mDelayAnim != null) {
mDelayAnim.cancel();
}
if (mSortedNodes.size() > 0) {
for (Node node : mSortedNodes) {
node.animation.end();
}
}
if (mListeners != null) {
ArrayList<AnimatorListener> tmpListeners = (ArrayList<AnimatorListener>) mListeners.clone();
for (AnimatorListener listener : tmpListeners) {
listener.onAnimationEnd(this);
}
}
mStarted = false;
}
}
@Override
public boolean isRunning() {
for (Node node : mNodes) {
if (node.animation.isRunning()) {
return true;
}
}
return false;
}
@Override
public boolean isStarted() {
return mStarted;
}
@Override
public long getStartDelay() {
return mStartDelay;
}
@Override
public void setStartDelay(long startDelay) {
mStartDelay = startDelay;
}
@Override
public long getDuration() {
return mDuration;
}
@Override
public AnimatorSet10 setDuration(long duration) {
if (duration < 0) {
throw new IllegalArgumentException("duration must be a value of zero or greater");
}
mDuration = duration;
return this;
}
@Override
public void setupStartValues() {
for (Node node : mNodes) {
node.animation.setupStartValues();
}
}
@Override
public void setupEndValues() {
for (Node node : mNodes) {
node.animation.setupEndValues();
}
}
@Override
public void pause() {
boolean previouslyPaused = mPaused;
super.pause();
if (!previouslyPaused && mPaused) {
if (mDelayAnim != null) {
mDelayAnim.pause();
} else {
for (Node node : mNodes) {
node.animation.pause();
}
}
}
}
@Override
public void resume() {
boolean previouslyPaused = mPaused;
super.resume();
if (previouslyPaused && !mPaused) {
if (mDelayAnim != null) {
mDelayAnim.resume();
} else {
for (Node node : mNodes) {
node.animation.resume();
}
}
}
}
@SuppressWarnings("unchecked")
@Override
public void start() {
mTerminated = false;
mStarted = true;
mPaused = false;
if (mDuration >= 0) {
for (Node node : mNodes) {
node.animation.setDuration(mDuration);
}
}
if (mInterpolator != null) {
for (Node node : mNodes) {
node.animation.setInterpolator(mInterpolator);
}
}
sortNodes();
int numSortedNodes = mSortedNodes.size();
for (Node node : mSortedNodes) {
ArrayList<AnimatorListener> oldListeners = node.animation.getListeners();
if (oldListeners != null && oldListeners.size() > 0) {
final ArrayList<AnimatorListener> clonedListeners = new
ArrayList<>(oldListeners);
for (AnimatorListener listener : clonedListeners) {
if (listener instanceof DependencyListener ||
listener instanceof AnimatorSetListener) {
node.animation.removeListener(listener);
}
}
}
}
final ArrayList<Node> nodesToStart = new ArrayList<>();
for (Node node : mSortedNodes) {
if (mSetListener == null) {
mSetListener = new AnimatorSetListener(this);
}
if (node.dependencies == null || node.dependencies.size() == 0) {
nodesToStart.add(node);
} else {
int numDependencies = node.dependencies.size();
for (int j = 0; j < numDependencies; ++j) {
Dependency dependency = node.dependencies.get(j);
dependency.node.animation.addListener(
new DependencyListener(this, node, dependency.rule));
}
node.tmpDependencies = (ArrayList<Dependency>) node.dependencies.clone();
}
node.animation.addListener(mSetListener);
}
if (mStartDelay <= 0) {
for (Node node : nodesToStart) {
node.animation.start();
mPlayingSet.add(node.animation);
}
} else {
mDelayAnim = ValueAnimator.ofFloat(0f, 1f);
mDelayAnim.setDuration(mStartDelay);
mDelayAnim.addListener(new AnimatorListenerAdapter10() {
boolean canceled = false;
public void onAnimationCancel(Animator10 anim) {
canceled = true;
}
public void onAnimationEnd(Animator10 anim) {
if (!canceled) {
int numNodes = nodesToStart.size();
for (Node node : nodesToStart) {
node.animation.start();
mPlayingSet.add(node.animation);
}
}
mDelayAnim = null;
}
});
mDelayAnim.start();
}
if (mListeners != null) {
ArrayList<AnimatorListener> tmpListeners =
(ArrayList<AnimatorListener>) mListeners.clone();
int numListeners = tmpListeners.size();
for (AnimatorListener tmpListener : tmpListeners) {
tmpListener.onAnimationStart(this);
}
}
if (mNodes.size() == 0 && mStartDelay == 0) {
mStarted = false;
if (mListeners != null) {
ArrayList<AnimatorListener> tmpListeners =
(ArrayList<AnimatorListener>) mListeners.clone();
int numListeners = tmpListeners.size();
for (AnimatorListener tmpListener : tmpListeners) {
tmpListener.onAnimationEnd(this);
}
}
}
}
@Override
public AnimatorSet10 clone() {
final AnimatorSet10 anim = (AnimatorSet10) super.clone();
anim.mNeedsSort = true;
anim.mTerminated = false;
anim.mStarted = false;
anim.mPlayingSet = new ArrayList<>();
anim.mNodeMap = new HashMap<>();
anim.mNodes = new ArrayList<>();
anim.mSortedNodes = new ArrayList<>();
HashMap<Node, Node> nodeCloneMap = new HashMap<>();
for (Node node : mNodes) {
Node nodeClone = node.clone();
nodeCloneMap.put(node, nodeClone);
anim.mNodes.add(nodeClone);
anim.mNodeMap.put(nodeClone.animation, nodeClone);
nodeClone.dependencies = null;
nodeClone.tmpDependencies = null;
nodeClone.nodeDependents = null;
nodeClone.nodeDependencies = null;
ArrayList<AnimatorListener> cloneListeners = nodeClone.animation.getListeners();
if (cloneListeners != null) {
ArrayList<AnimatorListener> listenersToRemove = null;
for (AnimatorListener listener : cloneListeners) {
if (listener instanceof AnimatorSetListener) {
if (listenersToRemove == null) {
listenersToRemove = new ArrayList<>();
}
listenersToRemove.add(listener);
}
}
if (listenersToRemove != null) {
for (AnimatorListener listener : listenersToRemove) {
cloneListeners.remove(listener);
}
}
}
}
for (Node node : mNodes) {
Node nodeClone = nodeCloneMap.get(node);
if (node.dependencies != null) {
for (Dependency dependency : node.dependencies) {
Node clonedDependencyNode = nodeCloneMap.get(dependency.node);
Dependency cloneDependency = new Dependency(clonedDependencyNode, dependency.rule);
nodeClone.addDependency(cloneDependency);
}
}
}
return anim;
}
private static class DependencyListener implements AnimatorListener {
private AnimatorSet10 mAnimatorSet;
private Node mNode;
private int mRule;
public DependencyListener(AnimatorSet10 animatorSet, Node node, int rule) {
this.mAnimatorSet = animatorSet;
this.mNode = node;
this.mRule = rule;
}
public void onAnimationCancel(Animator10 animation) {
}
public void onAnimationEnd(Animator10 animation) {
if (mRule == Dependency.AFTER) {
startIfReady(animation);
}
}
public void onAnimationRepeat(Animator10 animation) {
}
public void onAnimationStart(Animator10 animation) {
if (mRule == Dependency.WITH) {
startIfReady(animation);
}
}
private void startIfReady(Animator10 dependencyAnimation) {
if (mAnimatorSet.mTerminated) {
return;
}
Dependency dependencyToRemove = null;
int numDependencies = mNode.tmpDependencies.size();
for (int i = 0; i < numDependencies; ++i) {
Dependency dependency = mNode.tmpDependencies.get(i);
if (dependency.rule == mRule && dependency.node.animation == dependencyAnimation) {
dependencyToRemove = dependency;
dependencyAnimation.removeListener(this);
break;
}
}
mNode.tmpDependencies.remove(dependencyToRemove);
if (mNode.tmpDependencies.size() == 0) {
mNode.animation.start();
mAnimatorSet.mPlayingSet.add(mNode.animation);
}
}
}
private class AnimatorSetListener implements AnimatorListener {
private AnimatorSet10 mAnimatorSet;
AnimatorSetListener(AnimatorSet10 animatorSet) {
mAnimatorSet = animatorSet;
}
public void onAnimationCancel(Animator10 animation) {
if (!mTerminated) {
if (mPlayingSet.size() == 0) {
if (mListeners != null) {
int numListeners = mListeners.size();
for (AnimatorListener mListener : mListeners) {
mListener.onAnimationCancel(mAnimatorSet);
}
}
}
}
}
@SuppressWarnings("unchecked")
public void onAnimationEnd(Animator10 animation) {
animation.removeListener(this);
mPlayingSet.remove(animation);
Node animNode = mAnimatorSet.mNodeMap.get(animation);
animNode.done = true;
if (!mTerminated) {
ArrayList<Node> sortedNodes = mAnimatorSet.mSortedNodes;
boolean allDone = true;
int numSortedNodes = sortedNodes.size();
for (Node sortedNode : sortedNodes) {
if (!sortedNode.done) {
allDone = false;
break;
}
}
if (allDone) {
if (mListeners != null) {
ArrayList<AnimatorListener> tmpListeners =
(ArrayList<AnimatorListener>) mListeners.clone();
int numListeners = tmpListeners.size();
for (AnimatorListener tmpListener : tmpListeners) {
tmpListener.onAnimationEnd(mAnimatorSet);
}
}
mAnimatorSet.mStarted = false;
mAnimatorSet.mPaused = false;
}
}
}
public void onAnimationRepeat(Animator10 animation) {
}
public void onAnimationStart(Animator10 animation) {
}
}
private void sortNodes() {
if (mNeedsSort) {
mSortedNodes.clear();
ArrayList<Node> roots = new ArrayList<>();
int numNodes = mNodes.size();
for (Node node : mNodes) {
if (node.dependencies == null || node.dependencies.size() == 0) {
roots.add(node);
}
}
ArrayList<Node> tmpRoots = new ArrayList<>();
while (roots.size() > 0) {
int numRoots = roots.size();
for (Node root : roots) {
mSortedNodes.add(root);
if (root.nodeDependents != null) {
int numDependents = root.nodeDependents.size();
for (int j = 0; j < numDependents; ++j) {
Node node = root.nodeDependents.get(j);
node.nodeDependencies.remove(root);
if (node.nodeDependencies.size() == 0) {
tmpRoots.add(node);
}
}
}
}
roots.clear();
roots.addAll(tmpRoots);
tmpRoots.clear();
}
mNeedsSort = false;
if (mSortedNodes.size() != mNodes.size()) {
throw new IllegalStateException("Circular dependencies cannot exist in AnimatorSet");
}
} else {
int numNodes = mNodes.size();
for (Node node : mNodes) {
if (node.dependencies != null && node.dependencies.size() > 0) {
int numDependencies = node.dependencies.size();
for (int j = 0; j < numDependencies; ++j) {
Dependency dependency = node.dependencies.get(j);
if (node.nodeDependencies == null) {
node.nodeDependencies = new ArrayList<>();
}
if (!node.nodeDependencies.contains(dependency.node)) {
node.nodeDependencies.add(dependency.node);
}
}
}
node.done = false;
}
}
}
private static class Dependency {
static final int WITH = 0;
static final int AFTER = 1;
public Node node;
public int rule;
public Dependency(Node node, int rule) {
this.node = node;
this.rule = rule;
}
}
private static class Node implements Cloneable {
public Animator10 animation;
public ArrayList<Dependency> dependencies = null;
public ArrayList<Dependency> tmpDependencies = null;
public ArrayList<Node> nodeDependencies = null;
public ArrayList<Node> nodeDependents = null;
public boolean done = false;
public Node(Animator10 animation) {
this.animation = animation;
}
public void addDependency(Dependency dependency) {
if (dependencies == null) {
dependencies = new ArrayList<>();
nodeDependencies = new ArrayList<>();
}
dependencies.add(dependency);
if (!nodeDependencies.contains(dependency.node)) {
nodeDependencies.add(dependency.node);
}
Node dependencyNode = dependency.node;
if (dependencyNode.nodeDependents == null) {
dependencyNode.nodeDependents = new ArrayList<>();
}
dependencyNode.nodeDependents.add(this);
}
@Override
public Node clone() {
try {
Node node = (Node) super.clone();
node.animation = animation.clone();
return node;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
}
public class Builder {
private Node mCurrentNode;
Builder(Animator10 anim) {
mCurrentNode = mNodeMap.get(anim);
if (mCurrentNode == null) {
mCurrentNode = new Node(anim);
mNodeMap.put(anim, mCurrentNode);
mNodes.add(mCurrentNode);
}
}
public Builder with(Animator10 anim) {
Node node = mNodeMap.get(anim);
if (node == null) {
node = new Node(anim);
mNodeMap.put(anim, node);
mNodes.add(node);
}
Dependency dependency = new Dependency(mCurrentNode, Dependency.WITH);
node.addDependency(dependency);
return this;
}
public Builder before(Animator10 anim) {
Node node = mNodeMap.get(anim);
if (node == null) {
node = new Node(anim);
mNodeMap.put(anim, node);
mNodes.add(node);
}
Dependency dependency = new Dependency(mCurrentNode, Dependency.AFTER);
node.addDependency(dependency);
return this;
}
public Builder after(Animator10 anim) {
Node node = mNodeMap.get(anim);
if (node == null) {
node = new Node(anim);
mNodeMap.put(anim, node);
mNodes.add(node);
}
Dependency dependency = new Dependency(node, Dependency.AFTER);
mCurrentNode.addDependency(dependency);
return this;
}
public Builder after(long delay) {
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
anim.setDuration(delay);
after(anim);
return this;
}
}
}

View File

@ -1,24 +0,0 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.ui.Animation;
public class FloatEvaluator implements TypeEvaluator<Number> {
public Float evaluate(float fraction, Number startValue, Number endValue) {
float startFloat = startValue.floatValue();
return startFloat + fraction * (endValue.floatValue() - startFloat);
}
}

View File

@ -1,114 +0,0 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.ui.Animation;
import android.view.animation.Interpolator;
import org.telegram.ui.Animation.Keyframe.FloatKeyframe;
import java.util.ArrayList;
class FloatKeyframeSet extends KeyframeSet {
private float firstValue;
private float lastValue;
private float deltaValue;
private boolean firstTime = true;
public FloatKeyframeSet(FloatKeyframe... keyframes) {
super(keyframes);
}
@Override
public Object getValue(float fraction) {
return getFloatValue(fraction);
}
@Override
public FloatKeyframeSet clone() {
ArrayList<Keyframe> keyframes = mKeyframes;
int numKeyframes = mKeyframes.size();
FloatKeyframe[] newKeyframes = new FloatKeyframe[numKeyframes];
for (int i = 0; i < numKeyframes; ++i) {
newKeyframes[i] = (FloatKeyframe) keyframes.get(i).clone();
}
return new FloatKeyframeSet(newKeyframes);
}
@SuppressWarnings("unchecked")
public float getFloatValue(float fraction) {
if (mNumKeyframes == 2) {
if (firstTime) {
firstTime = false;
firstValue = ((FloatKeyframe) mKeyframes.get(0)).getFloatValue();
lastValue = ((FloatKeyframe) mKeyframes.get(1)).getFloatValue();
deltaValue = lastValue - firstValue;
}
if (mInterpolator != null) {
fraction = mInterpolator.getInterpolation(fraction);
}
if (mEvaluator == null) {
return firstValue + fraction * deltaValue;
} else {
return ((Number)mEvaluator.evaluate(fraction, firstValue, lastValue)).floatValue();
}
}
if (fraction <= 0f) {
final FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(0);
final FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(1);
float prevValue = prevKeyframe.getFloatValue();
float nextValue = nextKeyframe.getFloatValue();
float prevFraction = prevKeyframe.getFraction();
float nextFraction = nextKeyframe.getFraction();
final Interpolator interpolator = nextKeyframe.getInterpolator();
if (interpolator != null) {
fraction = interpolator.getInterpolation(fraction);
}
float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction);
return mEvaluator == null ? prevValue + intervalFraction * (nextValue - prevValue) : ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).floatValue();
} else if (fraction >= 1f) {
final FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(mNumKeyframes - 2);
final FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(mNumKeyframes - 1);
float prevValue = prevKeyframe.getFloatValue();
float nextValue = nextKeyframe.getFloatValue();
float prevFraction = prevKeyframe.getFraction();
float nextFraction = nextKeyframe.getFraction();
final Interpolator interpolator = nextKeyframe.getInterpolator();
if (interpolator != null) {
fraction = interpolator.getInterpolation(fraction);
}
float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction);
return mEvaluator == null ? prevValue + intervalFraction * (nextValue - prevValue) : ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).floatValue();
}
FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(0);
for (int i = 1; i < mNumKeyframes; ++i) {
FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(i);
if (fraction < nextKeyframe.getFraction()) {
final Interpolator interpolator = nextKeyframe.getInterpolator();
if (interpolator != null) {
fraction = interpolator.getInterpolation(fraction);
}
float intervalFraction = (fraction - prevKeyframe.getFraction()) /
(nextKeyframe.getFraction() - prevKeyframe.getFraction());
float prevValue = prevKeyframe.getFloatValue();
float nextValue = nextKeyframe.getFloatValue();
return mEvaluator == null ? prevValue + intervalFraction * (nextValue - prevValue) : ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).floatValue();
}
prevKeyframe = nextKeyframe;
}
return ((Number)mKeyframes.get(mNumKeyframes - 1).getValue()).floatValue();
}
}

View File

@ -1,30 +0,0 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.ui.Animation;
public abstract class FloatProperty10<T> extends Property<T, Float> {
public FloatProperty10(String name) {
super(Float.class, name);
}
public abstract void setValue(T object, float value);
@Override
final public void set(T object, Float value) {
setValue(object, value.floatValue());
}
}

View File

@ -1,24 +0,0 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.ui.Animation;
public class IntEvaluator implements TypeEvaluator<Integer> {
public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
int startInt = startValue;
return (int)(startInt + fraction * (endValue - startInt));
}
}

View File

@ -1,114 +0,0 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.ui.Animation;
import android.view.animation.Interpolator;
import org.telegram.ui.Animation.Keyframe.IntKeyframe;
import java.util.ArrayList;
class IntKeyframeSet extends KeyframeSet {
private int firstValue;
private int lastValue;
private int deltaValue;
private boolean firstTime = true;
public IntKeyframeSet(IntKeyframe... keyframes) {
super(keyframes);
}
@Override
public Object getValue(float fraction) {
return getIntValue(fraction);
}
@Override
public IntKeyframeSet clone() {
ArrayList<Keyframe> keyframes = mKeyframes;
int numKeyframes = mKeyframes.size();
IntKeyframe[] newKeyframes = new IntKeyframe[numKeyframes];
for (int i = 0; i < numKeyframes; ++i) {
newKeyframes[i] = (IntKeyframe) keyframes.get(i).clone();
}
return new IntKeyframeSet(newKeyframes);
}
@SuppressWarnings("unchecked")
public int getIntValue(float fraction) {
if (mNumKeyframes == 2) {
if (firstTime) {
firstTime = false;
firstValue = ((IntKeyframe) mKeyframes.get(0)).getIntValue();
lastValue = ((IntKeyframe) mKeyframes.get(1)).getIntValue();
deltaValue = lastValue - firstValue;
}
if (mInterpolator != null) {
fraction = mInterpolator.getInterpolation(fraction);
}
if (mEvaluator == null) {
return firstValue + (int)(fraction * deltaValue);
} else {
return ((Number)mEvaluator.evaluate(fraction, firstValue, lastValue)).intValue();
}
}
if (fraction <= 0f) {
final IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(0);
final IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(1);
int prevValue = prevKeyframe.getIntValue();
int nextValue = nextKeyframe.getIntValue();
float prevFraction = prevKeyframe.getFraction();
float nextFraction = nextKeyframe.getFraction();
final Interpolator interpolator = nextKeyframe.getInterpolator();
if (interpolator != null) {
fraction = interpolator.getInterpolation(fraction);
}
float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction);
return mEvaluator == null ? prevValue + (int)(intervalFraction * (nextValue - prevValue)) : ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).intValue();
} else if (fraction >= 1f) {
final IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(mNumKeyframes - 2);
final IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(mNumKeyframes - 1);
int prevValue = prevKeyframe.getIntValue();
int nextValue = nextKeyframe.getIntValue();
float prevFraction = prevKeyframe.getFraction();
float nextFraction = nextKeyframe.getFraction();
final Interpolator interpolator = nextKeyframe.getInterpolator();
if (interpolator != null) {
fraction = interpolator.getInterpolation(fraction);
}
float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction);
return mEvaluator == null ? prevValue + (int)(intervalFraction * (nextValue - prevValue)) : ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).intValue();
}
IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(0);
for (int i = 1; i < mNumKeyframes; ++i) {
IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(i);
if (fraction < nextKeyframe.getFraction()) {
final Interpolator interpolator = nextKeyframe.getInterpolator();
if (interpolator != null) {
fraction = interpolator.getInterpolation(fraction);
}
float intervalFraction = (fraction - prevKeyframe.getFraction()) / (nextKeyframe.getFraction() - prevKeyframe.getFraction());
int prevValue = prevKeyframe.getIntValue();
int nextValue = nextKeyframe.getIntValue();
return mEvaluator == null ? prevValue + (int)(intervalFraction * (nextValue - prevValue)) : ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).intValue();
}
prevKeyframe = nextKeyframe;
}
return ((Number)mKeyframes.get(mNumKeyframes - 1).getValue()).intValue();
}
}

View File

@ -1,30 +0,0 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.ui.Animation;
public abstract class IntProperty<T> extends Property<T, Integer> {
public IntProperty(String name) {
super(Integer.class, name);
}
public abstract void setValue(T object, int value);
@Override
final public void set(T object, Integer value) {
setValue(object, value.intValue());
}
}

View File

@ -1,187 +0,0 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.ui.Animation;
import android.view.animation.Interpolator;
public abstract class Keyframe implements Cloneable {
float mFraction;
Class mValueType;
private Interpolator mInterpolator = null;
boolean mHasValue = false;
public static Keyframe ofInt(float fraction, int value) {
return new IntKeyframe(fraction, value);
}
public static Keyframe ofInt(float fraction) {
return new IntKeyframe(fraction);
}
public static Keyframe ofFloat(float fraction, float value) {
return new FloatKeyframe(fraction, value);
}
public static Keyframe ofFloat(float fraction) {
return new FloatKeyframe(fraction);
}
public static Keyframe ofObject(float fraction, Object value) {
return new ObjectKeyframe(fraction, value);
}
public static Keyframe ofObject(float fraction) {
return new ObjectKeyframe(fraction, null);
}
public boolean hasValue() {
return mHasValue;
}
public abstract Object getValue();
public abstract void setValue(Object value);
public float getFraction() {
return mFraction;
}
public void setFraction(float fraction) {
mFraction = fraction;
}
public Interpolator getInterpolator() {
return mInterpolator;
}
public void setInterpolator(Interpolator interpolator) {
mInterpolator = interpolator;
}
public Class getType() {
return mValueType;
}
@Override
public abstract Keyframe clone();
static class ObjectKeyframe extends Keyframe {
Object mValue;
ObjectKeyframe(float fraction, Object value) {
mFraction = fraction;
mValue = value;
mHasValue = (value != null);
mValueType = mHasValue ? value.getClass() : Object.class;
}
public Object getValue() {
return mValue;
}
public void setValue(Object value) {
mValue = value;
mHasValue = (value != null);
}
@Override
public ObjectKeyframe clone() {
ObjectKeyframe kfClone = new ObjectKeyframe(getFraction(), mHasValue ? mValue : null);
kfClone.setInterpolator(getInterpolator());
return kfClone;
}
}
static class IntKeyframe extends Keyframe {
int mValue;
IntKeyframe(float fraction, int value) {
mFraction = fraction;
mValue = value;
mValueType = int.class;
mHasValue = true;
}
IntKeyframe(float fraction) {
mFraction = fraction;
mValueType = int.class;
}
public int getIntValue() {
return mValue;
}
public Object getValue() {
return mValue;
}
public void setValue(Object value) {
if (value != null && value.getClass() == Integer.class) {
mValue = (Integer) value;
mHasValue = true;
}
}
@Override
public IntKeyframe clone() {
IntKeyframe kfClone = mHasValue ? new IntKeyframe(getFraction(), mValue) : new IntKeyframe(getFraction());
kfClone.setInterpolator(getInterpolator());
return kfClone;
}
}
static class FloatKeyframe extends Keyframe {
float mValue;
FloatKeyframe(float fraction, float value) {
mFraction = fraction;
mValue = value;
mValueType = float.class;
mHasValue = true;
}
FloatKeyframe(float fraction) {
mFraction = fraction;
mValueType = float.class;
}
public float getFloatValue() {
return mValue;
}
public Object getValue() {
return mValue;
}
public void setValue(Object value) {
if (value != null && value.getClass() == Float.class) {
mValue = (Float) value;
mHasValue = true;
}
}
@Override
public FloatKeyframe clone() {
FloatKeyframe kfClone = mHasValue ? new FloatKeyframe(getFraction(), mValue) : new FloatKeyframe(getFraction());
kfClone.setInterpolator(getInterpolator());
return kfClone;
}
}
}

View File

@ -1,200 +0,0 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.ui.Animation;
import java.util.ArrayList;
import java.util.Arrays;
import android.util.Log;
import android.view.animation.Interpolator;
import org.telegram.ui.Animation.Keyframe.IntKeyframe;
import org.telegram.ui.Animation.Keyframe.FloatKeyframe;
import org.telegram.ui.Animation.Keyframe.ObjectKeyframe;
class KeyframeSet {
int mNumKeyframes;
Keyframe mFirstKeyframe;
Keyframe mLastKeyframe;
Interpolator mInterpolator;
ArrayList<Keyframe> mKeyframes;
TypeEvaluator mEvaluator;
public KeyframeSet(Keyframe... keyframes) {
mNumKeyframes = keyframes.length;
mKeyframes = new ArrayList<Keyframe>();
mKeyframes.addAll(Arrays.asList(keyframes));
mFirstKeyframe = mKeyframes.get(0);
mLastKeyframe = mKeyframes.get(mNumKeyframes - 1);
mInterpolator = mLastKeyframe.getInterpolator();
}
public static KeyframeSet ofInt(int... values) {
int numKeyframes = values.length;
IntKeyframe keyframes[] = new IntKeyframe[Math.max(numKeyframes,2)];
if (numKeyframes == 1) {
keyframes[0] = (IntKeyframe) Keyframe.ofInt(0f);
keyframes[1] = (IntKeyframe) Keyframe.ofInt(1f, values[0]);
} else {
keyframes[0] = (IntKeyframe) Keyframe.ofInt(0f, values[0]);
for (int i = 1; i < numKeyframes; ++i) {
keyframes[i] = (IntKeyframe) Keyframe.ofInt((float) i / (numKeyframes - 1), values[i]);
}
}
return new IntKeyframeSet(keyframes);
}
public static KeyframeSet ofFloat(float... values) {
boolean badValue = false;
int numKeyframes = values.length;
FloatKeyframe keyframes[] = new FloatKeyframe[Math.max(numKeyframes,2)];
if (numKeyframes == 1) {
keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f);
keyframes[1] = (FloatKeyframe) Keyframe.ofFloat(1f, values[0]);
if (Float.isNaN(values[0])) {
badValue = true;
}
} else {
keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f, values[0]);
for (int i = 1; i < numKeyframes; ++i) {
keyframes[i] = (FloatKeyframe) Keyframe.ofFloat((float) i / (numKeyframes - 1), values[i]);
if (Float.isNaN(values[i])) {
badValue = true;
}
}
}
if (badValue) {
Log.w("Animator", "Bad value (NaN) in float animator");
}
return new FloatKeyframeSet(keyframes);
}
public static KeyframeSet ofKeyframe(Keyframe... keyframes) {
int numKeyframes = keyframes.length;
boolean hasFloat = false;
boolean hasInt = false;
boolean hasOther = false;
for (Keyframe keyframe : keyframes) {
if (keyframe instanceof FloatKeyframe) {
hasFloat = true;
} else if (keyframe instanceof IntKeyframe) {
hasInt = true;
} else {
hasOther = true;
}
}
if (hasFloat && !hasInt && !hasOther) {
FloatKeyframe floatKeyframes[] = new FloatKeyframe[numKeyframes];
for (int i = 0; i < numKeyframes; ++i) {
floatKeyframes[i] = (FloatKeyframe) keyframes[i];
}
return new FloatKeyframeSet(floatKeyframes);
} else if (hasInt && !hasFloat && !hasOther) {
IntKeyframe intKeyframes[] = new IntKeyframe[numKeyframes];
for (int i = 0; i < numKeyframes; ++i) {
intKeyframes[i] = (IntKeyframe) keyframes[i];
}
return new IntKeyframeSet(intKeyframes);
} else {
return new KeyframeSet(keyframes);
}
}
public static KeyframeSet ofObject(Object... values) {
int numKeyframes = values.length;
ObjectKeyframe keyframes[] = new ObjectKeyframe[Math.max(numKeyframes,2)];
if (numKeyframes == 1) {
keyframes[0] = (ObjectKeyframe) Keyframe.ofObject(0f);
keyframes[1] = (ObjectKeyframe) Keyframe.ofObject(1f, values[0]);
} else {
keyframes[0] = (ObjectKeyframe) Keyframe.ofObject(0f, values[0]);
for (int i = 1; i < numKeyframes; ++i) {
keyframes[i] = (ObjectKeyframe) Keyframe.ofObject((float) i / (numKeyframes - 1), values[i]);
}
}
return new KeyframeSet(keyframes);
}
public void setEvaluator(TypeEvaluator evaluator) {
mEvaluator = evaluator;
}
@Override
public KeyframeSet clone() {
ArrayList<Keyframe> keyframes = mKeyframes;
int numKeyframes = mKeyframes.size();
Keyframe[] newKeyframes = new Keyframe[numKeyframes];
for (int i = 0; i < numKeyframes; ++i) {
newKeyframes[i] = keyframes.get(i).clone();
}
return new KeyframeSet(newKeyframes);
}
@SuppressWarnings("unchecked")
public Object getValue(float fraction) {
if (mNumKeyframes == 2) {
if (mInterpolator != null) {
fraction = mInterpolator.getInterpolation(fraction);
}
return mEvaluator.evaluate(fraction, mFirstKeyframe.getValue(), mLastKeyframe.getValue());
}
if (fraction <= 0f) {
final Keyframe nextKeyframe = mKeyframes.get(1);
final Interpolator interpolator = nextKeyframe.getInterpolator();
if (interpolator != null) {
fraction = interpolator.getInterpolation(fraction);
}
final float prevFraction = mFirstKeyframe.getFraction();
float intervalFraction = (fraction - prevFraction) / (nextKeyframe.getFraction() - prevFraction);
return mEvaluator.evaluate(intervalFraction, mFirstKeyframe.getValue(), nextKeyframe.getValue());
} else if (fraction >= 1f) {
final Keyframe prevKeyframe = mKeyframes.get(mNumKeyframes - 2);
final Interpolator interpolator = mLastKeyframe.getInterpolator();
if (interpolator != null) {
fraction = interpolator.getInterpolation(fraction);
}
final float prevFraction = prevKeyframe.getFraction();
float intervalFraction = (fraction - prevFraction) / (mLastKeyframe.getFraction() - prevFraction);
return mEvaluator.evaluate(intervalFraction, prevKeyframe.getValue(), mLastKeyframe.getValue());
}
Keyframe prevKeyframe = mFirstKeyframe;
for (int i = 1; i < mNumKeyframes; ++i) {
Keyframe nextKeyframe = mKeyframes.get(i);
if (fraction < nextKeyframe.getFraction()) {
final Interpolator interpolator = nextKeyframe.getInterpolator();
if (interpolator != null) {
fraction = interpolator.getInterpolation(fraction);
}
final float prevFraction = prevKeyframe.getFraction();
float intervalFraction = (fraction - prevFraction) / (nextKeyframe.getFraction() - prevFraction);
return mEvaluator.evaluate(intervalFraction, prevKeyframe.getValue(), nextKeyframe.getValue());
}
prevKeyframe = nextKeyframe;
}
return mLastKeyframe.getValue();
}
@Override
public String toString() {
String returnVal = " ";
for (int i = 0; i < mNumKeyframes; ++i) {
returnVal += mKeyframes.get(i).getValue() + " ";
}
return returnVal;
}
}

View File

@ -1,24 +0,0 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.ui.Animation;
public class NoSuchPropertyException extends RuntimeException {
public NoSuchPropertyException(String s) {
super(s);
}
}

View File

@ -1,488 +0,0 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.ui.Animation;
import android.view.View;
import java.util.HashMap;
public final class ObjectAnimator10 extends ValueAnimator {
private static final HashMap<String, Property> PROXY_PROPERTIES = new HashMap<String, Property>();
static {
Property<View, Float> ALPHA = new FloatProperty10<View>("alpha") {
@Override
public void setValue(View object, float value) {
View10.wrap(object).setAlpha(value);
}
@Override
public Float get(View object) {
return View10.wrap(object).getAlpha();
}
};
Property<View, Float> PIVOT_X = new FloatProperty10<View>("pivotX") {
@Override
public void setValue(View object, float value) {
View10.wrap(object).setPivotX(value);
}
@Override
public Float get(View object) {
return View10.wrap(object).getPivotX();
}
};
Property<View, Float> PIVOT_Y = new FloatProperty10<View>("pivotY") {
@Override
public void setValue(View object, float value) {
View10.wrap(object).setPivotY(value);
}
@Override
public Float get(View object) {
return View10.wrap(object).getPivotY();
}
};
Property<View, Float> TRANSLATION_X = new FloatProperty10<View>("translationX") {
@Override
public void setValue(View object, float value) {
View10.wrap(object).setTranslationX(value);
}
@Override
public Float get(View object) {
return View10.wrap(object).getTranslationX();
}
};
Property<View, Float> TRANSLATION_Y = new FloatProperty10<View>("translationY") {
@Override
public void setValue(View object, float value) {
View10.wrap(object).setTranslationY(value);
}
@Override
public Float get(View object) {
return View10.wrap(object).getTranslationY();
}
};
Property<View, Float> ROTATION = new FloatProperty10<View>("rotation") {
@Override
public void setValue(View object, float value) {
View10.wrap(object).setRotation(value);
}
@Override
public Float get(View object) {
return View10.wrap(object).getRotation();
}
};
Property<View, Float> ROTATION_X = new FloatProperty10<View>("rotationX") {
@Override
public void setValue(View object, float value) {
View10.wrap(object).setRotationX(value);
}
@Override
public Float get(View object) {
return View10.wrap(object).getRotationX();
}
};
Property<View, Float> ROTATION_Y = new FloatProperty10<View>("rotationY") {
@Override
public void setValue(View object, float value) {
View10.wrap(object).setRotationY(value);
}
@Override
public Float get(View object) {
return View10.wrap(object).getRotationY();
}
};
Property<View, Float> SCALE_X = new FloatProperty10<View>("scaleX") {
@Override
public void setValue(View object, float value) {
View10.wrap(object).setScaleX(value);
}
@Override
public Float get(View object) {
return View10.wrap(object).getScaleX();
}
};
Property<View, Float> SCALE_Y = new FloatProperty10<View>("scaleY") {
@Override
public void setValue(View object, float value) {
View10.wrap(object).setScaleY(value);
}
@Override
public Float get(View object) {
return View10.wrap(object).getScaleY();
}
};
Property<View, Integer> SCROLL_X = new IntProperty<View>("scrollX") {
@Override
public void setValue(View object, int value) {
View10.wrap(object).setScrollX(value);
}
@Override
public Integer get(View object) {
return View10.wrap(object).getScrollX();
}
};
Property<View, Integer> SCROLL_Y = new IntProperty<View>("scrollY") {
@Override
public void setValue(View object, int value) {
View10.wrap(object).setScrollY(value);
}
@Override
public Integer get(View object) {
return View10.wrap(object).getScrollY();
}
};
Property<View, Float> X = new FloatProperty10<View>("x") {
@Override
public void setValue(View object, float value) {
View10.wrap(object).setX(value);
}
@Override
public Float get(View object) {
return View10.wrap(object).getX();
}
};
Property<View, Float> Y = new FloatProperty10<View>("y") {
@Override
public void setValue(View object, float value) {
View10.wrap(object).setY(value);
}
@Override
public Float get(View object) {
return View10.wrap(object).getY();
}
};
PROXY_PROPERTIES.put("alpha", ALPHA);
PROXY_PROPERTIES.put("pivotX", PIVOT_X);
PROXY_PROPERTIES.put("pivotY", PIVOT_Y);
PROXY_PROPERTIES.put("translationX", TRANSLATION_X);
PROXY_PROPERTIES.put("translationY", TRANSLATION_Y);
PROXY_PROPERTIES.put("rotation", ROTATION);
PROXY_PROPERTIES.put("rotationX", ROTATION_X);
PROXY_PROPERTIES.put("rotationY", ROTATION_Y);
PROXY_PROPERTIES.put("scaleX", SCALE_X);
PROXY_PROPERTIES.put("scaleY", SCALE_Y);
PROXY_PROPERTIES.put("scrollX", SCROLL_X);
PROXY_PROPERTIES.put("scrollY", SCROLL_Y);
PROXY_PROPERTIES.put("x", X);
PROXY_PROPERTIES.put("y", Y);
}
private Object mTarget;
private String mPropertyName;
private Property mProperty;
private boolean mAutoCancel = false;
public void setPropertyName(String propertyName) {
if (mValues != null) {
PropertyValuesHolder valuesHolder = mValues[0];
String oldName = valuesHolder.getPropertyName();
valuesHolder.setPropertyName(propertyName);
mValuesMap.remove(oldName);
mValuesMap.put(propertyName, valuesHolder);
}
mPropertyName = propertyName;
mInitialized = false;
}
public void setProperty(Property property) {
if (mValues != null) {
PropertyValuesHolder valuesHolder = mValues[0];
String oldName = valuesHolder.getPropertyName();
valuesHolder.setProperty(property);
mValuesMap.remove(oldName);
mValuesMap.put(mPropertyName, valuesHolder);
}
if (mProperty != null) {
mPropertyName = property.getName();
}
mProperty = property;
mInitialized = false;
}
public String getPropertyName() {
String propertyName = null;
if (mPropertyName != null) {
propertyName = mPropertyName;
} else if (mProperty != null) {
propertyName = mProperty.getName();
} else if (mValues != null && mValues.length > 0) {
for (int i = 0; i < mValues.length; ++i) {
if (i == 0) {
propertyName = "";
} else {
propertyName += ",";
}
propertyName += mValues[i].getPropertyName();
}
}
return propertyName;
}
public ObjectAnimator10() {
}
private ObjectAnimator10(Object target, String propertyName) {
mTarget = target;
setPropertyName(propertyName);
}
private <T> ObjectAnimator10(T target, Property<T, ?> property) {
mTarget = target;
setProperty(property);
}
public static ObjectAnimator10 ofInt(Object target, String propertyName, int... values) {
ObjectAnimator10 anim = new ObjectAnimator10(target, propertyName);
anim.setIntValues(values);
return anim;
}
public static <T> ObjectAnimator10 ofInt(T target, Property<T, Integer> property, int... values) {
ObjectAnimator10 anim = new ObjectAnimator10(target, property);
anim.setIntValues(values);
return anim;
}
public static ObjectAnimator10 ofFloat(Object target, String propertyName, float... values) {
ObjectAnimator10 anim = new ObjectAnimator10(target, propertyName);
anim.setFloatValues(values);
return anim;
}
public static <T> ObjectAnimator10 ofFloat(T target, Property<T, Float> property, float... values) {
ObjectAnimator10 anim = new ObjectAnimator10(target, property);
anim.setFloatValues(values);
return anim;
}
public static ObjectAnimator10 ofObject(Object target, String propertyName, TypeEvaluator evaluator, Object... values) {
ObjectAnimator10 anim = new ObjectAnimator10(target, propertyName);
anim.setObjectValues(values);
anim.setEvaluator(evaluator);
return anim;
}
public static <T, V> ObjectAnimator10 ofObject(T target, Property<T, V> property, TypeEvaluator<V> evaluator, V... values) {
ObjectAnimator10 anim = new ObjectAnimator10(target, property);
anim.setObjectValues(values);
anim.setEvaluator(evaluator);
return anim;
}
public static ObjectAnimator10 ofPropertyValuesHolder(Object target, PropertyValuesHolder... values) {
ObjectAnimator10 anim = new ObjectAnimator10();
anim.mTarget = target;
anim.setValues(values);
return anim;
}
@SuppressWarnings("unchecked")
@Override
public void setIntValues(int... values) {
if (mValues == null || mValues.length == 0) {
if (mProperty != null) {
setValues(PropertyValuesHolder.ofInt(mProperty, values));
} else {
setValues(PropertyValuesHolder.ofInt(mPropertyName, values));
}
} else {
super.setIntValues(values);
}
}
@SuppressWarnings("unchecked")
@Override
public void setFloatValues(float... values) {
if (mValues == null || mValues.length == 0) {
if (mProperty != null) {
setValues(PropertyValuesHolder.ofFloat(mProperty, values));
} else {
setValues(PropertyValuesHolder.ofFloat(mPropertyName, values));
}
} else {
super.setFloatValues(values);
}
}
@Override
public void setObjectValues(Object... values) {
if (mValues == null || mValues.length == 0) {
if (mProperty != null) {
setValues(PropertyValuesHolder.ofObject(mProperty, null, values));
} else {
setValues(PropertyValuesHolder.ofObject(mPropertyName, null, values));
}
} else {
super.setObjectValues(values);
}
}
public void setAutoCancel(boolean cancel) {
mAutoCancel = cancel;
}
private boolean hasSameTargetAndProperties(Animator10 anim) {
if (anim instanceof ObjectAnimator10) {
PropertyValuesHolder[] theirValues = ((ObjectAnimator10) anim).getValues();
if (((ObjectAnimator10) anim).getTarget() == mTarget &&
mValues.length == theirValues.length) {
for (int i = 0; i < mValues.length; ++i) {
PropertyValuesHolder pvhMine = mValues[i];
PropertyValuesHolder pvhTheirs = theirValues[i];
if (pvhMine.getPropertyName() == null ||
!pvhMine.getPropertyName().equals(pvhTheirs.getPropertyName())) {
return false;
}
}
return true;
}
}
return false;
}
@Override
public void start() {
AnimationHandler handler = sAnimationHandler.get();
if (handler != null) {
int numAnims = handler.mAnimations.size();
for (int i = numAnims - 1; i >= 0; i--) {
if (handler.mAnimations.get(i) instanceof ObjectAnimator10) {
ObjectAnimator10 anim = (ObjectAnimator10) handler.mAnimations.get(i);
if (anim.mAutoCancel && hasSameTargetAndProperties(anim)) {
anim.cancel();
}
}
}
numAnims = handler.mPendingAnimations.size();
for (int i = numAnims - 1; i >= 0; i--) {
if (handler.mPendingAnimations.get(i) instanceof ObjectAnimator10) {
ObjectAnimator10 anim = (ObjectAnimator10) handler.mPendingAnimations.get(i);
if (anim.mAutoCancel && hasSameTargetAndProperties(anim)) {
anim.cancel();
}
}
}
numAnims = handler.mDelayedAnims.size();
for (int i = numAnims - 1; i >= 0; i--) {
if (handler.mDelayedAnims.get(i) instanceof ObjectAnimator10) {
ObjectAnimator10 anim = (ObjectAnimator10) handler.mDelayedAnims.get(i);
if (anim.mAutoCancel && hasSameTargetAndProperties(anim)) {
anim.cancel();
}
}
}
}
super.start();
}
@Override
void initAnimation() {
if (!mInitialized) {
if ((mProperty == null) && (mTarget instanceof View) && PROXY_PROPERTIES.containsKey(mPropertyName)) {
setProperty(PROXY_PROPERTIES.get(mPropertyName));
}
int numValues = mValues.length;
for (PropertyValuesHolder mValue : mValues) {
mValue.setupSetterAndGetter(mTarget);
}
super.initAnimation();
}
}
@Override
public ObjectAnimator10 setDuration(long duration) {
super.setDuration(duration);
return this;
}
public Object getTarget() {
return mTarget;
}
@Override
public void setTarget(Object target) {
if (mTarget != target) {
final Object oldTarget = mTarget;
mTarget = target;
if (oldTarget != null && target != null && oldTarget.getClass() == target.getClass()) {
return;
}
mInitialized = false;
}
}
@Override
public void setupStartValues() {
initAnimation();
int numValues = mValues.length;
for (PropertyValuesHolder mValue : mValues) {
mValue.setupStartValue(mTarget);
}
}
@Override
public void setupEndValues() {
initAnimation();
int numValues = mValues.length;
for (PropertyValuesHolder mValue : mValues) {
mValue.setupEndValue(mTarget);
}
}
@Override
void animateValue(float fraction) {
super.animateValue(fraction);
int numValues = mValues.length;
for (PropertyValuesHolder mValue : mValues) {
mValue.setAnimatedValue(mTarget);
}
}
@Override
public ObjectAnimator10 clone() {
return (ObjectAnimator10) super.clone();
}
}

View File

@ -1,49 +0,0 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.ui.Animation;
public abstract class Property<T, V> {
private final String mName;
private final Class<V> mType;
public static <T, V> Property<T, V> of(Class<T> hostType, Class<V> valueType, String name) {
return new ReflectiveProperty<T, V>(hostType, valueType, name);
}
public Property(Class<V> type, String name) {
mName = name;
mType = type;
}
public boolean isReadOnly() {
return false;
}
public void set(T object, V value) {
throw new UnsupportedOperationException("Property " + getName() +" is read-only");
}
public abstract V get(T object);
public String getName() {
return mName;
}
public Class<V> getType() {
return mType;
}
}

View File

@ -1,546 +0,0 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.ui.Animation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class PropertyValuesHolder implements Cloneable {
String mPropertyName;
protected Property mProperty;
Method mSetter = null;
private Method mGetter = null;
Class mValueType;
KeyframeSet mKeyframeSet = null;
private static final TypeEvaluator sIntEvaluator = new IntEvaluator();
private static final TypeEvaluator sFloatEvaluator = new FloatEvaluator();
private static Class[] FLOAT_VARIANTS = {float.class, Float.class, double.class, int.class, Double.class, Integer.class};
private static Class[] INTEGER_VARIANTS = {int.class, Integer.class, float.class, double.class, Float.class, Double.class};
private static Class[] DOUBLE_VARIANTS = {double.class, Double.class, float.class, int.class, Float.class, Integer.class};
private static final HashMap<Class, HashMap<String, Method>> sSetterPropertyMap = new HashMap<Class, HashMap<String, Method>>();
private static final HashMap<Class, HashMap<String, Method>> sGetterPropertyMap = new HashMap<Class, HashMap<String, Method>>();
final ReentrantReadWriteLock mPropertyMapLock = new ReentrantReadWriteLock();
final Object[] mTmpValueArray = new Object[1];
private TypeEvaluator mEvaluator;
private Object mAnimatedValue;
private PropertyValuesHolder(String propertyName) {
mPropertyName = propertyName;
}
private PropertyValuesHolder(Property property) {
mProperty = property;
if (property != null) {
mPropertyName = property.getName();
}
}
public static PropertyValuesHolder ofInt(String propertyName, int... values) {
return new IntPropertyValuesHolder(propertyName, values);
}
public static PropertyValuesHolder ofInt(Property<?, Integer> property, int... values) {
return new IntPropertyValuesHolder(property, values);
}
public static PropertyValuesHolder ofFloat(String propertyName, float... values) {
return new FloatPropertyValuesHolder(propertyName, values);
}
public static PropertyValuesHolder ofFloat(Property<?, Float> property, float... values) {
return new FloatPropertyValuesHolder(property, values);
}
public static PropertyValuesHolder ofObject(String propertyName, TypeEvaluator evaluator,
Object... values) {
PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName);
pvh.setObjectValues(values);
pvh.setEvaluator(evaluator);
return pvh;
}
public static <V> PropertyValuesHolder ofObject(Property property,
TypeEvaluator<V> evaluator, V... values) {
PropertyValuesHolder pvh = new PropertyValuesHolder(property);
pvh.setObjectValues(values);
pvh.setEvaluator(evaluator);
return pvh;
}
public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values) {
KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(values);
if (keyframeSet instanceof IntKeyframeSet) {
return new IntPropertyValuesHolder(propertyName, (IntKeyframeSet) keyframeSet);
} else if (keyframeSet instanceof FloatKeyframeSet) {
return new FloatPropertyValuesHolder(propertyName, (FloatKeyframeSet) keyframeSet);
} else {
PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName);
pvh.mKeyframeSet = keyframeSet;
pvh.mValueType = values[0].getType();
return pvh;
}
}
public static PropertyValuesHolder ofKeyframe(Property property, Keyframe... values) {
KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(values);
if (keyframeSet instanceof IntKeyframeSet) {
return new IntPropertyValuesHolder(property, (IntKeyframeSet) keyframeSet);
} else if (keyframeSet instanceof FloatKeyframeSet) {
return new FloatPropertyValuesHolder(property, (FloatKeyframeSet) keyframeSet);
} else {
PropertyValuesHolder pvh = new PropertyValuesHolder(property);
pvh.mKeyframeSet = keyframeSet;
pvh.mValueType = values[0].getType();
return pvh;
}
}
public void setIntValues(int... values) {
mValueType = int.class;
mKeyframeSet = KeyframeSet.ofInt(values);
}
public void setFloatValues(float... values) {
mValueType = float.class;
mKeyframeSet = KeyframeSet.ofFloat(values);
}
public void setKeyframes(Keyframe... values) {
int numKeyframes = values.length;
Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes, 2)];
mValueType = values[0].getType();
System.arraycopy(values, 0, keyframes, 0, numKeyframes);
mKeyframeSet = new KeyframeSet(keyframes);
}
public void setObjectValues(Object... values) {
mValueType = values[0].getClass();
mKeyframeSet = KeyframeSet.ofObject(values);
}
@SuppressWarnings("unchecked")
private Method getPropertyFunction(Class targetClass, String prefix, Class valueType) {
Method returnVal = null;
String methodName = getMethodName(prefix, mPropertyName);
Class args[] = null;
if (valueType == null) {
try {
returnVal = targetClass.getMethod(methodName);
} catch (Throwable e) {
try {
returnVal = targetClass.getDeclaredMethod(methodName);
returnVal.setAccessible(true);
} catch (Throwable e2) {
e2.printStackTrace();
}
}
} else {
args = new Class[1];
Class typeVariants[];
if (mValueType.equals(Float.class)) {
typeVariants = FLOAT_VARIANTS;
} else if (mValueType.equals(Integer.class)) {
typeVariants = INTEGER_VARIANTS;
} else if (mValueType.equals(Double.class)) {
typeVariants = DOUBLE_VARIANTS;
} else {
typeVariants = new Class[1];
typeVariants[0] = mValueType;
}
for (Class typeVariant : typeVariants) {
args[0] = typeVariant;
try {
returnVal = targetClass.getMethod(methodName, args);
mValueType = typeVariant;
return returnVal;
} catch (Throwable e) {
try {
returnVal = targetClass.getDeclaredMethod(methodName, args);
returnVal.setAccessible(true);
mValueType = typeVariant;
return returnVal;
} catch (Throwable e2) {
// Swallow the error and keep trying other variants
}
}
}
}
return returnVal;
}
private Method setupSetterOrGetter(Class targetClass, HashMap<Class, HashMap<String, Method>> propertyMapMap, String prefix, Class valueType) {
Method setterOrGetter = null;
try {
mPropertyMapLock.writeLock().lock();
HashMap<String, Method> propertyMap = propertyMapMap.get(targetClass);
if (propertyMap != null) {
setterOrGetter = propertyMap.get(mPropertyName);
}
if (setterOrGetter == null) {
setterOrGetter = getPropertyFunction(targetClass, prefix, valueType);
if (propertyMap == null) {
propertyMap = new HashMap<String, Method>();
propertyMapMap.put(targetClass, propertyMap);
}
propertyMap.put(mPropertyName, setterOrGetter);
}
} finally {
mPropertyMapLock.writeLock().unlock();
}
return setterOrGetter;
}
void setupSetter(Class targetClass) {
mSetter = setupSetterOrGetter(targetClass, sSetterPropertyMap, "set", mValueType);
}
private void setupGetter(Class targetClass) {
mGetter = setupSetterOrGetter(targetClass, sGetterPropertyMap, "get", null);
}
@SuppressWarnings("unchecked")
void setupSetterAndGetter(Object target) {
if (mProperty != null) {
try {
Object testValue = mProperty.get(target);
for (Keyframe kf : mKeyframeSet.mKeyframes) {
if (!kf.hasValue()) {
kf.setValue(mProperty.get(target));
}
}
return;
} catch (Throwable e) {
mProperty = null;
}
}
Class targetClass = target.getClass();
if (mSetter == null) {
setupSetter(targetClass);
}
for (Keyframe kf : mKeyframeSet.mKeyframes) {
if (!kf.hasValue()) {
if (mGetter == null) {
setupGetter(targetClass);
if (mGetter == null) {
return;
}
}
try {
kf.setValue(mGetter.invoke(target));
} catch (Throwable e) {
e.printStackTrace();
}
}
}
}
@SuppressWarnings("unchecked")
private void setupValue(Object target, Keyframe kf) {
if (mProperty != null) {
kf.setValue(mProperty.get(target));
}
try {
if (mGetter == null) {
Class targetClass = target.getClass();
setupGetter(targetClass);
if (mGetter == null) {
return;
}
}
kf.setValue(mGetter.invoke(target));
} catch (Throwable e) {
e.printStackTrace();
}
}
void setupStartValue(Object target) {
setupValue(target, mKeyframeSet.mKeyframes.get(0));
}
void setupEndValue(Object target) {
setupValue(target, mKeyframeSet.mKeyframes.get(mKeyframeSet.mKeyframes.size() - 1));
}
@Override
public PropertyValuesHolder clone() {
try {
PropertyValuesHolder newPVH = (PropertyValuesHolder) super.clone();
newPVH.mPropertyName = mPropertyName;
newPVH.mProperty = mProperty;
newPVH.mKeyframeSet = mKeyframeSet.clone();
newPVH.mEvaluator = mEvaluator;
return newPVH;
} catch (CloneNotSupportedException e) {
return null;
}
}
@SuppressWarnings("unchecked")
void setAnimatedValue(Object target) {
if (mProperty != null) {
mProperty.set(target, getAnimatedValue());
}
if (mSetter != null) {
try {
mTmpValueArray[0] = getAnimatedValue();
mSetter.invoke(target, mTmpValueArray);
} catch (Throwable e) {
e.printStackTrace();
}
}
}
void init() {
if (mEvaluator == null) {
mEvaluator = (mValueType == Integer.class) ? sIntEvaluator : (mValueType == Float.class) ? sFloatEvaluator : null;
}
if (mEvaluator != null) {
mKeyframeSet.setEvaluator(mEvaluator);
}
}
public void setEvaluator(TypeEvaluator evaluator) {
mEvaluator = evaluator;
mKeyframeSet.setEvaluator(evaluator);
}
void calculateValue(float fraction) {
mAnimatedValue = mKeyframeSet.getValue(fraction);
}
public void setPropertyName(String propertyName) {
mPropertyName = propertyName;
}
public void setProperty(Property property) {
mProperty = property;
}
public String getPropertyName() {
return mPropertyName;
}
Object getAnimatedValue() {
return mAnimatedValue;
}
@Override
public String toString() {
return mPropertyName + ": " + mKeyframeSet.toString();
}
static String getMethodName(String prefix, String propertyName) {
if (propertyName == null || propertyName.length() == 0) {
return prefix;
}
char firstLetter = Character.toUpperCase(propertyName.charAt(0));
String theRest = propertyName.substring(1);
return prefix + firstLetter + theRest;
}
static class IntPropertyValuesHolder extends PropertyValuesHolder {
private static final HashMap<Class, HashMap<String, Integer>> sJNISetterPropertyMap = new HashMap<Class, HashMap<String, Integer>>();
private IntProperty mIntProperty;
IntKeyframeSet mIntKeyframeSet;
int mIntAnimatedValue;
public IntPropertyValuesHolder(String propertyName, IntKeyframeSet keyframeSet) {
super(propertyName);
mValueType = int.class;
mKeyframeSet = keyframeSet;
mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet;
}
public IntPropertyValuesHolder(Property property, IntKeyframeSet keyframeSet) {
super(property);
mValueType = int.class;
mKeyframeSet = keyframeSet;
mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet;
if (property instanceof IntProperty) {
mIntProperty = (IntProperty) mProperty;
}
}
public IntPropertyValuesHolder(String propertyName, int... values) {
super(propertyName);
setIntValues(values);
}
public IntPropertyValuesHolder(Property property, int... values) {
super(property);
setIntValues(values);
if (property instanceof IntProperty) {
mIntProperty = (IntProperty) mProperty;
}
}
@Override
public void setIntValues(int... values) {
super.setIntValues(values);
mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet;
}
@Override
void calculateValue(float fraction) {
mIntAnimatedValue = mIntKeyframeSet.getIntValue(fraction);
}
@Override
Object getAnimatedValue() {
return mIntAnimatedValue;
}
@Override
public IntPropertyValuesHolder clone() {
IntPropertyValuesHolder newPVH = (IntPropertyValuesHolder) super.clone();
newPVH.mIntKeyframeSet = (IntKeyframeSet) newPVH.mKeyframeSet;
return newPVH;
}
@SuppressWarnings("unchecked")
@Override
void setAnimatedValue(Object target) {
if (mIntProperty != null) {
mIntProperty.setValue(target, mIntAnimatedValue);
return;
}
if (mProperty != null) {
mProperty.set(target, mIntAnimatedValue);
return;
}
if (mSetter != null) {
try {
mTmpValueArray[0] = mIntAnimatedValue;
mSetter.invoke(target, mTmpValueArray);
} catch (Throwable e) {
e.printStackTrace();
}
}
}
@Override
void setupSetter(Class targetClass) {
if (mProperty != null) {
return;
}
super.setupSetter(targetClass);
}
}
static class FloatPropertyValuesHolder extends PropertyValuesHolder {
private static final HashMap<Class, HashMap<String, Integer>> sJNISetterPropertyMap = new HashMap<Class, HashMap<String, Integer>>();
private FloatProperty10 mFloatProperty;
FloatKeyframeSet mFloatKeyframeSet;
float mFloatAnimatedValue;
public FloatPropertyValuesHolder(String propertyName, FloatKeyframeSet keyframeSet) {
super(propertyName);
mValueType = float.class;
mKeyframeSet = keyframeSet;
mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet;
}
public FloatPropertyValuesHolder(Property property, FloatKeyframeSet keyframeSet) {
super(property);
mValueType = float.class;
mKeyframeSet = keyframeSet;
mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet;
if (property instanceof FloatProperty10) {
mFloatProperty = (FloatProperty10) mProperty;
}
}
public FloatPropertyValuesHolder(String propertyName, float... values) {
super(propertyName);
setFloatValues(values);
}
public FloatPropertyValuesHolder(Property property, float... values) {
super(property);
setFloatValues(values);
if (property instanceof FloatProperty10) {
mFloatProperty = (FloatProperty10) mProperty;
}
}
@Override
public void setFloatValues(float... values) {
super.setFloatValues(values);
mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet;
}
@Override
void calculateValue(float fraction) {
mFloatAnimatedValue = mFloatKeyframeSet.getFloatValue(fraction);
}
@Override
Object getAnimatedValue() {
return mFloatAnimatedValue;
}
@Override
public FloatPropertyValuesHolder clone() {
FloatPropertyValuesHolder newPVH = (FloatPropertyValuesHolder) super.clone();
newPVH.mFloatKeyframeSet = (FloatKeyframeSet) newPVH.mKeyframeSet;
return newPVH;
}
@SuppressWarnings("unchecked")
@Override
void setAnimatedValue(Object target) {
if (mFloatProperty != null) {
mFloatProperty.setValue(target, mFloatAnimatedValue);
return;
}
if (mProperty != null) {
mProperty.set(target, mFloatAnimatedValue);
return;
}
if (mSetter != null) {
try {
mTmpValueArray[0] = mFloatAnimatedValue;
mSetter.invoke(target, mTmpValueArray);
} catch (Throwable e) {
e.printStackTrace();
}
}
}
@Override
void setupSetter(Class targetClass) {
if (mProperty != null) {
return;
}
super.setupSetter(targetClass);
}
}
}

View File

@ -1,182 +0,0 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.ui.Animation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Internal class to automatically generate a Property for a given class/name pair, given the
* specification of {@link Property#of(java.lang.Class, java.lang.Class, java.lang.String)}
*/
class ReflectiveProperty<T, V> extends Property<T, V> {
private static final String PREFIX_GET = "get";
private static final String PREFIX_IS = "is";
private static final String PREFIX_SET = "set";
private Method mSetter;
private Method mGetter;
private Field mField;
/**
* For given property name 'name', look for getName/isName method or 'name' field.
* Also look for setName method (optional - could be readonly). Failing method getters and
* field results in throwing NoSuchPropertyException.
*
* @param propertyHolder The class on which the methods or field are found
* @param name The name of the property, where this name is capitalized and appended to
* "get" and "is to search for the appropriate methods. If the get/is methods are not found,
* the constructor will search for a field with that exact name.
*/
public ReflectiveProperty(Class<T> propertyHolder, Class<V> valueType, String name) {
// TODO: cache reflection info for each new class/name pair
super(valueType, name);
char firstLetter = Character.toUpperCase(name.charAt(0));
String theRest = name.substring(1);
String capitalizedName = firstLetter + theRest;
String getterName = PREFIX_GET + capitalizedName;
try {
mGetter = propertyHolder.getMethod(getterName, (Class<?>[]) null);
} catch (NoSuchMethodException e) {
try {
/* The native implementation uses JNI to do reflection, which allows access to private methods.
* getDeclaredMethod(..) does not find superclass methods, so it's implemented as a fallback.
*/
mGetter = propertyHolder.getDeclaredMethod(getterName, (Class<?>[]) null);
mGetter.setAccessible(true);
} catch (NoSuchMethodException e2) {
// getName() not available - try isName() instead
getterName = PREFIX_IS + capitalizedName;
try {
mGetter = propertyHolder.getMethod(getterName, (Class<?>[]) null);
} catch (NoSuchMethodException e3) {
try {
/* The native implementation uses JNI to do reflection, which allows access to private methods.
* getDeclaredMethod(..) does not find superclass methods, so it's implemented as a fallback.
*/
mGetter = propertyHolder.getDeclaredMethod(getterName, (Class<?>[]) null);
mGetter.setAccessible(true);
} catch (NoSuchMethodException e4) {
// Try public field instead
try {
mField = propertyHolder.getField(name);
Class fieldType = mField.getType();
if (!typesMatch(valueType, fieldType)) {
throw new NoSuchPropertyException("Underlying type (" + fieldType + ") " +
"does not match Property type (" + valueType + ")");
}
return;
} catch (NoSuchFieldException e5) {
// no way to access property - throw appropriate exception
throw new NoSuchPropertyException("No accessor method or field found for"
+ " property with name " + name);
}
}
}
}
}
Class getterType = mGetter.getReturnType();
// Check to make sure our getter type matches our valueType
if (!typesMatch(valueType, getterType)) {
throw new NoSuchPropertyException("Underlying type (" + getterType + ") " +
"does not match Property type (" + valueType + ")");
}
String setterName = PREFIX_SET + capitalizedName;
try {
// mSetter = propertyHolder.getMethod(setterName, getterType);
// The native implementation uses JNI to do reflection, which allows access to private methods.
mSetter = propertyHolder.getDeclaredMethod(setterName, getterType);
mSetter.setAccessible(true);
} catch (NoSuchMethodException ignored) {
// Okay to not have a setter - just a readonly property
}
}
/**
* Utility method to check whether the type of the underlying field/method on the target
* object matches the type of the Property. The extra checks for primitive types are because
* generics will force the Property type to be a class, whereas the type of the underlying
* method/field will probably be a primitive type instead. Accept float as matching Float,
* etc.
*/
private boolean typesMatch(Class<V> valueType, Class getterType) {
if (getterType != valueType) {
if (getterType.isPrimitive()) {
return (getterType == float.class && valueType == Float.class) ||
(getterType == int.class && valueType == Integer.class) ||
(getterType == boolean.class && valueType == Boolean.class) ||
(getterType == long.class && valueType == Long.class) ||
(getterType == double.class && valueType == Double.class) ||
(getterType == short.class && valueType == Short.class) ||
(getterType == byte.class && valueType == Byte.class) ||
(getterType == char.class && valueType == Character.class);
}
return false;
}
return true;
}
@Override
public void set(T object, V value) {
if (mSetter != null) {
try {
mSetter.invoke(object, value);
} catch (IllegalAccessException e) {
throw new AssertionError();
} catch (InvocationTargetException e) {
throw new RuntimeException(e.getCause());
}
} else if (mField != null) {
try {
mField.set(object, value);
} catch (IllegalAccessException e) {
throw new AssertionError();
}
} else {
throw new UnsupportedOperationException("Property " + getName() +" is read-only");
}
}
@Override
public V get(T object) {
if (mGetter != null) {
try {
return (V) mGetter.invoke(object, (Object[])null);
} catch (IllegalAccessException e) {
throw new AssertionError();
} catch (InvocationTargetException e) {
throw new RuntimeException(e.getCause());
}
} else if (mField != null) {
try {
return (V) mField.get(object);
} catch (IllegalAccessException e) {
throw new AssertionError();
}
}
// Should not get here: there should always be a non-null getter or field
throw new AssertionError();
}
/**
* Returns false if there is no setter or public field underlying this Property.
*/
@Override
public boolean isReadOnly() {
return (mSetter == null && mField == null);
}
}

View File

@ -1,21 +0,0 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.ui.Animation;
public interface TypeEvaluator<T> {
T evaluate(float fraction, T startValue, T endValue);
}

View File

@ -1,675 +0,0 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.ui.Animation;
import android.os.Looper;
import android.util.AndroidRuntimeException;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import org.telegram.android.AndroidUtilities;
import java.util.ArrayList;
import java.util.HashMap;
public class ValueAnimator extends Animator10 {
private static float sDurationScale = 1.0f;
static final int STOPPED = 0;
static final int RUNNING = 1;
static final int SEEKED = 2;
long mStartTime;
long mSeekTime = -1;
private long mPauseTime;
private boolean mResumed = false;
protected static ThreadLocal<AnimationHandler> sAnimationHandler = new ThreadLocal<AnimationHandler>();
private static final Interpolator sDefaultInterpolator = new AccelerateDecelerateInterpolator();
private boolean mPlayingBackwards = false;
private int mCurrentIteration = 0;
private float mCurrentFraction = 0f;
private boolean mStartedDelay = false;
private long mDelayStartTime;
int mPlayingState = STOPPED;
private boolean mRunning = false;
private boolean mStarted = false;
private boolean mStartListenersCalled = false;
boolean mInitialized = false;
private long mDuration = (long)(300 * sDurationScale);
private long mUnscaledDuration = 300;
private long mStartDelay = 0;
private long mUnscaledStartDelay = 0;
private int mRepeatCount = 0;
private int mRepeatMode = RESTART;
private Interpolator mInterpolator = sDefaultInterpolator;
private ArrayList<AnimatorUpdateListener> mUpdateListeners = null;
PropertyValuesHolder[] mValues;
HashMap<String, PropertyValuesHolder> mValuesMap;
public static final int RESTART = 1;
public static final int REVERSE = 2;
public static final int INFINITE = -1;
public static void setDurationScale(float durationScale) {
sDurationScale = durationScale;
}
public static float getDurationScale() {
return sDurationScale;
}
public ValueAnimator() {
}
public static ValueAnimator ofInt(int... values) {
ValueAnimator anim = new ValueAnimator();
anim.setIntValues(values);
return anim;
}
public static ValueAnimator ofFloat(float... values) {
ValueAnimator anim = new ValueAnimator();
anim.setFloatValues(values);
return anim;
}
public static ValueAnimator ofPropertyValuesHolder(PropertyValuesHolder... values) {
ValueAnimator anim = new ValueAnimator();
anim.setValues(values);
return anim;
}
public static ValueAnimator ofObject(TypeEvaluator evaluator, Object... values) {
ValueAnimator anim = new ValueAnimator();
anim.setObjectValues(values);
anim.setEvaluator(evaluator);
return anim;
}
public void setIntValues(int... values) {
if (values == null || values.length == 0) {
return;
}
if (mValues == null || mValues.length == 0) {
setValues(PropertyValuesHolder.ofInt("", values));
} else {
PropertyValuesHolder valuesHolder = mValues[0];
valuesHolder.setIntValues(values);
}
mInitialized = false;
}
public void setFloatValues(float... values) {
if (values == null || values.length == 0) {
return;
}
if (mValues == null || mValues.length == 0) {
setValues(PropertyValuesHolder.ofFloat("", values));
} else {
PropertyValuesHolder valuesHolder = mValues[0];
valuesHolder.setFloatValues(values);
}
mInitialized = false;
}
public void setObjectValues(Object... values) {
if (values == null || values.length == 0) {
return;
}
if (mValues == null || mValues.length == 0) {
setValues(PropertyValuesHolder.ofObject("", null, values));
} else {
PropertyValuesHolder valuesHolder = mValues[0];
valuesHolder.setObjectValues(values);
}
mInitialized = false;
}
public void setValues(PropertyValuesHolder... values) {
int numValues = values.length;
mValues = values;
mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues);
for (PropertyValuesHolder valuesHolder : values) {
mValuesMap.put(valuesHolder.getPropertyName(), valuesHolder);
}
mInitialized = false;
}
public PropertyValuesHolder[] getValues() {
return mValues;
}
void initAnimation() {
if (!mInitialized) {
int numValues = mValues.length;
for (PropertyValuesHolder mValue : mValues) {
mValue.init();
}
mInitialized = true;
}
}
public ValueAnimator setDuration(long duration) {
if (duration < 0) {
throw new IllegalArgumentException("Animators cannot have negative duration: " + duration);
}
mUnscaledDuration = duration;
mDuration = (long)(duration * sDurationScale);
return this;
}
public long getDuration() {
return mUnscaledDuration;
}
public void setCurrentPlayTime(long playTime) {
initAnimation();
long currentTime = AnimationUtils.currentAnimationTimeMillis();
if (mPlayingState != RUNNING) {
mSeekTime = playTime;
mPlayingState = SEEKED;
}
mStartTime = currentTime - playTime;
doAnimationFrame(currentTime);
}
public long getCurrentPlayTime() {
if (!mInitialized || mPlayingState == STOPPED) {
return 0;
}
return AnimationUtils.currentAnimationTimeMillis() - mStartTime;
}
@SuppressWarnings("unchecked")
protected static class AnimationHandler implements Runnable {
protected final ArrayList<ValueAnimator> mAnimations = new ArrayList<ValueAnimator>();
private final ArrayList<ValueAnimator> mTmpAnimations = new ArrayList<ValueAnimator>();
protected final ArrayList<ValueAnimator> mPendingAnimations = new ArrayList<ValueAnimator>();
protected final ArrayList<ValueAnimator> mDelayedAnims = new ArrayList<ValueAnimator>();
private final ArrayList<ValueAnimator> mEndingAnims = new ArrayList<ValueAnimator>();
private final ArrayList<ValueAnimator> mReadyAnims = new ArrayList<ValueAnimator>();
private boolean mAnimationScheduled;
public void start() {
scheduleAnimation();
}
private void doAnimationFrame(long frameTime) {
while (mPendingAnimations.size() > 0) {
ArrayList<ValueAnimator> pendingCopy = (ArrayList<ValueAnimator>) mPendingAnimations.clone();
mPendingAnimations.clear();
int count = pendingCopy.size();
for (ValueAnimator anim : pendingCopy) {
if (anim.mStartDelay == 0) {
anim.startAnimation(this);
} else {
mDelayedAnims.add(anim);
}
}
}
int numDelayedAnims = mDelayedAnims.size();
for (ValueAnimator anim : mDelayedAnims) {
if (anim.delayedAnimationFrame(frameTime)) {
mReadyAnims.add(anim);
}
}
int numReadyAnims = mReadyAnims.size();
if (numReadyAnims > 0) {
for (ValueAnimator anim : mReadyAnims) {
anim.startAnimation(this);
anim.mRunning = true;
mDelayedAnims.remove(anim);
}
mReadyAnims.clear();
}
int numAnims = mAnimations.size();
for (ValueAnimator mAnimation : mAnimations) {
mTmpAnimations.add(mAnimation);
}
for (int i = 0; i < numAnims; ++i) {
ValueAnimator anim = mTmpAnimations.get(i);
if (mAnimations.contains(anim) && anim.doAnimationFrame(frameTime)) {
mEndingAnims.add(anim);
}
}
mTmpAnimations.clear();
if (mEndingAnims.size() > 0) {
for (ValueAnimator mEndingAnim : mEndingAnims) {
mEndingAnim.endAnimation(this);
}
mEndingAnims.clear();
}
if (!mAnimations.isEmpty() || !mDelayedAnims.isEmpty()) {
scheduleAnimation();
}
}
@Override
public void run() {
mAnimationScheduled = false;
doAnimationFrame(System.nanoTime() / 1000000);
}
private void scheduleAnimation() {
if (!mAnimationScheduled) {
AndroidUtilities.runOnUIThread(this);
mAnimationScheduled = true;
}
}
}
public long getStartDelay() {
return mUnscaledStartDelay;
}
public void setStartDelay(long startDelay) {
this.mStartDelay = (long)(startDelay * sDurationScale);
mUnscaledStartDelay = startDelay;
}
public Object getAnimatedValue() {
if (mValues != null && mValues.length > 0) {
return mValues[0].getAnimatedValue();
}
return null;
}
public Object getAnimatedValue(String propertyName) {
PropertyValuesHolder valuesHolder = mValuesMap.get(propertyName);
if (valuesHolder != null) {
return valuesHolder.getAnimatedValue();
} else {
return null;
}
}
public void setRepeatCount(int value) {
mRepeatCount = value;
}
public int getRepeatCount() {
return mRepeatCount;
}
public void setRepeatMode(int value) {
mRepeatMode = value;
}
public int getRepeatMode() {
return mRepeatMode;
}
public void addUpdateListener(AnimatorUpdateListener listener) {
if (mUpdateListeners == null) {
mUpdateListeners = new ArrayList<AnimatorUpdateListener>();
}
mUpdateListeners.add(listener);
}
public void removeAllUpdateListeners() {
if (mUpdateListeners == null) {
return;
}
mUpdateListeners.clear();
mUpdateListeners = null;
}
public void removeUpdateListener(AnimatorUpdateListener listener) {
if (mUpdateListeners == null) {
return;
}
mUpdateListeners.remove(listener);
if (mUpdateListeners.size() == 0) {
mUpdateListeners = null;
}
}
@Override
public void setInterpolator(Interpolator value) {
if (value != null) {
mInterpolator = value;
} else {
mInterpolator = new LinearInterpolator();
}
}
@Override
public Interpolator getInterpolator() {
return mInterpolator;
}
public void setEvaluator(TypeEvaluator value) {
if (value != null && mValues != null && mValues.length > 0) {
mValues[0].setEvaluator(value);
}
}
@SuppressWarnings("unchecked")
private void notifyStartListeners() {
if (mListeners != null && !mStartListenersCalled) {
ArrayList<AnimatorListener> tmpListeners = (ArrayList<AnimatorListener>) mListeners.clone();
int numListeners = tmpListeners.size();
for (AnimatorListener tmpListener : tmpListeners) {
tmpListener.onAnimationStart(this);
}
}
mStartListenersCalled = true;
}
private void start(boolean playBackwards) {
if (Looper.myLooper() == null) {
throw new AndroidRuntimeException("Animators may only be run on Looper threads");
}
mPlayingBackwards = playBackwards;
mCurrentIteration = 0;
mPlayingState = STOPPED;
mStarted = true;
mStartedDelay = false;
mPaused = false;
AnimationHandler animationHandler = getOrCreateAnimationHandler();
animationHandler.mPendingAnimations.add(this);
if (mStartDelay == 0) {
setCurrentPlayTime(0);
mPlayingState = STOPPED;
mRunning = true;
notifyStartListeners();
}
animationHandler.start();
}
@Override
public void start() {
start(false);
}
@SuppressWarnings("unchecked")
@Override
public void cancel() {
AnimationHandler handler = getOrCreateAnimationHandler();
if (mPlayingState != STOPPED || handler.mPendingAnimations.contains(this) || handler.mDelayedAnims.contains(this)) {
if ((mStarted || mRunning) && mListeners != null) {
if (!mRunning) {
notifyStartListeners();
}
ArrayList<AnimatorListener> tmpListeners = (ArrayList<AnimatorListener>) mListeners.clone();
for (AnimatorListener listener : tmpListeners) {
listener.onAnimationCancel(this);
}
}
endAnimation(handler);
}
}
@Override
public void end() {
AnimationHandler handler = getOrCreateAnimationHandler();
if (!handler.mAnimations.contains(this) && !handler.mPendingAnimations.contains(this)) {
mStartedDelay = false;
startAnimation(handler);
mStarted = true;
} else if (!mInitialized) {
initAnimation();
}
animateValue(mPlayingBackwards ? 0f : 1f);
endAnimation(handler);
}
@Override
public void resume() {
if (mPaused) {
mResumed = true;
}
super.resume();
}
@Override
public void pause() {
boolean previouslyPaused = mPaused;
super.pause();
if (!previouslyPaused && mPaused) {
mPauseTime = -1;
mResumed = false;
}
}
@Override
public boolean isRunning() {
return (mPlayingState == RUNNING || mRunning);
}
@Override
public boolean isStarted() {
return mStarted;
}
public void reverse() {
mPlayingBackwards = !mPlayingBackwards;
if (mPlayingState == RUNNING) {
long currentTime = AnimationUtils.currentAnimationTimeMillis();
long currentPlayTime = currentTime - mStartTime;
long timeLeft = mDuration - currentPlayTime;
mStartTime = currentTime - timeLeft;
} else if (mStarted) {
end();
} else {
start(true);
}
}
@SuppressWarnings("unchecked")
private void endAnimation(AnimationHandler handler) {
handler.mAnimations.remove(this);
handler.mPendingAnimations.remove(this);
handler.mDelayedAnims.remove(this);
mPlayingState = STOPPED;
mPaused = false;
if ((mStarted || mRunning) && mListeners != null) {
if (!mRunning) {
notifyStartListeners();
}
ArrayList<AnimatorListener> tmpListeners = (ArrayList<AnimatorListener>) mListeners.clone();
int numListeners = tmpListeners.size();
for (AnimatorListener tmpListener : tmpListeners) {
tmpListener.onAnimationEnd(this);
}
}
mRunning = false;
mStarted = false;
mStartListenersCalled = false;
mPlayingBackwards = false;
}
private void startAnimation(AnimationHandler handler) {
initAnimation();
handler.mAnimations.add(this);
if (mStartDelay > 0 && mListeners != null) {
notifyStartListeners();
}
}
private boolean delayedAnimationFrame(long currentTime) {
if (!mStartedDelay) {
mStartedDelay = true;
mDelayStartTime = currentTime;
} else {
if (mPaused) {
if (mPauseTime < 0) {
mPauseTime = currentTime;
}
return false;
} else if (mResumed) {
mResumed = false;
if (mPauseTime > 0) {
mDelayStartTime += (currentTime - mPauseTime);
}
}
long deltaTime = currentTime - mDelayStartTime;
if (deltaTime > mStartDelay) {
mStartTime = currentTime - (deltaTime - mStartDelay);
mPlayingState = RUNNING;
return true;
}
}
return false;
}
boolean animationFrame(long currentTime) {
boolean done = false;
switch (mPlayingState) {
case RUNNING:
case SEEKED:
float fraction = mDuration > 0 ? (float)(currentTime - mStartTime) / mDuration : 1f;
if (fraction >= 1f) {
if (mCurrentIteration < mRepeatCount || mRepeatCount == INFINITE) {
if (mListeners != null) {
int numListeners = mListeners.size();
for (AnimatorListener mListener : mListeners) {
mListener.onAnimationRepeat(this);
}
}
if (mRepeatMode == REVERSE) {
mPlayingBackwards = !mPlayingBackwards;
}
mCurrentIteration += (int)fraction;
fraction = fraction % 1f;
mStartTime += mDuration;
} else {
done = true;
fraction = Math.min(fraction, 1.0f);
}
}
if (mPlayingBackwards) {
fraction = 1f - fraction;
}
animateValue(fraction);
break;
}
return done;
}
final boolean doAnimationFrame(long frameTime) {
if (mPlayingState == STOPPED) {
mPlayingState = RUNNING;
if (mSeekTime < 0) {
mStartTime = frameTime;
} else {
mStartTime = frameTime - mSeekTime;
mSeekTime = -1;
}
}
if (mPaused) {
if (mPauseTime < 0) {
mPauseTime = frameTime;
}
return false;
} else if (mResumed) {
mResumed = false;
if (mPauseTime > 0) {
mStartTime += (frameTime - mPauseTime);
}
}
final long currentTime = Math.max(frameTime, mStartTime);
return animationFrame(currentTime);
}
public float getAnimatedFraction() {
return mCurrentFraction;
}
void animateValue(float fraction) {
fraction = mInterpolator.getInterpolation(fraction);
mCurrentFraction = fraction;
int numValues = mValues.length;
for (PropertyValuesHolder mValue : mValues) {
mValue.calculateValue(fraction);
}
if (mUpdateListeners != null) {
int numListeners = mUpdateListeners.size();
for (AnimatorUpdateListener mUpdateListener : mUpdateListeners) {
mUpdateListener.onAnimationUpdate(this);
}
}
}
@Override
public ValueAnimator clone() {
final ValueAnimator anim = (ValueAnimator) super.clone();
if (mUpdateListeners != null) {
ArrayList<AnimatorUpdateListener> oldListeners = mUpdateListeners;
anim.mUpdateListeners = new ArrayList<AnimatorUpdateListener>();
int numListeners = oldListeners.size();
for (AnimatorUpdateListener oldListener : oldListeners) {
anim.mUpdateListeners.add(oldListener);
}
}
anim.mSeekTime = -1;
anim.mPlayingBackwards = false;
anim.mCurrentIteration = 0;
anim.mInitialized = false;
anim.mPlayingState = STOPPED;
anim.mStartedDelay = false;
PropertyValuesHolder[] oldValues = mValues;
if (oldValues != null) {
int numValues = oldValues.length;
anim.mValues = new PropertyValuesHolder[numValues];
anim.mValuesMap = new HashMap<String, PropertyValuesHolder>(numValues);
for (int i = 0; i < numValues; ++i) {
PropertyValuesHolder newValuesHolder = oldValues[i].clone();
anim.mValues[i] = newValuesHolder;
anim.mValuesMap.put(newValuesHolder.getPropertyName(), newValuesHolder);
}
}
return anim;
}
public interface AnimatorUpdateListener {
void onAnimationUpdate(ValueAnimator animation);
}
public static int getCurrentAnimationsCount() {
AnimationHandler handler = sAnimationHandler.get();
return handler != null ? handler.mAnimations.size() : 0;
}
public static void clearAllAnimations() {
AnimationHandler handler = sAnimationHandler.get();
if (handler != null) {
handler.mAnimations.clear();
handler.mPendingAnimations.clear();
handler.mDelayedAnims.clear();
}
}
private static AnimationHandler getOrCreateAnimationHandler() {
AnimationHandler handler = sAnimationHandler.get();
if (handler == null) {
handler = new AnimationHandler();
sAnimationHandler.set(handler);
}
return handler;
}
}

View File

@ -1,349 +0,0 @@
/*
Copyright 2012 Jake Wharton
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package org.telegram.ui.Animation;
import android.graphics.Camera;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.os.Build;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import java.lang.ref.WeakReference;
import java.util.WeakHashMap;
public class View10 extends Animation {
public static boolean NEED_PROXY = Build.VERSION.SDK_INT < 11;
private static final WeakHashMap<View, View10> PROXIES = new WeakHashMap<>();
public static View10 wrap(View view) {
View10 proxy = PROXIES.get(view);
Animation animation = view.getAnimation();
if (proxy == null || proxy != animation && animation != null) {
proxy = new View10(view);
PROXIES.put(view, proxy);
} else if (animation == null) {
view.setAnimation(proxy);
}
return proxy;
}
private final WeakReference<View> mView;
private final Camera mCamera = new Camera();
private boolean mHasPivot;
private float mAlpha = 1;
private float mPivotX;
private float mPivotY;
private float mRotationX;
private float mRotationY;
private float mRotationZ;
private float mScaleX = 1;
private float mScaleY = 1;
private float mTranslationX;
private float mTranslationY;
private final RectF mBefore = new RectF();
private final RectF mAfter = new RectF();
private final Matrix mTempMatrix = new Matrix();
private View10(View view) {
setDuration(0);
setFillAfter(true);
view.setAnimation(this);
mView = new WeakReference<>(view);
}
public float getAlpha() {
return mAlpha;
}
public void setAlpha(float alpha) {
if (mAlpha != alpha) {
mAlpha = alpha;
View view = mView.get();
if (view != null) {
view.invalidate();
}
}
}
public float getPivotX() {
return mPivotX;
}
public void setPivotX(float pivotX) {
if (!mHasPivot || mPivotX != pivotX) {
prepareForUpdate();
mHasPivot = true;
mPivotX = pivotX;
invalidateAfterUpdate();
}
}
public float getPivotY() {
return mPivotY;
}
public void setPivotY(float pivotY) {
if (!mHasPivot || mPivotY != pivotY) {
prepareForUpdate();
mHasPivot = true;
mPivotY = pivotY;
invalidateAfterUpdate();
}
}
public float getRotation() {
return mRotationZ;
}
public void setRotation(float rotation) {
if (mRotationZ != rotation) {
prepareForUpdate();
mRotationZ = rotation;
invalidateAfterUpdate();
}
}
public float getRotationX() {
return mRotationX;
}
public void setRotationX(float rotationX) {
if (mRotationX != rotationX) {
prepareForUpdate();
mRotationX = rotationX;
invalidateAfterUpdate();
}
}
public float getRotationY() {
return mRotationY;
}
public void setRotationY(float rotationY) {
if (mRotationY != rotationY) {
prepareForUpdate();
mRotationY = rotationY;
invalidateAfterUpdate();
}
}
public float getScaleX() {
return mScaleX;
}
public void setScaleX(float scaleX) {
if (mScaleX != scaleX) {
prepareForUpdate();
mScaleX = scaleX;
invalidateAfterUpdate();
}
}
public float getScaleY() {
return mScaleY;
}
public void setScaleY(float scaleY) {
if (mScaleY != scaleY) {
prepareForUpdate();
mScaleY = scaleY;
invalidateAfterUpdate();
}
}
public int getScrollX() {
View view = mView.get();
if (view == null) {
return 0;
}
return view.getScrollX();
}
public void setScrollX(int value) {
View view = mView.get();
if (view != null) {
view.scrollTo(value, view.getScrollY());
}
}
public int getScrollY() {
View view = mView.get();
if (view == null) {
return 0;
}
return view.getScrollY();
}
public void setScrollY(int value) {
View view = mView.get();
if (view != null) {
view.scrollTo(view.getScrollX(), value);
}
}
public float getTranslationX() {
return mTranslationX;
}
public void setTranslationX(float translationX) {
if (mTranslationX != translationX) {
prepareForUpdate();
mTranslationX = translationX;
invalidateAfterUpdate();
}
}
public float getTranslationY() {
return mTranslationY;
}
public void setTranslationY(float translationY) {
if (mTranslationY != translationY) {
prepareForUpdate();
mTranslationY = translationY;
invalidateAfterUpdate();
}
}
public float getX() {
View view = mView.get();
if (view == null) {
return 0;
}
return view.getLeft() + mTranslationX;
}
public void setX(float x) {
View view = mView.get();
if (view != null) {
setTranslationX(x - view.getLeft());
}
}
public float getY() {
View view = mView.get();
if (view == null) {
return 0;
}
return view.getTop() + mTranslationY;
}
public void setY(float y) {
View view = mView.get();
if (view != null) {
setTranslationY(y - view.getTop());
}
}
private void prepareForUpdate() {
View view = mView.get();
if (view != null) {
computeRect(mBefore, view);
}
}
private void invalidateAfterUpdate() {
View view = mView.get();
if (view == null || view.getParent() == null) {
return;
}
final RectF after = mAfter;
computeRect(after, view);
after.union(mBefore);
((View) view.getParent()).invalidate(
(int) Math.floor(after.left),
(int) Math.floor(after.top),
(int) Math.ceil(after.right),
(int) Math.ceil(after.bottom));
}
private void computeRect(final RectF r, View view) {
final float w = view.getWidth();
final float h = view.getHeight();
r.set(0, 0, w, h);
final Matrix m = mTempMatrix;
m.reset();
transformMatrix(m, view);
mTempMatrix.mapRect(r);
r.offset(view.getLeft(), view.getTop());
if (r.right < r.left) {
final float f = r.right;
r.right = r.left;
r.left = f;
}
if (r.bottom < r.top) {
final float f = r.top;
r.top = r.bottom;
r.bottom = f;
}
}
private void transformMatrix(Matrix m, View view) {
final float w = view.getWidth();
final float h = view.getHeight();
final boolean hasPivot = mHasPivot;
final float pX = hasPivot ? mPivotX : w / 2f;
final float pY = hasPivot ? mPivotY : h / 2f;
final float rX = mRotationX;
final float rY = mRotationY;
final float rZ = mRotationZ;
if ((rX != 0) || (rY != 0) || (rZ != 0)) {
final Camera camera = mCamera;
camera.save();
camera.rotateX(rX);
camera.rotateY(rY);
camera.rotateZ(-rZ);
camera.getMatrix(m);
camera.restore();
m.preTranslate(-pX, -pY);
m.postTranslate(pX, pY);
}
final float sX = mScaleX;
final float sY = mScaleY;
if ((sX != 1.0f) || (sY != 1.0f)) {
m.postScale(sX, sY);
final float sPX = -(pX / w) * ((sX * w) - w);
final float sPY = -(pY / h) * ((sY * h) - h);
m.postTranslate(sPX, sPY);
}
m.postTranslate(mTranslationX, mTranslationY);
}
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
View view = mView.get();
if (view != null) {
t.setAlpha(mAlpha);
transformMatrix(t.getMatrix(), view);
}
}
}

View File

@ -1,112 +0,0 @@
/*
* 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.AnimationCompat;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import org.telegram.ui.Animation.Animator10;
import org.telegram.ui.Animation.AnimatorListenerAdapter10;
import org.telegram.ui.Animation.View10;
public class AnimatorListenerAdapterProxy {
protected Object animatorListenerAdapter;
public AnimatorListenerAdapterProxy() {
if (View10.NEED_PROXY) {
animatorListenerAdapter = new AnimatorListenerAdapter10() {
@Override
public void onAnimationCancel(Animator10 animation) {
AnimatorListenerAdapterProxy.this.onAnimationCancel(animation);
}
@Override
public void onAnimationEnd(Animator10 animation) {
AnimatorListenerAdapterProxy.this.onAnimationEnd(animation);
}
@Override
public void onAnimationRepeat(Animator10 animation) {
AnimatorListenerAdapterProxy.this.onAnimationRepeat(animation);
}
@Override
public void onAnimationStart(Animator10 animation) {
AnimatorListenerAdapterProxy.this.onAnimationStart(animation);
}
@Override
public void onAnimationPause(Animator10 animation) {
AnimatorListenerAdapterProxy.this.onAnimationPause(animation);
}
@Override
public void onAnimationResume(Animator10 animation) {
AnimatorListenerAdapterProxy.this.onAnimationResume(animation);
}
};
} else {
animatorListenerAdapter = new AnimatorListenerAdapter() {
@Override
public void onAnimationCancel(Animator animation) {
AnimatorListenerAdapterProxy.this.onAnimationCancel(animation);
}
@Override
public void onAnimationEnd(Animator animation) {
AnimatorListenerAdapterProxy.this.onAnimationEnd(animation);
}
@Override
public void onAnimationRepeat(Animator animation) {
AnimatorListenerAdapterProxy.this.onAnimationRepeat(animation);
}
@Override
public void onAnimationStart(Animator animation) {
AnimatorListenerAdapterProxy.this.onAnimationStart(animation);
}
@Override
public void onAnimationPause(Animator animation) {
AnimatorListenerAdapterProxy.this.onAnimationPause(animation);
}
@Override
public void onAnimationResume(Animator animation) {
AnimatorListenerAdapterProxy.this.onAnimationResume(animation);
}
};
}
}
public void onAnimationCancel(Object animation) {
}
public void onAnimationEnd(Object animation) {
}
public void onAnimationRepeat(Object animation) {
}
public void onAnimationStart(Object animation) {
}
public void onAnimationPause(Object animation) {
}
public void onAnimationResume(Object animation) {
}
}

View File

@ -1,128 +0,0 @@
/*
* 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.AnimationCompat;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.view.animation.Interpolator;
import org.telegram.ui.Animation.Animator10;
import org.telegram.ui.Animation.AnimatorListenerAdapter10;
import org.telegram.ui.Animation.AnimatorSet10;
import org.telegram.ui.Animation.View10;
import java.lang.reflect.Array;
import java.util.ArrayList;
public class AnimatorSetProxy {
private Object animatorSet;
public static <T, U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
return copyOfRange(original, 0, newLength, newType);
}
@SuppressWarnings("unchecked")
public static <T, U> T[] copyOfRange(U[] original, int start, int end, Class<? extends T[]> newType) {
if (start > end) {
throw new IllegalArgumentException();
}
int originalLength = original.length;
if (start < 0 || start > originalLength) {
throw new ArrayIndexOutOfBoundsException();
}
int resultLength = end - start;
int copyLength = Math.min(resultLength, originalLength - start);
T[] result = (T[]) Array.newInstance(newType.getComponentType(), resultLength);
System.arraycopy(original, start, result, 0, copyLength);
return result;
}
public AnimatorSetProxy() {
if (View10.NEED_PROXY) {
animatorSet = new AnimatorSet10();
} else {
animatorSet = new AnimatorSet();
}
}
@SuppressWarnings("unchecked")
public void playTogether(Object... items) {
if (View10.NEED_PROXY) {
Animator10[] animators = copyOf(items, items.length, Animator10[].class);
((AnimatorSet10) animatorSet).playTogether(animators);
} else {
Animator[] animators = copyOf(items, items.length, Animator[].class);
((AnimatorSet) animatorSet).playTogether(animators);
}
}
public void playTogether(ArrayList<Object> items) {
if (View10.NEED_PROXY) {
ArrayList<Animator10> animators = new ArrayList<Animator10>();
for (Object obj : items) {
animators.add((Animator10)obj);
}
((AnimatorSet10) animatorSet).playTogether(animators);
} else {
ArrayList<Animator> animators = new ArrayList<Animator>();
for (Object obj : items) {
animators.add((Animator)obj);
}
((AnimatorSet) animatorSet).playTogether(animators);
}
}
public AnimatorSetProxy setDuration(long duration) {
if (View10.NEED_PROXY) {
((AnimatorSet10) animatorSet).setDuration(duration);
} else {
((AnimatorSet) animatorSet).setDuration(duration);
}
return this;
}
public void start() {
if (View10.NEED_PROXY) {
((AnimatorSet10) animatorSet).start();
} else {
((AnimatorSet) animatorSet).start();
}
}
public void cancel() {
if (View10.NEED_PROXY) {
((AnimatorSet10) animatorSet).cancel();
} else {
((AnimatorSet) animatorSet).cancel();
}
}
public void addListener(AnimatorListenerAdapterProxy listener) {
if (View10.NEED_PROXY) {
((AnimatorSet10) animatorSet).addListener((AnimatorListenerAdapter10) listener.animatorListenerAdapter);
} else {
((AnimatorSet) animatorSet).addListener((AnimatorListenerAdapter) listener.animatorListenerAdapter);
}
}
public void setInterpolator(Interpolator interpolator) {
if (View10.NEED_PROXY) {
((AnimatorSet10) animatorSet).setInterpolator(interpolator);
} else {
((AnimatorSet) animatorSet).setInterpolator(interpolator);
}
}
@Override
public boolean equals(Object o) {
return animatorSet == o;
}
}

View File

@ -1,129 +0,0 @@
/*
* 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.AnimationCompat;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.view.animation.Interpolator;
import org.telegram.ui.Animation.AnimatorListenerAdapter10;
import org.telegram.ui.Animation.ObjectAnimator10;
import org.telegram.ui.Animation.View10;
public class ObjectAnimatorProxy {
private Object objectAnimator;
public ObjectAnimatorProxy(Object animator) {
objectAnimator = animator;
}
public static Object ofFloat(Object target, String propertyName, float... values) {
if (View10.NEED_PROXY) {
return ObjectAnimator10.ofFloat(target, propertyName, values);
} else {
return ObjectAnimator.ofFloat(target, propertyName, values);
}
}
public static Object ofInt(Object target, String propertyName, int... values) {
if (View10.NEED_PROXY) {
return ObjectAnimator10.ofInt(target, propertyName, values);
} else {
return ObjectAnimator.ofInt(target, propertyName, values);
}
}
public static ObjectAnimatorProxy ofFloatProxy(Object target, String propertyName, float... values) {
if (View10.NEED_PROXY) {
return new ObjectAnimatorProxy(ObjectAnimator10.ofFloat(target, propertyName, values));
} else {
return new ObjectAnimatorProxy(ObjectAnimator.ofFloat(target, propertyName, values));
}
}
public static ObjectAnimatorProxy ofIntProxy(Object target, String propertyName, int... values) {
if (View10.NEED_PROXY) {
return new ObjectAnimatorProxy(ObjectAnimator10.ofInt(target, propertyName, values));
} else {
return new ObjectAnimatorProxy(ObjectAnimator.ofInt(target, propertyName, values));
}
}
public ObjectAnimatorProxy setDuration(long duration) {
if (View10.NEED_PROXY) {
((ObjectAnimator10) objectAnimator).setDuration(duration);
} else {
((ObjectAnimator) objectAnimator).setDuration(duration);
}
return this;
}
public void setInterpolator(Interpolator value) {
if (View10.NEED_PROXY) {
((ObjectAnimator10) objectAnimator).setInterpolator(value);
} else {
((ObjectAnimator) objectAnimator).setInterpolator(value);
}
}
public void start() {
if (View10.NEED_PROXY) {
((ObjectAnimator10) objectAnimator).start();
} else {
((ObjectAnimator) objectAnimator).start();
}
}
public void setAutoCancel(boolean cancel) {
if (View10.NEED_PROXY) {
((ObjectAnimator10) objectAnimator).setAutoCancel(cancel);
} else {
((ObjectAnimator) objectAnimator).setAutoCancel(cancel);
}
}
public boolean isRunning() {
if (View10.NEED_PROXY) {
return ((ObjectAnimator10) objectAnimator).isRunning();
} else {
return ((ObjectAnimator) objectAnimator).isRunning();
}
}
public void end() {
if (View10.NEED_PROXY) {
((ObjectAnimator10) objectAnimator).end();
} else {
((ObjectAnimator) objectAnimator).end();
}
}
public void cancel() {
if (View10.NEED_PROXY) {
((ObjectAnimator10) objectAnimator).cancel();
} else {
((ObjectAnimator) objectAnimator).cancel();
}
}
public ObjectAnimatorProxy addListener(AnimatorListenerAdapterProxy listener) {
if (View10.NEED_PROXY) {
((ObjectAnimator10) objectAnimator).addListener((AnimatorListenerAdapter10) listener.animatorListenerAdapter);
} else {
((ObjectAnimator) objectAnimator).addListener((AnimatorListenerAdapter) listener.animatorListenerAdapter);
}
return this;
}
@Override
public boolean equals(Object o) {
return objectAnimator == o;
}
}

View File

@ -1,248 +0,0 @@
/*
* 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.AnimationCompat;
import android.view.View;
import org.telegram.ui.Animation.View10;
public class ViewProxy {
public static float getAlpha(View view) {
if (View10.NEED_PROXY) {
return View10.wrap(view).getAlpha();
} else {
return view.getAlpha();
}
}
public static void setAlpha(View view, float alpha) {
if (View10.NEED_PROXY) {
View10.wrap(view).setAlpha(alpha);
} else {
view.setAlpha(alpha);
}
}
public static float getPivotX(View view) {
if (View10.NEED_PROXY) {
return View10.wrap(view).getPivotX();
} else {
return view.getPivotX();
}
}
public static void setPivotX(View view, float pivotX) {
if (View10.NEED_PROXY) {
View10.wrap(view).setPivotX(pivotX);
} else {
view.setPivotX(pivotX);
}
}
public static float getPivotY(View view) {
if (View10.NEED_PROXY) {
return View10.wrap(view).getPivotY();
} else {
return view.getPivotY();
}
}
public static void setPivotY(View view, float pivotY) {
if (View10.NEED_PROXY) {
View10.wrap(view).setPivotY(pivotY);
} else {
view.setPivotY(pivotY);
}
}
public static float getRotation(View view) {
if (View10.NEED_PROXY) {
return View10.wrap(view).getRotation();
} else {
return view.getRotation();
}
}
public static void setRotation(View view, float rotation) {
if (View10.NEED_PROXY) {
View10.wrap(view).setRotation(rotation);
} else {
view.setRotation(rotation);
}
}
public static float getRotationX(View view) {
if (View10.NEED_PROXY) {
return View10.wrap(view).getRotationX();
} else {
return view.getRotationX();
}
}
public void setRotationX(View view, float rotationX) {
if (View10.NEED_PROXY) {
View10.wrap(view).setRotationX(rotationX);
} else {
view.setRotationX(rotationX);
}
}
public static float getRotationY(View view) {
if (View10.NEED_PROXY) {
return View10.wrap(view).getRotationY();
} else {
return view.getRotationY();
}
}
public void setRotationY(View view, float rotationY) {
if (View10.NEED_PROXY) {
View10.wrap(view).setRotationY(rotationY);
} else {
view.setRotationY(rotationY);
}
}
public static float getScaleX(View view) {
if (View10.NEED_PROXY) {
return View10.wrap(view).getScaleX();
} else {
return view.getScaleX();
}
}
public static void setScaleX(View view, float scaleX) {
if (View10.NEED_PROXY) {
View10.wrap(view).setScaleX(scaleX);
} else {
view.setScaleX(scaleX);
}
}
public static float getScaleY(View view) {
if (View10.NEED_PROXY) {
return View10.wrap(view).getScaleY();
} else {
return view.getScaleY();
}
}
public static void setScaleY(View view, float scaleY) {
if (View10.NEED_PROXY) {
View10.wrap(view).setScaleY(scaleY);
} else {
view.setScaleY(scaleY);
}
}
public static int getScrollX(View view) {
if (View10.NEED_PROXY) {
return View10.wrap(view).getScrollX();
} else {
return view.getScrollX();
}
}
public static void setScrollX(View view, int value) {
if (View10.NEED_PROXY) {
View10.wrap(view).setScrollX(value);
} else {
view.setScrollX(value);
}
}
public static int getScrollY(View view) {
if (View10.NEED_PROXY) {
return View10.wrap(view).getScrollY();
} else {
return view.getScrollY();
}
}
public static void setScrollY(View view, int value) {
if (View10.NEED_PROXY) {
View10.wrap(view).setScrollY(value);
} else {
view.setScrollY(value);
}
}
public static float getTranslationX(View view) {
if (View10.NEED_PROXY) {
return View10.wrap(view).getTranslationX();
} else {
return view.getTranslationX();
}
}
public static void setTranslationX(View view, float translationX) {
if (View10.NEED_PROXY) {
View10.wrap(view).setTranslationX(translationX);
} else {
view.setTranslationX(translationX);
}
}
public static float getTranslationY(View view) {
if (View10.NEED_PROXY) {
return View10.wrap(view).getTranslationY();
} else {
return view.getTranslationY();
}
}
public static void setTranslationY(View view, float translationY) {
if (View10.NEED_PROXY) {
View10.wrap(view).setTranslationY(translationY);
} else {
view.setTranslationY(translationY);
}
}
public static float getX(View view) {
if (View10.NEED_PROXY) {
return View10.wrap(view).getX();
} else {
return view.getX();
}
}
public static void setX(View view, float x) {
if (View10.NEED_PROXY) {
View10.wrap(view).setX(x);
} else {
view.setX(x);
}
}
public static float getY(View view) {
if (View10.NEED_PROXY) {
return View10.wrap(view).getY();
} else {
return view.getY();
}
}
public static void setY(View view, float y) {
if (View10.NEED_PROXY) {
View10.wrap(view).setY(y);
} else {
view.setY(y);
}
}
public static Object wrap(View view) {
if (View10.NEED_PROXY) {
return View10.wrap(view);
} else {
return view;
}
}
}

View File

@ -36,6 +36,7 @@ import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.Adapters.BaseFragmentAdapter;
import org.telegram.ui.Cells.TextInfoCell;
import org.telegram.ui.Cells.UserCell;
import org.telegram.ui.Components.LayoutHelper;
public class BlockedUsersActivity extends BaseFragment implements NotificationCenter.NotificationCenterDelegate, ContactsActivity.ContactsActivityDelegate {
@ -99,8 +100,8 @@ public class BlockedUsersActivity extends BaseFragment implements NotificationCe
emptyTextView.setText(LocaleController.getString("NoBlocked", R.string.NoBlocked));
frameLayout.addView(emptyTextView);
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) emptyTextView.getLayoutParams();
layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT;
layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT;
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
layoutParams.gravity = Gravity.TOP;
emptyTextView.setLayoutParams(layoutParams);
emptyTextView.setOnTouchListener(new View.OnTouchListener() {
@ -113,15 +114,15 @@ public class BlockedUsersActivity extends BaseFragment implements NotificationCe
progressView = new FrameLayout(context);
frameLayout.addView(progressView);
layoutParams = (FrameLayout.LayoutParams) progressView.getLayoutParams();
layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT;
layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT;
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
progressView.setLayoutParams(layoutParams);
ProgressBar progressBar = new ProgressBar(context);
progressView.addView(progressBar);
layoutParams = (FrameLayout.LayoutParams) progressView.getLayoutParams();
layoutParams.width = FrameLayout.LayoutParams.WRAP_CONTENT;
layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT;
layoutParams.width = LayoutHelper.WRAP_CONTENT;
layoutParams.height = LayoutHelper.WRAP_CONTENT;
layoutParams.gravity = Gravity.CENTER;
progressView.setLayoutParams(layoutParams);
@ -136,8 +137,8 @@ public class BlockedUsersActivity extends BaseFragment implements NotificationCe
}
frameLayout.addView(listView);
layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams();
layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT;
layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT;
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
listView.setLayoutParams(layoutParams);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

View File

@ -34,6 +34,7 @@ import org.telegram.messenger.R;
import org.telegram.messenger.TLRPC;
import org.telegram.messenger.UserConfig;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.ImageListActivity;
import org.telegram.ui.PhotoViewer;
public class ChatActionCell extends BaseCell {
@ -44,8 +45,6 @@ public class ChatActionCell extends BaseCell {
void needOpenUserProfile(int uid);
}
private static Drawable backgroundBlack;
private static Drawable backgroundBlue;
private static TextPaint textPaint;
private static Drawable backgroundWhite;
@ -69,12 +68,8 @@ public class ChatActionCell extends BaseCell {
public ChatActionCell(Context context) {
super(context);
if (backgroundBlack == null) {
backgroundBlack = getResources().getDrawable(R.drawable.system_black);
backgroundBlue = getResources().getDrawable(R.drawable.system_blue);
if (textPaint == null) {
backgroundWhite = getResources().getDrawable(R.drawable.system_white);
textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
textPaint.setColor(0xffffffff);
textPaint.linkColor = 0xffffffff;
@ -276,9 +271,21 @@ public class ChatActionCell extends BaseCell {
textPaint.linkColor = AndroidUtilities.getIntDarkerColor("chatDateColor", -0x50);
}
textPaint.setTextSize(AndroidUtilities.dp(themePrefs.getInt("chatDateSize", 16)));//16
setBubbles(themePrefs.getString("chatBubbleStyle", ImageListActivity.getBubbleName(0)));
backgroundWhite.setColorFilter(themePrefs.getInt("chatDateBubbleColor", 0x59000000), PorterDuff.Mode.MULTIPLY);
}
private void setBubbles(String bubble){
if(bubble.equals(ImageListActivity.getBubbleName(0))){
backgroundWhite = getResources().getDrawable(R.drawable.system_white);
} else if(bubble.equals(ImageListActivity.getBubbleName(1))){
backgroundWhite = getResources().getDrawable(R.drawable.system_white);
} else if(bubble.equals(ImageListActivity.getBubbleName(2))){
backgroundWhite = getResources().getDrawable(R.drawable.system_white_3);
} else if(bubble.equals(ImageListActivity.getBubbleName(3))){
backgroundWhite = getResources().getDrawable(R.drawable.system_white_4);
}
}
@Override
protected void onDraw(Canvas canvas) {
if (currentMessageObject == null) {

View File

@ -10,6 +10,7 @@ package org.telegram.ui.Cells;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.text.StaticLayout;
@ -19,27 +20,21 @@ import android.view.SoundEffectConstants;
import org.telegram.android.AndroidUtilities;
import org.telegram.android.ImageLoader;
import org.telegram.messenger.FileLoader;
import org.telegram.android.MediaController;
import org.telegram.messenger.TLRPC;
import org.telegram.android.MessagesController;
import org.telegram.messenger.R;
import org.telegram.android.MessageObject;
import org.telegram.android.ImageReceiver;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.android.MessagesController;
import org.telegram.messenger.FileLoader;
import org.telegram.ui.Components.ProgressView;
import org.telegram.ui.Components.ResourceLoader;
import org.telegram.ui.Components.SeekBar;
import java.io.File;
public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelegate, MediaController.FileDownloadProgressListener {
private static Drawable[][] statesDrawable = new Drawable[8][2];
private static TextPaint timePaint;
private static Paint circlePaint;
private ImageReceiver avatarImage;
private AvatarDrawable avatarDrawable;
private boolean needAvatarImage = false;
private SeekBar seekBar;
private ProgressView progressView;
private int seekBarX;
@ -50,66 +45,47 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
private int buttonY;
private boolean buttonPressed = false;
private boolean avatarPressed = false;
private StaticLayout timeLayout;
private int timeX;
private int timeWidth;
private String lastTimeString = null;
private int TAG;
public TLRPC.User audioUser;
private TLRPC.FileLocation currentPhoto;
public ChatAudioCell(Context context) {
super(context);
TAG = MediaController.getInstance().generateObserverTag();
avatarImage = new ImageReceiver(this);
avatarImage.setRoundRadius(AndroidUtilities.dp(25));
seekBar = new SeekBar(context);
seekBar.delegate = this;
progressView = new ProgressView();
avatarDrawable = new AvatarDrawable();
drawForwardedName = true;
/*avatarDrawable = new AvatarDrawable();
//Chat Audio Photo
int radius = AndroidUtilities.dp(AndroidUtilities.getIntDef("chatAvatarRadius", 32));
avatarImage.setRoundRadius(radius);
avatarDrawable.setRadius(radius);
avatarDrawable.setRadius(radius);*/
//
if (timePaint == null) {
statesDrawable[0][0] = getResources().getDrawable(R.drawable.play1);
statesDrawable[0][1] = getResources().getDrawable(R.drawable.play1_pressed);
statesDrawable[1][0] = getResources().getDrawable(R.drawable.pause1);
statesDrawable[1][1] = getResources().getDrawable(R.drawable.pause1_pressed);
statesDrawable[2][0] = getResources().getDrawable(R.drawable.audioload1);
statesDrawable[2][1] = getResources().getDrawable(R.drawable.audioload1_pressed);
statesDrawable[3][0] = getResources().getDrawable(R.drawable.audiocancel1);
statesDrawable[3][1] = getResources().getDrawable(R.drawable.audiocancel1_pressed);
statesDrawable[4][0] = getResources().getDrawable(R.drawable.play2);
statesDrawable[4][1] = getResources().getDrawable(R.drawable.play2_pressed);
statesDrawable[5][0] = getResources().getDrawable(R.drawable.pause2);
statesDrawable[5][1] = getResources().getDrawable(R.drawable.pause2_pressed);
statesDrawable[6][0] = getResources().getDrawable(R.drawable.audioload2);
statesDrawable[6][1] = getResources().getDrawable(R.drawable.audioload2_pressed);
statesDrawable[7][0] = getResources().getDrawable(R.drawable.audiocancel2);
statesDrawable[7][1] = getResources().getDrawable(R.drawable.audiocancel2_pressed);
timePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
timePaint.setTextSize(AndroidUtilities.dp(12));
circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (avatarImage != null) {
avatarImage.clearImage();
currentPhoto = null;
}
MediaController.getInstance().removeLoadingFileObserver(this);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
updateButtonState();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
@ -127,9 +103,6 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
buttonPressed = true;
invalidate();
result = true;
} else if (needAvatarImage && avatarImage.isInsideImage(x, y)) {
avatarPressed = true;
result = true;
}
} else if (buttonPressed) {
if (event.getAction() == MotionEvent.ACTION_UP) {
@ -146,20 +119,6 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
invalidate();
}
}
} else if (avatarPressed) {
if (event.getAction() == MotionEvent.ACTION_UP) {
avatarPressed = false;
playSoundEffect(SoundEffectConstants.CLICK);
if (delegate != null) {
delegate.didPressedUserAvatar(this, audioUser);
}
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
avatarPressed = false;
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (!avatarImage.isInsideImage(x, y)) {
avatarPressed = false;
}
}
}
if (!result) {
result = super.onTouchEvent(event);
@ -172,6 +131,9 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
private void didPressedButton() {
if (buttonState == 0) {
boolean result = MediaController.getInstance().playAudio(currentMessageObject);
if (!currentMessageObject.isOut() && currentMessageObject.isContentUnread()) {
MessagesController.getInstance().markMessageContentAsRead(currentMessageObject.getId());
}
if (result) {
buttonState = 1;
invalidate();
@ -216,7 +178,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
}
String timeString = String.format("%02d:%02d", duration / 60, duration % 60);
if (lastTimeString == null || lastTimeString != null && !lastTimeString.equals(timeString)) {
int timeWidth = (int)Math.ceil(timePaint.measureText(timeString));
timeWidth = (int)Math.ceil(timePaint.measureText(timeString));
timeLayout = new StaticLayout(timeString, timePaint, timeWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
}
invalidate();
@ -231,6 +193,12 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
}
public void updateButtonState() {
if (currentMessageObject == null) {
return;
}
if (currentMessageObject.isOut() && currentMessageObject.isSending()) {
buttonState = 4;
} else {
String fileName = currentMessageObject.getFileName();
File cacheFile = FileLoader.getPathToMessage(currentMessageObject.messageOwner);
if (cacheFile.exists()) {
@ -257,6 +225,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
}
}
}
}
updateProgress();
}
@ -301,65 +270,39 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
setMeasuredDimension(width, AndroidUtilities.dp(68) + namesOffset);
setMeasuredDimension(width, AndroidUtilities.dp(66) + namesOffset);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
int x;
if (currentMessageObject.isOut()) {
x = layoutWidth - backgroundWidth + AndroidUtilities.dp(8);
seekBarX = layoutWidth - backgroundWidth + AndroidUtilities.dp(97);
buttonX = layoutWidth - backgroundWidth + AndroidUtilities.dp(67);
timeX = layoutWidth - backgroundWidth + AndroidUtilities.dp(71);
seekBarX = layoutWidth - backgroundWidth + AndroidUtilities.dp(55);
buttonX = layoutWidth - backgroundWidth + AndroidUtilities.dp(13);
timeX = layoutWidth - backgroundWidth + AndroidUtilities.dp(66);
} else {
if (isChat) {
x = AndroidUtilities.dp(69);
seekBarX = AndroidUtilities.dp(158);
buttonX = AndroidUtilities.dp(128);
timeX = AndroidUtilities.dp(132);
seekBarX = AndroidUtilities.dp(116);
buttonX = AndroidUtilities.dp(74);
timeX = AndroidUtilities.dp(127);
} else {
x = AndroidUtilities.dp(16);
seekBarX = AndroidUtilities.dp(106);
buttonX = AndroidUtilities.dp(76);
timeX = AndroidUtilities.dp(80);
seekBarX = AndroidUtilities.dp(64);
buttonX = AndroidUtilities.dp(22);
timeX = AndroidUtilities.dp(75);
}
}
int diff = 0;
if (needAvatarImage) {
avatarImage.setImageCoords(x, AndroidUtilities.dp(9) + namesOffset, AndroidUtilities.dp(50), AndroidUtilities.dp(50));
} else {
diff = AndroidUtilities.dp(56);
seekBarX -= diff;
buttonX -= diff;
timeX -= diff;
}
seekBar.width = backgroundWidth - AndroidUtilities.dp(112) + diff;
seekBar.width = backgroundWidth - AndroidUtilities.dp(70);
seekBar.height = AndroidUtilities.dp(30);
progressView.width = backgroundWidth - AndroidUtilities.dp(136) + diff;
progressView.width = backgroundWidth - AndroidUtilities.dp(94);
progressView.height = AndroidUtilities.dp(30);
seekBarY = AndroidUtilities.dp(13) + namesOffset;
buttonY = AndroidUtilities.dp(10) + namesOffset;
seekBarY = AndroidUtilities.dp(11) + namesOffset;
buttonY = AndroidUtilities.dp(13) + namesOffset;
updateProgress();
}
@Override
protected boolean isUserDataChanged() {
TLRPC.User newUser = MessagesController.getInstance().getUser(currentMessageObject.messageOwner.media.audio.user_id);
TLRPC.FileLocation newPhoto = null;
if (avatarImage != null && newUser != null && newUser.photo != null) {
newPhoto = newUser.photo.photo_small;
}
return currentPhoto == null && newPhoto != null || currentPhoto != null && newPhoto == null || currentPhoto != null && newPhoto != null && (currentPhoto.local_id != newPhoto.local_id || currentPhoto.volume_id != newPhoto.volume_id) || super.isUserDataChanged();
}
@Override
public void setMessageObject(MessageObject messageObject) {
if (currentMessageObject != messageObject || isUserDataChanged()) {
@ -373,23 +316,6 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
if (uid == 0) {
uid = messageObject.messageOwner.from_id;
}
needAvatarImage = !(messageObject.messageOwner.to_id != null && messageObject.messageOwner.to_id.chat_id != 0 && !messageObject.isOut() && messageObject.messageOwner.media.audio.user_id == messageObject.messageOwner.from_id);
audioUser = MessagesController.getInstance().getUser(uid);
if (needAvatarImage) {
if (audioUser != null) {
if (audioUser.photo != null) {
currentPhoto = audioUser.photo.photo_small;
} else {
currentPhoto = null;
}
avatarDrawable.setInfo(audioUser);
} else {
avatarDrawable.setInfo(uid, null, null, false);
currentPhoto = null;
}
avatarImage.setImage(currentPhoto, "50_50", avatarDrawable, false);
}
if (messageObject.isOut()) {
seekBar.type = 0;
@ -412,10 +338,6 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
return;
}
if (needAvatarImage) {
avatarImage.draw(canvas);
}
canvas.save();
if (buttonState == 0 || buttonState == 1) {
canvas.translate(seekBarX, seekBarY);
@ -427,22 +349,25 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
canvas.restore();
int state = buttonState;
if (!currentMessageObject.isOut()) {
state += 4;
timePaint.setColor(0xffa1aab3);
} else {
if (currentMessageObject.isOut()) {
timePaint.setColor(0xff70b15c);
circlePaint.setColor(0xff87bf78);
} else {
state += 5;
timePaint.setColor(0xffa1aab3);
circlePaint.setColor(0xff4195e5);
}
Drawable buttonDrawable = statesDrawable[state][buttonPressed ? 1 : 0];
int side = AndroidUtilities.dp(36);
int x = (side - buttonDrawable.getIntrinsicWidth()) / 2;
int y = (side - buttonDrawable.getIntrinsicHeight()) / 2;
setDrawableBounds(buttonDrawable, x + buttonX, y + buttonY);
Drawable buttonDrawable = ResourceLoader.audioStatesDrawable[state][buttonPressed ? 1 : 0];
setDrawableBounds(buttonDrawable, buttonX, buttonY);
buttonDrawable.draw(canvas);
canvas.save();
canvas.translate(timeX, AndroidUtilities.dp(45) + namesOffset);
canvas.translate(timeX, AndroidUtilities.dp(42) + namesOffset);
timeLayout.draw(canvas);
canvas.restore();
if (currentMessageObject.isContentUnread()) {
canvas.drawCircle(timeX + timeWidth + AndroidUtilities.dp(8), AndroidUtilities.dp(49.5f) + namesOffset, AndroidUtilities.dp(3), circlePaint);
}
}
}

View File

@ -14,12 +14,14 @@ import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.style.ClickableSpan;
import android.view.MotionEvent;
import android.view.SoundEffectConstants;
@ -36,6 +38,8 @@ import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.messenger.TLRPC;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.ResourceLoader;
import org.telegram.ui.Components.StaticLayoutEx;
public class ChatBaseCell extends BaseCell {
@ -48,6 +52,46 @@ public class ChatBaseCell extends BaseCell {
boolean canPerformActions();
}
protected class MyPath extends Path {
private StaticLayout currentLayout;
private int currentLine;
private float lastTop = -1;
public void setCurrentLayout(StaticLayout layout, int start) {
currentLayout = layout;
currentLine = layout.getLineForOffset(start);
lastTop = -1;
}
@Override
public void addRect(float left, float top, float right, float bottom, Direction dir) {
if (lastTop == -1) {
lastTop = top;
} else if (lastTop != top) {
lastTop = top;
currentLine++;
}
float lineRight = currentLayout.getLineRight(currentLine);
float lineLeft = currentLayout.getLineLeft(currentLine);
if (left >= lineRight) {
return;
}
if (right > lineRight) {
right = lineRight;
}
if (left < lineLeft) {
left = lineLeft;
}
super.addRect(left, top, right, bottom, dir);
}
}
protected ClickableSpan pressedLink;
protected boolean linkPreviewPressed;
protected MyPath urlPath = new MyPath();
protected static Paint urlPaint;
public boolean isChat = false;
protected boolean isPressed = false;
protected boolean forwardName = false;
@ -59,26 +103,6 @@ public class ChatBaseCell extends BaseCell {
protected boolean drawBackground = true;
protected MessageObject currentMessageObject;
private static Drawable backgroundDrawableIn;
private static Drawable backgroundDrawableInSelected;
private static Drawable backgroundDrawableOut;
private static Drawable backgroundDrawableOutSelected;
private static Drawable backgroundMediaDrawableIn;
private static Drawable backgroundMediaDrawableInSelected;
private static Drawable backgroundMediaDrawableOut;
private static Drawable backgroundMediaDrawableOutSelected;
private static Drawable checkDrawable;
private static Drawable halfCheckDrawable;
private static Drawable clockDrawable;
private static Drawable broadcastDrawable;
private static Drawable checkMediaDrawable;
private static Drawable halfCheckMediaDrawable;
private static Drawable clockMediaDrawable;
private static Drawable broadcastMediaDrawable;
private static Drawable errorDrawable;
private static Drawable backgroundBlack;
private static Drawable backgroundBlue;
protected static Drawable mediaBackgroundDrawable;
private static TextPaint timePaintIn;
private static TextPaint timePaintOut;
private static TextPaint timeMediaPaint;
@ -144,30 +168,14 @@ public class ChatBaseCell extends BaseCell {
private int last_send_state = 0;
private int last_delete_date = 0;
private int leftBound = 52;//52
private int avatarSize = AndroidUtilities.dp(42);
protected boolean avatarAlignTop = false;
private int avatarLeft = AndroidUtilities.dp(6);
public ChatBaseCell(Context context) {
super(context);
if (backgroundDrawableIn == null) {
backgroundDrawableIn = getResources().getDrawable(R.drawable.msg_in);
backgroundDrawableInSelected = getResources().getDrawable(R.drawable.msg_in_selected);
backgroundDrawableOut = getResources().getDrawable(R.drawable.msg_out);
backgroundDrawableOutSelected = getResources().getDrawable(R.drawable.msg_out_selected);
backgroundMediaDrawableIn = getResources().getDrawable(R.drawable.msg_in_photo);
backgroundMediaDrawableInSelected = getResources().getDrawable(R.drawable.msg_in_photo_selected);
backgroundMediaDrawableOut = getResources().getDrawable(R.drawable.msg_out_photo);
backgroundMediaDrawableOutSelected = getResources().getDrawable(R.drawable.msg_out_photo_selected);
checkDrawable = getResources().getDrawable(R.drawable.msg_check);
halfCheckDrawable = getResources().getDrawable(R.drawable.msg_halfcheck);
clockDrawable = getResources().getDrawable(R.drawable.msg_clock);
checkMediaDrawable = getResources().getDrawable(R.drawable.msg_check_w);
halfCheckMediaDrawable = getResources().getDrawable(R.drawable.msg_halfcheck_w);
clockMediaDrawable = getResources().getDrawable(R.drawable.msg_clock_photo);
errorDrawable = getResources().getDrawable(R.drawable.msg_warning);
mediaBackgroundDrawable = getResources().getDrawable(R.drawable.phototime);
broadcastDrawable = getResources().getDrawable(R.drawable.broadcast3);
broadcastMediaDrawable = getResources().getDrawable(R.drawable.broadcast4);
backgroundBlack = getResources().getDrawable(R.drawable.system_black);
backgroundBlue = getResources().getDrawable(R.drawable.system_blue);
if (timePaintIn == null) {
timePaintIn = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
timePaintIn.setTextSize(AndroidUtilities.dp(12));
timePaintIn.setColor(0xffa1aab3);
@ -206,54 +214,83 @@ public class ChatBaseCell extends BaseCell {
int radius = AndroidUtilities.dp(themePrefs.getInt("chatAvatarRadius", 32));
avatarImage.setRoundRadius(radius);
avatarDrawable.setRadius(radius);
avatarSize = AndroidUtilities.dp(themePrefs.getInt("chatAvatarSize", 42));
avatarLeft = AndroidUtilities.dp(themePrefs.getInt("chatAvatarMarginLeft", 6));
avatarAlignTop = themePrefs.getBoolean("chatAvatarAlignTop", false);
//setBubbles(themePrefs.getString("chatBubbleStyle", ImageListActivity.getBubbleName(0)));
}
private void updateTheme(){
SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE);
int tColor = themePrefs.getInt("themeColor", AndroidUtilities.defColor);
int defColor = themePrefs.getInt("themeColor", AndroidUtilities.defColor);
int lColor = AndroidUtilities.getDefBubbleColor();
int dColor = AndroidUtilities.getIntDarkerColor("themeColor", 0x15);
int dColor = AndroidUtilities.setDarkColor(defColor, 0x15);
int rBubbleColor = themePrefs.getInt("chatRBubbleColor", lColor);
int rBubbleSColor = AndroidUtilities.getIntDarkerColor("chatRBubbleColor", 0x15);
int rBubbleSColor = AndroidUtilities.setDarkColor(rBubbleColor, 0x15);
int lBubbleColor = themePrefs.getInt("chatLBubbleColor", 0xffffffff);
backgroundDrawableOut.setColorFilter(rBubbleColor, PorterDuff.Mode.SRC_IN);
backgroundMediaDrawableOut.setColorFilter(rBubbleColor, PorterDuff.Mode.SRC_IN);
backgroundDrawableOutSelected.setColorFilter(rBubbleSColor, PorterDuff.Mode.SRC_IN);
backgroundMediaDrawableOutSelected.setColorFilter(rBubbleSColor, PorterDuff.Mode.SRC_IN);
backgroundDrawableIn.setColorFilter(lBubbleColor, PorterDuff.Mode.MULTIPLY);
backgroundMediaDrawableIn.setColorFilter(lBubbleColor, PorterDuff.Mode.MULTIPLY);
int checksColor = themePrefs.getInt("chatChecksColor", tColor);
checkDrawable.setColorFilter(checksColor, PorterDuff.Mode.SRC_IN);
halfCheckDrawable.setColorFilter(checksColor, PorterDuff.Mode.SRC_IN);
clockDrawable.setColorFilter(checksColor, PorterDuff.Mode.SRC_IN);
int lBubbleSColor = AndroidUtilities.setDarkColor(lBubbleColor, 0x15);
timePaintOut.setColor(themePrefs.getInt("chatRTimeColor", dColor));
timePaintOut.setTextSize(AndroidUtilities.dp(themePrefs.getInt("chatTimeSize", 12)));
timePaintIn.setColor(themePrefs.getInt("chatLTimeColor", 0xffa1aab3));
timePaintIn.setTextSize(AndroidUtilities.dp(themePrefs.getInt("chatTimeSize", 12)));
int linkColor = themePrefs.getInt("chatLLinkColor", tColor);
int linkColor = themePrefs.getInt("chatLLinkColor", defColor);
int bColor = AndroidUtilities.getIntAlphaColor("chatLBubbleColor", 0xffffffff, 0.9f);
if(currentMessageObject.isOut()){
bColor = AndroidUtilities.getIntAlphaColor("chatRBubbleColor", lColor, 0.9f);
linkColor = themePrefs.getInt("chatRLinkColor", tColor);
linkColor = themePrefs.getInt("chatRLinkColor", defColor);
}
mediaBackgroundDrawable.setColorFilter(bColor, PorterDuff.Mode.SRC_IN);
replyTextPaint.linkColor = linkColor;
//ResourceLoader.loadRecources(getContext());
/*if(ResourceLoader.mediaBackgroundDrawable == null){
ResourceLoader.mediaBackgroundDrawable = getResources().getDrawable(R.drawable.phototime);
ResourceLoader.checkDrawable = getResources().getDrawable(R.drawable.msg_check);
ResourceLoader.halfCheckDrawable = getResources().getDrawable(R.drawable.msg_halfcheck);
ResourceLoader.clockDrawable = getResources().getDrawable(R.drawable.msg_clock);
ResourceLoader.checkMediaDrawable = getResources().getDrawable(R.drawable.msg_check_w);
ResourceLoader.halfCheckMediaDrawable = getResources().getDrawable(R.drawable.msg_halfcheck_w);
ResourceLoader.clockMediaDrawable = getResources().getDrawable(R.drawable.msg_clock_photo);
//ResourceLoader.videoIconDrawable = getResources().getDrawable(R.drawable.ic_video);
ResourceLoader.docMenuInDrawable = getResources().getDrawable(R.drawable.doc_actions_b);
ResourceLoader.docMenuOutDrawable = getResources().getDrawable(R.drawable.doc_actions_g);
}*/
ResourceLoader.mediaBackgroundDrawable.setColorFilter(bColor, PorterDuff.Mode.SRC_IN);
ResourceLoader.backgroundDrawableOut.setColorFilter(rBubbleColor, PorterDuff.Mode.SRC_IN);
ResourceLoader.backgroundMediaDrawableOut.setColorFilter(rBubbleColor, PorterDuff.Mode.SRC_IN);
ResourceLoader.backgroundDrawableOutSelected.setColorFilter(rBubbleSColor, PorterDuff.Mode.SRC_IN);
ResourceLoader.backgroundMediaDrawableOutSelected.setColorFilter(rBubbleSColor, PorterDuff.Mode.SRC_IN);
ResourceLoader.backgroundDrawableIn.setColorFilter(lBubbleColor, PorterDuff.Mode.SRC_IN);
ResourceLoader.backgroundMediaDrawableIn.setColorFilter(lBubbleColor, PorterDuff.Mode.SRC_IN);
ResourceLoader.backgroundDrawableInSelected.setColorFilter(lBubbleSColor, PorterDuff.Mode.SRC_IN);
ResourceLoader.backgroundMediaDrawableInSelected.setColorFilter(lBubbleSColor, PorterDuff.Mode.SRC_IN);
int checksColor = themePrefs.getInt("chatChecksColor", defColor);
ResourceLoader.checkDrawable.setColorFilter(checksColor, PorterDuff.Mode.SRC_IN);
ResourceLoader.halfCheckDrawable.setColorFilter(checksColor, PorterDuff.Mode.SRC_IN);
ResourceLoader.clockDrawable.setColorFilter(checksColor, PorterDuff.Mode.SRC_IN);
ResourceLoader.checkMediaDrawable.setColorFilter(checksColor, PorterDuff.Mode.MULTIPLY);
ResourceLoader.halfCheckMediaDrawable.setColorFilter(checksColor, PorterDuff.Mode.MULTIPLY);
ResourceLoader.halfCheckMediaDrawable.setColorFilter(checksColor, PorterDuff.Mode.MULTIPLY);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
avatarImage.clearImage();
replyImageReceiver.clearImage();
currentPhoto = null;
currentReplyPhoto = null;
avatarImage.onDetachedFromWindow();
replyImageReceiver.onDetachedFromWindow();
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
avatarImage.onAttachedToWindow();
replyImageReceiver.onAttachedToWindow();
}
@Override
@ -262,6 +299,14 @@ public class ChatBaseCell extends BaseCell {
invalidate();
}
protected void resetPressedLink() {
if (pressedLink != null) {
pressedLink = null;
}
linkPreviewPressed = false;
invalidate();
}
public void setDelegate(ChatBaseCellDelegate delegate) {
this.delegate = delegate;
}
@ -336,6 +381,20 @@ public class ChatBaseCell extends BaseCell {
return currentForwardNameString == null && newNameString != null || currentForwardNameString != null && newNameString == null || currentForwardNameString != null && newNameString != null && !currentForwardNameString.equals(newNameString);
}
protected void measureTime(MessageObject messageObject) {
if (!media) {
if (messageObject.isOut()) {
currentTimePaint = timePaintOut;
} else {
currentTimePaint = timePaintIn;
}
} else {
currentTimePaint = timeMediaPaint;
}
currentTimeString = LocaleController.formatterDay.format((long) (messageObject.messageOwner.date) * 1000);
timeWidth = (int)Math.ceil(currentTimePaint.measureText(currentTimeString));
}
public void setMessageObject(MessageObject messageObject) {
currentMessageObject = messageObject;
last_send_state = messageObject.messageOwner.send_state;
@ -415,7 +474,7 @@ public class ChatBaseCell extends BaseCell {
CharSequence str = TextUtils.ellipsize(currentForwardNameString.replace("\n", " "), forwardNamePaint, forwardedNameWidth - AndroidUtilities.dp(40), TextUtils.TruncateAt.END);
str = AndroidUtilities.replaceTags(String.format("%s\n%s <b>%s</b>", LocaleController.getString("ForwardedMessage", R.string.ForwardedMessage), LocaleController.getString("From", R.string.From), str));
forwardedNameLayout = new StaticLayout(str, forwardNamePaint, forwardedNameWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
forwardedNameLayout = StaticLayoutEx.createStaticLayout(str, forwardNamePaint, forwardedNameWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false, TextUtils.TruncateAt.END, forwardedNameWidth, 2);
if (forwardedNameLayout.getLineCount() > 1) {
forwardedNameWidth = Math.max((int) Math.ceil(forwardedNameLayout.getLineWidth(0)), (int) Math.ceil(forwardedNameLayout.getLineWidth(1)));
namesOffset += AndroidUtilities.dp(36);
@ -629,20 +688,21 @@ public class ChatBaseCell extends BaseCell {
timeLayout = new StaticLayout(currentTimeString, currentTimePaint, timeWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
if (!media) {
if (!currentMessageObject.isOut()) {
timeX = backgroundWidth - AndroidUtilities.dp(9) - timeWidth + (isChat ? AndroidUtilities.dp(52) : 0);
timeX = backgroundWidth - AndroidUtilities.dp(9) - timeWidth + (isChat ? AndroidUtilities.dp(leftBound) : 0);
} else {
timeX = layoutWidth - timeWidth - AndroidUtilities.dp(38.5f);
}
} else {
if (!currentMessageObject.isOut()) {
timeX = backgroundWidth - AndroidUtilities.dp(4) - timeWidth + (isChat ? AndroidUtilities.dp(52) : 0);
timeX = backgroundWidth - AndroidUtilities.dp(4) - timeWidth + (isChat ? AndroidUtilities.dp(leftBound) : 0);
} else {
timeX = layoutWidth - timeWidth - AndroidUtilities.dp(42.0f);
}
}
if (isAvatarVisible) {
avatarImage.setImageCoords(AndroidUtilities.dp(6), layoutHeight - AndroidUtilities.dp(45), AndroidUtilities.dp(42), AndroidUtilities.dp(42));
//avatarImage.setImageCoords(AndroidUtilities.dp(6), layoutHeight - AndroidUtilities.dp(45), AndroidUtilities.dp(42), AndroidUtilities.dp(42));
avatarImage.setImageCoords(avatarLeft, avatarAlignTop ? AndroidUtilities.dp(3) : layoutHeight - AndroidUtilities.dp(3) - avatarSize, avatarSize, avatarSize);
}
wasLayout = true;
@ -662,7 +722,7 @@ public class ChatBaseCell extends BaseCell {
@Override
protected void onDraw(Canvas canvas) {
updateTheme();
if (currentMessageObject == null) {
return;
}
@ -675,39 +735,39 @@ public class ChatBaseCell extends BaseCell {
if (isAvatarVisible) {
avatarImage.draw(canvas);
}
updateTheme();
Drawable currentBackgroundDrawable = null;
if (currentMessageObject.isOut()) {
if (isPressed() && isCheckPressed || !isCheckPressed && isPressed || isHighlighted) {
if (!media) {
currentBackgroundDrawable = backgroundDrawableOutSelected;
currentBackgroundDrawable = ResourceLoader.backgroundDrawableOutSelected;
} else {
currentBackgroundDrawable = backgroundMediaDrawableOutSelected;
currentBackgroundDrawable = ResourceLoader.backgroundMediaDrawableOutSelected;
}
} else {
if (!media) {
currentBackgroundDrawable = backgroundDrawableOut;
currentBackgroundDrawable = ResourceLoader.backgroundDrawableOut;
} else {
currentBackgroundDrawable = backgroundMediaDrawableOut;
currentBackgroundDrawable = ResourceLoader.backgroundMediaDrawableOut;
}
}
setDrawableBounds(currentBackgroundDrawable, layoutWidth - backgroundWidth - (!media ? 0 : AndroidUtilities.dp(9)), AndroidUtilities.dp(1), backgroundWidth, layoutHeight - AndroidUtilities.dp(2));
} else {
if (isPressed() && isCheckPressed || !isCheckPressed && isPressed || isHighlighted) {
if (!media) {
currentBackgroundDrawable = backgroundDrawableInSelected;
currentBackgroundDrawable = ResourceLoader.backgroundDrawableInSelected;
} else {
currentBackgroundDrawable = backgroundMediaDrawableInSelected;
currentBackgroundDrawable = ResourceLoader.backgroundMediaDrawableInSelected;
}
} else {
if (!media) {
currentBackgroundDrawable = backgroundDrawableIn;
currentBackgroundDrawable = ResourceLoader.backgroundDrawableIn;
} else {
currentBackgroundDrawable = backgroundMediaDrawableIn;
currentBackgroundDrawable = ResourceLoader.backgroundMediaDrawableIn;
}
}
if (isChat) {
setDrawableBounds(currentBackgroundDrawable, AndroidUtilities.dp(52 + (!media ? 0 : 9)), AndroidUtilities.dp(1), backgroundWidth, layoutHeight - AndroidUtilities.dp(2));
setDrawableBounds(currentBackgroundDrawable, AndroidUtilities.dp(leftBound + (!media ? 0 : 9)), AndroidUtilities.dp(1), backgroundWidth, layoutHeight - AndroidUtilities.dp(2));
} else {
setDrawableBounds(currentBackgroundDrawable, (!media ? 0 : AndroidUtilities.dp(9)), AndroidUtilities.dp(1), backgroundWidth, layoutHeight - AndroidUtilities.dp(2));
}
@ -732,13 +792,14 @@ public class ChatBaseCell extends BaseCell {
if (drawForwardedName && forwardedNameLayout != null) {
forwardNameY = AndroidUtilities.dp(10 + (drawName ? 19 : 0));
int defColor = themePrefs.getInt("themeColor",AndroidUtilities.defColor);
if (currentMessageObject.isOut()) {
//forwardNamePaint.setColor(0xff4a923c);
forwardNamePaint.setColor(themePrefs.getInt("chatForwardColor", AndroidUtilities.getIntDarkerColor("themeColor", 0x15)));
forwardNamePaint.setColor(themePrefs.getInt("chatForwardColor", AndroidUtilities.setDarkColor(defColor, 0x15)));
forwardNameX = currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(10);
} else {
//forwardNamePaint.setColor(0xff006fc8);
forwardNamePaint.setColor(themePrefs.getInt("chatForwardColor", 0xff006fc8));
forwardNamePaint.setColor(themePrefs.getInt("chatForwardColor", defColor));
forwardNameX = currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(19);
}
canvas.save();
@ -762,25 +823,34 @@ public class ChatBaseCell extends BaseCell {
}
Drawable back;
if (ApplicationLoader.isCustomTheme()) {
back = backgroundBlack;
back = ResourceLoader.backgroundBlack;
} else {
back = backgroundBlue;
back = ResourceLoader.backgroundBlue;
}
replyStartY = layoutHeight - AndroidUtilities.dp(58);
back.setBounds(replyStartX - AndroidUtilities.dp(7), replyStartY - AndroidUtilities.dp(6), replyStartX - AndroidUtilities.dp(7) + backWidth, replyStartY + AndroidUtilities.dp(41));
back.draw(canvas);
} else {
if (currentMessageObject.isOut()) {
int color = themePrefs.getInt("chatForwardColor", AndroidUtilities.getIntDarkerColor("themeColor", 0x15));
if (currentMessageObject.isOut()) {
replyLinePaint.setColor(color);//0xff8dc97a);
replyNamePaint.setColor(color);//0xff61a349);
int outColor = themePrefs.getInt("chatRTextColor", 0xff000000);
if (currentMessageObject.replyMessageObject != null && currentMessageObject.replyMessageObject.type == 0) {
replyTextPaint.setColor(outColor);//0xff000000);
} else {
replyTextPaint.setColor(color);//0xff70b15c);
}
replyStartX = currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(11);
} else {
int color = themePrefs.getInt("chatForwardColor", 0xff999999);
replyLinePaint.setColor(color);//0xff6c9fd2);
replyNamePaint.setColor(color);//0xff377aae);
int inColor = themePrefs.getInt("chatLTextColor", 0xff000000);
if (currentMessageObject.replyMessageObject != null && currentMessageObject.replyMessageObject.type == 0) {
replyTextPaint.setColor(inColor);//0xff000000);
} else {
replyTextPaint.setColor(color);//0xff999999);
}
if (currentMessageObject.contentType == 1 && media) {
replyStartX = currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(11);
} else {
@ -808,10 +878,10 @@ public class ChatBaseCell extends BaseCell {
}
}
if (drawTime) {
if (drawTime || !media) {
if (media) {
setDrawableBounds(mediaBackgroundDrawable, timeX - AndroidUtilities.dp(3), layoutHeight - AndroidUtilities.dp(27.5f), timeWidth + AndroidUtilities.dp(6 + (currentMessageObject.isOut() ? 20 : 0)), AndroidUtilities.dp(16.5f));
mediaBackgroundDrawable.draw(canvas);
setDrawableBounds(ResourceLoader.mediaBackgroundDrawable, timeX - AndroidUtilities.dp(3), layoutHeight - AndroidUtilities.dp(27.5f), timeWidth + AndroidUtilities.dp(6 + (currentMessageObject.isOut() ? 20 : 0)), AndroidUtilities.dp(16.5f));
ResourceLoader.mediaBackgroundDrawable.draw(canvas);
canvas.save();
canvas.translate(timeX, layoutHeight - AndroidUtilities.dp(12.0f) - timeLayout.getHeight());
@ -854,62 +924,62 @@ public class ChatBaseCell extends BaseCell {
}
if (drawClock) {
clockDrawable = clockMediaDrawable;
//ResourceLoader.clockDrawable = ResourceLoader.clockMediaDrawable;
if (!media) {
setDrawableBounds(clockDrawable, layoutWidth - AndroidUtilities.dp(18.5f) - clockDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.5f) - clockDrawable.getIntrinsicHeight());
clockDrawable.draw(canvas);
setDrawableBounds(ResourceLoader.clockDrawable, layoutWidth - AndroidUtilities.dp(18.5f) - ResourceLoader.clockDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.5f) - ResourceLoader.clockDrawable.getIntrinsicHeight());
ResourceLoader.clockDrawable.draw(canvas);
} else {
setDrawableBounds(clockMediaDrawable, layoutWidth - AndroidUtilities.dp(22.0f) - clockMediaDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.0f) - clockMediaDrawable.getIntrinsicHeight());
clockMediaDrawable.draw(canvas);
setDrawableBounds(ResourceLoader.clockMediaDrawable, layoutWidth - AndroidUtilities.dp(22.0f) - ResourceLoader.clockMediaDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.0f) - ResourceLoader.clockMediaDrawable.getIntrinsicHeight());
ResourceLoader.clockMediaDrawable.draw(canvas);
}
}
if (isBroadcast) {
if (drawCheck1 || drawCheck2) {
if (!media) {
setDrawableBounds(broadcastDrawable, layoutWidth - AndroidUtilities.dp(20.5f) - broadcastDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.0f) - broadcastDrawable.getIntrinsicHeight());
broadcastDrawable.draw(canvas);
setDrawableBounds(ResourceLoader.broadcastDrawable, layoutWidth - AndroidUtilities.dp(20.5f) - ResourceLoader.broadcastDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.0f) - ResourceLoader.broadcastDrawable.getIntrinsicHeight());
ResourceLoader.broadcastDrawable.draw(canvas);
} else {
setDrawableBounds(broadcastMediaDrawable, layoutWidth - AndroidUtilities.dp(24.0f) - broadcastMediaDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.0f) - broadcastMediaDrawable.getIntrinsicHeight());
broadcastMediaDrawable.draw(canvas);
setDrawableBounds(ResourceLoader.broadcastMediaDrawable, layoutWidth - AndroidUtilities.dp(24.0f) - ResourceLoader.broadcastMediaDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.0f) - ResourceLoader.broadcastMediaDrawable.getIntrinsicHeight());
ResourceLoader.broadcastMediaDrawable.draw(canvas);
}
}
} else {
if (drawCheck2) {
checkDrawable = checkMediaDrawable;
//ResourceLoader.checkDrawable = ResourceLoader.checkMediaDrawable;
if (!media) {
if (drawCheck1) {
setDrawableBounds(checkDrawable, layoutWidth - AndroidUtilities.dp(22.5f) - checkDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.5f) - checkDrawable.getIntrinsicHeight());
setDrawableBounds(ResourceLoader.checkDrawable, layoutWidth - AndroidUtilities.dp(22.5f) - ResourceLoader.checkDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.0f) - ResourceLoader.checkDrawable.getIntrinsicHeight());
} else {
setDrawableBounds(checkDrawable, layoutWidth - AndroidUtilities.dp(18.5f) - checkDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.5f) - checkDrawable.getIntrinsicHeight());
setDrawableBounds(ResourceLoader.checkDrawable, layoutWidth - AndroidUtilities.dp(18.5f) - ResourceLoader.checkDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.0f) - ResourceLoader.checkDrawable.getIntrinsicHeight());
}
checkDrawable.draw(canvas);
ResourceLoader.checkDrawable.draw(canvas);
} else {
if (drawCheck1) {
setDrawableBounds(checkMediaDrawable, layoutWidth - AndroidUtilities.dp(26.0f) - checkMediaDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.0f) - checkMediaDrawable.getIntrinsicHeight());
setDrawableBounds(ResourceLoader.checkMediaDrawable, layoutWidth - AndroidUtilities.dp(26.0f) - ResourceLoader.checkMediaDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.0f) - ResourceLoader.checkMediaDrawable.getIntrinsicHeight());
} else {
setDrawableBounds(checkMediaDrawable, layoutWidth - AndroidUtilities.dp(22.0f) - checkMediaDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.0f) - checkMediaDrawable.getIntrinsicHeight());
setDrawableBounds(ResourceLoader.checkMediaDrawable, layoutWidth - AndroidUtilities.dp(22.0f) - ResourceLoader.checkMediaDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.0f) - ResourceLoader.checkMediaDrawable.getIntrinsicHeight());
}
checkMediaDrawable.draw(canvas);
ResourceLoader.checkMediaDrawable.draw(canvas);
}
}
if (drawCheck1) {
halfCheckDrawable = halfCheckMediaDrawable;
//ResourceLoader.halfCheckDrawable = ResourceLoader.halfCheckMediaDrawable;
if (!media) {
setDrawableBounds(halfCheckDrawable, layoutWidth - AndroidUtilities.dp(18) - halfCheckDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.5f) - halfCheckDrawable.getIntrinsicHeight());
halfCheckDrawable.draw(canvas);
setDrawableBounds(ResourceLoader.halfCheckDrawable, layoutWidth - AndroidUtilities.dp(18) - ResourceLoader.halfCheckDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.0f) - ResourceLoader.halfCheckDrawable.getIntrinsicHeight());
ResourceLoader.halfCheckDrawable.draw(canvas);
} else {
setDrawableBounds(halfCheckMediaDrawable, layoutWidth - AndroidUtilities.dp(20.5f) - halfCheckMediaDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.0f) - halfCheckMediaDrawable.getIntrinsicHeight());
halfCheckMediaDrawable.draw(canvas);
setDrawableBounds(ResourceLoader.halfCheckMediaDrawable, layoutWidth - AndroidUtilities.dp(20.5f) - ResourceLoader.halfCheckMediaDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.0f) - ResourceLoader.halfCheckMediaDrawable.getIntrinsicHeight());
ResourceLoader.halfCheckMediaDrawable.draw(canvas);
}
}
}
if (drawError) {
if (!media) {
setDrawableBounds(errorDrawable, layoutWidth - AndroidUtilities.dp(18) - errorDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(6.5f) - errorDrawable.getIntrinsicHeight());
errorDrawable.draw(canvas);
setDrawableBounds(ResourceLoader.errorDrawable, layoutWidth - AndroidUtilities.dp(18) - ResourceLoader.errorDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(6.5f) - ResourceLoader.errorDrawable.getIntrinsicHeight());
ResourceLoader.errorDrawable.draw(canvas);
} else {
setDrawableBounds(errorDrawable, layoutWidth - AndroidUtilities.dp(20.5f) - errorDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(12.5f) - errorDrawable.getIntrinsicHeight());
errorDrawable.draw(canvas);
setDrawableBounds(ResourceLoader.errorDrawable, layoutWidth - AndroidUtilities.dp(20.5f) - ResourceLoader.errorDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(12.5f) - ResourceLoader.errorDrawable.getIntrinsicHeight());
ResourceLoader.errorDrawable.draw(canvas);
}
}
}

View File

@ -18,9 +18,11 @@ import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.text.Spannable;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.style.ClickableSpan;
import android.view.MotionEvent;
import android.view.SoundEffectConstants;
@ -35,12 +37,16 @@ import org.telegram.android.SendMessagesHelper;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.messenger.TLRPC;
import org.telegram.messenger.Utilities;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.GifDrawable;
import org.telegram.ui.Components.RadialProgress;
import org.telegram.ui.Components.ResourceLoader;
import org.telegram.ui.Components.StaticLayoutEx;
import org.telegram.ui.Components.URLSpanNoUnderline;
import org.telegram.ui.PhotoViewer;
import java.io.File;
@ -50,22 +56,17 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
public interface ChatMediaCellDelegate {
void didClickedImage(ChatMediaCell cell);
void didPressedOther(ChatMediaCell cell);
}
private static Drawable placeholderDocInDrawable;
private static Drawable placeholderDocOutDrawable;
private static Drawable videoIconDrawable;
private static Drawable docMenuInDrawable;
private static Drawable docMenuOutDrawable;
private static Drawable docMenuWhiteDrawable;
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 deleteProgressPaint;
private static TextPaint locationTitlePaint;
private static TextPaint locationAddressPaint;
private GifDrawable gifDrawable = null;
private RadialProgress radialProgress;
@ -79,6 +80,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
private ImageReceiver photoImage;
private boolean photoNotSet = false;
private boolean cancelLoading = false;
private int additionHeight;
private boolean allowedToSetPhoto = true;
@ -95,11 +97,12 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
private int infoWidth;
private int infoOffset = 0;
private String currentInfoString;
//Plus
private StaticLayout infoLayout2;
private int infoWidth2;
private static TextPaint senderPaint;
private int infoOffset2 = 0;
//
private StaticLayout nameLayout;
private int nameWidth = 0;
private String currentNameString;
@ -107,30 +110,14 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
private ChatMediaCellDelegate mediaDelegate = null;
private RectF deleteProgressRect = new RectF();
private int captionX;
private int captionY;
private int captionHeight;
public ChatMediaCell(Context context) {
super(context);
if (placeholderDocInDrawable == null) {
placeholderDocInDrawable = getResources().getDrawable(R.drawable.doc_blue);
placeholderDocOutDrawable = getResources().getDrawable(R.drawable.doc_green);
buttonStatesDrawables[0] = getResources().getDrawable(R.drawable.photoload);
buttonStatesDrawables[1] = getResources().getDrawable(R.drawable.photocancel);
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);
buttonStatesDrawablesDoc[0][1] = getResources().getDrawable(R.drawable.docload_g);
buttonStatesDrawablesDoc[1][1] = getResources().getDrawable(R.drawable.doccancel_g);
buttonStatesDrawablesDoc[2][1] = getResources().getDrawable(R.drawable.docpause_g);
videoIconDrawable = getResources().getDrawable(R.drawable.ic_video);
docMenuInDrawable = getResources().getDrawable(R.drawable.doc_actions_b);
docMenuOutDrawable = getResources().getDrawable(R.drawable.doc_actions_g);
if (infoPaint == null) {
infoPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
infoPaint.setTextSize(AndroidUtilities.dp(12));
@ -139,8 +126,6 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
namePaint.setTextSize(AndroidUtilities.dp(16));
//namePaint.setColor(AndroidUtilities.getIntDef("chatFileInfoColor", 0xff212121));
docMenuWhiteDrawable = getResources().getDrawable(R.drawable.doc_actions_w);
//docMenuWhiteDrawable.setColorFilter(AndroidUtilities.getIntDef("chatFileInfoColor", 0xff70b15c), PorterDuff.Mode.MULTIPLY);
senderPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
senderPaint.setColor(0xffffffff);
senderPaint.setTextSize(AndroidUtilities.dp(15));
@ -149,6 +134,13 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
deleteProgressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
deleteProgressPaint.setColor(0xffe4e2e0);
locationTitlePaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
locationTitlePaint.setTextSize(AndroidUtilities.dp(14));
locationTitlePaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
locationAddressPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
locationAddressPaint.setTextSize(AndroidUtilities.dp(14));
}
TAG = MediaController.getInstance().generateObserverTag();
@ -173,12 +165,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (photoImage != null) {
photoImage.clearImage();
currentPhotoObject = null;
currentPhotoObjectThumb = null;
}
currentUrl = null;
photoImage.onDetachedFromWindow();
if (gifDrawable != null) {
MediaController.getInstance().clearGifDrawable(this);
gifDrawable = null;
@ -186,6 +173,14 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
MediaController.getInstance().removeLoadingFileObserver(this);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (photoImage.onAttachedToWindow()) {
updateButtonState(false);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
@ -193,6 +188,78 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
boolean result = false;
int side = AndroidUtilities.dp(48);
if (currentMessageObject.caption instanceof Spannable && !isPressed) {
if (event.getAction() == MotionEvent.ACTION_DOWN || (linkPreviewPressed || pressedLink != null) && event.getAction() == MotionEvent.ACTION_UP) {
if (nameLayout != null && x >= captionX && x <= captionX + backgroundWidth && y >= captionY && y <= captionY + captionHeight) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
resetPressedLink();
try {
int x2 = (int) (x - captionX);
int y2 = (int) (y - captionY);
final int line = nameLayout.getLineForVertical(y2);
final int off = nameLayout.getOffsetForHorizontal(line, x2);
final float left = nameLayout.getLineLeft(line);
if (left <= x2 && left + nameLayout.getLineWidth(line) >= x2) {
Spannable buffer = (Spannable) currentMessageObject.caption;
ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
if (link.length != 0) {
resetPressedLink();
pressedLink = link[0];
linkPreviewPressed = true;
result = true;
try {
int start = buffer.getSpanStart(pressedLink);
urlPath.setCurrentLayout(nameLayout, start);
nameLayout.getSelectionPath(start, buffer.getSpanEnd(pressedLink), urlPath);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
} else {
resetPressedLink();
}
} else {
resetPressedLink();
}
} catch (Exception e) {
resetPressedLink();
FileLog.e("tmessages", e);
}
} else if (linkPreviewPressed) {
try {
if (pressedLink instanceof URLSpanNoUnderline) {
String url = ((URLSpanNoUnderline) pressedLink).getURL();
if (url.startsWith("@") || url.startsWith("#")) {
if (delegate != null) {
delegate.didPressUrl(url);
}
}
} else {
pressedLink.onClick(this);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
resetPressedLink();
result = true;
}
} else {
resetPressedLink();
}
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
resetPressedLink();
}
if (result && event.getAction() == MotionEvent.ACTION_DOWN) {
startCheckLongPress();
}
if (event.getAction() != MotionEvent.ACTION_DOWN && event.getAction() != MotionEvent.ACTION_MOVE) {
cancelCheckLongPress();
}
if (result) {
return result;
}
}
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (delegate == null || delegate.canPerformActions()) {
if (buttonState != -1 && x >= buttonX && x <= buttonX + side && y >= buttonY && y <= buttonY + side) {
@ -331,25 +398,59 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
Drawable currentButtonDrawable = null;
if (currentMessageObject.type == 9 && gifDrawable == null) {
if (buttonState == 1 && !currentMessageObject.isSending()) {
return buttonStatesDrawablesDoc[2][currentMessageObject.isOut() ? 1 : 0];
return ResourceLoader.buttonStatesDrawablesDoc[2][currentMessageObject.isOut() ? 1 : 0];
} else {
return buttonStatesDrawablesDoc[buttonState][currentMessageObject.isOut() ? 1 : 0];
return ResourceLoader.buttonStatesDrawablesDoc[buttonState][currentMessageObject.isOut() ? 1 : 0];
}
} else {
if (buttonState == 1 && !currentMessageObject.isSending()) {
return buttonStatesDrawables[4];
return ResourceLoader.buttonStatesDrawables[4];
} else {
return buttonStatesDrawables[buttonState];
return ResourceLoader.buttonStatesDrawables[buttonState];
}
}
} else if (buttonState == -1) {
if (currentMessageObject.type == 9 && gifDrawable == null) {
return currentMessageObject.isOut() ? placeholderDocOutDrawable : placeholderDocInDrawable;
//return getThumbForName(currentMessageObject.getFileName());
return currentMessageObject.isOut() ? ResourceLoader.placeholderDocOutDrawable : ResourceLoader.placeholderDocInDrawable;
}
}
return null;
}
}/*
//Plus
private int icons[] = {
R.drawable.media_doc_blue,
R.drawable.media_doc_green,
R.drawable.media_doc_red,
R.drawable.media_doc_yellow
};
private Drawable getThumbForName(String name) {
if (name != null && name.length() != 0) {
int color = -1;
if (name.contains(".doc") || name.contains(".txt") || name.contains(".psd")) {
color = 0;
} else if (name.contains(".xls") || name.contains(".csv")) {
color = 1;
} else if (name.contains(".pdf") || name.contains(".ppt") || name.contains(".key")) {
color = 2;
} else if (name.contains(".zip") || name.contains(".rar") || name.contains(".ai") || name.contains(".mp3") || name.contains(".mov") || name.contains(".avi")) {
color = 3;
}
if (color == -1) {
int idx;
String ext = (idx = name.lastIndexOf(".")) == -1 ? "" : name.substring(idx + 1);
if (ext.length() != 0) {
color = ext.charAt(0) % icons.length;
} else {
color = name.charAt(0) % icons.length;
}
}
return getResources().getDrawable(icons[color]);
}
return getResources().getDrawable(icons[0]);
}*/
//
private void didPressedButton(boolean animated) {
if (buttonState == 0) {
cancelLoading = false;
@ -410,7 +511,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
}
double lat = object.messageOwner.media.geo.lat;
double lon = object.messageOwner.media.geo._long;
String url = String.format(Locale.US, "https://maps.googleapis.com/maps/api/staticmap?center=%f,%f&zoom=13&size=100x100&maptype=roadmap&scale=%d&markers=color:red|size:big|%f,%f&sensor=false", lat, lon, Math.min(2, (int)Math.ceil(AndroidUtilities.density)), lat, lon);
String url = String.format(Locale.US, "https://maps.googleapis.com/maps/api/staticmap?center=%f,%f&zoom=13&size=100x100&maptype=roadmap&scale=%d&markers=color:red|size:big|%f,%f&sensor=false", lat, lon, Math.min(2, (int) Math.ceil(AndroidUtilities.density)), lat, lon);
if (!url.equals(currentUrl)) {
return true;
}
@ -427,10 +528,12 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
@Override
public void setMessageObject(MessageObject messageObject) {
media = messageObject.type != 9;
boolean dataChanged = currentMessageObject == messageObject && (isUserDataChanged() || photoNotSet);
if (currentMessageObject != messageObject || isPhotoDataChanged(messageObject) || dataChanged) {
media = messageObject.type != 9;
cancelLoading = false;
additionHeight = 0;
resetPressedLink();
buttonState = -1;
gifDrawable = null;
@ -454,6 +557,12 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
}
if (currentNameString == null || !currentNameString.equals(name)) {
currentNameString = name;
nameLayout = StaticLayoutEx.createStaticLayout(currentNameString, namePaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false, TextUtils.TruncateAt.END, maxWidth, 1);
if (nameLayout.getLineCount() > 0) {
nameWidth = Math.min(maxWidth, (int) Math.ceil(nameLayout.getLineWidth(0)));
} else {
nameWidth = maxWidth;
}
nameWidth = Math.min(maxWidth, (int) Math.ceil(namePaint.measureText(currentNameString)));
CharSequence str = TextUtils.ellipsize(currentNameString, namePaint, nameWidth, TextUtils.TruncateAt.END);
nameLayout = new StaticLayout(str, namePaint, nameWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
@ -475,21 +584,20 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
if (currentInfoString == null || !currentInfoString.equals(str)) {
currentInfoString = str;
infoOffset = 0;
if(currentMessageObject != null && (currentMessageObject.isOut() || !isChat) ){
infoWidth = Math.min(maxWidth, (int) Math.ceil(infoPaint.measureText(currentInfoString)));
infoLayout2 = null;
}else{
if(isChat){
TLRPC.User fromUser = MessagesController.getInstance().getUser(messageObject.messageOwner.from_id);
String senderName = String.format("%s %s", fromUser.first_name, fromUser.last_name);
infoWidth2 = Math.min(maxWidth, (int) Math.ceil(senderPaint.measureText(senderName)));
CharSequence str2 = TextUtils.ellipsize(senderName, senderPaint, infoWidth2, TextUtils.TruncateAt.END);
infoLayout2 = new StaticLayout(str2, senderPaint, infoWidth2, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
}
infoWidth = Math.max(infoWidth2, (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);
//
}
} else if (messageObject.type == 8) { //GIF
gifDrawable = MediaController.getInstance().getGifDrawable(this, false);
@ -498,20 +606,8 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
if (currentInfoString == null || !currentInfoString.equals(str)) {
currentInfoString = str;
infoOffset = 0;
//
if(currentMessageObject != null && (currentMessageObject.isOut() || !isChat) ){
//infoWidth = (int) Math.ceil(infoPaint.measureText(currentInfoString));
//infoLayout = new StaticLayout(currentInfoString, infoPaint, infoWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
infoLayout = null;
infoLayout2 = null;
}else{
TLRPC.User fromUser = MessagesController.getInstance().getUser(messageObject.messageOwner.from_id);
String senderName = String.format("%s %s", fromUser.first_name, fromUser.last_name);
infoWidth = (int) Math.ceil(senderPaint.measureText(senderName));
infoLayout = new StaticLayout(senderName, senderPaint, infoWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
infoWidth2 = (int) Math.ceil(infoPaint.measureText(currentInfoString));
infoLayout2 = new StaticLayout(currentInfoString, infoPaint, infoWidth2, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
}
infoWidth = (int) Math.ceil(infoPaint.measureText(currentInfoString));
infoLayout = new StaticLayout(currentInfoString, infoPaint, infoWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
}
nameLayout = null;
currentNameString = null;
@ -522,49 +618,52 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
String str = String.format("%d:%02d, %s", minutes, seconds, Utilities.formatFileSize(messageObject.messageOwner.media.video.size));
if (currentInfoString == null || !currentInfoString.equals(str)) {
currentInfoString = str;
infoOffset = videoIconDrawable.getIntrinsicWidth() + AndroidUtilities.dp(4);
if(currentMessageObject != null && (currentMessageObject.isOut() || !isChat)){
//infoOffset = ResourceLoader.videoIconDrawable.getIntrinsicWidth() + AndroidUtilities.dp(4);
//infoWidth = (int) Math.ceil(infoPaint.measureText(currentInfoString));
//infoLayout = new StaticLayout(currentInfoString, infoPaint, infoWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
//Plus
infoLayout = null;
infoLayout2 = null;
}else{
if(isChat){
infoOffset2 = ResourceLoader.videoIconDrawable.getIntrinsicWidth() + AndroidUtilities.dp(5);
infoOffset = 0;
TLRPC.User fromUser = MessagesController.getInstance().getUser(messageObject.messageOwner.from_id);
String senderName = String.format("%s %s", fromUser.first_name, fromUser.last_name);
infoWidth = (int) Math.ceil(senderPaint.measureText(senderName));
infoLayout = new StaticLayout(senderName, senderPaint, infoWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
infoWidth2 = (int) Math.ceil(infoPaint.measureText(currentInfoString));
//infoWidth = (int) Math.ceil(senderPaint.measureText(senderName));
infoWidth = Math.max(infoWidth2, (int) Math.ceil(senderPaint.measureText(senderName)));
infoLayout = new StaticLayout(senderName, senderPaint, infoWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
infoLayout2 = new StaticLayout(currentInfoString, infoPaint, infoWidth2, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
}
}//
}
nameLayout = null;
currentNameString = null;
} else if (messageObject.type == 1) { //PHOTO
}//Plus: member name in photos
else if (messageObject.type == 1) { //PHOTO
TLRPC.User fromUser = MessagesController.getInstance().getUser(messageObject.messageOwner.from_id);
String senderName = String.format("%s %s", fromUser.first_name, fromUser.last_name);
if (currentInfoString == null || !currentInfoString.equals(senderName)) {
currentInfoString = senderName;
infoOffset = 0;
if(currentMessageObject != null && (currentMessageObject.isOut() || !isChat) ){
infoLayout = null;
}else{
if(isChat){
infoWidth = (int) Math.ceil(senderPaint.measureText(currentInfoString));
infoLayout = new StaticLayout(currentInfoString, senderPaint, infoWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
}
if(!isChat)infoLayout = null;
infoLayout2 = null;
}
nameLayout = null;
currentNameString = null;
}
infoLayout2 = null;
}//
else {
currentInfoString = null;
currentNameString = null;
infoLayout = null;
nameLayout = null;
updateSecretTimeText();
infoLayout2 = null;
infoLayout2 = null; //Plus
}
if (messageObject.type == 9) { //doc
photoWidth = AndroidUtilities.dp(86);
@ -581,17 +680,46 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
photoImage.setImageBitmap((BitmapDrawable) null);
}
} else if (messageObject.type == 4) { //geo
double lat = messageObject.messageOwner.media.geo.lat;
double lon = messageObject.messageOwner.media.geo._long;
if (messageObject.messageOwner.media.title != null && messageObject.messageOwner.media.title.length() > 0) {
int maxWidth = (AndroidUtilities.isTablet() ? AndroidUtilities.getMinTabletSide() : Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y)) - AndroidUtilities.dp((isChat && !messageObject.isOut() ? 102 : 40) + 86 + 24);
nameLayout = StaticLayoutEx.createStaticLayout(messageObject.messageOwner.media.title, locationTitlePaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false, TextUtils.TruncateAt.END, maxWidth - AndroidUtilities.dp(4), 3);
int lineCount = nameLayout.getLineCount();
if (messageObject.messageOwner.media.address != null && messageObject.messageOwner.media.address.length() > 0) {
infoLayout = StaticLayoutEx.createStaticLayout(messageObject.messageOwner.media.address, locationAddressPaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false, TextUtils.TruncateAt.END, maxWidth - AndroidUtilities.dp(4), Math.min(3, 4 - lineCount));
} else {
infoLayout = null;
}
media = false;
measureTime(messageObject);
photoWidth = AndroidUtilities.dp(86);
photoHeight = AndroidUtilities.dp(86);
maxWidth = timeWidth + AndroidUtilities.dp(messageObject.isOut() ? 29 : 9);
for (int a = 0; a < lineCount; a++) {
maxWidth = (int) Math.max(maxWidth, nameLayout.getLineWidth(a) + AndroidUtilities.dp(16));
}
if (infoLayout != null) {
lineCount = infoLayout.getLineCount();
for (int a = 0; a < infoLayout.getLineCount(); a++) {
maxWidth = (int) Math.max(maxWidth, infoLayout.getLineWidth(a) + AndroidUtilities.dp(16));
}
}
backgroundWidth = photoWidth + AndroidUtilities.dp(21) + maxWidth;
currentUrl = String.format(Locale.US, "https://maps.googleapis.com/maps/api/staticmap?center=%f,%f&zoom=13&size=72x72&maptype=roadmap&scale=%d&markers=color:red|size:big|%f,%f&sensor=false", lat, lon, Math.min(2, (int) Math.ceil(AndroidUtilities.density)), lat, lon);
} else {
photoWidth = AndroidUtilities.dp(200);
photoHeight = AndroidUtilities.dp(100);
backgroundWidth = photoWidth + AndroidUtilities.dp(12);
currentUrl = String.format(Locale.US, "https://maps.googleapis.com/maps/api/staticmap?center=%f,%f&zoom=13&size=200x100&maptype=roadmap&scale=%d&markers=color:red|size:big|%f,%f&sensor=false", lat, lon, Math.min(2, (int) Math.ceil(AndroidUtilities.density)), lat, lon);
}
double lat = messageObject.messageOwner.media.geo.lat;
double lon = messageObject.messageOwner.media.geo._long;
currentUrl = String.format(Locale.US, "https://maps.googleapis.com/maps/api/staticmap?center=%f,%f&zoom=13&size=200x100&maptype=roadmap&scale=%d&markers=color:red|size:big|%f,%f&sensor=false", lat, lon, Math.min(2, (int)Math.ceil(AndroidUtilities.density)), lat, lon);
photoImage.setNeedsQualityThumb(false);
photoImage.setShouldGenerateQualityThumb(false);
photoImage.setParentMessageObject(null);
photoImage.setImage(currentUrl, null, null, 0);
photoImage.setImage(currentUrl, null, messageObject.isOut() ? ResourceLoader.geoOutDrawable : ResourceLoader.geoInDrawable, 0);
} else if (messageObject.type == 13) { //webp
drawBackground = false;
for (TLRPC.DocumentAttribute attribute : messageObject.messageOwner.media.document.attributes) {
@ -614,11 +742,11 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
}
if (photoHeight > maxHeight) {
photoWidth *= maxHeight / photoHeight;
photoHeight = (int)maxHeight;
photoHeight = (int) maxHeight;
}
if (photoWidth > maxWidth) {
photoHeight *= maxWidth / photoWidth;
photoWidth = (int)maxWidth;
photoWidth = (int) maxWidth;
}
backgroundWidth = photoWidth + AndroidUtilities.dp(12);
currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 80);
@ -674,10 +802,16 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
}
//8 - gif, 1 - photo, 3 - video
if (messageObject.caption != null) {
media = false;
}
currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, AndroidUtilities.getPhotoSize());
if (currentPhotoObject != null) {
if (currentPhotoObject == currentPhotoObjectThumb) {
currentPhotoObjectThumb = null;
}
boolean noSize = false;
if (messageObject.type == 3 || messageObject.type == 8) {
noSize = true;
@ -712,6 +846,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
w = (int) (currentPhotoObject.w / hScale);
}
}
measureTime(messageObject);
int timeWidthTotal = timeWidth + AndroidUtilities.dp(14 + (messageObject.isOut() ? 20 : 0));
if (w < timeWidthTotal) {
w = timeWidthTotal;
@ -728,6 +863,20 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
photoWidth = w;
photoHeight = h;
backgroundWidth = w + AndroidUtilities.dp(12);
if (!media) {
backgroundWidth += AndroidUtilities.dp(9);
}
if (messageObject.caption != null) {
nameLayout = new StaticLayout(messageObject.caption, MessageObject.textPaint, photoWidth - AndroidUtilities.dp(10), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
if (nameLayout.getLineCount() > 0) {
captionHeight = nameLayout.getHeight();
additionHeight += captionHeight + AndroidUtilities.dp(9);
float lastLineWidth = nameLayout.getLineWidth(nameLayout.getLineCount() - 1) + nameLayout.getLineLeft(nameLayout.getLineCount() - 1);
if (photoWidth - AndroidUtilities.dp(8) - lastLineWidth < timeWidthTotal) {
additionHeight += AndroidUtilities.dp(14);
}
}
}
currentPhotoFilter = String.format(Locale.US, "%d_%d", (int) (w / AndroidUtilities.density), (int) (h / AndroidUtilities.density));
if (messageObject.photoThumbs.size() > 1 || messageObject.type == 3 || messageObject.type == 8) {
@ -769,7 +918,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
photoImage.setImage(null, null, currentPhotoObject.location, currentPhotoFilter, 0, false);
}
} else {
photoImage.setImageBitmap((Bitmap)null);
photoImage.setImageBitmap((Bitmap) null);
}
}
super.setMessageObject(messageObject);
@ -790,7 +939,8 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
if (currentPhotoObject == null) {
return;
}
fileName = FileLoader.getAttachFileName(currentPhotoObject);
//fileName = FileLoader.getAttachFileName(currentPhotoObject);
fileName = FileLoader.getAttachFileName(currentPhotoObject, currentMessageObject.isOut());
cacheFile = FileLoader.getPathToMessage(currentMessageObject.messageOwner);
} else if (currentMessageObject.type == 8 || currentMessageObject.type == 3 || currentMessageObject.type == 9) {
if (currentMessageObject.messageOwner.attachPath != null && currentMessageObject.messageOwner.attachPath.length() != 0) {
@ -828,6 +978,11 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
if (cacheFile.exists() && cacheFile.length() == 0) {
cacheFile.delete();
}
//
if (!currentMessageObject.isOut() && cacheFile.exists() && cacheFile.length() != 0 && currentMessageObject.messageOwner.media.document != null) {
if(cacheFile.lastModified()/1000 < currentMessageObject.messageOwner.media.document.date)cacheFile.delete();
}
//
if (!cacheFile.exists()) {
MediaController.getInstance().addLoadingFileObserver(fileName, this);
float setProgress = 0;
@ -865,7 +1020,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), photoHeight + AndroidUtilities.dp(14) + namesOffset);
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), photoHeight + AndroidUtilities.dp(14) + namesOffset + additionHeight);
}
@Override
@ -888,8 +1043,8 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
}
photoImage.setImageCoords(x, AndroidUtilities.dp(7) + namesOffset, photoWidth, photoHeight);
int size = AndroidUtilities.dp(48);
buttonX = (int)(x + (photoWidth - size) / 2.0f);
buttonY = (int)(AndroidUtilities.dp(7) + (photoHeight - size) / 2.0f) + namesOffset;
buttonX = (int) (x + (photoWidth - size) / 2.0f);
buttonY = (int) (AndroidUtilities.dp(7) + (photoHeight - size) / 2.0f) + namesOffset;
radialProgress.setProgressRect(buttonX, buttonY, buttonX + AndroidUtilities.dp(48), buttonY + AndroidUtilities.dp(48));
deleteProgressRect.set(buttonX + AndroidUtilities.dp(3), buttonY + AndroidUtilities.dp(3), buttonX + AndroidUtilities.dp(45), buttonY + AndroidUtilities.dp(45));
@ -906,7 +1061,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
if (currentInfoString == null || !currentInfoString.equals(str)) {
currentInfoString = str;
infoOffset = 0;
infoWidth = (int)Math.ceil(infoPaint.measureText(currentInfoString));
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();
@ -945,7 +1100,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
radialProgress.setHideCurrentDrawable(false);
SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE);
int tColor = themePrefs.getInt("themeColor", AndroidUtilities.defColor);
//int tColor = themePrefs.getInt("themeColor", AndroidUtilities.defColor);
if (currentMessageObject.type == 9) {
Drawable menuDrawable = null;
int color = themePrefs.getInt("chatRTextColor", 0xff000000);
@ -953,16 +1108,16 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
//infoPaint.setColor(0xff70b15c);
infoPaint.setColor(color);
docBackPaint.setColor(0xffdaf5c3);
docMenuWhiteDrawable.setColorFilter(themePrefs.getInt("chatRTimeColor", AndroidUtilities.getIntDarkerColor("themeColor", 0x15)), PorterDuff.Mode.MULTIPLY);
menuDrawable = docMenuOutDrawable = docMenuWhiteDrawable;
ResourceLoader.docMenuOutDrawable.setColorFilter(themePrefs.getInt("chatRTimeColor", AndroidUtilities.getIntDarkerColor("themeColor", 0x15)), PorterDuff.Mode.SRC_IN);
menuDrawable = ResourceLoader.docMenuOutDrawable;
namePaint.setColor(color);
} else {
color = themePrefs.getInt("chatLTextColor", 0xff000000);
//infoPaint.setColor(0xffa1adbb);
infoPaint.setColor(color);
docBackPaint.setColor(0xffebf0f5);
docMenuWhiteDrawable.setColorFilter(themePrefs.getInt("chatLTimeColor", 0xffa1adbb), PorterDuff.Mode.MULTIPLY);
menuDrawable = docMenuInDrawable = docMenuWhiteDrawable;
ResourceLoader.docMenuInDrawable.setColorFilter(themePrefs.getInt("chatLTimeColor", 0xffa1adbb), PorterDuff.Mode.SRC_IN);
menuDrawable = ResourceLoader.docMenuInDrawable;
namePaint.setColor(color);
}
@ -972,15 +1127,15 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
if (buttonState >= 0 && buttonState < 4) {
if (!imageDrawn) {
if (buttonState == 1 && !currentMessageObject.isSending()) {
radialProgress.swapBackground(buttonStatesDrawablesDoc[2][currentMessageObject.isOut() ? 1 : 0]);
radialProgress.swapBackground(ResourceLoader.buttonStatesDrawablesDoc[2][currentMessageObject.isOut() ? 1 : 0]);
} else {
radialProgress.swapBackground(buttonStatesDrawablesDoc[buttonState][currentMessageObject.isOut() ? 1 : 0]);
radialProgress.swapBackground(ResourceLoader.buttonStatesDrawablesDoc[buttonState][currentMessageObject.isOut() ? 1 : 0]);
}
} else {
if (buttonState == 1 && !currentMessageObject.isSending()) {
radialProgress.swapBackground(buttonStatesDrawables[4]);
radialProgress.swapBackground(ResourceLoader.buttonStatesDrawables[4]);
} else {
radialProgress.swapBackground(buttonStatesDrawables[buttonState]);
radialProgress.swapBackground(ResourceLoader.buttonStatesDrawables[buttonState]);
}
}
}
@ -1011,16 +1166,16 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
drawable = 6;
}
}
setDrawableBounds(buttonStatesDrawables[drawable], buttonX, buttonY);
buttonStatesDrawables[drawable].setAlpha((int)(255 * (1.0f - radialProgress.getAlpha())));
buttonStatesDrawables[drawable].draw(canvas);
setDrawableBounds(ResourceLoader.buttonStatesDrawables[drawable], buttonX, buttonY);
ResourceLoader.buttonStatesDrawables[drawable].setAlpha((int) (255 * (1.0f - radialProgress.getAlpha())));
ResourceLoader.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);
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);
invalidate((int) deleteProgressRect.left - offset, (int) deleteProgressRect.top - offset, (int) deleteProgressRect.right + offset * 2, (int) deleteProgressRect.bottom + offset * 2);
}
updateSecretTimeText();
}
@ -1030,12 +1185,66 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
if(themePrefs.getBoolean("chatMemberColorCheck", false)){
senderPaint.setColor(themePrefs.getInt("chatMemberColor", AndroidUtilities.getIntDarkerColor("themeColor", 0x15)));
}else{
//if(currentMessageObject.type == 9){
senderPaint.setColor(AvatarDrawable.getNameColorForId(MessagesController.getInstance().getUser(currentMessageObject.messageOwner.from_id).id));
//}else{
//senderPaint.setColor(0xffffffff);
//}
}
if (currentMessageObject.type == 1 || currentMessageObject.type == 3) {//1: photo 3: video
if (nameLayout != null) {
canvas.save();
canvas.translate(captionX = photoImage.getImageX() + AndroidUtilities.dp(5), captionY = photoImage.getImageY() + photoHeight + AndroidUtilities.dp(6));
if (pressedLink != null) {
canvas.drawPath(urlPath, urlPaint);
}
nameLayout.draw(canvas);
canvas.restore();
}
if (infoLayout != null && (buttonState == 1 || buttonState == 0 || buttonState == 3 || currentMessageObject.isSecretPhoto() || currentMessageObject.type == 1)) {
infoPaint.setColor(0xffffffff);
if (currentMessageObject.type == 1){
setDrawableBounds(ResourceLoader.mediaBackgroundDrawable, photoImage.getImageX() + AndroidUtilities.dp(4), photoImage.getImageY() + AndroidUtilities.dp(4), infoWidth + AndroidUtilities.dp(8) + infoOffset, AndroidUtilities.dp(20));
}else if (currentMessageObject.type == 3){
setDrawableBounds(ResourceLoader.mediaBackgroundDrawable, photoImage.getImageX() + AndroidUtilities.dp(4), photoImage.getImageY() + AndroidUtilities.dp(4), infoWidth + AndroidUtilities.dp(8) + infoOffset2, AndroidUtilities.dp(35));
}else{
setDrawableBounds(ResourceLoader.mediaBackgroundDrawable, photoImage.getImageX() + AndroidUtilities.dp(4), photoImage.getImageY() + AndroidUtilities.dp(4), infoWidth + AndroidUtilities.dp(8) + infoOffset, AndroidUtilities.dp(16.5f));
}
ResourceLoader.mediaBackgroundDrawable.draw(canvas);
if (currentMessageObject.type == 3) {
//setDrawableBounds(ResourceLoader.videoIconDrawable, photoImage.getImageX() + AndroidUtilities.dp(8), photoImage.getImageY() + AndroidUtilities.dp(7.5f));
if (infoLayout2 != null) {
setDrawableBounds(ResourceLoader.videoIconDrawable, photoImage.getImageX() + AndroidUtilities.dp(8), 2*(photoImage.getImageY() + AndroidUtilities.dp(10)));
}else{
setDrawableBounds(ResourceLoader.videoIconDrawable, photoImage.getImageX() + AndroidUtilities.dp(8), photoImage.getImageY() + AndroidUtilities.dp(8));
}
ResourceLoader.videoIconDrawable.draw(canvas);
}
canvas.save();
canvas.translate(photoImage.getImageX() + AndroidUtilities.dp(8) + infoOffset, photoImage.getImageY() + AndroidUtilities.dp(5.5f));
infoLayout.draw(canvas);
if (infoLayout2 != null) {
canvas.translate(infoOffset2, photoImage.getImageY() + AndroidUtilities.dp(12));
infoLayout2.draw(canvas);
}
canvas.restore();
}
} else if (currentMessageObject.type == 4) {
if (nameLayout != null) {
locationAddressPaint.setColor(currentMessageObject.isOut() ? 0xff70b15c : 0xff999999);
canvas.save();
canvas.translate(photoImage.getImageX() + photoImage.getImageWidth() + AndroidUtilities.dp(10), photoImage.getImageY() + AndroidUtilities.dp(3));
nameLayout.draw(canvas);
canvas.restore();
if (infoLayout != null) {
canvas.save();
canvas.translate(photoImage.getImageX() + photoImage.getImageWidth() + AndroidUtilities.dp(10), photoImage.getImageY() + AndroidUtilities.dp(nameLayout.getLineCount() * 16 + 5));
infoLayout.draw(canvas);
canvas.restore();
}
}
} else if (currentMessageObject.type == 9) {
if (nameLayout != null) {
if (infoLayout2 != null) {
canvas.save();
@ -1045,51 +1254,30 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
}
canvas.save();
canvas.translate(photoImage.getImageX() + photoImage.getImageWidth() + AndroidUtilities.dp(10), photoImage.getImageY() + AndroidUtilities.dp(30));
canvas.translate(photoImage.getImageX() + photoImage.getImageWidth() + AndroidUtilities.dp(10), photoImage.getImageY() + AndroidUtilities.dp(30));//8
nameLayout.draw(canvas);
canvas.restore();
if (infoLayout != null) {
canvas.save();
canvas.translate(photoImage.getImageX() + photoImage.getImageWidth() + AndroidUtilities.dp(10), photoImage.getImageY() + AndroidUtilities.dp(50));
canvas.translate(photoImage.getImageX() + photoImage.getImageWidth() + AndroidUtilities.dp(10), photoImage.getImageY() + AndroidUtilities.dp(50));//30
infoLayout.draw(canvas);
canvas.restore();
}
} else if (infoLayout != null && (buttonState == 1 || buttonState == 0 || buttonState == 3 || currentMessageObject.isSecretPhoto() || currentMessageObject.type == 1 || (buttonState == 2 && currentMessageObject.type == 8) )) {
//infoPaint.setColor(0xffffffff);
if(currentMessageObject.isOut()){
int color = themePrefs.getInt("chatRTextColor", 0xff000000);
infoPaint.setColor(color);
videoIconDrawable.setColorFilter(color, PorterDuff.Mode.MULTIPLY);
}else{
int color = themePrefs.getInt("chatLTextColor", 0xff000000);
infoPaint.setColor(color);
videoIconDrawable.setColorFilter(color, PorterDuff.Mode.MULTIPLY);
}
if (currentMessageObject.type == 1){
setDrawableBounds(mediaBackgroundDrawable, photoImage.getImageX() + AndroidUtilities.dp(4), photoImage.getImageY() + AndroidUtilities.dp(4), infoWidth + AndroidUtilities.dp(8) + infoOffset, AndroidUtilities.dp(20));
} else {
setDrawableBounds(mediaBackgroundDrawable, photoImage.getImageX() + AndroidUtilities.dp(4), photoImage.getImageY() + AndroidUtilities.dp(4), Math.max(infoWidth , infoWidth2 + infoOffset) + AndroidUtilities.dp(8) + infoOffset, 2 * AndroidUtilities.dp(20));
}
mediaBackgroundDrawable.draw(canvas);
if (currentMessageObject.type == 3) {
if (infoLayout2 != null) {
setDrawableBounds(videoIconDrawable, photoImage.getImageX() + AndroidUtilities.dp(8), 2*(photoImage.getImageY() + AndroidUtilities.dp(10)));
}else{
setDrawableBounds(videoIconDrawable, photoImage.getImageX() + AndroidUtilities.dp(8), photoImage.getImageY() + AndroidUtilities.dp(8));
}
videoIconDrawable.draw(canvas);
}
} else if (nameLayout != null) {
canvas.save();
canvas.translate(photoImage.getImageX() + AndroidUtilities.dp(8) + infoOffset, photoImage.getImageY() + AndroidUtilities.dp(6));
infoLayout.draw(canvas);
if (infoLayout2 != null) {
canvas.translate(infoOffset, photoImage.getImageY() + AndroidUtilities.dp(12));
infoLayout2.draw(canvas);
}
canvas.translate(photoImage.getImageX() + photoImage.getImageWidth() + AndroidUtilities.dp(10), photoImage.getImageY() + AndroidUtilities.dp(8));
nameLayout.draw(canvas);
canvas.restore();
if (infoLayout != null) {
canvas.save();
canvas.translate(photoImage.getImageX() + photoImage.getImageWidth() + AndroidUtilities.dp(10), photoImage.getImageY() + AndroidUtilities.dp(30));
infoLayout.draw(canvas);
canvas.restore();
}
}
}

View File

@ -13,7 +13,6 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.provider.Browser;
@ -35,6 +34,7 @@ import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.messenger.TLRPC;
import org.telegram.ui.Components.ResourceLoader;
import org.telegram.ui.Components.StaticLayoutEx;
import org.telegram.ui.Components.URLSpanNoUnderline;
@ -44,11 +44,7 @@ public class ChatMessageCell extends ChatBaseCell {
private int textX, textY;
private int totalHeight = 0;
private ClickableSpan pressedLink;
private int linkBlockNum;
private MyPath urlPath = new MyPath();
private boolean linkPreviewPressed;
private static Paint urlPaint;
private int lastVisibleBlockNum = 0;
private int firstVisibleBlockNum = 0;
@ -60,7 +56,6 @@ public class ChatMessageCell extends ChatBaseCell {
private boolean hasLinkPreview;
private int linkPreviewHeight;
private boolean isInstagram;
private int smallImageX;
private int descriptionY;
private int durationWidth;
private StaticLayout siteNameLayout;
@ -69,47 +64,9 @@ public class ChatMessageCell extends ChatBaseCell {
private StaticLayout durationLayout;
private StaticLayout authorLayout;
private static TextPaint durationPaint;
private TLRPC.PhotoSize currentPhotoObject;
private TLRPC.PhotoSize currentPhotoObjectThumb;
private boolean imageCleared;
private static Drawable igvideoDrawable;
private class MyPath extends Path {
private StaticLayout currentLayout;
private int currentLine;
private float lastTop = -1;
public void setCurrentLayout(StaticLayout layout, int start) {
currentLayout = layout;
currentLine = layout.getLineForOffset(start);
lastTop = -1;
}
@Override
public void addRect(float left, float top, float right, float bottom, Direction dir) {
if (lastTop == -1) {
lastTop = top;
} else if (lastTop != top) {
lastTop = top;
currentLine++;
}
float lineRight = currentLayout.getLineRight(currentLine);
float lineLeft = currentLayout.getLineLeft(currentLine);
if (left >= lineRight) {
return;
}
if (right > lineRight) {
right = lineRight;
}
if (left < lineLeft) {
left = lineLeft;
}
super.addRect(left, top, right, bottom, dir);
}
}
public ChatMessageCell(Context context) {
super(context);
drawForwardedName = true;
@ -120,35 +77,27 @@ public class ChatMessageCell extends ChatBaseCell {
}
}
private void resetPressedLink() {
if (pressedLink != null) {
pressedLink = null;
}
linkPreviewPressed = false;
invalidate();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean result = false;
if (currentMessageObject != null && currentMessageObject.textLayoutBlocks != null && !currentMessageObject.textLayoutBlocks.isEmpty() && currentMessageObject.messageText instanceof Spannable && !isPressed) {
if (event.getAction() == MotionEvent.ACTION_DOWN || (linkPreviewPressed || pressedLink != null) && event.getAction() == MotionEvent.ACTION_UP) {
int x = (int)event.getX();
int y = (int)event.getY();
int x = (int) event.getX();
int y = (int) event.getY();
if (x >= textX && y >= textY && x <= textX + currentMessageObject.textWidth && y <= textY + currentMessageObject.textHeight) {
y -= textY;
int blockNum = Math.max(0, y / currentMessageObject.blockHeight);
if (blockNum < currentMessageObject.textLayoutBlocks.size()) {
try {
MessageObject.TextLayoutBlock block = currentMessageObject.textLayoutBlocks.get(blockNum);
x -= textX - (int)Math.ceil(block.textXOffset);
x -= textX - (int) Math.ceil(block.textXOffset);
y -= block.textYOffset;
final int line = block.textLayout.getLineForVertical(y);
final int off = block.textLayout.getOffsetForHorizontal(line, x) + block.charactersOffset;
final float left = block.textLayout.getLineLeft(line);
if (left <= x && left + block.textLayout.getLineWidth(line) >= x) {
Spannable buffer = (Spannable)currentMessageObject.messageText;
Spannable buffer = (Spannable) currentMessageObject.messageText;
ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
if (link.length != 0) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
@ -320,7 +269,7 @@ public class ChatMessageCell extends ChatBaseCell {
pos--;
if (stringBuilder.charAt(pos + addedChars) == ' ') {
stringBuilder.replace(pos + addedChars, pos + addedChars + 1, "\n");
} else {
} else if (stringBuilder.charAt(pos + addedChars) != '\n') {
stringBuilder.insert(pos + addedChars, "\n");
addedChars++;
}
@ -333,7 +282,7 @@ public class ChatMessageCell extends ChatBaseCell {
@Override
protected boolean isUserDataChanged() {
if (imageCleared || !hasLinkPreview && currentMessageObject.messageOwner.media != null && currentMessageObject.messageOwner.media.webpage instanceof TLRPC.TL_webPage) {
if (!hasLinkPreview && currentMessageObject.messageOwner.media != null && currentMessageObject.messageOwner.media.webpage instanceof TLRPC.TL_webPage) {
return true;
}
//suppress warning
@ -343,14 +292,13 @@ public class ChatMessageCell extends ChatBaseCell {
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (linkImageView != null) {
linkImageView.clearImage();
if (currentPhotoObject != null) {
imageCleared = true;
currentPhotoObject = null;
currentPhotoObjectThumb = null;
}
linkImageView.onDetachedFromWindow();
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
linkImageView.onAttachedToWindow();
}
@Override
@ -365,16 +313,12 @@ public class ChatMessageCell extends ChatBaseCell {
resetPressedLink();
linkPreviewPressed = false;
linkPreviewHeight = 0;
smallImageX = 0;
isInstagram = false;
durationLayout = null;
descriptionLayout = null;
titleLayout = null;
siteNameLayout = null;
authorLayout = null;
currentPhotoObject = null;
imageCleared = false;
currentPhotoObjectThumb = null;
int maxWidth;
if (AndroidUtilities.isTablet()) {
@ -427,13 +371,19 @@ public class ChatMessageCell extends ChatBaseCell {
linkPreviewMaxWidth = Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) - AndroidUtilities.dp(80);
}
}
TLRPC.TL_webPage webPage = (TLRPC.TL_webPage) messageObject.messageOwner.media.webpage;
if (webPage.site_name != null && webPage.photo != null && webPage.site_name.toLowerCase().equals("instagram")) {
linkPreviewMaxWidth = Math.max(AndroidUtilities.displaySize.y / 3, currentMessageObject.textWidth);
}
int additinalWidth = AndroidUtilities.dp(10);
int restLinesCount = 3;
int additionalHeight = 0;
linkPreviewMaxWidth -= additinalWidth;
hasLinkPreview = true;
TLRPC.TL_webPage webPage = (TLRPC.TL_webPage) messageObject.messageOwner.media.webpage;
if (currentMessageObject.photoThumbs == null && webPage.photo != null) {
currentMessageObject.generateThumbs(true);
@ -477,7 +427,6 @@ public class ChatMessageCell extends ChatBaseCell {
for (int a = 0; a < titleLayout.getLineCount(); a++) {
int width = (int) Math.ceil(titleLayout.getLineWidth(a));
if (a < restLines) {
smallImageX = Math.max(smallImageX, width);
width += AndroidUtilities.dp(48 + 2);
}
maxChildWidth = Math.max(maxChildWidth, width + additinalWidth);
@ -529,7 +478,6 @@ public class ChatMessageCell extends ChatBaseCell {
for (int a = 0; a < descriptionLayout.getLineCount(); a++) {
int width = (int) Math.ceil(descriptionLayout.getLineWidth(a));
if (a < restLines) {
smallImageX = Math.max(smallImageX, width);
width += AndroidUtilities.dp(48 + 2);
}
maxChildWidth = Math.max(maxChildWidth, width + additinalWidth);
@ -546,8 +494,8 @@ public class ChatMessageCell extends ChatBaseCell {
isSmallImage = false;
}
int maxPhotoWidth = smallImage ? AndroidUtilities.dp(48) : linkPreviewMaxWidth;
currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, maxPhotoWidth);
currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 80);
TLRPC.PhotoSize currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, maxPhotoWidth, true);
TLRPC.PhotoSize currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 80);
if (currentPhotoObjectThumb == currentPhotoObject) {
currentPhotoObjectThumb = null;
}
@ -573,10 +521,12 @@ public class ChatMessageCell extends ChatBaseCell {
float scale = width / (float) maxPhotoWidth;
width /= scale;
height /= scale;
if (webPage.site_name != null && !webPage.site_name.toLowerCase().equals("instagram")) {
if (height > AndroidUtilities.displaySize.y / 3) {
height = AndroidUtilities.displaySize.y / 3;
}
}
}
if (isSmallImage) {
if (AndroidUtilities.dp(50) + additionalHeight > linkPreviewHeight) {
totalHeight += AndroidUtilities.dp(50) + additionalHeight - linkPreviewHeight + AndroidUtilities.dp(8);
@ -767,7 +717,7 @@ public class ChatMessageCell extends ChatBaseCell {
}
if (isSmallImage) {
linkImageView.setImageCoords(textX + smallImageX + AndroidUtilities.dp(12), smallImageStartY, linkImageView.getImageWidth(), linkImageView.getImageHeight());
linkImageView.setImageCoords(textX + backgroundWidth - AndroidUtilities.dp(77), smallImageStartY, linkImageView.getImageWidth(), linkImageView.getImageHeight());
} else {
linkImageView.setImageCoords(textX + AndroidUtilities.dp(10), linkPreviewY, linkImageView.getImageWidth(), linkImageView.getImageHeight());
}
@ -783,8 +733,8 @@ public class ChatMessageCell extends ChatBaseCell {
if (durationLayout != null) {
int x = linkImageView.getImageX() + linkImageView.getImageWidth() - AndroidUtilities.dp(8) - durationWidth;
int y = linkImageView.getImageY() + linkImageView.getImageHeight() - AndroidUtilities.dp(19);
mediaBackgroundDrawable.setBounds(x - AndroidUtilities.dp(4), y - AndroidUtilities.dp(1.5f), x + durationWidth + AndroidUtilities.dp(4), y + AndroidUtilities.dp(14.5f));
mediaBackgroundDrawable.draw(canvas);
ResourceLoader.mediaBackgroundDrawable.setBounds(x - AndroidUtilities.dp(4), y - AndroidUtilities.dp(1.5f), x + durationWidth + AndroidUtilities.dp(4), y + AndroidUtilities.dp(14.5f));
ResourceLoader.mediaBackgroundDrawable.draw(canvas);
canvas.save();
canvas.translate(x, y);

View File

@ -37,6 +37,7 @@ import org.telegram.ui.Components.AvatarDrawable;
public class DialogCell extends BaseCell {
private static TextPaint namePaint;
private static TextPaint groupPaint;
private static TextPaint nameEncryptedPaint;
private static TextPaint nameUnknownPaint;
private static TextPaint messagePaint;
@ -55,14 +56,6 @@ public class DialogCell extends BaseCell {
private static Drawable broadcastDrawable;
private static Drawable muteDrawable;
private static Drawable checkWhiteDrawable;
private static Drawable halfCheckWhiteDrawable;
private static Drawable countWhiteDrawable;
private static Drawable lockWhiteDrawable;
private static Drawable groupWhiteDrawable;
private static Drawable broadcastWhiteDrawable;
//private static Drawable muteWhiteDrawable;
private static Paint linePaint;
private long currentDialogId;
@ -123,6 +116,10 @@ public class DialogCell extends BaseCell {
private int avatarTop = AndroidUtilities.dp(10);
private int avatarSize = AndroidUtilities.dp(52);
private int avatarLeftMargin;
private void init() {
if (namePaint == null) {
namePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
@ -130,6 +127,11 @@ public class DialogCell extends BaseCell {
namePaint.setColor(0xff212121);
namePaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
groupPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
groupPaint.setTextSize(AndroidUtilities.dp(17));
groupPaint.setColor(0xff212121);
groupPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
nameEncryptedPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
nameEncryptedPaint.setTextSize(AndroidUtilities.dp(17));
nameEncryptedPaint.setColor(0xff00a60e);
@ -175,20 +177,6 @@ public class DialogCell extends BaseCell {
broadcastDrawable = getResources().getDrawable(R.drawable.list_broadcast);
muteDrawable = getResources().getDrawable(R.drawable.mute_grey);
checkWhiteDrawable = getResources().getDrawable(R.drawable.dialogs_check_white);
checkDrawable = checkWhiteDrawable;
halfCheckWhiteDrawable = getResources().getDrawable(R.drawable.dialogs_halfcheck_white);
halfCheckDrawable = halfCheckWhiteDrawable;
countWhiteDrawable = getResources().getDrawable(R.drawable.dialogs_badge_white);
countDrawable = countWhiteDrawable;
lockWhiteDrawable = getResources().getDrawable(R.drawable.list_secret_white);
lockDrawable = lockWhiteDrawable;
groupWhiteDrawable = getResources().getDrawable(R.drawable.list_group_white);
groupDrawable = groupWhiteDrawable;
broadcastWhiteDrawable = getResources().getDrawable(R.drawable.list_broadcast_white);
broadcastDrawable = broadcastWhiteDrawable;
//muteWhiteDrawable = getResources().getDrawable(R.drawable.mute_white);
//muteDrawable = muteWhiteDrawable;
updateTheme();
}
}
@ -229,9 +217,13 @@ public class DialogCell extends BaseCell {
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (avatarImage != null) {
avatarImage.clearImage();
avatarImage.onDetachedFromWindow();
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
avatarImage.onAttachedToWindow();
}
@Override
@ -377,13 +369,22 @@ public class DialogCell extends BaseCell {
checkMessage = false;
SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE);
int defColor = themePrefs.getInt("themeColor", AndroidUtilities.defColor);
String hexColor = String.format("#%08X", (0xFFFFFFFF & defColor));
String hexMsgColor = String.format("#%08X", (0xFFFFFFFF & themePrefs.getInt("chatsMessageColor", 0xff8f8f8f)));
//String hexColor = String.format("#%08X", (0xFFFFFFFF & defColor));
String hexMsgColor = String.format("#%08X", (0xFFFFFFFF & themePrefs.getInt("chatsMessageColor", 0xff808080)));
String hexDarkColor = String.format("#%08X", (0xFFFFFFFF & themePrefs.getInt("chatsMemberColor", AndroidUtilities.getIntDarkerColor("themeColor", 0x15))));
if (message.caption != null) {
String mess = message.caption.toString();
if (mess.length() > 150) {
mess = mess.substring(0, 150);
}
mess = mess.replace("\n", " "); //hexMsgColor //hexMsgColor
//messageString = Emoji.replaceEmoji(AndroidUtilities.replaceTags(String.format("<c#ff4d83b3>%s:</c> <c#ff808080>%s</c>", name, mess)), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20));
messageString = Emoji.replaceEmoji(AndroidUtilities.replaceTags(String.format("<c" + hexDarkColor + ">%s:</c> <c" + hexMsgColor + ">%s</c>", name, mess)), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20));
} else {
if (message.messageOwner.media != null && !message.isMediaEmpty()) {
currentMessagePaint = messagePrintingPaint;
//messageString = Emoji.replaceEmoji(AndroidUtilities.replaceTags(String.format("<c#ff4d83b3>%s:</c> <c#ff4d83b3>%s</c>", name, message.messageText)), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20));
messageString = Emoji.replaceEmoji(AndroidUtilities.replaceTags(String.format("<c" + hexColor + ">%s:</c> <c" + hexColor + ">%s</c>", name, message.messageText)), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20));
messageString = Emoji.replaceEmoji(AndroidUtilities.replaceTags(String.format("<c" + hexDarkColor + ">%s:</c> <c" + hexDarkColor + ">%s</c>", name, message.messageText)), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20));
} else {
if (message.messageOwner.message != null) {
String mess = message.messageOwner.message;
@ -395,6 +396,10 @@ public class DialogCell extends BaseCell {
messageString = Emoji.replaceEmoji(AndroidUtilities.replaceTags(String.format("<c" + hexDarkColor + ">%s:</c> <c" + hexMsgColor + ">%s</c>", name, mess.replace("<", "&lt;").replace(">", "&gt;"))), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20));
}
}
}
} else {
if (message.caption != null) {
messageString = message.caption;
} else {
messageString = message.messageText;
if (message.messageOwner.media != null && !message.isMediaEmpty()) {
@ -403,6 +408,7 @@ public class DialogCell extends BaseCell {
}
}
}
}
if (unreadCount != 0) {
drawCount = true;
@ -452,6 +458,7 @@ public class DialogCell extends BaseCell {
if (chat != null) {
nameString = chat.title;
currentNamePaint = groupPaint;
} else if (user != null) {
if (user.id / 1000 != 777 && user.id / 1000 != 333 && ContactsController.getInstance().contactsDict.get(user.id) == null) {
if (ContactsController.getInstance().contactsDict.size() == 0 && (!ContactsController.getInstance().contactsLoaded || ContactsController.getInstance().isLoadingContacts())) {
@ -542,12 +549,16 @@ public class DialogCell extends BaseCell {
int avatarLeft;
if (!LocaleController.isRTL) {
messageLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
avatarLeft = AndroidUtilities.dp(AndroidUtilities.isTablet() ? 13 : 9);
//avatarLeft = AndroidUtilities.dp(AndroidUtilities.isTablet() ? 13 : 9);
avatarLeft = avatarLeftMargin;
} else {
messageLeft = AndroidUtilities.dp(16);
avatarLeft = getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.isTablet() ? 65 : 61);
//avatarLeft = getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.isTablet() ? 65 : 61);
avatarLeft = getMeasuredWidth() - avatarSize - avatarLeftMargin;
}
avatarImage.setImageCoords(avatarLeft, avatarTop, AndroidUtilities.dp(52), AndroidUtilities.dp(52));
//avatarImage.setImageCoords(avatarLeft, avatarTop, AndroidUtilities.dp(52), AndroidUtilities.dp(52));
avatarTop = (getMeasuredHeight() - (avatarSize)) / 2;
avatarImage.setImageCoords(avatarLeft, avatarTop, avatarSize, avatarSize);
if (drawError) {
int w = errorDrawable.getIntrinsicWidth() + AndroidUtilities.dp(8);
messageWidth -= w;
@ -677,12 +688,14 @@ public class DialogCell extends BaseCell {
if (mask != 0) {
boolean continueUpdate = false;
if (isDialogCell && (mask & MessagesController.UPDATE_MASK_USER_PRINT) != 0) {
if (isDialogCell) {
if ((mask & MessagesController.UPDATE_MASK_USER_PRINT) != 0) {
CharSequence printString = MessagesController.getInstance().printingStrings.get(currentDialogId);
if (lastPrintString != null && printString == null || lastPrintString == null && printString != null || lastPrintString != null && printString != null && !lastPrintString.equals(printString)) {
continueUpdate = true;
}
}
}
if (!continueUpdate && (mask & MessagesController.UPDATE_MASK_AVATAR) != 0) {
if (chat == null) {
continueUpdate = true;
@ -777,16 +790,23 @@ public class DialogCell extends BaseCell {
private void updateTheme(){
SharedPreferences themePrefs = ApplicationLoader.applicationContext.getSharedPreferences(AndroidUtilities.THEME_PREFS, AndroidUtilities.THEME_PREFS_MODE);
int tColor = themePrefs.getInt("themeColor", AndroidUtilities.defColor);
int dColor = AndroidUtilities.getIntDarkerColor("themeColor",0x15);
int dColor = AndroidUtilities.getIntDarkerColor("themeColor", 0x15);
int nColor = themePrefs.getInt("chatsNameColor", 0xff212121);
namePaint.setTextSize(AndroidUtilities.dp(themePrefs.getInt("chatsNameSize", 17)));
namePaint.setColor(themePrefs.getInt("chatsNameColor", 0xff212121));
namePaint.setColor(nColor);
groupPaint.setTextSize(AndroidUtilities.dp(themePrefs.getInt("chatsGroupNameSize", themePrefs.getInt("chatsNameSize", 17))));
groupPaint.setColor(themePrefs.getInt("chatsGroupNameColor", nColor));
lockDrawable.setColorFilter(themePrefs.getInt("chatsNameColor", tColor), PorterDuff.Mode.SRC_IN);
nameEncryptedPaint.setTextSize(AndroidUtilities.dp(themePrefs.getInt("chatsNameSize", 17)));
nameEncryptedPaint.setColor(themePrefs.getInt("chatsNameColor", dColor));//0xff00a60e
nameUnknownPaint.setTextSize(AndroidUtilities.dp(themePrefs.getInt("chatsNameSize", 17)));
nameUnknownPaint.setColor(themePrefs.getInt("chatsNameColor", 0xff000000));//0xff4d83b3
nameUnknownPaint.setColor(themePrefs.getInt("chatsUnknownNameColor", nColor));//0xff4d83b3
messagePaint.setTextSize(AndroidUtilities.dp(themePrefs.getInt("chatsMessageSize", 16)));
messagePaint.setColor(themePrefs.getInt("chatsMessageColor", 0xff8f8f8f));
@ -803,16 +823,15 @@ public class DialogCell extends BaseCell {
countPaint.setTextSize(AndroidUtilities.dp(themePrefs.getInt("chatsCountSize", 13)));
countPaint.setColor(themePrefs.getInt("chatsCountColor", 0xffffffff));
checkWhiteDrawable.setColorFilter(themePrefs.getInt("chatsChecksColor", tColor), PorterDuff.Mode.MULTIPLY);
halfCheckWhiteDrawable.setColorFilter(themePrefs.getInt("chatsChecksColor", tColor), PorterDuff.Mode.MULTIPLY);
checkDrawable.setColorFilter(themePrefs.getInt("chatsChecksColor", tColor), PorterDuff.Mode.SRC_IN);
halfCheckDrawable.setColorFilter(themePrefs.getInt("chatsChecksColor", tColor), PorterDuff.Mode.SRC_IN);
clockDrawable.setColorFilter(themePrefs.getInt("chatsChecksColor", tColor), PorterDuff.Mode.SRC_IN);
countWhiteDrawable.setColorFilter(themePrefs.getInt("chatsCountBGColor", tColor), PorterDuff.Mode.MULTIPLY);
lockWhiteDrawable.setColorFilter(dColor, PorterDuff.Mode.MULTIPLY);
countDrawable.setColorFilter(themePrefs.getInt("chatsCountBGColor", tColor), PorterDuff.Mode.SRC_IN);
int nColor = themePrefs.getInt("chatsNameColor", 0xff000000);
groupWhiteDrawable.setColorFilter(nColor, PorterDuff.Mode.MULTIPLY);
broadcastWhiteDrawable.setColorFilter(nColor, PorterDuff.Mode.MULTIPLY);
nColor = themePrefs.getInt("chatsNameColor", 0xff000000);
groupDrawable.setColorFilter(nColor, PorterDuff.Mode.SRC_IN);
broadcastDrawable.setColorFilter(nColor, PorterDuff.Mode.SRC_IN);
int mColor = themePrefs.getInt("chatsMuteColor", 0xffa8a8a8);
//muteWhiteDrawable.setColorFilter(mColor, PorterDuff.Mode.MULTIPLY);
@ -823,6 +842,8 @@ public class DialogCell extends BaseCell {
int radius = AndroidUtilities.dp(themePrefs.getInt("chatsAvatarRadius", 32));
if(avatarImage != null)avatarImage.setRoundRadius(radius);
if(avatarDrawable != null)avatarDrawable.setRadius(radius);
avatarSize = AndroidUtilities.dp(themePrefs.getInt("chatsAvatarSize", 52));
avatarLeftMargin = AndroidUtilities.dp(themePrefs.getInt("chatsAvatarMarginLeft", AndroidUtilities.isTablet() ? 13 : 9));
}

View File

@ -13,7 +13,6 @@ import android.graphics.Canvas;
import android.graphics.Paint;
import org.telegram.android.AndroidUtilities;
import org.telegram.ui.LaunchActivity;
public class DividerCell extends BaseCell {

View File

@ -17,6 +17,7 @@ import android.widget.FrameLayout;
import android.widget.TextView;
import org.telegram.android.AndroidUtilities;
import org.telegram.ui.Components.LayoutHelper;
public class DrawerActionCell extends FrameLayout {
@ -36,8 +37,8 @@ public class DrawerActionCell extends FrameLayout {
textView.setCompoundDrawablePadding(AndroidUtilities.dp(34));
addView(textView);
LayoutParams layoutParams = (LayoutParams) textView.getLayoutParams();
layoutParams.width = LayoutParams.MATCH_PARENT;
layoutParams.height = LayoutParams.MATCH_PARENT;
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
layoutParams.gravity = Gravity.LEFT;
layoutParams.leftMargin = AndroidUtilities.dp(14);
layoutParams.rightMargin = AndroidUtilities.dp(16);

View File

@ -37,6 +37,7 @@ import org.telegram.messenger.TLRPC;
import org.telegram.messenger.UserConfig;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.PhotoViewer;
public class DrawerProfileCell extends FrameLayout implements PhotoViewer.PhotoViewerProvider{
@ -59,7 +60,7 @@ public class DrawerProfileCell extends FrameLayout implements PhotoViewer.PhotoV
shadowView.setImageResource(R.drawable.bottom_shadow);
addView(shadowView);
LayoutParams layoutParams = (FrameLayout.LayoutParams) shadowView.getLayoutParams();
layoutParams.width = LayoutParams.MATCH_PARENT;
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = AndroidUtilities.dp(70);
layoutParams.gravity = Gravity.LEFT | Gravity.BOTTOM;
shadowView.setLayoutParams(layoutParams);
@ -99,8 +100,8 @@ public class DrawerProfileCell extends FrameLayout implements PhotoViewer.PhotoV
nameTextView.setGravity(Gravity.LEFT);
addView(nameTextView);
layoutParams = (FrameLayout.LayoutParams) nameTextView.getLayoutParams();
layoutParams.width = LayoutParams.MATCH_PARENT;
layoutParams.height = LayoutParams.WRAP_CONTENT;
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.WRAP_CONTENT;
layoutParams.gravity = Gravity.LEFT | Gravity.BOTTOM;
layoutParams.leftMargin = AndroidUtilities.dp(16);
layoutParams.bottomMargin = AndroidUtilities.dp(28);
@ -116,8 +117,8 @@ public class DrawerProfileCell extends FrameLayout implements PhotoViewer.PhotoV
phoneTextView.setGravity(Gravity.LEFT);
addView(phoneTextView);
layoutParams = (FrameLayout.LayoutParams) phoneTextView.getLayoutParams();
layoutParams.width = LayoutParams.MATCH_PARENT;
layoutParams.height = LayoutParams.WRAP_CONTENT;
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.WRAP_CONTENT;
layoutParams.gravity = Gravity.LEFT | Gravity.BOTTOM;
layoutParams.leftMargin = AndroidUtilities.dp(16);
layoutParams.bottomMargin = AndroidUtilities.dp(9);

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