Commit cd9d188f authored by DrKLO's avatar DrKLO

Merge branch 'dev'

parents fd69c56f abf8f6f6
## 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.
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
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
**Beware of using dev branch and uploading it to any markets, in most cases it will work as you expecting**
First of all your should take a look to **src/main/java/org/telegram/messenger/BuildVars.java** and fill it with correct values.
**Beware of using the dev branch and uploading it to any markets, in many cases it not will work as expected**.
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.
### Localization
......
......@@ -19,13 +19,13 @@ tasks.withType(JavaCompile) {
dependencies {
compile 'com.android.support:support-v4:20.0.+'
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.+'
}
android {
compileSdkVersion 19
buildToolsVersion '20.0.0'
compileSdkVersion 21
buildToolsVersion '21.0.2'
signingConfigs {
debug {
......@@ -80,7 +80,7 @@ android {
defaultConfig {
minSdkVersion 8
targetSdkVersion 19
versionCode 355
versionName "1.9.4"
versionCode 374
versionName "1.9.6"
}
}
......@@ -9,12 +9,11 @@ static inline uint64_t get_colors (const uint8_t *p) {
return p[0] + (p[1] << 16) + ((uint64_t)p[2] << 32);
}
static void fastBlur(int imageWidth, int imageHeight, int imageStride, void *pixels) {
static void fastBlurMore(int imageWidth, int imageHeight, int imageStride, void *pixels, int radius) {
uint8_t *pix = (uint8_t *)pixels;
const int w = imageWidth;
const int h = imageHeight;
const int stride = imageStride;
const int radius = 3;
const int r1 = radius + 1;
const int div = radius * 2 + 1;
......@@ -23,6 +22,98 @@ static void fastBlur(int imageWidth, int imageHeight, int imageStride, void *pix
}
uint64_t *rgb = malloc(imageWidth * imageHeight * sizeof(uint64_t));
if (rgb == NULL) {
return;
}
int x, y, i;
int yw = 0;
const int we = w - r1;
for (y = 0; y < h; y++) {
uint64_t cur = get_colors (&pix[yw]);
uint64_t rgballsum = -radius * cur;
uint64_t rgbsum = cur * ((r1 * (r1 + 1)) >> 1);
for (i = 1; i <= radius; i++) {
uint64_t cur = get_colors (&pix[yw + i * 4]);
rgbsum += cur * (r1 - i);
rgballsum += cur;
}
x = 0;
#define update(start, middle, end) \
rgb[y * w + x] = (rgbsum >> 6) & 0x00FF00FF00FF00FF; \
rgballsum += get_colors (&pix[yw + (start) * 4]) - 2 * get_colors (&pix[yw + (middle) * 4]) + get_colors (&pix[yw + (end) * 4]); \
rgbsum += rgballsum; \
x++; \
while (x < r1) {
update (0, x, x + r1);
}
while (x < we) {
update (x - r1, x, x + r1);
}
while (x < w) {
update (x - r1, x, w - 1);
}
#undef update
yw += stride;
}
const int he = h - r1;
for (x = 0; x < w; x++) {
uint64_t rgballsum = -radius * rgb[x];
uint64_t rgbsum = rgb[x] * ((r1 * (r1 + 1)) >> 1);
for (i = 1; i <= radius; i++) {
rgbsum += rgb[i * w + x] * (r1 - i);
rgballsum += rgb[i * w + x];
}
y = 0;
int yi = x * 4;
#define update(start, middle, end) \
int64_t res = rgbsum >> 6; \
pix[yi] = res; \
pix[yi + 1] = res >> 16; \
pix[yi + 2] = res >> 32; \
rgballsum += rgb[x + (start) * w] - 2 * rgb[x + (middle) * w] + rgb[x + (end) * w]; \
rgbsum += rgballsum; \
y++; \
yi += stride;
while (y < r1) {
update (0, y, y + r1);
}
while (y < he) {
update (y - r1, y, y + r1);
}
while (y < h) {
update (y - r1, y, h - 1);
}
#undef update
}
}
static void fastBlur(int imageWidth, int imageHeight, int imageStride, void *pixels, int radius) {
uint8_t *pix = (uint8_t *)pixels;
const int w = imageWidth;
const int h = imageHeight;
const int stride = imageStride;
const int r1 = radius + 1;
const int div = radius * 2 + 1;
if (radius > 15 || div >= w || div >= h || w * h > 90 * 90 || imageStride > imageWidth * 4) {
return;
}
uint64_t *rgb = malloc(imageWidth * imageHeight * sizeof(uint64_t));
if (rgb == NULL) {
return;
}
int x, y, i;
......@@ -111,7 +202,7 @@ METHODDEF(void) my_error_exit(j_common_ptr cinfo) {
longjmp(myerr->setjmp_buffer, 1);
}
JNIEXPORT void Java_org_telegram_messenger_Utilities_blurBitmap(JNIEnv *env, jclass class, jobject bitmap) {
JNIEXPORT void Java_org_telegram_messenger_Utilities_blurBitmap(JNIEnv *env, jclass class, jobject bitmap, int radius) {
if (!bitmap) {
return;
}
......@@ -130,7 +221,11 @@ JNIEXPORT void Java_org_telegram_messenger_Utilities_blurBitmap(JNIEnv *env, jcl
if (AndroidBitmap_lockPixels(env, bitmap, &pixels) < 0) {
return;
}
fastBlur(info.width, info.height, info.stride, pixels);
if (radius <= 3) {
fastBlur(info.width, info.height, info.stride, pixels, radius);
} else {
fastBlurMore(info.width, info.height, info.stride, pixels, radius);
}
AndroidBitmap_unlockPixels(env, bitmap);
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -9,7 +9,9 @@
package org.telegram.android;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Point;
......@@ -21,17 +23,23 @@ import android.view.Surface;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.messenger.TLRPC;
import org.telegram.messenger.UserConfig;
import org.telegram.ui.ApplicationLoader;
import org.telegram.ui.Views.NumberPicker;
import java.io.File;
import java.lang.reflect.Field;
import java.util.Hashtable;
import java.util.Locale;
public class AndroidUtilities {
private static final Hashtable<String, Typeface> typefaceCache = new Hashtable<String, Typeface>();
private static int prevOrientation = -10;
private static boolean waitingForSms = false;
......@@ -210,7 +218,7 @@ public class AndroidUtilities {
}
public static File getCacheDir() {
if (Environment.getExternalStorageState().startsWith(Environment.MEDIA_MOUNTED)) {
if (Environment.getExternalStorageState() == null || Environment.getExternalStorageState().startsWith(Environment.MEDIA_MOUNTED)) {
try {
File file = ApplicationLoader.applicationContext.getExternalCacheDir();
if (file != null) {
......@@ -239,6 +247,10 @@ public class AndroidUtilities {
return (int)Math.ceil(density * value);
}
public static float dpf2(float value) {
return density * value;
}
public static void checkDisplaySize() {
try {
WindowManager manager = (WindowManager)ApplicationLoader.applicationContext.getSystemService(Context.WINDOW_SERVICE);
......@@ -262,6 +274,22 @@ public class AndroidUtilities {
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) {
RunOnUIThread(runnable, 0);
}
......@@ -274,6 +302,10 @@ public class AndroidUtilities {
}
}
public static void CancelRunOnUIThread(Runnable runnable) {
ApplicationLoader.applicationHandler.removeCallbacks(runnable);
}
public static boolean isTablet() {
if (isTablet == null) {
isTablet = ApplicationLoader.applicationContext.getResources().getBoolean(R.bool.isTablet);
......@@ -367,4 +399,106 @@ public class AndroidUtilities {
}
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 {
ContentResolver cr = ApplicationLoader.applicationContext.getContentResolver();
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);
if (pCur != null) {
if (pCur.getCount() > 0) {
......@@ -262,9 +262,9 @@ public class ContactsController {
Integer id = pCur.getInt(0);
if (ids.length() != 0) {
ids += ",";
ids.append(",");
}
ids += id;
ids.append(id);
int type = pCur.getInt(2);
Contact contact = contactsMap.get(id);
......@@ -299,7 +299,7 @@ public class ContactsController {
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) {
while (pCur.moveToNext()) {
int id = pCur.getInt(0);
......@@ -844,14 +844,14 @@ public class ContactsController {
return 0;
}
});
String ids = "";
StringBuilder ids = new StringBuilder();
for (TLRPC.TL_contact aContactsArr : contactsArr) {
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);
}
......@@ -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 ArrayList<String> sortedSectionsArray = new ArrayList<String>();
......@@ -1114,11 +1114,11 @@ public class ContactsController {
}
arr.add(value);
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);
Collections.sort(sortedSectionsArray, new Comparator<String>() {
......@@ -1189,8 +1189,8 @@ public class ContactsController {
}
FileLog.e("tmessages", "process update - contacts add = " + newC.size() + " delete = " + contactsTD.size());
String toAdd = "";
String toDelete = "";
StringBuilder toAdd = new StringBuilder();
StringBuilder toDelete = new StringBuilder();
boolean reloadContacts = false;
for (TLRPC.TL_contact newContact : newC) {
......@@ -1216,9 +1216,9 @@ public class ContactsController {
}
}
if (toAdd.length() != 0) {
toAdd += ",";
toAdd.append(",");
}
toAdd += user.phone;
toAdd.append(user.phone);
}
for (final Integer uid : contactsTD) {
......@@ -1252,14 +1252,14 @@ public class ContactsController {
}
}
if (toDelete.length() != 0) {
toDelete += ",";
toDelete.append(",");
}
toDelete += user.phone;
toDelete.append(user.phone);
}
}
if (toAdd.length() != 0 || toDelete.length() != 0) {
MessagesStorage.getInstance().applyPhoneBookUpdates(toAdd, toDelete);
MessagesStorage.getInstance().applyPhoneBookUpdates(toAdd.toString(), toDelete.toString());
}
if (reloadContacts) {
......
......@@ -28,7 +28,6 @@ import android.provider.MediaStore;
import org.telegram.messenger.DispatchQueue;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.messenger.TLRPC;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities;
......@@ -293,7 +292,7 @@ public class ImageLoader {
}
}
if (image != null && blur && bitmapH < 100 && bitmapW < 100) {
Utilities.blurBitmap(image);
Utilities.blurBitmap(image, 3);
}
}
if (runtimeHack != null) {
......@@ -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) {
if ((fileLocation == null && httpUrl == null) || imageView == null || (fileLocation != null && !(fileLocation instanceof TLRPC.TL_fileLocation) && !(fileLocation instanceof TLRPC.TL_fileEncryptedLocation))) {
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;
public class NativeLoader {
private static final long sizes[] = new long[] {
946908, //armeabi
1028848, //armeabi-v7a
1603780, //x86
955148, //armeabi
1041184, //armeabi-v7a
1616116, //x86
0, //mips
};
......
......@@ -41,6 +41,7 @@ public class NotificationCenter {
public static final int openedChatChanged = 29;
public static final int hideEmojiKeyboard = 30;
public static final int stopEncodingService = 31;
public static final int didCreatedNewDeleteTask = 32;
public static final int wallpapersDidLoaded = 171;
public static final int closeOtherAppActivities = 702;
......@@ -67,6 +68,7 @@ public class NotificationCenter {
public final static int screenshotTook = 50007;
public final static int albumsDidLoaded = 50008;
public final static int audioDidSent = 50009;
public final static int audioDidStarted = 50010;
final private HashMap<Integer, ArrayList<Object>> observers = new HashMap<Integer, ArrayList<Object>>();
......
......@@ -21,7 +21,7 @@ public class PhotoObject {
public TLRPC.PhotoSize photoOwner;
public Bitmap image;
public PhotoObject(TLRPC.PhotoSize photo, int preview) {
public PhotoObject(TLRPC.PhotoSize photo, int preview, boolean secret) {
photoOwner = photo;
if (preview != 0 && photo instanceof TLRPC.TL_photoCachedSize) {
......@@ -34,7 +34,13 @@ public class PhotoObject {
image = BitmapFactory.decodeByteArray(photoOwner.bytes, 0, photoOwner.bytes.length, opts);
if (image != null) {
if (preview == 2) {
Utilities.blurBitmap(image);
if (secret) {
Utilities.blurBitmap(image, 7);
Utilities.blurBitmap(image, 7);
Utilities.blurBitmap(image, 7);
} else {
Utilities.blurBitmap(image, 3);
}
}
if (ImageLoader.getInstance().runtimeHack != null) {
ImageLoader.getInstance().runtimeHack.trackFree(image.getRowBytes() * image.getHeight());
......
......@@ -45,7 +45,7 @@ public class VideoEncodingService extends Service implements NotificationCenter.
public void didReceivedNotification(int id, Object... args) {
if (id == NotificationCenter.FileUploadProgressChanged) {
String fileName = (String)args[0];
if (path.equals(fileName)) {
if (path != null && path.equals(fileName)) {
Float progress = (Float) args[1];
Boolean enc = (Boolean) args[2];
currentProgress = (int)(progress * 100);
......
......@@ -54,12 +54,13 @@ public class MP4Builder {
private InterleaveChunkMdat mdat = null;
private Mp4Movie currentMp4Movie = null;
FileOutputStream fos = null;
private FileOutputStream fos = null;
private FileChannel fc = null;
private long dataOffset = 0;
private long writedSinceLastMdat = 0;
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 {
currentMp4Movie = mp4Movie;
......@@ -74,6 +75,8 @@ public class MP4Builder {
mdat = new InterleaveChunkMdat();
sizeBuffer = ByteBuffer.allocateDirect(4);
return this;
}
......@@ -87,7 +90,7 @@ public class MP4Builder {
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) {
mdat.setContentSize(0);
mdat.getBox(fc);
......@@ -109,9 +112,16 @@ public class MP4Builder {
}
currentMp4Movie.addSample(trackIndex, dataOffset, bufferInfo);
byteBuf.position(bufferInfo.offset);
byteBuf.position(bufferInfo.offset + (isAudio ? 0 : 4));
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);
dataOffset += bufferInfo.size;
......
......@@ -833,7 +833,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
}
object = invoke;
}
TLRPC.invokeWithLayer17 invoke = new TLRPC.invokeWithLayer17();
TLRPC.invokeWithLayer18 invoke = new TLRPC.invokeWithLayer18();
invoke.query = object;
FileLog.d("wrap in layer", "" + object);
return invoke;
......@@ -997,6 +997,10 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
return (int)(System.currentTimeMillis() / 1000) + timeDifference;
}
public int getTimeDifference() {
return timeDifference;
}
private void processRequestQueue(int requestClass, int _datacenterId) {
boolean haveNetwork = true;//isNetworkOnline();
......@@ -1382,7 +1386,9 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
if (rawRequest != null && (rawRequest instanceof TLRPC.TL_messages_sendMessage ||
rawRequest instanceof TLRPC.TL_messages_sendMedia ||
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) {
hasSendMessage = true;
......@@ -1400,7 +1406,9 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
if (currentRawRequest instanceof TLRPC.TL_messages_sendMessage ||
currentRawRequest instanceof TLRPC.TL_messages_sendMedia ||
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);
}
}
......@@ -1410,7 +1418,9 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
if (request.rawRequest instanceof TLRPC.TL_messages_sendMessage ||
request.rawRequest instanceof TLRPC.TL_messages_sendMedia ||
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)) {
maxRequestId = Math.max(maxRequestId, request.runningMessageId);
}
......@@ -1604,12 +1614,12 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
TLRPC.TL_protoMessage message = networkMessage.protoMessage;
if (BuildVars.DEBUG_VERSION) {
if (message.body instanceof TLRPC.invokeWithLayer17) {
FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer17)message.body).query);
if (message.body instanceof TLRPC.invokeWithLayer18) {
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) {
TLRPC.initConnection r = (TLRPC.initConnection)message.body;
if (r.query instanceof TLRPC.invokeWithLayer17) {
FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer17)r.query).query);
if (r.query instanceof TLRPC.invokeWithLayer18) {
FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer18)r.query).query);
} else {
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.
TLRPC.TL_protoMessage message = networkMessage.protoMessage;
containerMessages.add(message);
if (BuildVars.DEBUG_VERSION) {
if (message.body instanceof TLRPC.invokeWithLayer17) {
FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer17)message.body).query);
if (message.body instanceof TLRPC.invokeWithLayer18) {
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) {
TLRPC.initConnection r = (TLRPC.initConnection)message.body;
if (r.query instanceof TLRPC.invokeWithLayer17) {
FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer17)r.query).query);
if (r.query instanceof TLRPC.invokeWithLayer18) {
FileLog.d("tmessages", connection.getSissionId() + ":DC" + datacenter.datacenterId + "> Send message (" + message.seqno + ", " + message.msg_id + "): " + ((TLRPC.invokeWithLayer18)r.query).query);
} else {
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.
int errorCode = ((TLRPC.RpcError) resultContainer.result).error_code;
if (errorCode == 500 || errorCode < 0) {
if ((request.flags & RPCRequest.RPCRequestClassFailOnServerErrors) != 0) {
if (request.serverFailureCount < 1) {
discardResponse = true;
request.runningMinStartTime = request.runningStartTime + 1;
}
} else {
if ((request.flags & RPCRequest.RPCRequestClassFailOnServerErrors) == 0) {
discardResponse = true;
int delay = Math.min(1, request.serverFailureCount * 2);
request.runningMinStartTime = request.runningStartTime + delay;
......@@ -2433,6 +2438,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
}
});
} else if ((connection.transportRequestClass & RPCRequest.RPCRequestClassPush) != 0) {
FileLog.e("tmessages", "call connection closed");
sendingPushPing = false;
lastPushPingTime = System.currentTimeMillis() - 60000 * 3 + 4000;
}
......
......@@ -63,7 +63,7 @@ public class DispatchQueue extends Thread {
postRunnable(runnable, 0);
}
public void postRunnable(Runnable runnable, int delay) {
public void postRunnable(Runnable runnable, long delay) {
if (handler == null) {
synchronized (handlerSyncObject) {
if (handler == null) {
......
......@@ -176,7 +176,7 @@ public class FileLoader {
}
if (small) {
currentUploadSmallOperationsCount--;
if (currentUploadSmallOperationsCount < 2) {
if (currentUploadSmallOperationsCount < 1) {
FileUploadOperation operation = uploadSmallOperationQueue.poll();
if (operation != null) {
currentUploadSmallOperationsCount++;
......@@ -185,7 +185,7 @@ public class FileLoader {
}
} else {
currentUploadOperationsCount--;
if (currentUploadOperationsCount < 2) {
if (currentUploadOperationsCount < 1) {
FileUploadOperation operation = uploadOperationQueue.poll();
if (operation != null) {
currentUploadOperationsCount++;
......@@ -227,7 +227,7 @@ public class FileLoader {
});
if (small) {
currentUploadSmallOperationsCount--;
if (currentUploadSmallOperationsCount < 2) {
if (currentUploadSmallOperationsCount < 1) {
FileUploadOperation operation = uploadSmallOperationQueue.poll();
if (operation != null) {
currentUploadSmallOperationsCount++;
......@@ -236,7 +236,7 @@ public class FileLoader {
}
} else {
currentUploadOperationsCount--;
if (currentUploadOperationsCount < 2) {
if (currentUploadOperationsCount < 1) {
FileUploadOperation operation = uploadOperationQueue.poll();
if (operation != null) {
currentUploadOperationsCount++;
......@@ -259,14 +259,14 @@ public class FileLoader {
}
};
if (small) {
if (currentUploadSmallOperationsCount < 2) {
if (currentUploadSmallOperationsCount < 1) {
currentUploadSmallOperationsCount++;
operation.start();
} else {
uploadSmallOperationQueue.add(operation);
}
} else {
if (currentUploadOperationsCount < 2) {
if (currentUploadOperationsCount < 1) {
currentUploadOperationsCount++;
operation.start();
} else {
......@@ -564,18 +564,30 @@ public class FileLoader {
if (message == null) {
return new File("");
}
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);
if (message instanceof TLRPC.TL_messageService) {
if (message.action.photo != null) {
ArrayList<TLRPC.PhotoSize> sizes = message.action.photo.sizes;
if (sizes.size() > 0) {
TLRPC.PhotoSize sizeFull = getClosestPhotoSizeWithSize(sizes, AndroidUtilities.getPhotoSize());
if (sizeFull != null) {
return getPathToAttach(sizeFull);
}
}
}
} else {
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 {
}
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 {
classStore.put(TLRPC.TL_updateReadMessages.constructor, TLRPC.TL_updateReadMessages.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_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);
......@@ -226,6 +227,7 @@ public class TLClassStore {
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);
......@@ -362,6 +364,13 @@ public class TLClassStore {
classStore.put(TLRPC.TL_messageService_old.constructor, TLRPC.TL_messageService_old.class);
classStore.put(TLRPC.TL_decryptedMessageService_old.constructor, TLRPC.TL_decryptedMessageService_old.class);
classStore.put(TLRPC.TL_decryptedMessage_old.constructor, TLRPC.TL_decryptedMessage_old.class);
classStore.put(TLRPC.TL_message_secret.constructor, TLRPC.TL_message_secret.class);
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;
......
......@@ -9,7 +9,6 @@
package org.telegram.messenger;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
......@@ -28,7 +27,6 @@ import net.hockeyapp.android.CrashManager;
import net.hockeyapp.android.CrashManagerListener;
import net.hockeyapp.android.UpdateManager;
import org.telegram.android.LocaleController;
import org.telegram.ui.ApplicationLoader;
import java.io.ByteArrayInputStream;
......@@ -74,8 +72,6 @@ public class Utilities {
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static ProgressDialog progressDialog;
static {
try {
File URANDOM_FILE = new File("/dev/urandom");
......@@ -112,7 +108,7 @@ public class Utilities {
public native static long doPQNative(long _what);
public native static void loadBitmap(String path, int[] bitmap, int scale, int format, int width, int height);
public native static void blurBitmap(Object bitmap);
public native static void blurBitmap(Object bitmap, int radius);
public native static int convertVideoFrame(ByteBuffer src, ByteBuffer dest, int destFormat, int width, int height, int padding, int swap);
private native static void aesIgeEncryption(ByteBuffer buffer, byte[] key, byte[] iv, boolean encrypt, int offset, int length);
......@@ -427,34 +423,6 @@ public class Utilities {
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 {
OutputStream out = new FileOutputStream(destFile);
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;
import android.widget.BaseAdapter;
public class BaseFragmentAdapter extends BaseAdapter {
public void onFragmentCreate() {
}
......
......@@ -21,6 +21,7 @@ import org.telegram.android.MessagesController;
import org.telegram.messenger.R;
import org.telegram.ui.Cells.ChatOrUserCell;
import org.telegram.ui.Views.SectionedBaseAdapter;
import org.telegram.ui.Views.SettingsSectionLayout;
import java.util.ArrayList;
import java.util.HashMap;
......@@ -202,12 +203,10 @@ public class ContactsActivityAdapter extends SectionedBaseAdapter {
if (usersAsSections) {
if (section < ContactsController.getInstance().sortedUsersSectionsArray.size()) {
if (convertView == null) {
LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = li.inflate(R.layout.settings_section_layout, parent, false);
convertView = new SettingsSectionLayout(mContext);
convertView.setBackgroundColor(0xffffffff);
}
TextView textView = (TextView)convertView.findViewById(R.id.settings_section_text);
textView.setText(ContactsController.getInstance().sortedUsersSectionsArray.get(section));
((SettingsSectionLayout) convertView).setText(ContactsController.getInstance().sortedUsersSectionsArray.get(section));
return convertView;
}
} else {
......@@ -221,12 +220,10 @@ public class ContactsActivityAdapter extends SectionedBaseAdapter {
}
if (convertView == null) {
LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = li.inflate(R.layout.settings_section_layout, parent, false);
convertView = new SettingsSectionLayout(mContext);
convertView.setBackgroundColor(0xffffffff);
}
TextView textView = (TextView)convertView.findViewById(R.id.settings_section_text);
textView.setText(ContactsController.getInstance().sortedContactsSectionsArray.get(section - 1));
((SettingsSectionLayout) convertView).setText(ContactsController.getInstance().sortedContactsSectionsArray.get(section - 1));
return convertView;
}
}
......@@ -9,10 +9,13 @@
package org.telegram.ui.Adapters;
import android.content.Context;
import android.text.Html;
import android.view.View;
import android.view.ViewGroup;
import org.telegram.android.AndroidUtilities;
import org.telegram.android.LocaleController;
import org.telegram.messenger.R;
import org.telegram.messenger.TLRPC;
import org.telegram.android.ContactsController;
import org.telegram.messenger.FileLog;
......@@ -20,28 +23,34 @@ import org.telegram.android.MessagesController;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities;
import org.telegram.ui.Cells.ChatOrUserCell;
import org.telegram.ui.Views.SettingsSectionLayout;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Timer;
import java.util.TimerTask;
public class ContactsActivitySearchAdapter extends BaseFragmentAdapter {
public class ContactsActivitySearchAdapter extends BaseContactsSearchAdapter {
private Context mContext;
private HashMap<Integer, TLRPC.User> ignoreUsers;
private ArrayList<TLRPC.User> searchResult;
private ArrayList<CharSequence> searchResultNames;
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;
ignoreUsers = arg1;
allowUsernameSearch = usernameSearch;
}
public void searchDialogs(final String query) {
if (query == null) {
searchResult = null;
searchResultNames = null;
searchResult.clear();
searchResultNames.clear();
if (allowUsernameSearch) {
queryServerSearch(null);
}
notifyDataSetChanged();
} else {
try {
......@@ -63,7 +72,7 @@ public class ContactsActivitySearchAdapter extends BaseFragmentAdapter {
}
processSearch(query);
}
}, 100, 300);
}, 200, 300);
}
}
......@@ -71,6 +80,9 @@ public class ContactsActivitySearchAdapter extends BaseFragmentAdapter {
AndroidUtilities.RunOnUIThread(new Runnable() {
@Override
public void run() {
if (allowUsernameSearch) {
queryServerSearch(query);
}
final ArrayList<TLRPC.TL_contact> contactsCopy = new ArrayList<TLRPC.TL_contact>();
contactsCopy.addAll(ContactsController.getInstance().contacts);
Utilities.searchQueue.postRunnable(new Runnable() {
......@@ -87,12 +99,25 @@ public class ContactsActivitySearchAdapter extends BaseFragmentAdapter {
for (TLRPC.TL_contact contact : contactsCopy) {
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();
int found = 0;
if (name.startsWith(q) || name.contains(" " + q)) {
if (user.id == UserConfig.getClientUserId()) {
continue;
found = 1;
} 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);
}
}
......@@ -117,28 +142,43 @@ public class ContactsActivitySearchAdapter extends BaseFragmentAdapter {
@Override
public boolean areAllItemsEnabled() {
return true;
return false;
}
@Override
public boolean isEnabled(int i) {
return true;
return i != searchResult.size();
}
@Override
public int getCount() {
if (searchResult == null) {
return 0;
int count = searchResult.size();
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
public TLRPC.User getItem(int i) {
if (searchResult != null) {
if (i >= 0 && i < searchResult.size()) {
return searchResult.get(i);
}
int localCount = searchResult.size();
int globalCount = globalSearch.size();
if (i >= 0 && i < localCount) {
return searchResult.get(i);
} else if (i > localCount && i <= globalCount + localCount) {
return globalSearch.get(i - localCount - 1);
}
return null;
}
......@@ -155,24 +195,47 @@ public class ContactsActivitySearchAdapter extends BaseFragmentAdapter {
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
if (view == null) {
view = new ChatOrUserCell(mContext);
((ChatOrUserCell)view).usePadding = false;
}
((ChatOrUserCell) view).useSeparator = i != searchResult.size() - 1;
if (i == searchResult.size()) {
if (view == null) {
view = new SettingsSectionLayout(mContext);
((SettingsSectionLayout) view).setText(LocaleController.getString("GlobalSearch", R.string.GlobalSearch));
}
} else {
if (view == null) {
view = new ChatOrUserCell(mContext);
((ChatOrUserCell) view).usePadding = false;
}
Object obj = searchResult.get(i);
TLRPC.User user = MessagesController.getInstance().getUser(((TLRPC.User)obj).id);
((ChatOrUserCell) view).useSeparator = (i != getCount() - 1 && i != searchResult.size() - 1);
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, searchResultNames.get(i), null);
((ChatOrUserCell) view).setData(user, null, null, name, username);
if (ignoreUsers != null) {
if (ignoreUsers.containsKey(user.id)) {
((ChatOrUserCell)view).drawAlpha = 0.5f;
} else {
((ChatOrUserCell)view).drawAlpha = 1.0f;
if (ignoreUsers != null) {
if (ignoreUsers.containsKey(user.id)) {
((ChatOrUserCell) view).drawAlpha = 0.5f;
} else {
((ChatOrUserCell) view).drawAlpha = 1.0f;
}
}
}
}
......@@ -181,16 +244,19 @@ public class ContactsActivitySearchAdapter extends BaseFragmentAdapter {
@Override
public int getItemViewType(int i) {
if (i == searchResult.size()) {
return 1;
}
return 0;
}
@Override
public int getViewTypeCount() {
return 1;
return 2;
}
@Override
public boolean isEmpty() {
return searchResult == null || searchResult.size() == 0;
return searchResult.isEmpty() && globalSearch.isEmpty();
}
}
......@@ -10,10 +10,43 @@ package org.telegram.ui.Cells;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
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) {
super(context);
}
......@@ -25,4 +58,29 @@ public class BaseCell extends View {
protected void setDrawableBounds(Drawable drawable, int x, int y, int w, int 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
private static TextPaint timePaint;
private ImageReceiver avatarImage;
private boolean needAvatarImage = false;
private SeekBar seekBar;
private ProgressView progressView;
private int seekBarX;
......@@ -44,9 +45,9 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
private int buttonState = 0;
private int buttonX;
private int buttonY;
private int buttonPressed = 0;
private boolean buttonPressed = false;
private int avatarPressed = 0;
private boolean avatarPressed = false;
private StaticLayout timeLayout;
private int timeX;
......@@ -56,7 +57,6 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
public TLRPC.User audioUser;
private TLRPC.FileLocation currentPhoto;
private String currentNameString;
public ChatAudioCell(Context context) {
super(context);
......@@ -115,40 +115,40 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
int side = AndroidUtilities.dp(36);
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (x >= buttonX && x <= buttonX + side && y >= buttonY && y <= buttonY + side) {
buttonPressed = 1;
buttonPressed = true;
invalidate();
result = true;
} else if (avatarImage.isInsideImage(x, y)) {
avatarPressed = 1;
} else if (needAvatarImage && avatarImage.isInsideImage(x, y)) {
avatarPressed = true;
result = true;
}
} else if (buttonPressed == 1) {
} else if (buttonPressed) {
if (event.getAction() == MotionEvent.ACTION_UP) {
buttonPressed = 0;
buttonPressed = false;
playSoundEffect(SoundEffectConstants.CLICK);
didPressedButton();
invalidate();
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
buttonPressed = 0;
buttonPressed = false;
invalidate();
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (!(x >= buttonX && x <= buttonX + side && y >= buttonY && y <= buttonY + side)) {
buttonPressed = 0;
buttonPressed = false;
invalidate();
}
}
} else if (avatarPressed == 1) {
} else if (avatarPressed) {
if (event.getAction() == MotionEvent.ACTION_UP) {
avatarPressed = 0;
avatarPressed = false;
playSoundEffect(SoundEffectConstants.CLICK);
if (delegate != null) {
delegate.didPressedUserAvatar(this, audioUser);
}
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
avatarPressed = 0;
avatarPressed = false;
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (!avatarImage.isInsideImage(x, y)) {
avatarPressed = 0;
avatarPressed = false;
}
}
}
......@@ -301,7 +301,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
int x;
if (currentMessageObject.isOut()) {
x = layoutWidth - backgroundWidth + AndroidUtilities.dp(9);
x = layoutWidth - backgroundWidth + AndroidUtilities.dp(8);
seekBarX = layoutWidth - backgroundWidth + AndroidUtilities.dp(97);
buttonX = layoutWidth - backgroundWidth + AndroidUtilities.dp(67);
timeX = layoutWidth - backgroundWidth + AndroidUtilities.dp(71);
......@@ -318,11 +318,19 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
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);
progressView.width = backgroundWidth - AndroidUtilities.dp(136);
progressView.width = backgroundWidth - AndroidUtilities.dp(136) + diff;
progressView.height = AndroidUtilities.dp(30);
seekBarY = AndroidUtilities.dp(13);
buttonY = AndroidUtilities.dp(10);
......@@ -349,14 +357,18 @@ 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 (audioUser != null) {
if (audioUser.photo != null) {
currentPhoto = audioUser.photo.photo_small;
if (needAvatarImage) {
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()) {
......@@ -380,7 +392,9 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
return;
}
avatarImage.draw(canvas, avatarImage.getImageX(), avatarImage.getImageY(), AndroidUtilities.dp(50), AndroidUtilities.dp(50));
if (needAvatarImage) {
avatarImage.draw(canvas);
}
canvas.save();
if (buttonState == 0 || buttonState == 1) {
......@@ -399,7 +413,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
} else {
timePaint.setColor(0xff70b15c);
}
Drawable buttonDrawable = statesDrawable[state][buttonPressed];
Drawable buttonDrawable = statesDrawable[state][buttonPressed ? 1 : 0];
int side = AndroidUtilities.dp(36);
int x = (side - buttonDrawable.getIntrinsicWidth()) / 2;
int y = (side - buttonDrawable.getIntrinsicHeight()) / 2;
......
......@@ -41,7 +41,7 @@ public class ChatOrUserCell extends BaseCell {
private CharSequence currentName;
private ImageReceiver avatarImage;
private String subLabel;
private CharSequence subLabel;
private ChatOrUserCellLayout cellLayout;
private TLRPC.User user = null;
......@@ -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;
user = u;
chat = c;
......@@ -236,6 +236,15 @@ public class ChatOrUserCell extends BaseCell {
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) {
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 {
canvas.restore();
}
avatarImage.draw(canvas, cellLayout.avatarLeft, cellLayout.avatarTop, AndroidUtilities.dp(50), AndroidUtilities.dp(50));
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);
}
}
avatarImage.draw(canvas);
}
private class ChatOrUserCellLayout {
......@@ -381,7 +381,7 @@ public class ChatOrUserCell extends BaseCell {
onlineLeft = usePadding ? AndroidUtilities.dp(11) : 0;
}
String onlineString = "";
CharSequence onlineString = "";
TextPaint currentOnlinePaint = offlinePaint;
if (subLabel != null) {
......
......@@ -91,6 +91,6 @@ public class BackupImageView extends View {
@Override
protected void onDraw(Canvas canvas) {
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