Commit cd9d188f authored by DrKLO's avatar DrKLO

Merge branch 'dev'

parents fd69c56f abf8f6f6
## Telegram messenger for Android ## Telegram messenger for Android
[Telegram](http://telegram.org) is a messaging app with a focus on speed and security. It’s superfast, simple and free. [Telegram](http://telegram.org) is a messaging app with a focus on speed and security. It’s superfast, simple and free.
This repo contains the official source code for [Telegram App for Android](https://play.google.com/store/apps/details?id=org.telegram.messenger).
This repo contains official [Telegram App for Android](https://play.google.com/store/apps/details?id=org.telegram.messenger) source code. ##Creating your Telegram Application
We welcome all developers to use our API and source code to create applications on our platform.
There are several things we require from **all developers** for the moment.
1. [**Obtain your own api_id**](https://core.telegram.org/api/obtaining_api_id) for your application.
2. Please **do not** use the name Telegram for your app — or make sure your users understand that it is unofficial.
3. Kindly **do not** use our standard logo (white paper plane in a blue circle) as your app's logo.
3. Please study our [**security guidelines**](https://core.telegram.org/mtproto/security_guidelines) and take good care of your users' data and privacy.
4. Please remember to publish **your** code too in order to comply with the licences.
### API, Protocol documentation ### API, Protocol documentation
Documentation for Telegram API is available here: http://core.telegram.org/api Telegram API manuals: http://core.telegram.org/api
Documentation for MTproto protocol is available here: http://core.telegram.org/mtproto MTproto protocol manuals: http://core.telegram.org/mtproto
### Usage ### Usage
**Beware of using dev branch and uploading it to any markets, in most cases it will work as you expecting** **Beware of using the dev branch and uploading it to any markets, in many cases it not will work as expected**.
First of all your should take a look to **src/main/java/org/telegram/messenger/BuildVars.java** and fill it with correct values.
First of all, take a look at **src/main/java/org/telegram/messenger/BuildVars.java** and fill it with correct values.
Import the root folder into your IDE (tested on Android Studio), then run project. Import the root folder into your IDE (tested on Android Studio), then run project.
### Localization ### Localization
......
...@@ -19,13 +19,13 @@ tasks.withType(JavaCompile) { ...@@ -19,13 +19,13 @@ tasks.withType(JavaCompile) {
dependencies { dependencies {
compile 'com.android.support:support-v4:20.0.+' compile 'com.android.support:support-v4:20.0.+'
compile 'com.google.android.gms:play-services:3.2.+' compile 'com.google.android.gms:play-services:3.2.+'
compile 'net.hockeyapp.android:HockeySDK:3.0.1' compile 'net.hockeyapp.android:HockeySDK:3.0.2'
compile 'com.googlecode.mp4parser:isoparser:1.0.+' compile 'com.googlecode.mp4parser:isoparser:1.0.+'
} }
android { android {
compileSdkVersion 19 compileSdkVersion 21
buildToolsVersion '20.0.0' buildToolsVersion '21.0.2'
signingConfigs { signingConfigs {
debug { debug {
...@@ -80,7 +80,7 @@ android { ...@@ -80,7 +80,7 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 8 minSdkVersion 8
targetSdkVersion 19 targetSdkVersion 19
versionCode 355 versionCode 374
versionName "1.9.4" versionName "1.9.6"
} }
} }
...@@ -9,12 +9,11 @@ static inline uint64_t get_colors (const uint8_t *p) { ...@@ -9,12 +9,11 @@ static inline uint64_t get_colors (const uint8_t *p) {
return p[0] + (p[1] << 16) + ((uint64_t)p[2] << 32); return p[0] + (p[1] << 16) + ((uint64_t)p[2] << 32);
} }
static void fastBlur(int imageWidth, int imageHeight, int imageStride, void *pixels) { static void fastBlurMore(int imageWidth, int imageHeight, int imageStride, void *pixels, int radius) {
uint8_t *pix = (uint8_t *)pixels; uint8_t *pix = (uint8_t *)pixels;
const int w = imageWidth; const int w = imageWidth;
const int h = imageHeight; const int h = imageHeight;
const int stride = imageStride; const int stride = imageStride;
const int radius = 3;
const int r1 = radius + 1; const int r1 = radius + 1;
const int div = radius * 2 + 1; const int div = radius * 2 + 1;
...@@ -23,6 +22,98 @@ static void fastBlur(int imageWidth, int imageHeight, int imageStride, void *pix ...@@ -23,6 +22,98 @@ static void fastBlur(int imageWidth, int imageHeight, int imageStride, void *pix
} }
uint64_t *rgb = malloc(imageWidth * imageHeight * sizeof(uint64_t)); uint64_t *rgb = malloc(imageWidth * imageHeight * sizeof(uint64_t));
if (rgb == NULL) {
return;
}
int x, y, i;
int yw = 0;
const int we = w - r1;
for (y = 0; y < h; y++) {
uint64_t cur = get_colors (&pix[yw]);
uint64_t rgballsum = -radius * cur;
uint64_t rgbsum = cur * ((r1 * (r1 + 1)) >> 1);
for (i = 1; i <= radius; i++) {
uint64_t cur = get_colors (&pix[yw + i * 4]);
rgbsum += cur * (r1 - i);
rgballsum += cur;
}
x = 0;
#define update(start, middle, end) \
rgb[y * w + x] = (rgbsum >> 6) & 0x00FF00FF00FF00FF; \
rgballsum += get_colors (&pix[yw + (start) * 4]) - 2 * get_colors (&pix[yw + (middle) * 4]) + get_colors (&pix[yw + (end) * 4]); \
rgbsum += rgballsum; \
x++; \
while (x < r1) {
update (0, x, x + r1);
}
while (x < we) {
update (x - r1, x, x + r1);
}
while (x < w) {
update (x - r1, x, w - 1);
}
#undef update
yw += stride;
}
const int he = h - r1;
for (x = 0; x < w; x++) {
uint64_t rgballsum = -radius * rgb[x];
uint64_t rgbsum = rgb[x] * ((r1 * (r1 + 1)) >> 1);
for (i = 1; i <= radius; i++) {
rgbsum += rgb[i * w + x] * (r1 - i);
rgballsum += rgb[i * w + x];
}
y = 0;
int yi = x * 4;
#define update(start, middle, end) \
int64_t res = rgbsum >> 6; \
pix[yi] = res; \
pix[yi + 1] = res >> 16; \
pix[yi + 2] = res >> 32; \
rgballsum += rgb[x + (start) * w] - 2 * rgb[x + (middle) * w] + rgb[x + (end) * w]; \
rgbsum += rgballsum; \
y++; \
yi += stride;
while (y < r1) {
update (0, y, y + r1);
}
while (y < he) {
update (y - r1, y, y + r1);
}
while (y < h) {
update (y - r1, y, h - 1);
}
#undef update
}
}
static void fastBlur(int imageWidth, int imageHeight, int imageStride, void *pixels, int radius) {
uint8_t *pix = (uint8_t *)pixels;
const int w = imageWidth;
const int h = imageHeight;
const int stride = imageStride;
const int r1 = radius + 1;
const int div = radius * 2 + 1;
if (radius > 15 || div >= w || div >= h || w * h > 90 * 90 || imageStride > imageWidth * 4) {
return;
}
uint64_t *rgb = malloc(imageWidth * imageHeight * sizeof(uint64_t));
if (rgb == NULL) {
return;
}
int x, y, i; int x, y, i;
...@@ -111,7 +202,7 @@ METHODDEF(void) my_error_exit(j_common_ptr cinfo) { ...@@ -111,7 +202,7 @@ METHODDEF(void) my_error_exit(j_common_ptr cinfo) {
longjmp(myerr->setjmp_buffer, 1); longjmp(myerr->setjmp_buffer, 1);
} }
JNIEXPORT void Java_org_telegram_messenger_Utilities_blurBitmap(JNIEnv *env, jclass class, jobject bitmap) { JNIEXPORT void Java_org_telegram_messenger_Utilities_blurBitmap(JNIEnv *env, jclass class, jobject bitmap, int radius) {
if (!bitmap) { if (!bitmap) {
return; return;
} }
...@@ -130,7 +221,11 @@ JNIEXPORT void Java_org_telegram_messenger_Utilities_blurBitmap(JNIEnv *env, jcl ...@@ -130,7 +221,11 @@ JNIEXPORT void Java_org_telegram_messenger_Utilities_blurBitmap(JNIEnv *env, jcl
if (AndroidBitmap_lockPixels(env, bitmap, &pixels) < 0) { if (AndroidBitmap_lockPixels(env, bitmap, &pixels) < 0) {
return; return;
} }
fastBlur(info.width, info.height, info.stride, pixels); if (radius <= 3) {
fastBlur(info.width, info.height, info.stride, pixels, radius);
} else {
fastBlurMore(info.width, info.height, info.stride, pixels, radius);
}
AndroidBitmap_unlockPixels(env, bitmap); AndroidBitmap_unlockPixels(env, bitmap);
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -9,7 +9,9 @@ ...@@ -9,7 +9,9 @@
package org.telegram.android; package org.telegram.android;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.Point; import android.graphics.Point;
...@@ -21,17 +23,23 @@ import android.view.Surface; ...@@ -21,17 +23,23 @@ import android.view.Surface;
import android.view.View; import android.view.View;
import android.view.WindowManager; import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import org.telegram.messenger.FileLog; import org.telegram.messenger.FileLog;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.messenger.TLRPC;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.ui.ApplicationLoader; import org.telegram.ui.ApplicationLoader;
import org.telegram.ui.Views.NumberPicker;
import java.io.File; import java.io.File;
import java.lang.reflect.Field;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Locale; import java.util.Locale;
public class AndroidUtilities { public class AndroidUtilities {
private static final Hashtable<String, Typeface> typefaceCache = new Hashtable<String, Typeface>(); private static final Hashtable<String, Typeface> typefaceCache = new Hashtable<String, Typeface>();
private static int prevOrientation = -10; private static int prevOrientation = -10;
private static boolean waitingForSms = false; private static boolean waitingForSms = false;
...@@ -210,7 +218,7 @@ public class AndroidUtilities { ...@@ -210,7 +218,7 @@ public class AndroidUtilities {
} }
public static File getCacheDir() { public static File getCacheDir() {
if (Environment.getExternalStorageState().startsWith(Environment.MEDIA_MOUNTED)) { if (Environment.getExternalStorageState() == null || Environment.getExternalStorageState().startsWith(Environment.MEDIA_MOUNTED)) {
try { try {
File file = ApplicationLoader.applicationContext.getExternalCacheDir(); File file = ApplicationLoader.applicationContext.getExternalCacheDir();
if (file != null) { if (file != null) {
...@@ -239,6 +247,10 @@ public class AndroidUtilities { ...@@ -239,6 +247,10 @@ public class AndroidUtilities {
return (int)Math.ceil(density * value); return (int)Math.ceil(density * value);
} }
public static float dpf2(float value) {
return density * value;
}
public static void checkDisplaySize() { public static void checkDisplaySize() {
try { try {
WindowManager manager = (WindowManager)ApplicationLoader.applicationContext.getSystemService(Context.WINDOW_SERVICE); WindowManager manager = (WindowManager)ApplicationLoader.applicationContext.getSystemService(Context.WINDOW_SERVICE);
...@@ -262,6 +274,22 @@ public class AndroidUtilities { ...@@ -262,6 +274,22 @@ public class AndroidUtilities {
return 0x0000000100000000L | ((long)id & 0x00000000FFFFFFFFL); return 0x0000000100000000L | ((long)id & 0x00000000FFFFFFFFL);
} }
public static int getMyLayerVersion(int layer) {
return layer & 0xffff;
}
public static int getPeerLayerVersion(int layer) {
return (layer >> 16) & 0xffff;
}
public static int setMyLayerVersion(int layer, int version) {
return layer & 0xffff0000 | version;
}
public static int setPeerLayerVersion(int layer, int version) {
return layer & 0x0000ffff | (version << 16);
}
public static void RunOnUIThread(Runnable runnable) { public static void RunOnUIThread(Runnable runnable) {
RunOnUIThread(runnable, 0); RunOnUIThread(runnable, 0);
} }
...@@ -274,6 +302,10 @@ public class AndroidUtilities { ...@@ -274,6 +302,10 @@ public class AndroidUtilities {
} }
} }
public static void CancelRunOnUIThread(Runnable runnable) {
ApplicationLoader.applicationHandler.removeCallbacks(runnable);
}
public static boolean isTablet() { public static boolean isTablet() {
if (isTablet == null) { if (isTablet == null) {
isTablet = ApplicationLoader.applicationContext.getResources().getBoolean(R.bool.isTablet); isTablet = ApplicationLoader.applicationContext.getResources().getBoolean(R.bool.isTablet);
...@@ -367,4 +399,106 @@ public class AndroidUtilities { ...@@ -367,4 +399,106 @@ public class AndroidUtilities {
} }
return photoSize; return photoSize;
} }
public static String formatTTLString(int ttl) {
if (ttl < 60) {
return LocaleController.formatPluralString("Seconds", ttl);
} else if (ttl < 60 * 60) {
return LocaleController.formatPluralString("Minutes", ttl / 60);
} else if (ttl < 60 * 60 * 24) {
return LocaleController.formatPluralString("Hours", ttl / 60 / 60);
} else if (ttl < 60 * 60 * 24 * 7) {
return LocaleController.formatPluralString("Days", ttl / 60 / 60 / 24);
} else {
int days = ttl / 60 / 60 / 24;
if (ttl % 7 == 0) {
return LocaleController.formatPluralString("Weeks", days / 7);
} else {
return String.format("%s %s", LocaleController.formatPluralString("Weeks", days / 7), LocaleController.formatPluralString("Days", days % 7));
}
}
}
public static AlertDialog.Builder buildTTLAlert(final Context context, final TLRPC.EncryptedChat encryptedChat) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(LocaleController.getString("MessageLifetime", R.string.MessageLifetime));
final NumberPicker numberPicker = new NumberPicker(context);
numberPicker.setMinValue(0);
numberPicker.setMaxValue(20);
if (encryptedChat.ttl > 0 && encryptedChat.ttl < 16) {
numberPicker.setValue(encryptedChat.ttl);
} else if (encryptedChat.ttl == 30) {
numberPicker.setValue(16);
} else if (encryptedChat.ttl == 60) {
numberPicker.setValue(17);
} else if (encryptedChat.ttl == 60 * 60) {
numberPicker.setValue(18);
} else if (encryptedChat.ttl == 60 * 60 * 24) {
numberPicker.setValue(19);
} else if (encryptedChat.ttl == 60 * 60 * 24 * 7) {
numberPicker.setValue(20);
} else if (encryptedChat.ttl == 0) {
numberPicker.setValue(5);
}
numberPicker.setFormatter(new NumberPicker.Formatter() {
@Override
public String format(int value) {
if (value == 0) {
return LocaleController.getString("ShortMessageLifetimeForever", R.string.ShortMessageLifetimeForever);
} else if (value >= 1 && value < 16) {
return AndroidUtilities.formatTTLString(value);
} else if (value == 16) {
return AndroidUtilities.formatTTLString(30);
} else if (value == 17) {
return AndroidUtilities.formatTTLString(60);
} else if (value == 18) {
return AndroidUtilities.formatTTLString(60 * 60);
} else if (value == 19) {
return AndroidUtilities.formatTTLString(60 * 60 * 24);
} else if (value == 20) {
return AndroidUtilities.formatTTLString(60 * 60 * 24 * 7);
}
return "";
}
});
builder.setView(numberPicker);
builder.setNegativeButton(LocaleController.getString("Done", R.string.Done), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
int oldValue = encryptedChat.ttl;
which = numberPicker.getValue();
if (which >= 0 && which < 16) {
encryptedChat.ttl = which;
} else if (which == 16) {
encryptedChat.ttl = 30;
} else if (which == 17) {
encryptedChat.ttl = 60;
} else if (which == 18) {
encryptedChat.ttl = 60 * 60;
} else if (which == 19) {
encryptedChat.ttl = 60 * 60 * 24;
} else if (which == 20) {
encryptedChat.ttl = 60 * 60 * 24 * 7;
}
if (oldValue != encryptedChat.ttl) {
SendMessagesHelper.getInstance().sendTTLMessage(encryptedChat, null);
MessagesStorage.getInstance().updateEncryptedChatTTL(encryptedChat);
}
}
});
return builder;
}
public static void clearCursorDrawable(EditText editText) {
if (editText == null || Build.VERSION.SDK_INT < 12) {
return;
}
try {
Field mCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes");
mCursorDrawableRes.setAccessible(true);
mCursorDrawableRes.setInt(editText, 0);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
} }
...@@ -236,7 +236,7 @@ public class ContactsController { ...@@ -236,7 +236,7 @@ public class ContactsController {
ContentResolver cr = ApplicationLoader.applicationContext.getContentResolver(); ContentResolver cr = ApplicationLoader.applicationContext.getContentResolver();
HashMap<String, Contact> shortContacts = new HashMap<String, Contact>(); HashMap<String, Contact> shortContacts = new HashMap<String, Contact>();
String ids = ""; StringBuilder ids = new StringBuilder();
Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projectionPhones, null, null, null); Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projectionPhones, null, null, null);
if (pCur != null) { if (pCur != null) {
if (pCur.getCount() > 0) { if (pCur.getCount() > 0) {
...@@ -262,9 +262,9 @@ public class ContactsController { ...@@ -262,9 +262,9 @@ public class ContactsController {
Integer id = pCur.getInt(0); Integer id = pCur.getInt(0);
if (ids.length() != 0) { if (ids.length() != 0) {
ids += ","; ids.append(",");
} }
ids += id; ids.append(id);
int type = pCur.getInt(2); int type = pCur.getInt(2);
Contact contact = contactsMap.get(id); Contact contact = contactsMap.get(id);
...@@ -299,7 +299,7 @@ public class ContactsController { ...@@ -299,7 +299,7 @@ public class ContactsController {
pCur.close(); pCur.close();
} }
pCur = cr.query(ContactsContract.Data.CONTENT_URI, projectionNames, ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID + " IN (" + ids + ") AND " + ContactsContract.Data.MIMETYPE + " = '" + ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE + "'", null, null); pCur = cr.query(ContactsContract.Data.CONTENT_URI, projectionNames, ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID + " IN (" + ids.toString() + ") AND " + ContactsContract.Data.MIMETYPE + " = '" + ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE + "'", null, null);
if (pCur != null && pCur.getCount() > 0) { if (pCur != null && pCur.getCount() > 0) {
while (pCur.moveToNext()) { while (pCur.moveToNext()) {
int id = pCur.getInt(0); int id = pCur.getInt(0);
...@@ -844,14 +844,14 @@ public class ContactsController { ...@@ -844,14 +844,14 @@ public class ContactsController {
return 0; return 0;
} }
}); });
String ids = ""; StringBuilder ids = new StringBuilder();
for (TLRPC.TL_contact aContactsArr : contactsArr) { for (TLRPC.TL_contact aContactsArr : contactsArr) {
if (ids.length() != 0) { if (ids.length() != 0) {
ids += ","; ids.append(",");
} }
ids += aContactsArr.user_id; ids.append(aContactsArr.user_id);
} }
UserConfig.contactsHash = Utilities.MD5(ids); UserConfig.contactsHash = Utilities.MD5(ids.toString());
UserConfig.saveConfig(false); UserConfig.saveConfig(false);
} }
...@@ -1084,7 +1084,7 @@ public class ContactsController { ...@@ -1084,7 +1084,7 @@ public class ContactsController {
}); });
} }
String ids = ""; StringBuilder ids = new StringBuilder();
final HashMap<String, ArrayList<TLRPC.TL_contact>> sectionsDict = new HashMap<String, ArrayList<TLRPC.TL_contact>>(); final HashMap<String, ArrayList<TLRPC.TL_contact>> sectionsDict = new HashMap<String, ArrayList<TLRPC.TL_contact>>();
final ArrayList<String> sortedSectionsArray = new ArrayList<String>(); final ArrayList<String> sortedSectionsArray = new ArrayList<String>();
...@@ -1114,11 +1114,11 @@ public class ContactsController { ...@@ -1114,11 +1114,11 @@ public class ContactsController {
} }
arr.add(value); arr.add(value);
if (ids.length() != 0) { if (ids.length() != 0) {
ids += ","; ids.append(",");
} }
ids += value.user_id; ids.append(value.user_id);
} }
UserConfig.contactsHash = Utilities.MD5(ids); UserConfig.contactsHash = Utilities.MD5(ids.toString());
UserConfig.saveConfig(false); UserConfig.saveConfig(false);
Collections.sort(sortedSectionsArray, new Comparator<String>() { Collections.sort(sortedSectionsArray, new Comparator<String>() {
...@@ -1189,8 +1189,8 @@ public class ContactsController { ...@@ -1189,8 +1189,8 @@ public class ContactsController {
} }
FileLog.e("tmessages", "process update - contacts add = " + newC.size() + " delete = " + contactsTD.size()); FileLog.e("tmessages", "process update - contacts add = " + newC.size() + " delete = " + contactsTD.size());
String toAdd = ""; StringBuilder toAdd = new StringBuilder();
String toDelete = ""; StringBuilder toDelete = new StringBuilder();
boolean reloadContacts = false; boolean reloadContacts = false;
for (TLRPC.TL_contact newContact : newC) { for (TLRPC.TL_contact newContact : newC) {
...@@ -1216,9 +1216,9 @@ public class ContactsController { ...@@ -1216,9 +1216,9 @@ public class ContactsController {
} }
} }
if (toAdd.length() != 0) { if (toAdd.length() != 0) {
toAdd += ","; toAdd.append(",");
} }
toAdd += user.phone; toAdd.append(user.phone);
} }
for (final Integer uid : contactsTD) { for (final Integer uid : contactsTD) {
...@@ -1252,14 +1252,14 @@ public class ContactsController { ...@@ -1252,14 +1252,14 @@ public class ContactsController {
} }
} }
if (toDelete.length() != 0) { if (toDelete.length() != 0) {
toDelete += ","; toDelete.append(",");
} }
toDelete += user.phone; toDelete.append(user.phone);
} }
} }
if (toAdd.length() != 0 || toDelete.length() != 0) { if (toAdd.length() != 0 || toDelete.length() != 0) {
MessagesStorage.getInstance().applyPhoneBookUpdates(toAdd, toDelete); MessagesStorage.getInstance().applyPhoneBookUpdates(toAdd.toString(), toDelete.toString());
} }
if (reloadContacts) { if (reloadContacts) {
......
...@@ -28,7 +28,6 @@ import android.provider.MediaStore; ...@@ -28,7 +28,6 @@ import android.provider.MediaStore;
import org.telegram.messenger.DispatchQueue; import org.telegram.messenger.DispatchQueue;
import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog; import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.messenger.TLRPC; import org.telegram.messenger.TLRPC;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities; import org.telegram.messenger.Utilities;
...@@ -293,7 +292,7 @@ public class ImageLoader { ...@@ -293,7 +292,7 @@ public class ImageLoader {
} }
} }
if (image != null && blur && bitmapH < 100 && bitmapW < 100) { if (image != null && blur && bitmapH < 100 && bitmapW < 100) {
Utilities.blurBitmap(image); Utilities.blurBitmap(image, 3);
} }
} }
if (runtimeHack != null) { if (runtimeHack != null) {
...@@ -832,6 +831,10 @@ public class ImageLoader { ...@@ -832,6 +831,10 @@ public class ImageLoader {
}); });
} }
public void putImageToCache(BitmapDrawable bitmap, String key) {
memCache.put(key, bitmap);
}
public void loadImage(final TLRPC.FileLocation fileLocation, final String httpUrl, final ImageReceiver imageView, final int size, final boolean cacheOnly) { public void loadImage(final TLRPC.FileLocation fileLocation, final String httpUrl, final ImageReceiver imageView, final int size, final boolean cacheOnly) {
if ((fileLocation == null && httpUrl == null) || imageView == null || (fileLocation != null && !(fileLocation instanceof TLRPC.TL_fileLocation) && !(fileLocation instanceof TLRPC.TL_fileEncryptedLocation))) { if ((fileLocation == null && httpUrl == null) || imageView == null || (fileLocation != null && !(fileLocation instanceof TLRPC.TL_fileLocation) && !(fileLocation instanceof TLRPC.TL_fileEncryptedLocation))) {
return; return;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -24,9 +24,9 @@ import java.util.zip.ZipFile; ...@@ -24,9 +24,9 @@ import java.util.zip.ZipFile;
public class NativeLoader { public class NativeLoader {
private static final long sizes[] = new long[] { private static final long sizes[] = new long[] {
946908, //armeabi 955148, //armeabi
1028848, //armeabi-v7a 1041184, //armeabi-v7a
1603780, //x86 1616116, //x86
0, //mips 0, //mips
}; };
......
...@@ -41,6 +41,7 @@ public class NotificationCenter { ...@@ -41,6 +41,7 @@ public class NotificationCenter {
public static final int openedChatChanged = 29; public static final int openedChatChanged = 29;
public static final int hideEmojiKeyboard = 30; public static final int hideEmojiKeyboard = 30;
public static final int stopEncodingService = 31; public static final int stopEncodingService = 31;
public static final int didCreatedNewDeleteTask = 32;
public static final int wallpapersDidLoaded = 171; public static final int wallpapersDidLoaded = 171;
public static final int closeOtherAppActivities = 702; public static final int closeOtherAppActivities = 702;
...@@ -67,6 +68,7 @@ public class NotificationCenter { ...@@ -67,6 +68,7 @@ public class NotificationCenter {
public final static int screenshotTook = 50007; public final static int screenshotTook = 50007;
public final static int albumsDidLoaded = 50008; public final static int albumsDidLoaded = 50008;
public final static int audioDidSent = 50009; public final static int audioDidSent = 50009;
public final static int audioDidStarted = 50010;
final private HashMap<Integer, ArrayList<Object>> observers = new HashMap<Integer, ArrayList<Object>>(); final private HashMap<Integer, ArrayList<Object>> observers = new HashMap<Integer, ArrayList<Object>>();
......
...@@ -21,7 +21,7 @@ public class PhotoObject { ...@@ -21,7 +21,7 @@ public class PhotoObject {
public TLRPC.PhotoSize photoOwner; public TLRPC.PhotoSize photoOwner;
public Bitmap image; public Bitmap image;
public PhotoObject(TLRPC.PhotoSize photo, int preview) { public PhotoObject(TLRPC.PhotoSize photo, int preview, boolean secret) {
photoOwner = photo; photoOwner = photo;
if (preview != 0 && photo instanceof TLRPC.TL_photoCachedSize) { if (preview != 0 && photo instanceof TLRPC.TL_photoCachedSize) {
...@@ -34,7 +34,13 @@ public class PhotoObject { ...@@ -34,7 +34,13 @@ public class PhotoObject {
image = BitmapFactory.decodeByteArray(photoOwner.bytes, 0, photoOwner.bytes.length, opts); image = BitmapFactory.decodeByteArray(photoOwner.bytes, 0, photoOwner.bytes.length, opts);
if (image != null) { if (image != null) {
if (preview == 2) { if (preview == 2) {
Utilities.blurBitmap(image); if (secret) {
Utilities.blurBitmap(image, 7);
Utilities.blurBitmap(image, 7);
Utilities.blurBitmap(image, 7);
} else {
Utilities.blurBitmap(image, 3);
}
} }
if (ImageLoader.getInstance().runtimeHack != null) { if (ImageLoader.getInstance().runtimeHack != null) {
ImageLoader.getInstance().runtimeHack.trackFree(image.getRowBytes() * image.getHeight()); ImageLoader.getInstance().runtimeHack.trackFree(image.getRowBytes() * image.getHeight());
......
...@@ -45,7 +45,7 @@ public class VideoEncodingService extends Service implements NotificationCenter. ...@@ -45,7 +45,7 @@ public class VideoEncodingService extends Service implements NotificationCenter.
public void didReceivedNotification(int id, Object... args) { public void didReceivedNotification(int id, Object... args) {
if (id == NotificationCenter.FileUploadProgressChanged) { if (id == NotificationCenter.FileUploadProgressChanged) {
String fileName = (String)args[0]; String fileName = (String)args[0];
if (path.equals(fileName)) { if (path != null && path.equals(fileName)) {
Float progress = (Float) args[1]; Float progress = (Float) args[1];
Boolean enc = (Boolean) args[2]; Boolean enc = (Boolean) args[2];
currentProgress = (int)(progress * 100); currentProgress = (int)(progress * 100);
......
...@@ -54,12 +54,13 @@ public class MP4Builder { ...@@ -54,12 +54,13 @@ public class MP4Builder {
private InterleaveChunkMdat mdat = null; private InterleaveChunkMdat mdat = null;
private Mp4Movie currentMp4Movie = null; private Mp4Movie currentMp4Movie = null;
FileOutputStream fos = null; private FileOutputStream fos = null;
private FileChannel fc = null; private FileChannel fc = null;
private long dataOffset = 0; private long dataOffset = 0;
private long writedSinceLastMdat = 0; private long writedSinceLastMdat = 0;
private boolean writeNewMdat = true; private boolean writeNewMdat = true;
HashMap<Track, long[]> track2SampleSizes = new HashMap<Track, long[]>(); private HashMap<Track, long[]> track2SampleSizes = new HashMap<Track, long[]>();
private ByteBuffer sizeBuffer = null;
public MP4Builder createMovie(Mp4Movie mp4Movie) throws Exception { public MP4Builder createMovie(Mp4Movie mp4Movie) throws Exception {
currentMp4Movie = mp4Movie; currentMp4Movie = mp4Movie;
...@@ -74,6 +75,8 @@ public class MP4Builder { ...@@ -74,6 +75,8 @@ public class MP4Builder {
mdat = new InterleaveChunkMdat(); mdat = new InterleaveChunkMdat();
sizeBuffer = ByteBuffer.allocateDirect(4);
return this; return this;
} }
...@@ -87,7 +90,7 @@ public class MP4Builder { ...@@ -87,7 +90,7 @@ public class MP4Builder {
fos.flush(); fos.flush();
} }
public boolean writeSampleData(int trackIndex, ByteBuffer byteBuf, MediaCodec.BufferInfo bufferInfo) throws Exception { public boolean writeSampleData(int trackIndex, ByteBuffer byteBuf, MediaCodec.BufferInfo bufferInfo, boolean isAudio) throws Exception {
if (writeNewMdat) { if (writeNewMdat) {
mdat.setContentSize(0); mdat.setContentSize(0);
mdat.getBox(fc); mdat.getBox(fc);
...@@ -109,9 +112,16 @@ public class MP4Builder { ...@@ -109,9 +112,16 @@ public class MP4Builder {
} }
currentMp4Movie.addSample(trackIndex, dataOffset, bufferInfo); currentMp4Movie.addSample(trackIndex, dataOffset, bufferInfo);
byteBuf.position(bufferInfo.offset); byteBuf.position(bufferInfo.offset + (isAudio ? 0 : 4));
byteBuf.limit(bufferInfo.offset + bufferInfo.size); byteBuf.limit(bufferInfo.offset + bufferInfo.size);
if (!isAudio) {
sizeBuffer.position(0);
sizeBuffer.putInt(bufferInfo.size - 4);
sizeBuffer.position(0);
fc.write(sizeBuffer);
}
fc.write(byteBuf); fc.write(byteBuf);
dataOffset += bufferInfo.size; dataOffset += bufferInfo.size;
......
...@@ -833,7 +833,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. ...@@ -833,7 +833,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
} }
object = invoke; object = invoke;
} }
TLRPC.invokeWithLayer17 invoke = new TLRPC.invokeWithLayer17(); TLRPC.invokeWithLayer18 invoke = new TLRPC.invokeWithLayer18();
invoke.query = object; invoke.query = object;
FileLog.d("wrap in layer", "" + object); FileLog.d("wrap in layer", "" + object);
return invoke; return invoke;
...@@ -997,6 +997,10 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. ...@@ -997,6 +997,10 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
return (int)(System.currentTimeMillis() / 1000) + timeDifference; return (int)(System.currentTimeMillis() / 1000) + timeDifference;
} }
public int getTimeDifference() {
return timeDifference;
}
private void processRequestQueue(int requestClass, int _datacenterId) { private void processRequestQueue(int requestClass, int _datacenterId) {
boolean haveNetwork = true;//isNetworkOnline(); boolean haveNetwork = true;//isNetworkOnline();
...@@ -1382,7 +1386,9 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. ...@@ -1382,7 +1386,9 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
if (rawRequest != null && (rawRequest instanceof TLRPC.TL_messages_sendMessage || if (rawRequest != null && (rawRequest instanceof TLRPC.TL_messages_sendMessage ||
rawRequest instanceof TLRPC.TL_messages_sendMedia || rawRequest instanceof TLRPC.TL_messages_sendMedia ||
rawRequest instanceof TLRPC.TL_messages_forwardMessages || rawRequest instanceof TLRPC.TL_messages_forwardMessages ||
rawRequest instanceof TLRPC.TL_messages_sendEncrypted)) { rawRequest instanceof TLRPC.TL_messages_sendEncrypted ||
rawRequest instanceof TLRPC.TL_messages_sendEncryptedFile ||
rawRequest instanceof TLRPC.TL_messages_sendEncryptedService)) {
if (rawRequest instanceof TLRPC.TL_messages_sendMessage) { if (rawRequest instanceof TLRPC.TL_messages_sendMessage) {
hasSendMessage = true; hasSendMessage = true;
...@@ -1400,7 +1406,9 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. ...@@ -1400,7 +1406,9 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
if (currentRawRequest instanceof TLRPC.TL_messages_sendMessage || if (currentRawRequest instanceof TLRPC.TL_messages_sendMessage ||
currentRawRequest instanceof TLRPC.TL_messages_sendMedia || currentRawRequest instanceof TLRPC.TL_messages_sendMedia ||
currentRawRequest instanceof TLRPC.TL_messages_forwardMessages || currentRawRequest instanceof TLRPC.TL_messages_forwardMessages ||
currentRawRequest instanceof TLRPC.TL_messages_sendEncrypted) { currentRawRequest instanceof TLRPC.TL_messages_sendEncrypted ||
currentRawRequest instanceof TLRPC.TL_messages_sendEncryptedFile ||
currentRawRequest instanceof TLRPC.TL_messages_sendEncryptedService) {
currentRequests.add(currentMessage.msg_id); currentRequests.add(currentMessage.msg_id);
} }
} }
...@@ -1410,7 +1418,9 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. ...@@ -1410,7 +1418,9 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
if (request.rawRequest instanceof TLRPC.TL_messages_sendMessage || if (request.rawRequest instanceof TLRPC.TL_messages_sendMessage ||
request.rawRequest instanceof TLRPC.TL_messages_sendMedia || request.rawRequest instanceof TLRPC.TL_messages_sendMedia ||
request.rawRequest instanceof TLRPC.TL_messages_forwardMessages || request.rawRequest instanceof TLRPC.TL_messages_forwardMessages ||
request.rawRequest instanceof TLRPC.TL_messages_sendEncrypted) { request.rawRequest instanceof TLRPC.TL_messages_sendEncrypted ||
request.rawRequest instanceof TLRPC.TL_messages_sendEncryptedFile ||
request.rawRequest instanceof TLRPC.TL_messages_sendEncryptedService) {
if (!currentRequests.contains(request.runningMessageId)) { if (!currentRequests.contains(request.runningMessageId)) {
maxRequestId = Math.max(maxRequestId, request.runningMessageId); maxRequestId = Math.max(maxRequestId, request.runningMessageId);
} }
...@@ -1604,12 +1614,12 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. ...@@ -1604,12 +1614,12 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
TLRPC.TL_protoMessage message = networkMessage.protoMessage; TLRPC.TL_protoMessage message = networkMessage.protoMessage;
if (BuildVars.DEBUG_VERSION) { if (BuildVars.DEBUG_VERSION) {
if (message.body instanceof TLRPC.invokeWithLayer17) { if (message.body instanceof TLRPC.invokeWithLayer18) {
FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer17)message.body).query); FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer18)message.body).query);
} else if (message.body instanceof TLRPC.initConnection) { } 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.invokeWithLayer17) { if (r.query instanceof TLRPC.invokeWithLayer18) {
FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer17)r.query).query); FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer18)r.query).query);
} else { } else {
FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + r.query); FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + r.query);
} }
...@@ -1644,12 +1654,12 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. ...@@ -1644,12 +1654,12 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
TLRPC.TL_protoMessage message = networkMessage.protoMessage; TLRPC.TL_protoMessage message = networkMessage.protoMessage;
containerMessages.add(message); containerMessages.add(message);
if (BuildVars.DEBUG_VERSION) { if (BuildVars.DEBUG_VERSION) {
if (message.body instanceof TLRPC.invokeWithLayer17) { if (message.body instanceof TLRPC.invokeWithLayer18) {
FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer17)message.body).query); FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer18)message.body).query);
} else if (message.body instanceof TLRPC.initConnection) { } 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.invokeWithLayer17) { if (r.query instanceof TLRPC.invokeWithLayer18) {
FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer17)r.query).query); FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer18)r.query).query);
} else { } else {
FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + r.query); FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + r.query);
} }
...@@ -2066,12 +2076,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. ...@@ -2066,12 +2076,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
int errorCode = ((TLRPC.RpcError) resultContainer.result).error_code; int errorCode = ((TLRPC.RpcError) resultContainer.result).error_code;
if (errorCode == 500 || errorCode < 0) { if (errorCode == 500 || errorCode < 0) {
if ((request.flags & RPCRequest.RPCRequestClassFailOnServerErrors) != 0) { if ((request.flags & RPCRequest.RPCRequestClassFailOnServerErrors) == 0) {
if (request.serverFailureCount < 1) {
discardResponse = true;
request.runningMinStartTime = request.runningStartTime + 1;
}
} else {
discardResponse = true; discardResponse = true;
int delay = Math.min(1, request.serverFailureCount * 2); int delay = Math.min(1, request.serverFailureCount * 2);
request.runningMinStartTime = request.runningStartTime + delay; request.runningMinStartTime = request.runningStartTime + delay;
...@@ -2433,6 +2438,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection. ...@@ -2433,6 +2438,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
} }
}); });
} else if ((connection.transportRequestClass & RPCRequest.RPCRequestClassPush) != 0) { } else if ((connection.transportRequestClass & RPCRequest.RPCRequestClassPush) != 0) {
FileLog.e("tmessages", "call connection closed");
sendingPushPing = false; sendingPushPing = false;
lastPushPingTime = System.currentTimeMillis() - 60000 * 3 + 4000; lastPushPingTime = System.currentTimeMillis() - 60000 * 3 + 4000;
} }
......
...@@ -63,7 +63,7 @@ public class DispatchQueue extends Thread { ...@@ -63,7 +63,7 @@ public class DispatchQueue extends Thread {
postRunnable(runnable, 0); postRunnable(runnable, 0);
} }
public void postRunnable(Runnable runnable, int delay) { public void postRunnable(Runnable runnable, long delay) {
if (handler == null) { if (handler == null) {
synchronized (handlerSyncObject) { synchronized (handlerSyncObject) {
if (handler == null) { if (handler == null) {
......
...@@ -176,7 +176,7 @@ public class FileLoader { ...@@ -176,7 +176,7 @@ public class FileLoader {
} }
if (small) { if (small) {
currentUploadSmallOperationsCount--; currentUploadSmallOperationsCount--;
if (currentUploadSmallOperationsCount < 2) { if (currentUploadSmallOperationsCount < 1) {
FileUploadOperation operation = uploadSmallOperationQueue.poll(); FileUploadOperation operation = uploadSmallOperationQueue.poll();
if (operation != null) { if (operation != null) {
currentUploadSmallOperationsCount++; currentUploadSmallOperationsCount++;
...@@ -185,7 +185,7 @@ public class FileLoader { ...@@ -185,7 +185,7 @@ public class FileLoader {
} }
} else { } else {
currentUploadOperationsCount--; currentUploadOperationsCount--;
if (currentUploadOperationsCount < 2) { if (currentUploadOperationsCount < 1) {
FileUploadOperation operation = uploadOperationQueue.poll(); FileUploadOperation operation = uploadOperationQueue.poll();
if (operation != null) { if (operation != null) {
currentUploadOperationsCount++; currentUploadOperationsCount++;
...@@ -227,7 +227,7 @@ public class FileLoader { ...@@ -227,7 +227,7 @@ public class FileLoader {
}); });
if (small) { if (small) {
currentUploadSmallOperationsCount--; currentUploadSmallOperationsCount--;
if (currentUploadSmallOperationsCount < 2) { if (currentUploadSmallOperationsCount < 1) {
FileUploadOperation operation = uploadSmallOperationQueue.poll(); FileUploadOperation operation = uploadSmallOperationQueue.poll();
if (operation != null) { if (operation != null) {
currentUploadSmallOperationsCount++; currentUploadSmallOperationsCount++;
...@@ -236,7 +236,7 @@ public class FileLoader { ...@@ -236,7 +236,7 @@ public class FileLoader {
} }
} else { } else {
currentUploadOperationsCount--; currentUploadOperationsCount--;
if (currentUploadOperationsCount < 2) { if (currentUploadOperationsCount < 1) {
FileUploadOperation operation = uploadOperationQueue.poll(); FileUploadOperation operation = uploadOperationQueue.poll();
if (operation != null) { if (operation != null) {
currentUploadOperationsCount++; currentUploadOperationsCount++;
...@@ -259,14 +259,14 @@ public class FileLoader { ...@@ -259,14 +259,14 @@ public class FileLoader {
} }
}; };
if (small) { if (small) {
if (currentUploadSmallOperationsCount < 2) { if (currentUploadSmallOperationsCount < 1) {
currentUploadSmallOperationsCount++; currentUploadSmallOperationsCount++;
operation.start(); operation.start();
} else { } else {
uploadSmallOperationQueue.add(operation); uploadSmallOperationQueue.add(operation);
} }
} else { } else {
if (currentUploadOperationsCount < 2) { if (currentUploadOperationsCount < 1) {
currentUploadOperationsCount++; currentUploadOperationsCount++;
operation.start(); operation.start();
} else { } else {
...@@ -564,18 +564,30 @@ public class FileLoader { ...@@ -564,18 +564,30 @@ public class FileLoader {
if (message == null) { if (message == null) {
return new File(""); return new File("");
} }
if (message.media instanceof TLRPC.TL_messageMediaVideo) { if (message instanceof TLRPC.TL_messageService) {
return getPathToAttach(message.media.video); if (message.action.photo != null) {
} else if (message.media instanceof TLRPC.TL_messageMediaDocument) { ArrayList<TLRPC.PhotoSize> sizes = message.action.photo.sizes;
return getPathToAttach(message.media.document); if (sizes.size() > 0) {
} else if (message.media instanceof TLRPC.TL_messageMediaAudio) { TLRPC.PhotoSize sizeFull = getClosestPhotoSizeWithSize(sizes, AndroidUtilities.getPhotoSize());
return getPathToAttach(message.media.audio); if (sizeFull != null) {
} else if (message.media instanceof TLRPC.TL_messageMediaPhoto) { return getPathToAttach(sizeFull);
ArrayList<TLRPC.PhotoSize> sizes = message.media.photo.sizes; }
if (sizes.size() > 0) { }
TLRPC.PhotoSize sizeFull = getClosestPhotoSizeWithSize(sizes, AndroidUtilities.getPhotoSize()); }
if (sizeFull != null) { } else {
return getPathToAttach(sizeFull); if (message.media instanceof TLRPC.TL_messageMediaVideo) {
return getPathToAttach(message.media.video);
} else if (message.media instanceof TLRPC.TL_messageMediaDocument) {
return getPathToAttach(message.media.document);
} else if (message.media instanceof TLRPC.TL_messageMediaAudio) {
return getPathToAttach(message.media.audio);
} else if (message.media instanceof TLRPC.TL_messageMediaPhoto) {
ArrayList<TLRPC.PhotoSize> sizes = message.media.photo.sizes;
if (sizes.size() > 0) {
TLRPC.PhotoSize sizeFull = getClosestPhotoSizeWithSize(sizes, AndroidUtilities.getPhotoSize());
if (sizeFull != null) {
return getPathToAttach(sizeFull);
}
} }
} }
} }
...@@ -692,4 +704,26 @@ public class FileLoader { ...@@ -692,4 +704,26 @@ public class FileLoader {
} }
return ""; return "";
} }
public void deleteFiles(final ArrayList<File> files) {
if (files == null || files.isEmpty()) {
return;
}
fileLoaderQueue.postRunnable(new Runnable() {
@Override
public void run() {
for (File file : files) {
if (file.exists()) {
try {
if (!file.delete()) {
file.deleteOnExit();
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
}
}
});
}
} }
...@@ -198,6 +198,7 @@ public class TLClassStore { ...@@ -198,6 +198,7 @@ public class TLClassStore {
classStore.put(TLRPC.TL_updateReadMessages.constructor, TLRPC.TL_updateReadMessages.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_updateChatParticipantDelete.constructor, TLRPC.TL_updateChatParticipantDelete.class);
classStore.put(TLRPC.TL_updateRestoreMessages.constructor, TLRPC.TL_updateRestoreMessages.class); classStore.put(TLRPC.TL_updateRestoreMessages.constructor, TLRPC.TL_updateRestoreMessages.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_updateNotifySettings.constructor, TLRPC.TL_updateNotifySettings.class);
classStore.put(TLRPC.TL_updateUserTyping.constructor, TLRPC.TL_updateUserTyping.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_updateChatUserTyping.constructor, TLRPC.TL_updateChatUserTyping.class);
...@@ -226,6 +227,7 @@ public class TLClassStore { ...@@ -226,6 +227,7 @@ public class TLClassStore {
classStore.put(TLRPC.TL_inputEncryptedFileEmpty.constructor, TLRPC.TL_inputEncryptedFileEmpty.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_inputEncryptedFileUploaded.constructor, TLRPC.TL_inputEncryptedFileUploaded.class);
classStore.put(TLRPC.TL_decryptedMessageActionFlushHistory.constructor, TLRPC.TL_decryptedMessageActionFlushHistory.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_decryptedMessageActionNotifyLayer.constructor, TLRPC.TL_decryptedMessageActionNotifyLayer.class);
classStore.put(TLRPC.TL_decryptedMessageActionSetMessageTTL.constructor, TLRPC.TL_decryptedMessageActionSetMessageTTL.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_decryptedMessageActionDeleteMessages.constructor, TLRPC.TL_decryptedMessageActionDeleteMessages.class);
...@@ -362,6 +364,13 @@ public class TLClassStore { ...@@ -362,6 +364,13 @@ public class TLClassStore {
classStore.put(TLRPC.TL_messageService_old.constructor, TLRPC.TL_messageService_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_decryptedMessageService_old.constructor, TLRPC.TL_decryptedMessageService_old.class);
classStore.put(TLRPC.TL_decryptedMessage_old.constructor, TLRPC.TL_decryptedMessage_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);
} }
static TLClassStore store = null; static TLClassStore store = null;
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
package org.telegram.messenger; package org.telegram.messenger;
import android.app.Activity; import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ContentUris; import android.content.ContentUris;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
...@@ -28,7 +27,6 @@ import net.hockeyapp.android.CrashManager; ...@@ -28,7 +27,6 @@ import net.hockeyapp.android.CrashManager;
import net.hockeyapp.android.CrashManagerListener; import net.hockeyapp.android.CrashManagerListener;
import net.hockeyapp.android.UpdateManager; import net.hockeyapp.android.UpdateManager;
import org.telegram.android.LocaleController;
import org.telegram.ui.ApplicationLoader; import org.telegram.ui.ApplicationLoader;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
...@@ -74,8 +72,6 @@ public class Utilities { ...@@ -74,8 +72,6 @@ public class Utilities {
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray(); final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static ProgressDialog progressDialog;
static { static {
try { try {
File URANDOM_FILE = new File("/dev/urandom"); File URANDOM_FILE = new File("/dev/urandom");
...@@ -112,7 +108,7 @@ public class Utilities { ...@@ -112,7 +108,7 @@ public class Utilities {
public native static long doPQNative(long _what); public native static long doPQNative(long _what);
public native static void loadBitmap(String path, int[] bitmap, int scale, int format, int width, int height); public native static void loadBitmap(String path, int[] bitmap, int scale, int format, int width, int height);
public native static void blurBitmap(Object bitmap); public native static void blurBitmap(Object bitmap, int radius);
public native static int convertVideoFrame(ByteBuffer src, ByteBuffer dest, int destFormat, int width, int height, int padding, int swap); public native static int convertVideoFrame(ByteBuffer src, ByteBuffer dest, int destFormat, int width, int height, int padding, int swap);
private native static void aesIgeEncryption(ByteBuffer buffer, byte[] key, byte[] iv, boolean encrypt, int offset, int length); private native static void aesIgeEncryption(ByteBuffer buffer, byte[] key, byte[] iv, boolean encrypt, int offset, int length);
...@@ -427,34 +423,6 @@ public class Utilities { ...@@ -427,34 +423,6 @@ public class Utilities {
return packedData; return packedData;
} }
public static void ShowProgressDialog(final Activity activity, final String message) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if(!activity.isFinishing()) {
progressDialog = new ProgressDialog(activity);
if (message != null) {
progressDialog.setMessage(message);
}
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setCancelable(false);
progressDialog.show();
}
}
});
}
public static void HideProgressDialog(Activity activity) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (progressDialog != null) {
progressDialog.dismiss();
}
}
});
}
public static boolean copyFile(InputStream sourceFile, File destFile) throws IOException { public static boolean copyFile(InputStream sourceFile, File destFile) throws IOException {
OutputStream out = new FileOutputStream(destFile); OutputStream out = new FileOutputStream(destFile);
byte[] buf = new byte[4096]; byte[] buf = new byte[4096];
......
/*
* 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.Adapters;
import org.telegram.android.AndroidUtilities;
import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.RPCRequest;
import org.telegram.messenger.TLObject;
import org.telegram.messenger.TLRPC;
import java.util.ArrayList;
public class BaseContactsSearchAdapter extends BaseFragmentAdapter {
protected ArrayList<TLRPC.User> globalSearch = new ArrayList<TLRPC.User>();
private long reqId = 0;
private int lastReqId;
protected String lastFoundUsername = null;
public void queryServerSearch(final String query) {
if (query == null || query.length() < 5) {
if (reqId != 0) {
ConnectionsManager.getInstance().cancelRpc(reqId, true);
reqId = 0;
}
globalSearch.clear();
lastReqId = 0;
notifyDataSetChanged();
return;
}
TLRPC.TL_contacts_search req = new TLRPC.TL_contacts_search();
req.q = query;
req.limit = 50;
final int currentReqId = ++lastReqId;
reqId = ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() {
@Override
public void run(final TLObject response, final TLRPC.TL_error error) {
AndroidUtilities.RunOnUIThread(new Runnable() {
@Override
public void run() {
if (currentReqId == lastReqId) {
if (error == null) {
TLRPC.TL_contacts_found res = (TLRPC.TL_contacts_found) response;
globalSearch = res.users;
lastFoundUsername = query;
notifyDataSetChanged();
}
}
reqId = 0;
}
});
}
}, true, RPCRequest.RPCRequestClassGeneric | RPCRequest.RPCRequestClassFailOnServerErrors);
}
}
...@@ -14,6 +14,7 @@ import android.view.ViewGroup; ...@@ -14,6 +14,7 @@ import android.view.ViewGroup;
import android.widget.BaseAdapter; import android.widget.BaseAdapter;
public class BaseFragmentAdapter extends BaseAdapter { public class BaseFragmentAdapter extends BaseAdapter {
public void onFragmentCreate() { public void onFragmentCreate() {
} }
......
...@@ -21,6 +21,7 @@ import org.telegram.android.MessagesController; ...@@ -21,6 +21,7 @@ import org.telegram.android.MessagesController;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.ui.Cells.ChatOrUserCell; import org.telegram.ui.Cells.ChatOrUserCell;
import org.telegram.ui.Views.SectionedBaseAdapter; import org.telegram.ui.Views.SectionedBaseAdapter;
import org.telegram.ui.Views.SettingsSectionLayout;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
...@@ -202,12 +203,10 @@ public class ContactsActivityAdapter extends SectionedBaseAdapter { ...@@ -202,12 +203,10 @@ public class ContactsActivityAdapter extends SectionedBaseAdapter {
if (usersAsSections) { if (usersAsSections) {
if (section < ContactsController.getInstance().sortedUsersSectionsArray.size()) { if (section < ContactsController.getInstance().sortedUsersSectionsArray.size()) {
if (convertView == null) { if (convertView == null) {
LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = new SettingsSectionLayout(mContext);
convertView = li.inflate(R.layout.settings_section_layout, parent, false);
convertView.setBackgroundColor(0xffffffff); convertView.setBackgroundColor(0xffffffff);
} }
TextView textView = (TextView)convertView.findViewById(R.id.settings_section_text); ((SettingsSectionLayout) convertView).setText(ContactsController.getInstance().sortedUsersSectionsArray.get(section));
textView.setText(ContactsController.getInstance().sortedUsersSectionsArray.get(section));
return convertView; return convertView;
} }
} else { } else {
...@@ -221,12 +220,10 @@ public class ContactsActivityAdapter extends SectionedBaseAdapter { ...@@ -221,12 +220,10 @@ public class ContactsActivityAdapter extends SectionedBaseAdapter {
} }
if (convertView == null) { if (convertView == null) {
LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = new SettingsSectionLayout(mContext);
convertView = li.inflate(R.layout.settings_section_layout, parent, false);
convertView.setBackgroundColor(0xffffffff); convertView.setBackgroundColor(0xffffffff);
} }
TextView textView = (TextView)convertView.findViewById(R.id.settings_section_text); ((SettingsSectionLayout) convertView).setText(ContactsController.getInstance().sortedContactsSectionsArray.get(section - 1));
textView.setText(ContactsController.getInstance().sortedContactsSectionsArray.get(section - 1));
return convertView; return convertView;
} }
} }
...@@ -9,10 +9,13 @@ ...@@ -9,10 +9,13 @@
package org.telegram.ui.Adapters; package org.telegram.ui.Adapters;
import android.content.Context; import android.content.Context;
import android.text.Html;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import org.telegram.android.AndroidUtilities; import org.telegram.android.AndroidUtilities;
import org.telegram.android.LocaleController;
import org.telegram.messenger.R;
import org.telegram.messenger.TLRPC; import org.telegram.messenger.TLRPC;
import org.telegram.android.ContactsController; import org.telegram.android.ContactsController;
import org.telegram.messenger.FileLog; import org.telegram.messenger.FileLog;
...@@ -20,28 +23,34 @@ import org.telegram.android.MessagesController; ...@@ -20,28 +23,34 @@ import org.telegram.android.MessagesController;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities; import org.telegram.messenger.Utilities;
import org.telegram.ui.Cells.ChatOrUserCell; import org.telegram.ui.Cells.ChatOrUserCell;
import org.telegram.ui.Views.SettingsSectionLayout;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
public class ContactsActivitySearchAdapter extends BaseFragmentAdapter { public class ContactsActivitySearchAdapter extends BaseContactsSearchAdapter {
private Context mContext; private Context mContext;
private HashMap<Integer, TLRPC.User> ignoreUsers; private HashMap<Integer, TLRPC.User> ignoreUsers;
private ArrayList<TLRPC.User> searchResult; private ArrayList<TLRPC.User> searchResult;
private ArrayList<CharSequence> searchResultNames; private ArrayList<CharSequence> searchResultNames;
private Timer searchTimer; private Timer searchTimer;
private boolean allowUsernameSearch;
public ContactsActivitySearchAdapter(Context context, HashMap<Integer, TLRPC.User> arg1) { public ContactsActivitySearchAdapter(Context context, HashMap<Integer, TLRPC.User> arg1, boolean usernameSearch) {
mContext = context; mContext = context;
ignoreUsers = arg1; ignoreUsers = arg1;
allowUsernameSearch = usernameSearch;
} }
public void searchDialogs(final String query) { public void searchDialogs(final String query) {
if (query == null) { if (query == null) {
searchResult = null; searchResult.clear();
searchResultNames = null; searchResultNames.clear();
if (allowUsernameSearch) {
queryServerSearch(null);
}
notifyDataSetChanged(); notifyDataSetChanged();
} else { } else {
try { try {
...@@ -63,7 +72,7 @@ public class ContactsActivitySearchAdapter extends BaseFragmentAdapter { ...@@ -63,7 +72,7 @@ public class ContactsActivitySearchAdapter extends BaseFragmentAdapter {
} }
processSearch(query); processSearch(query);
} }
}, 100, 300); }, 200, 300);
} }
} }
...@@ -71,6 +80,9 @@ public class ContactsActivitySearchAdapter extends BaseFragmentAdapter { ...@@ -71,6 +80,9 @@ public class ContactsActivitySearchAdapter extends BaseFragmentAdapter {
AndroidUtilities.RunOnUIThread(new Runnable() { AndroidUtilities.RunOnUIThread(new Runnable() {
@Override @Override
public void run() { public void run() {
if (allowUsernameSearch) {
queryServerSearch(query);
}
final ArrayList<TLRPC.TL_contact> contactsCopy = new ArrayList<TLRPC.TL_contact>(); final ArrayList<TLRPC.TL_contact> contactsCopy = new ArrayList<TLRPC.TL_contact>();
contactsCopy.addAll(ContactsController.getInstance().contacts); contactsCopy.addAll(ContactsController.getInstance().contacts);
Utilities.searchQueue.postRunnable(new Runnable() { Utilities.searchQueue.postRunnable(new Runnable() {
...@@ -87,12 +99,25 @@ public class ContactsActivitySearchAdapter extends BaseFragmentAdapter { ...@@ -87,12 +99,25 @@ public class ContactsActivitySearchAdapter extends BaseFragmentAdapter {
for (TLRPC.TL_contact contact : contactsCopy) { for (TLRPC.TL_contact contact : contactsCopy) {
TLRPC.User user = MessagesController.getInstance().getUser(contact.user_id); TLRPC.User user = MessagesController.getInstance().getUser(contact.user_id);
if (user.id == UserConfig.getClientUserId()) {
continue;
}
String name = ContactsController.formatName(user.first_name, user.last_name).toLowerCase(); String name = ContactsController.formatName(user.first_name, user.last_name).toLowerCase();
int found = 0;
if (name.startsWith(q) || name.contains(" " + q)) { if (name.startsWith(q) || name.contains(" " + q)) {
if (user.id == UserConfig.getClientUserId()) { found = 1;
continue; } else if (user.username != null && user.username.startsWith(q)) {
found = 2;
}
if (found != 0) {
if (found == 1) {
resultArrayNames.add(Utilities.generateSearchName(user.first_name, user.last_name, q));
} else {
resultArrayNames.add(Utilities.generateSearchName("@" + user.username, null, "@" + q));
} }
resultArrayNames.add(Utilities.generateSearchName(user.first_name, user.last_name, q));
resultArray.add(user); resultArray.add(user);
} }
} }
...@@ -117,28 +142,43 @@ public class ContactsActivitySearchAdapter extends BaseFragmentAdapter { ...@@ -117,28 +142,43 @@ public class ContactsActivitySearchAdapter extends BaseFragmentAdapter {
@Override @Override
public boolean areAllItemsEnabled() { public boolean areAllItemsEnabled() {
return true; return false;
} }
@Override @Override
public boolean isEnabled(int i) { public boolean isEnabled(int i) {
return true; return i != searchResult.size();
} }
@Override @Override
public int getCount() { public int getCount() {
if (searchResult == null) { int count = searchResult.size();
return 0; int globalCount = globalSearch.size();
if (globalCount != 0) {
count += globalCount + 1;
} }
return searchResult.size(); return count;
}
public boolean isGlobalSearch(int i) {
int localCount = searchResult.size();
int globalCount = globalSearch.size();
if (i >= 0 && i < localCount) {
return false;
} else if (i > localCount && i <= globalCount + localCount) {
return true;
}
return false;
} }
@Override @Override
public TLRPC.User getItem(int i) { public TLRPC.User getItem(int i) {
if (searchResult != null) { int localCount = searchResult.size();
if (i >= 0 && i < searchResult.size()) { int globalCount = globalSearch.size();
return searchResult.get(i); if (i >= 0 && i < localCount) {
} return searchResult.get(i);
} else if (i > localCount && i <= globalCount + localCount) {
return globalSearch.get(i - localCount - 1);
} }
return null; return null;
} }
...@@ -155,24 +195,47 @@ public class ContactsActivitySearchAdapter extends BaseFragmentAdapter { ...@@ -155,24 +195,47 @@ public class ContactsActivitySearchAdapter extends BaseFragmentAdapter {
@Override @Override
public View getView(int i, View view, ViewGroup viewGroup) { public View getView(int i, View view, ViewGroup viewGroup) {
if (view == null) { if (i == searchResult.size()) {
view = new ChatOrUserCell(mContext); if (view == null) {
((ChatOrUserCell)view).usePadding = false; view = new SettingsSectionLayout(mContext);
} ((SettingsSectionLayout) view).setText(LocaleController.getString("GlobalSearch", R.string.GlobalSearch));
}
((ChatOrUserCell) view).useSeparator = i != searchResult.size() - 1; } else {
if (view == null) {
view = new ChatOrUserCell(mContext);
((ChatOrUserCell) view).usePadding = false;
}
Object obj = searchResult.get(i); ((ChatOrUserCell) view).useSeparator = (i != getCount() - 1 && i != searchResult.size() - 1);
TLRPC.User user = MessagesController.getInstance().getUser(((TLRPC.User)obj).id); TLRPC.User user = getItem(i);
if (user != null) {
CharSequence username = null;
CharSequence name = null;
if (i < searchResult.size()) {
name = searchResultNames.get(i);
if (name != null && user != null && user.username != null && user.username.length() > 0) {
if (name.toString().startsWith("@" + user.username)) {
username = name;
name = null;
}
}
} else if (i > searchResult.size() && user.username != null) {
try {
username = Html.fromHtml(String.format("<font color=\"#357aa8\">@%s</font>%s", user.username.substring(0, lastFoundUsername.length()), user.username.substring(lastFoundUsername.length())));
} catch (Exception e) {
username = user.username;
FileLog.e("tmessages", e);
}
}
if (user != null) { ((ChatOrUserCell) view).setData(user, null, null, name, username);
((ChatOrUserCell)view).setData(user, null, null, searchResultNames.get(i), null);
if (ignoreUsers != null) { if (ignoreUsers != null) {
if (ignoreUsers.containsKey(user.id)) { if (ignoreUsers.containsKey(user.id)) {
((ChatOrUserCell)view).drawAlpha = 0.5f; ((ChatOrUserCell) view).drawAlpha = 0.5f;
} else { } else {
((ChatOrUserCell)view).drawAlpha = 1.0f; ((ChatOrUserCell) view).drawAlpha = 1.0f;
}
} }
} }
} }
...@@ -181,16 +244,19 @@ public class ContactsActivitySearchAdapter extends BaseFragmentAdapter { ...@@ -181,16 +244,19 @@ public class ContactsActivitySearchAdapter extends BaseFragmentAdapter {
@Override @Override
public int getItemViewType(int i) { public int getItemViewType(int i) {
if (i == searchResult.size()) {
return 1;
}
return 0; return 0;
} }
@Override @Override
public int getViewTypeCount() { public int getViewTypeCount() {
return 1; return 2;
} }
@Override @Override
public boolean isEmpty() { public boolean isEmpty() {
return searchResult == null || searchResult.size() == 0; return searchResult.isEmpty() && globalSearch.isEmpty();
} }
} }
...@@ -10,10 +10,43 @@ package org.telegram.ui.Cells; ...@@ -10,10 +10,43 @@ package org.telegram.ui.Cells;
import android.content.Context; import android.content.Context;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewConfiguration;
public class BaseCell extends View { public class BaseCell extends View {
private final class CheckForTap implements Runnable {
public void run() {
if (pendingCheckForLongPress == null) {
pendingCheckForLongPress = new CheckForLongPress();
}
pendingCheckForLongPress.currentPressCount = ++pressCount;
postDelayed(pendingCheckForLongPress, ViewConfiguration.getLongPressTimeout() - ViewConfiguration.getTapTimeout());
}
}
class CheckForLongPress implements Runnable {
public int currentPressCount;
public void run() {
if (checkingForLongPress && getParent() != null && currentPressCount == pressCount) {
checkingForLongPress = false;
MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_CANCEL, 0, 0, 0);
onTouchEvent(event);
event.recycle();
performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
onLongPress();
}
}
}
private boolean checkingForLongPress = false;
private CheckForLongPress pendingCheckForLongPress = null;
private int pressCount = 0;
private CheckForTap pendingCheckForTap = null;
public BaseCell(Context context) { public BaseCell(Context context) {
super(context); super(context);
} }
...@@ -25,4 +58,29 @@ public class BaseCell extends View { ...@@ -25,4 +58,29 @@ public class BaseCell extends View {
protected void setDrawableBounds(Drawable drawable, int x, int y, int w, int h) { protected void setDrawableBounds(Drawable drawable, int x, int y, int w, int h) {
drawable.setBounds(x, y, x + w, y + h); drawable.setBounds(x, y, x + w, y + h);
} }
protected void startCheckLongPress() {
if (checkingForLongPress) {
return;
}
checkingForLongPress = true;
if (pendingCheckForTap == null) {
pendingCheckForTap = new CheckForTap();
}
postDelayed(pendingCheckForTap, ViewConfiguration.getTapTimeout());
}
protected void cancelCheckLongPress() {
checkingForLongPress = false;
if (pendingCheckForLongPress != null) {
removeCallbacks(pendingCheckForLongPress);
}
if (pendingCheckForTap != null) {
removeCallbacks(pendingCheckForTap);
}
}
protected void onLongPress() {
}
} }
...@@ -36,6 +36,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega ...@@ -36,6 +36,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
private static TextPaint timePaint; private static TextPaint timePaint;
private ImageReceiver avatarImage; private ImageReceiver avatarImage;
private boolean needAvatarImage = false;
private SeekBar seekBar; private SeekBar seekBar;
private ProgressView progressView; private ProgressView progressView;
private int seekBarX; private int seekBarX;
...@@ -44,9 +45,9 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega ...@@ -44,9 +45,9 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
private int buttonState = 0; private int buttonState = 0;
private int buttonX; private int buttonX;
private int buttonY; private int buttonY;
private int buttonPressed = 0; private boolean buttonPressed = false;
private int avatarPressed = 0; private boolean avatarPressed = false;
private StaticLayout timeLayout; private StaticLayout timeLayout;
private int timeX; private int timeX;
...@@ -56,7 +57,6 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega ...@@ -56,7 +57,6 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
public TLRPC.User audioUser; public TLRPC.User audioUser;
private TLRPC.FileLocation currentPhoto; private TLRPC.FileLocation currentPhoto;
private String currentNameString;
public ChatAudioCell(Context context) { public ChatAudioCell(Context context) {
super(context); super(context);
...@@ -115,40 +115,40 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega ...@@ -115,40 +115,40 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
int side = AndroidUtilities.dp(36); int side = AndroidUtilities.dp(36);
if (event.getAction() == MotionEvent.ACTION_DOWN) { if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (x >= buttonX && x <= buttonX + side && y >= buttonY && y <= buttonY + side) { if (x >= buttonX && x <= buttonX + side && y >= buttonY && y <= buttonY + side) {
buttonPressed = 1; buttonPressed = true;
invalidate(); invalidate();
result = true; result = true;
} else if (avatarImage.isInsideImage(x, y)) { } else if (needAvatarImage && avatarImage.isInsideImage(x, y)) {
avatarPressed = 1; avatarPressed = true;
result = true; result = true;
} }
} else if (buttonPressed == 1) { } else if (buttonPressed) {
if (event.getAction() == MotionEvent.ACTION_UP) { if (event.getAction() == MotionEvent.ACTION_UP) {
buttonPressed = 0; buttonPressed = false;
playSoundEffect(SoundEffectConstants.CLICK); playSoundEffect(SoundEffectConstants.CLICK);
didPressedButton(); didPressedButton();
invalidate(); invalidate();
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) { } else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
buttonPressed = 0; buttonPressed = false;
invalidate(); invalidate();
} else if (event.getAction() == MotionEvent.ACTION_MOVE) { } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (!(x >= buttonX && x <= buttonX + side && y >= buttonY && y <= buttonY + side)) { if (!(x >= buttonX && x <= buttonX + side && y >= buttonY && y <= buttonY + side)) {
buttonPressed = 0; buttonPressed = false;
invalidate(); invalidate();
} }
} }
} else if (avatarPressed == 1) { } else if (avatarPressed) {
if (event.getAction() == MotionEvent.ACTION_UP) { if (event.getAction() == MotionEvent.ACTION_UP) {
avatarPressed = 0; avatarPressed = false;
playSoundEffect(SoundEffectConstants.CLICK); playSoundEffect(SoundEffectConstants.CLICK);
if (delegate != null) { if (delegate != null) {
delegate.didPressedUserAvatar(this, audioUser); delegate.didPressedUserAvatar(this, audioUser);
} }
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) { } else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
avatarPressed = 0; avatarPressed = false;
} else if (event.getAction() == MotionEvent.ACTION_MOVE) { } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (!avatarImage.isInsideImage(x, y)) { if (!avatarImage.isInsideImage(x, y)) {
avatarPressed = 0; avatarPressed = false;
} }
} }
} }
...@@ -301,7 +301,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega ...@@ -301,7 +301,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
int x; int x;
if (currentMessageObject.isOut()) { if (currentMessageObject.isOut()) {
x = layoutWidth - backgroundWidth + AndroidUtilities.dp(9); x = layoutWidth - backgroundWidth + AndroidUtilities.dp(8);
seekBarX = layoutWidth - backgroundWidth + AndroidUtilities.dp(97); seekBarX = layoutWidth - backgroundWidth + AndroidUtilities.dp(97);
buttonX = layoutWidth - backgroundWidth + AndroidUtilities.dp(67); buttonX = layoutWidth - backgroundWidth + AndroidUtilities.dp(67);
timeX = layoutWidth - backgroundWidth + AndroidUtilities.dp(71); timeX = layoutWidth - backgroundWidth + AndroidUtilities.dp(71);
...@@ -318,11 +318,19 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega ...@@ -318,11 +318,19 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
timeX = AndroidUtilities.dp(80); timeX = AndroidUtilities.dp(80);
} }
} }
avatarImage.setImageCoords(x, AndroidUtilities.dp(9), AndroidUtilities.dp(50), AndroidUtilities.dp(50)); int diff = 0;
if (needAvatarImage) {
avatarImage.setImageCoords(x, AndroidUtilities.dp(9), AndroidUtilities.dp(50), AndroidUtilities.dp(50));
} else {
diff = AndroidUtilities.dp(56);
seekBarX -= diff;
buttonX -= diff;
timeX -= diff;
}
seekBar.width = backgroundWidth - AndroidUtilities.dp(112); seekBar.width = backgroundWidth - AndroidUtilities.dp(112) + diff;
seekBar.height = AndroidUtilities.dp(30); seekBar.height = AndroidUtilities.dp(30);
progressView.width = backgroundWidth - AndroidUtilities.dp(136); progressView.width = backgroundWidth - AndroidUtilities.dp(136) + diff;
progressView.height = AndroidUtilities.dp(30); progressView.height = AndroidUtilities.dp(30);
seekBarY = AndroidUtilities.dp(13); seekBarY = AndroidUtilities.dp(13);
buttonY = AndroidUtilities.dp(10); buttonY = AndroidUtilities.dp(10);
...@@ -349,14 +357,18 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega ...@@ -349,14 +357,18 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
if (uid == 0) { if (uid == 0) {
uid = messageObject.messageOwner.from_id; 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); audioUser = MessagesController.getInstance().getUser(uid);
if (audioUser != null) {
if (audioUser.photo != null) { if (needAvatarImage) {
currentPhoto = audioUser.photo.photo_small; if (audioUser != null) {
if (audioUser.photo != null) {
currentPhoto = audioUser.photo.photo_small;
}
avatarImage.setImage(currentPhoto, "50_50", getResources().getDrawable(AndroidUtilities.getUserAvatarForId(uid)), false);
} else {
avatarImage.setImage(null, "50_50", getResources().getDrawable(AndroidUtilities.getUserAvatarForId(uid)), false);
} }
avatarImage.setImage(currentPhoto, "50_50", getResources().getDrawable(AndroidUtilities.getUserAvatarForId(uid)), false);
} else {
avatarImage.setImage((TLRPC.FileLocation)null, "50_50", getResources().getDrawable(AndroidUtilities.getUserAvatarForId(uid)), false);
} }
if (messageObject.isOut()) { if (messageObject.isOut()) {
...@@ -380,7 +392,9 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega ...@@ -380,7 +392,9 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
return; return;
} }
avatarImage.draw(canvas, avatarImage.getImageX(), avatarImage.getImageY(), AndroidUtilities.dp(50), AndroidUtilities.dp(50)); if (needAvatarImage) {
avatarImage.draw(canvas);
}
canvas.save(); canvas.save();
if (buttonState == 0 || buttonState == 1) { if (buttonState == 0 || buttonState == 1) {
...@@ -399,7 +413,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega ...@@ -399,7 +413,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
} else { } else {
timePaint.setColor(0xff70b15c); timePaint.setColor(0xff70b15c);
} }
Drawable buttonDrawable = statesDrawable[state][buttonPressed]; Drawable buttonDrawable = statesDrawable[state][buttonPressed ? 1 : 0];
int side = AndroidUtilities.dp(36); int side = AndroidUtilities.dp(36);
int x = (side - buttonDrawable.getIntrinsicWidth()) / 2; int x = (side - buttonDrawable.getIntrinsicWidth()) / 2;
int y = (side - buttonDrawable.getIntrinsicHeight()) / 2; int y = (side - buttonDrawable.getIntrinsicHeight()) / 2;
......
...@@ -41,7 +41,7 @@ public class ChatOrUserCell extends BaseCell { ...@@ -41,7 +41,7 @@ public class ChatOrUserCell extends BaseCell {
private CharSequence currentName; private CharSequence currentName;
private ImageReceiver avatarImage; private ImageReceiver avatarImage;
private String subLabel; private CharSequence subLabel;
private ChatOrUserCellLayout cellLayout; private ChatOrUserCellLayout cellLayout;
private TLRPC.User user = null; private TLRPC.User user = null;
...@@ -112,7 +112,7 @@ public class ChatOrUserCell extends BaseCell { ...@@ -112,7 +112,7 @@ public class ChatOrUserCell extends BaseCell {
} }
} }
public void setData(TLRPC.User u, TLRPC.Chat c, TLRPC.EncryptedChat ec, CharSequence n, String s) { public void setData(TLRPC.User u, TLRPC.Chat c, TLRPC.EncryptedChat ec, CharSequence n, CharSequence s) {
currentName = n; currentName = n;
user = u; user = u;
chat = c; chat = c;
...@@ -236,6 +236,15 @@ public class ChatOrUserCell extends BaseCell { ...@@ -236,6 +236,15 @@ public class ChatOrUserCell extends BaseCell {
return; return;
} }
if (useSeparator) {
int h = getMeasuredHeight();
if (!usePadding) {
canvas.drawLine(0, h - 1, getMeasuredWidth(), h - 1, linePaint);
} else {
canvas.drawLine(AndroidUtilities.dp(11), h - 1, getMeasuredWidth() - AndroidUtilities.dp(11), h - 1, linePaint);
}
}
if (drawAlpha != 1) { if (drawAlpha != 1) {
canvas.saveLayerAlpha(0, 0, canvas.getWidth(), canvas.getHeight(), (int)(255 * drawAlpha), Canvas.HAS_ALPHA_LAYER_SAVE_FLAG); canvas.saveLayerAlpha(0, 0, canvas.getWidth(), canvas.getHeight(), (int)(255 * drawAlpha), Canvas.HAS_ALPHA_LAYER_SAVE_FLAG);
} }
...@@ -263,16 +272,7 @@ public class ChatOrUserCell extends BaseCell { ...@@ -263,16 +272,7 @@ public class ChatOrUserCell extends BaseCell {
canvas.restore(); canvas.restore();
} }
avatarImage.draw(canvas, cellLayout.avatarLeft, cellLayout.avatarTop, AndroidUtilities.dp(50), AndroidUtilities.dp(50)); avatarImage.draw(canvas);
if (useSeparator) {
int h = getMeasuredHeight();
if (!usePadding) {
canvas.drawLine(0, h - 1, getMeasuredWidth(), h, linePaint);
} else {
canvas.drawLine(AndroidUtilities.dp(11), h - 1, getMeasuredWidth() - AndroidUtilities.dp(11), h, linePaint);
}
}
} }
private class ChatOrUserCellLayout { private class ChatOrUserCellLayout {
...@@ -381,7 +381,7 @@ public class ChatOrUserCell extends BaseCell { ...@@ -381,7 +381,7 @@ public class ChatOrUserCell extends BaseCell {
onlineLeft = usePadding ? AndroidUtilities.dp(11) : 0; onlineLeft = usePadding ? AndroidUtilities.dp(11) : 0;
} }
String onlineString = ""; CharSequence onlineString = "";
TextPaint currentOnlinePaint = offlinePaint; TextPaint currentOnlinePaint = offlinePaint;
if (subLabel != null) { if (subLabel != null) {
......
...@@ -91,6 +91,6 @@ public class BackupImageView extends View { ...@@ -91,6 +91,6 @@ public class BackupImageView extends View {
@Override @Override
protected void onDraw(Canvas canvas) { protected void onDraw(Canvas canvas) {
imageReceiver.setImageCoords(0, 0, getWidth(), getHeight()); imageReceiver.setImageCoords(0, 0, getWidth(), getHeight());
imageReceiver.draw(canvas, 0, 0, getWidth(), getHeight()); imageReceiver.draw(canvas);
} }
} }
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment