update to 2.9.1

This commit is contained in:
DrKLO 2015-05-22 00:27:27 +03:00
parent 2b8304ebf4
commit 2b81b7f01e
180 changed files with 13675 additions and 8826 deletions

View File

@ -3,7 +3,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.1.3'
classpath 'com.android.tools.build:gradle:1.2.3'
}
}
apply plugin: 'com.android.application'
@ -81,7 +81,7 @@ android {
defaultConfig {
minSdkVersion 8
targetSdkVersion 22
versionCode 521
versionName "2.8.1"
versionCode 541
versionName "2.9.1"
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -123,6 +123,18 @@
android:windowSoftInputMode="adjustResize|stateHidden">
</activity>
<receiver android:name="org.telegram.android.AutoMessageHeardReceiver">
<intent-filter>
<action android:name="org.telegram.messenger.ACTION_MESSAGE_HEARD"/>
</intent-filter>
</receiver>
<receiver android:name="org.telegram.android.AutoMessageReplyReceiver">
<intent-filter>
<action android:name="org.telegram.messenger.ACTION_MESSAGE_REPLY"/>
</intent-filter>
</receiver>
<receiver android:name="org.telegram.android.SmsListener">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
@ -168,6 +180,8 @@
<meta-data android:name="com.sec.android.multiwindow.MINIMUM_SIZE_W" android:value="632dp" />
<meta-data android:name="com.sec.android.multiwindow.MINIMUM_SIZE_H" android:value="598dp" />
<meta-data android:name="com.google.android.gms.car.application" android:resource="@xml/automotive_app_desc" />
</application>
</manifest>

View File

@ -27,11 +27,11 @@ package org.telegram.PhoneFormat;
import java.util.ArrayList;
public class CallingCodeInfo {
public ArrayList<String> countries = new ArrayList<String>();
public ArrayList<String> countries = new ArrayList<>();
public String callingCode = "";
public ArrayList<String> trunkPrefixes = new ArrayList<String>();
public ArrayList<String> intlPrefixes = new ArrayList<String>();
public ArrayList<RuleSet> ruleSets = new ArrayList<RuleSet>();
public ArrayList<String> trunkPrefixes = new ArrayList<>();
public ArrayList<String> intlPrefixes = new ArrayList<>();
public ArrayList<RuleSet> ruleSets = new ArrayList<>();
//public ArrayList formatStrings;
String matchingAccessCode(String str) {
@ -107,14 +107,14 @@ public class CallingCodeInfo {
for (RuleSet set : ruleSets) {
boolean valid = set.isValid(str, intlPrefix, trunkPrefix, true);
if (valid) {
return valid;
return true;
}
}
for (RuleSet set : ruleSets) {
boolean valid = set.isValid(str, intlPrefix, trunkPrefix, false);
if (valid) {
return valid;
return true;
}
}

View File

@ -8,19 +8,26 @@
package org.telegram.android;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
@ -39,6 +46,11 @@ import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import net.hockeyapp.android.CrashManager;
import net.hockeyapp.android.CrashManagerListener;
import net.hockeyapp.android.UpdateManager;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
@ -53,11 +65,20 @@ import org.telegram.ui.Components.ForegroundDetector;
import org.telegram.ui.Components.NumberPicker;
import org.telegram.ui.Components.TypefaceSpan;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;
import java.util.Locale;
public class AndroidUtilities {
@ -159,7 +180,7 @@ public class AndroidUtilities {
}
public static boolean isWaitingForSms() {
boolean value = false;
boolean value;
synchronized (smsLock) {
value = waitingForSms;
}
@ -575,11 +596,12 @@ public class AndroidUtilities {
}
}
@SuppressLint("NewApi")
public static void clearDrawableAnimation(View view) {
if (Build.VERSION.SDK_INT < 21 || view == null) {
return;
}
Drawable drawable = null;
Drawable drawable;
if (view instanceof ListView) {
drawable = ((ListView) view).getSelector();
if (drawable != null) {
@ -596,9 +618,9 @@ public class AndroidUtilities {
public static Spannable replaceTags(String str) {
try {
int start = -1;
int start;
int startColor = -1;
int end = -1;
int end;
StringBuilder stringBuilder = new StringBuilder(str);
while ((start = stringBuilder.indexOf("<br>")) != -1) {
stringBuilder.replace(start, start + 4, "\n");
@ -608,7 +630,7 @@ public class AndroidUtilities {
}
ArrayList<Integer> bolds = new ArrayList<>();
ArrayList<Integer> colors = new ArrayList<>();
while ((start = stringBuilder.indexOf("<b>")) != -1 || (startColor = stringBuilder.indexOf("<c")) != -1) {
while ((start = stringBuilder.indexOf("<b>")) != -1 || (startColor = stringBuilder.indexOf("<c#")) != -1) {
if (start != -1) {
stringBuilder.replace(start, start + 3, "");
end = stringBuilder.indexOf("</b>");
@ -628,6 +650,7 @@ public class AndroidUtilities {
colors.add(startColor);
colors.add(end);
colors.add(color);
startColor = -1;
}
}
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(stringBuilder);
@ -726,4 +749,290 @@ public class AndroidUtilities {
window.clearFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
}
}*/
public static void checkForCrashes(Activity context) {
CrashManager.register(context, BuildVars.HOCKEY_APP_HASH, new CrashManagerListener() {
@Override
public boolean includeDeviceData() {
return true;
}
});
}
public static void checkForUpdates(Activity context) {
if (BuildVars.DEBUG_VERSION) {
UpdateManager.register(context, BuildVars.HOCKEY_APP_HASH);
}
}
public static void unregisterUpdates() {
if (BuildVars.DEBUG_VERSION) {
UpdateManager.unregister();
}
}
public static void addMediaToGallery(String fromPath) {
if (fromPath == null) {
return;
}
File f = new File(fromPath);
Uri contentUri = Uri.fromFile(f);
addMediaToGallery(contentUri);
}
public static void addMediaToGallery(Uri uri) {
if (uri == null) {
return;
}
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mediaScanIntent.setData(uri);
ApplicationLoader.applicationContext.sendBroadcast(mediaScanIntent);
}
private static File getAlbumDir() {
File storageDir = null;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
storageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "Telegram");
if (!storageDir.mkdirs()) {
if (!storageDir.exists()){
FileLog.d("tmessages", "failed to create directory");
return null;
}
}
} else {
FileLog.d("tmessages", "External storage is not mounted READ/WRITE.");
}
return storageDir;
}
@SuppressLint("NewApi")
public static String getPath(final Uri uri) {
try {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
if (isKitKat && DocumentsContract.isDocumentUri(ApplicationLoader.applicationContext, uri)) {
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
} else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(ApplicationLoader.applicationContext, contentUri, null, null);
} else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
switch (type) {
case "image":
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
break;
case "video":
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
break;
case "audio":
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
break;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[] {
split[1]
};
return getDataColumn(ApplicationLoader.applicationContext, contentUri, selection, selectionArgs);
}
} else if ("content".equalsIgnoreCase(uri.getScheme())) {
return getDataColumn(ApplicationLoader.applicationContext, uri, null, null);
} else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
return null;
}
public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {
column
};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
} finally {
if (cursor != null) {
cursor.close();
}
}
return null;
}
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
public static File generatePicturePath() {
try {
File storageDir = getAlbumDir();
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
return new File(storageDir, "IMG_" + timeStamp + ".jpg");
} catch (Exception e) {
FileLog.e("tmessages", e);
}
return null;
}
public static CharSequence generateSearchName(String name, String name2, String q) {
if (name == null && name2 == null) {
return "";
}
SpannableStringBuilder builder = new SpannableStringBuilder();
String wholeString = name;
if (wholeString == null || wholeString.length() == 0) {
wholeString = name2;
} else if (name2 != null && name2.length() != 0) {
wholeString += " " + name2;
}
wholeString = wholeString.trim();
String lower = " " + wholeString.toLowerCase();
int index;
int lastIndex = 0;
while ((index = lower.indexOf(" " + q, lastIndex)) != -1) {
int idx = index - (index == 0 ? 0 : 1);
int end = q.length() + (index == 0 ? 0 : 1) + idx;
if (lastIndex != 0 && lastIndex != idx + 1) {
builder.append(wholeString.substring(lastIndex, idx));
} else if (lastIndex == 0 && idx != 0) {
builder.append(wholeString.substring(0, idx));
}
String query = wholeString.substring(idx, end);
if (query.startsWith(" ")) {
builder.append(" ");
}
query = query.trim();
builder.append(AndroidUtilities.replaceTags("<c#ff4d83b3>" + query + "</c>"));
lastIndex = end;
}
if (lastIndex != -1 && lastIndex != wholeString.length()) {
builder.append(wholeString.substring(lastIndex, wholeString.length()));
}
return builder;
}
public static File generateVideoPath() {
try {
File storageDir = getAlbumDir();
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
return new File(storageDir, "VID_" + timeStamp + ".mp4");
} catch (Exception e) {
FileLog.e("tmessages", e);
}
return null;
}
public static String formatFileSize(long size) {
if (size < 1024) {
return String.format("%d B", size);
} else if (size < 1024 * 1024) {
return String.format("%.1f KB", size / 1024.0f);
} else if (size < 1024 * 1024 * 1024) {
return String.format("%.1f MB", size / 1024.0f / 1024.0f);
} else {
return String.format("%.1f GB", size / 1024.0f / 1024.0f / 1024.0f);
}
}
public static byte[] decodeQuotedPrintable(final byte[] bytes) {
if (bytes == null) {
return null;
}
final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
for (int i = 0; i < bytes.length; i++) {
final int b = bytes[i];
if (b == '=') {
try {
final int u = Character.digit((char) bytes[++i], 16);
final int l = Character.digit((char) bytes[++i], 16);
buffer.write((char) ((u << 4) + l));
} catch (Exception e) {
FileLog.e("tmessages", e);
return null;
}
} else {
buffer.write(b);
}
}
byte[] array = buffer.toByteArray();
try {
buffer.close();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
return array;
}
public static boolean copyFile(InputStream sourceFile, File destFile) throws IOException {
OutputStream out = new FileOutputStream(destFile);
byte[] buf = new byte[4096];
int len;
while ((len = sourceFile.read(buf)) > 0) {
Thread.yield();
out.write(buf, 0, len);
}
out.close();
return true;
}
public static boolean copyFile(File sourceFile, File destFile) throws IOException {
if (!destFile.exists()) {
destFile.createNewFile();
}
FileInputStream source = null;
FileOutputStream destination = null;
try {
source = new FileInputStream(sourceFile);
destination = new FileOutputStream(destFile);
destination.getChannel().transferFrom(source.getChannel(), 0, source.getChannel().size());
} catch (Exception e) {
FileLog.e("tmessages", e);
return false;
} finally {
if (source != null) {
source.close();
}
if (destination != null) {
destination.close();
}
}
return true;
}
}

View File

@ -0,0 +1,26 @@
/*
* This is the source code of Telegram for Android v. 2.x.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-2015.
*/
package org.telegram.android;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class AutoMessageHeardReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
long dialog_id = intent.getLongExtra("dialog_id", 0);
int max_id = intent.getIntExtra("max_id", 0);
if (dialog_id == 0 || max_id == 0) {
return;
}
MessagesController.getInstance().markDialogAsRead(dialog_id, max_id, max_id, 0, 0, true, false);
}
}

View File

@ -0,0 +1,37 @@
/*
* This is the source code of Telegram for Android v. 2.x.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.android;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.RemoteInput;
public class AutoMessageReplyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
if (remoteInput == null) {
return;
}
CharSequence text = remoteInput.getCharSequence(NotificationsController.EXTRA_VOICE_REPLY);
if (text == null || text.length() == 0) {
return;
}
long dialog_id = intent.getLongExtra("dialog_id", 0);
int max_id = intent.getIntExtra("max_id", 0);
if (dialog_id == 0 || max_id == 0) {
return;
}
SendMessagesHelper.getInstance().sendMessage(text.toString(), dialog_id, null, null, true);
MessagesController.getInstance().markDialogAsRead(dialog_id, max_id, max_id, 0, 0, true, false);
}
}

View File

@ -221,7 +221,7 @@ public class Emoji {
private static void loadEmoji(final int page) {
try {
float scale = 1.0f;
float scale;
int imageResize = 1;
if (AndroidUtilities.density <= 1.0f) {
scale = 2.0f;
@ -257,7 +257,7 @@ public class Emoji {
imageFile = ApplicationLoader.applicationContext.getFileStreamPath(imageName);
if (!imageFile.exists()) {
InputStream is = ApplicationLoader.applicationContext.getAssets().open("emoji/" + imageName);
Utilities.copyFile(is, imageFile);
AndroidUtilities.copyFile(is, imageFile);
is.close();
}
@ -276,7 +276,7 @@ public class Emoji {
imageFile = ApplicationLoader.applicationContext.getFileStreamPath(imageName);
if (!imageFile.exists()) {
InputStream is = ApplicationLoader.applicationContext.getAssets().open("emoji/" + imageName);
Utilities.copyFile(is, imageFile);
AndroidUtilities.copyFile(is, imageFile);
is.close();
}

View File

@ -67,11 +67,12 @@ public class ImageLoader {
private DispatchQueue cacheThumbOutQueue = new DispatchQueue("cacheThumbOutQueue");
private DispatchQueue thumbGeneratingQueue = new DispatchQueue("thumbGeneratingQueue");
private DispatchQueue imageLoadQueue = new DispatchQueue("imageLoadQueue");
private DispatchQueue recycleQueue = new DispatchQueue("recycleQueue");
private ConcurrentHashMap<String, Float> fileProgresses = new ConcurrentHashMap<>();
private HashMap<String, ThumbGenerateTask> thumbGenerateTasks = new HashMap<>();
private static byte[] bytes;
private static byte[] bytesThumb;
private static byte[] header = new byte[12];
private static byte[] headerThumb = new byte[12];
private int currentHttpTasksCount = 0;
private LinkedList<HttpFileTask> httpFileLoadTasks = new LinkedList<>();
@ -116,8 +117,24 @@ public class ImageLoader {
try {
URL downloadUrl = new URL(url);
httpConnection = downloadUrl.openConnection();
httpConnection.addRequestProperty("User-Agent", "Mozilla/5.0 (Linux; Android 4.4; Nexus 5 Build/_BuildID_) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36");
httpConnection.addRequestProperty("Referer", "google.com");
httpConnection.setConnectTimeout(5000);
httpConnection.setReadTimeout(5000);
if (httpConnection instanceof HttpURLConnection) {
HttpURLConnection httpURLConnection = (HttpURLConnection) httpConnection;
httpURLConnection.setInstanceFollowRedirects(true);
int status = httpURLConnection.getResponseCode();
if (status == HttpURLConnection.HTTP_MOVED_TEMP || status == HttpURLConnection.HTTP_MOVED_PERM || status == HttpURLConnection.HTTP_SEE_OTHER) {
String newUrl = httpURLConnection.getHeaderField("Location");
String cookies = httpURLConnection.getHeaderField("Set-Cookie");
downloadUrl = new URL(newUrl);
httpConnection = downloadUrl.openConnection();
httpConnection.setRequestProperty("Cookie", cookies);
httpConnection.addRequestProperty("User-Agent", "Mozilla/5.0 (Linux; Android 4.4; Nexus 5 Build/_BuildID_) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36");
httpConnection.addRequestProperty("Referer", "google.com");
}
}
httpConnection.connect();
httpConnectionStream = httpConnection.getInputStream();
@ -137,29 +154,31 @@ public class ImageLoader {
FileLog.e("tmessages", e);
}
try {
byte[] data = new byte[1024 * 4];
while (true) {
if (isCancelled()) {
break;
}
try {
int readed = httpConnectionStream.read(data);
if (readed > 0) {
fileOutputStream.write(data, 0, readed);
} else if (readed == -1) {
done = true;
break;
} else {
if (httpConnectionStream != null) {
try {
byte[] data = new byte[1024 * 4];
while (true) {
if (isCancelled()) {
break;
}
try {
int read = httpConnectionStream.read(data);
if (read > 0) {
fileOutputStream.write(data, 0, read);
} else if (read == -1) {
done = true;
break;
} else {
break;
}
} catch (Exception e) {
FileLog.e("tmessages", e);
break;
}
} catch (Exception e) {
FileLog.e("tmessages", e);
break;
}
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
try {
@ -175,7 +194,6 @@ public class ImageLoader {
if (httpConnectionStream != null) {
httpConnectionStream.close();
}
httpConnectionStream = null;
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
@ -235,12 +253,16 @@ public class ImageLoader {
try {
URL downloadUrl = new URL(cacheImage.httpUrl);
httpConnection = downloadUrl.openConnection();
httpConnection.addRequestProperty("User-Agent", "Mozilla/5.0 (Linux; Android 4.4; Nexus 5 Build/_BuildID_) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36");
httpConnection.addRequestProperty("Referer", "google.com");
httpConnection.setConnectTimeout(5000);
httpConnection.setReadTimeout(5000);
if (httpConnection instanceof HttpURLConnection) {
((HttpURLConnection) httpConnection).setInstanceFollowRedirects(true);
}
if (!isCancelled()) {
httpConnection.connect();
httpConnectionStream = httpConnection.getInputStream();
fileOutputStream = new RandomAccessFile(cacheImage.tempFilePath, "rws");
}
} catch (Throwable e) {
@ -260,37 +282,39 @@ public class ImageLoader {
FileLog.e("tmessages", e);
}
try {
byte[] data = new byte[1024 * 2];
int totalLoaded = 0;
while (true) {
if (isCancelled()) {
break;
}
try {
int readed = httpConnectionStream.read(data);
if (readed > 0) {
totalLoaded += readed;
fileOutputStream.write(data, 0, readed);
if (imageSize != 0) {
reportProgress(totalLoaded / (float) imageSize);
}
} else if (readed == -1) {
done = true;
if (imageSize != 0) {
reportProgress(1.0f);
}
break;
} else {
if (httpConnectionStream != null) {
try {
byte[] data = new byte[1024 * 2];
int totalLoaded = 0;
while (true) {
if (isCancelled()) {
break;
}
try {
int read = httpConnectionStream.read(data);
if (read > 0) {
totalLoaded += read;
fileOutputStream.write(data, 0, read);
if (imageSize != 0) {
reportProgress(totalLoaded / (float) imageSize);
}
} else if (read == -1) {
done = true;
if (imageSize != 0) {
reportProgress(1.0f);
}
break;
} else {
break;
}
} catch (Exception e) {
FileLog.e("tmessages", e);
break;
}
} catch (Exception e) {
FileLog.e("tmessages", e);
break;
}
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
}
@ -307,7 +331,6 @@ public class ImageLoader {
if (httpConnectionStream != null) {
httpConnectionStream.close();
}
httpConnectionStream = null;
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
@ -446,7 +469,6 @@ public class ImageLoader {
Bitmap scaledBitmap = Bitmap.createScaledBitmap(originalBitmap, (int) (w / scaleFactor), (int) (h / scaleFactor), true);
if (scaledBitmap != originalBitmap) {
originalBitmap.recycle();
callGC();
}
originalBitmap = scaledBitmap;
FileOutputStream stream = new FileOutputStream(thumbFile);
@ -513,14 +535,41 @@ public class ImageLoader {
Bitmap image = null;
File cacheFileFinal = cacheImage.finalFilePath;
boolean canDeleteFile = true;
boolean isWebp = false;
boolean useNativeWebpLoaded = false;
if (cacheFileFinal.toString().endsWith("webp")) {
isWebp = true;
if (Build.VERSION.SDK_INT < 18) {
RandomAccessFile randomAccessFile = null;
try {
randomAccessFile = new RandomAccessFile(cacheFileFinal, "r");
byte[] bytes;
if (cacheImage.thumb) {
bytes = headerThumb;
} else {
bytes = header;
}
randomAccessFile.readFully(bytes, 0, bytes.length);
String str = new String(bytes);
if (str != null) {
str = str.toLowerCase();
if (str.startsWith("riff") && str.endsWith("webp")) {
useNativeWebpLoaded = true;
}
}
randomAccessFile.close();
} catch (Exception e) {
FileLog.e("tmessages", e);
} finally {
if (randomAccessFile != null) {
try {
randomAccessFile.close();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
}
}
if (cacheImage.thumb) {
int blurType = 0;
if (cacheImage.filter != null) {
if (cacheImage.filter.contains("b2")) {
@ -543,11 +592,11 @@ public class ImageLoader {
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inSampleSize = 1;
if (!isWebp && Build.VERSION.SDK_INT > 10 && Build.VERSION.SDK_INT < 21) {
if (!useNativeWebpLoaded && Build.VERSION.SDK_INT > 10 && Build.VERSION.SDK_INT < 21) {
opts.inPurgeable = true;
}
if (isWebp) {
if (useNativeWebpLoaded) {
RandomAccessFile file = new RandomAccessFile(cacheFileFinal, "r");
ByteBuffer buffer = file.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, cacheFileFinal.length());
image = Utilities.loadWebpImage(buffer, buffer.limit(), null);
@ -570,20 +619,18 @@ public class ImageLoader {
}
if (image == null) {
if (canDeleteFile && (cacheFileFinal.length() == 0 || cacheImage.filter == null)) {
if (cacheFileFinal.length() == 0 || cacheImage.filter == null) {
cacheFileFinal.delete();
}
} else {
if (image != null) {
if (blurType == 1) {
Utilities.blurBitmap(image, 3, opts.inPurgeable ? 0 : 1);
} else if (blurType == 2) {
Utilities.blurBitmap(image, 1, opts.inPurgeable ? 0 : 1);
} else if (blurType == 3) {
Utilities.blurBitmap(image, 7, opts.inPurgeable ? 0 : 1);
Utilities.blurBitmap(image, 7, opts.inPurgeable ? 0 : 1);
Utilities.blurBitmap(image, 7, opts.inPurgeable ? 0 : 1);
}
if (blurType == 1) {
Utilities.blurBitmap(image, 3, opts.inPurgeable ? 0 : 1);
} else if (blurType == 2) {
Utilities.blurBitmap(image, 1, opts.inPurgeable ? 0 : 1);
} else if (blurType == 3) {
Utilities.blurBitmap(image, 7, opts.inPurgeable ? 0 : 1);
Utilities.blurBitmap(image, 7, opts.inPurgeable ? 0 : 1);
Utilities.blurBitmap(image, 7, opts.inPurgeable ? 0 : 1);
}
if (blurType == 0 && opts.inPurgeable) {
Utilities.pinBitmap(image);
@ -685,7 +732,7 @@ public class ImageLoader {
} else {
opts.inPreferredConfig = Bitmap.Config.RGB_565;
}
if (!isWebp && Build.VERSION.SDK_INT > 10 && Build.VERSION.SDK_INT < 21) {
if (!useNativeWebpLoaded && Build.VERSION.SDK_INT > 10 && Build.VERSION.SDK_INT < 21) {
opts.inPurgeable = true;
}
@ -698,7 +745,7 @@ public class ImageLoader {
}
}
if (image == null) {
if (isWebp) {
if (useNativeWebpLoaded) {
RandomAccessFile file = new RandomAccessFile(cacheFileFinal, "r");
ByteBuffer buffer = file.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, cacheFileFinal.length());
image = Utilities.loadWebpImage(buffer, buffer.limit(), null);
@ -734,7 +781,6 @@ public class ImageLoader {
Bitmap scaledBitmap = Bitmap.createScaledBitmap(image, (int) w_filter, (int) (bitmapH / scaleFactor), true);
if (image != scaledBitmap) {
image.recycle();
callGC();
image = scaledBitmap;
}
}
@ -746,7 +792,7 @@ public class ImageLoader {
if (!blured && opts.inPurgeable) {
Utilities.pinBitmap(image);
}
if (runtimeHack != null) {
if (runtimeHack != null && image != null) {
runtimeHack.trackFree(image.getRowBytes() * image.getHeight());
}
}
@ -774,7 +820,6 @@ public class ImageLoader {
runtimeHack.trackAlloc(image.getRowBytes() * image.getHeight());
}
image.recycle();
callGC();
}
}
final BitmapDrawable toSetFinal = toSet;
@ -853,6 +898,7 @@ public class ImageLoader {
protected String key;
protected String url;
protected String filter;
protected String ext;
protected TLObject location;
protected File finalFilePath;
@ -897,7 +943,7 @@ public class ImageLoader {
imageReceiverArray.clear();
if (location != null) {
if (location instanceof TLRPC.FileLocation) {
FileLoader.getInstance().cancelLoadFile((TLRPC.FileLocation) location);
FileLoader.getInstance().cancelLoadFile((TLRPC.FileLocation) location, ext);
} else if (location instanceof TLRPC.Document) {
FileLoader.getInstance().cancelLoadFile((TLRPC.Document) location);
}
@ -1019,11 +1065,16 @@ public class ImageLoader {
}
@Override
public void fileDidUploaded(final String location, final TLRPC.InputFile inputFile, final TLRPC.InputEncryptedFile inputEncryptedFile) {
public void fileDidUploaded(final String location, final TLRPC.InputFile inputFile, final TLRPC.InputEncryptedFile inputEncryptedFile, final byte[] key, final byte[] iv) {
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.FileDidUpload, location, inputFile, inputEncryptedFile);
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.FileDidUpload, location, inputFile, inputEncryptedFile, key, iv);
}
});
fileProgresses.remove(location);
}
});
@ -1034,7 +1085,12 @@ public class ImageLoader {
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.FileDidFailUpload, location, isEncrypted);
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.FileDidFailUpload, location, isEncrypted);
}
});
fileProgresses.remove(location);
}
});
@ -1049,7 +1105,7 @@ public class ImageLoader {
if (location != null) {
if (MediaController.getInstance().canSaveToGallery() && telegramPath != null && finalFile != null && finalFile.exists() && (location.endsWith(".mp4") || location.endsWith(".jpg"))) {
if (finalFile.toString().startsWith(telegramPath.toString())) {
Utilities.addMediaToGallery(finalFile.toString());
AndroidUtilities.addMediaToGallery(finalFile.toString());
}
}
}
@ -1250,17 +1306,6 @@ public class ImageLoader {
}
}
public void callGC() {
if (Build.VERSION.SDK_INT > 13) {
recycleQueue.postRunnable(new Runnable() {
@Override
public void run() {
//System.gc();
}
});
}
}
public boolean decrementUseCount(String key) {
Integer count = bitmapUseCounts.get(key);
if (count == null) {
@ -1394,7 +1439,7 @@ public class ImageLoader {
}
}
private void createLoadOperationForImageReceiver(final ImageReceiver imageReceiver, final String key, final String url, final TLObject imageLocation, final String httpLocation, final String filter, final int size, final boolean cacheOnly, final int thumb) {
private void createLoadOperationForImageReceiver(final ImageReceiver imageReceiver, final String key, final String url, final String ext, final TLObject imageLocation, final String httpLocation, final String filter, final int size, final boolean cacheOnly, final int thumb) {
if (imageReceiver == null || url == null || key == null) {
return;
}
@ -1510,6 +1555,7 @@ public class ImageLoader {
img.key = key;
img.filter = filter;
img.httpUrl = httpLocation;
img.ext = ext;
img.addImageReceiver(imageReceiver);
if (onlyCache || cacheFile.exists()) {
img.finalFilePath = cacheFile;
@ -1527,7 +1573,7 @@ public class ImageLoader {
if (httpLocation == null) {
if (imageLocation instanceof TLRPC.FileLocation) {
TLRPC.FileLocation location = (TLRPC.FileLocation) imageLocation;
FileLoader.getInstance().loadFile(location, size, size == 0 || location.key != null || cacheOnly);
FileLoader.getInstance().loadFile(location, ext, size, size == 0 || location.key != null || cacheOnly);
} else if (imageLocation instanceof TLRPC.Document) {
FileLoader.getInstance().loadFile((TLRPC.Document) imageLocation, true, true);
}
@ -1584,7 +1630,10 @@ public class ImageLoader {
String thumbUrl = null;
key = null;
thumbKey = null;
String ext = null;
String ext = imageReceiver.getExt();
if (ext == null) {
ext = "jpg";
}
if (httpLocation != null) {
key = Utilities.MD5(httpLocation);
url = key + "." + getHttpUrlExtension(httpLocation);
@ -1592,9 +1641,8 @@ public class ImageLoader {
if (imageLocation instanceof TLRPC.FileLocation) {
TLRPC.FileLocation location = (TLRPC.FileLocation) imageLocation;
key = location.volume_id + "_" + location.local_id;
ext = "." + (location.ext != null ? location.ext : "jpg");
url = key + ext;
if (location.ext != null || location.key != null || location.volume_id == Integer.MIN_VALUE && location.local_id < 0) {
url = key + "." + ext;
if (imageReceiver.getExt() != null || location.key != null || location.volume_id == Integer.MIN_VALUE && location.local_id < 0) {
saveImageToCache = true;
}
} else if (imageLocation instanceof TLRPC.Document) {
@ -1603,10 +1651,19 @@ public class ImageLoader {
return;
}
key = location.dc_id + "_" + location.id;
ext = ".webp";
url = key + ext;
String docExt = FileLoader.getDocumentFileName(location);
int idx;
if (docExt == null || (idx = docExt.lastIndexOf(".")) == -1) {
docExt = "";
} else {
docExt = docExt.substring(idx);
if (docExt.length() <= 1) {
docExt = "";
}
}
url = key + docExt;
if (thumbKey != null) {
thumbUrl = thumbKey + ext;
thumbUrl = thumbKey + "." + ext;
}
saveImageToCache = true;
}
@ -1619,11 +1676,7 @@ public class ImageLoader {
if (thumbLocation != null) {
thumbKey = thumbLocation.volume_id + "_" + thumbLocation.local_id;
if (ext != null) {
thumbUrl = thumbKey + ext;
} else {
thumbUrl = thumbKey + "." + (thumbLocation.ext != null ? thumbLocation.ext : "jpg");
}
thumbUrl = thumbKey + "." + ext;
}
String filter = imageReceiver.getFilter();
@ -1636,10 +1689,10 @@ public class ImageLoader {
}
if (httpLocation != null) {
createLoadOperationForImageReceiver(imageReceiver, key, url, null, httpLocation, filter, 0, true, 0);
createLoadOperationForImageReceiver(imageReceiver, key, url, ext, null, httpLocation, filter, 0, true, 0);
} else {
createLoadOperationForImageReceiver(imageReceiver, thumbKey, thumbUrl, thumbLocation, null, thumbFilter, 0, true, thumbSet ? 2 : 1);
createLoadOperationForImageReceiver(imageReceiver, key, url, imageLocation, null, filter, imageReceiver.getSize(), saveImageToCache || imageReceiver.getCacheOnly(), 0);
createLoadOperationForImageReceiver(imageReceiver, thumbKey, thumbUrl, ext, thumbLocation, null, thumbFilter, 0, true, thumbSet ? 2 : 1);
createLoadOperationForImageReceiver(imageReceiver, key, url, ext, imageLocation, null, filter, imageReceiver.getSize(), saveImageToCache || imageReceiver.getCacheOnly(), 0);
}
}
@ -1682,6 +1735,7 @@ public class ImageLoader {
cacheImage.key = img.key;
cacheImage.httpUrl = img.httpUrl;
cacheImage.thumb = img.thumb;
cacheImage.ext = img.ext;
cacheImage.cacheTask = task = new CacheOutTask(cacheImage);
cacheImage.filter = img.filter;
imageLoadingByKeys.put(cacheImage.key, cacheImage);
@ -1821,7 +1875,7 @@ public class ImageLoader {
path = uri.getPath();
} else {
try {
path = Utilities.getPath(uri);
path = AndroidUtilities.getPath(uri);
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
@ -1861,7 +1915,7 @@ public class ImageLoader {
if (path != null) {
exifPath = path;
} else if (uri != null) {
exifPath = Utilities.getPath(uri);
exifPath = AndroidUtilities.getPath(uri);
}
Matrix matrix = null;
@ -1919,9 +1973,7 @@ public class ImageLoader {
FileLog.e("tmessages", e);
} finally {
try {
if (parcelFD != null) {
parcelFD.close();
}
parcelFD.close();
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
@ -1931,8 +1983,25 @@ public class ImageLoader {
return b;
}
public static void fillPhotoSizeWithBytes(TLRPC.PhotoSize photoSize) {
if (photoSize == null || photoSize.bytes != null) {
return;
}
File file = FileLoader.getPathToAttach(photoSize, true);
try {
RandomAccessFile f = new RandomAccessFile(file, "r");
int len = (int) f.length();
if (len < 20000) {
photoSize.bytes = new byte[(int) f.length()];
f.readFully(photoSize.bytes, 0, photoSize.bytes.length);
}
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
}
private static TLRPC.PhotoSize scaleAndSaveImageInternal(Bitmap bitmap, int w, int h, float photoW, float photoH, float scaleFactor, int quality, boolean cache, boolean scaleAnyway) throws Exception {
Bitmap scaledBitmap = null;
Bitmap scaledBitmap;
if (scaleFactor > 1 || scaleAnyway) {
scaledBitmap = Bitmap.createScaledBitmap(bitmap, w, h, true);
} else {
@ -2055,12 +2124,6 @@ public class ImageLoader {
} else if (message.media instanceof TLRPC.TL_messageMediaDocument) {
if (message.media.document.thumb instanceof TLRPC.TL_photoCachedSize) {
photoSize = message.media.document.thumb;
for (TLRPC.DocumentAttribute attribute : message.media.document.attributes) {
if (attribute instanceof TLRPC.TL_documentAttributeSticker) {
photoSize.location.ext = "webp";
break;
}
}
}
} else if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
if (message.media.webpage.photo != null) {

View File

@ -43,6 +43,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
public String thumbFilter;
public int size;
public boolean cacheOnly;
public String ext;
}
private View parentView;
@ -59,6 +60,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
private String currentHttpUrl;
private String currentFilter;
private String currentThumbFilter;
private String currentExt;
private TLRPC.FileLocation currentThumbLocation;
private int currentSize;
private boolean currentCacheOnly;
@ -68,6 +70,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
private boolean needsQualityThumb;
private boolean shouldGenerateQualityThumb;
private boolean invalidateAll;
private int imageX, imageY, imageW, imageH;
private Rect drawRegion = new Rect();
@ -104,27 +107,27 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
canceledLoading = true;
}
public void setImage(TLObject path, String filter, Drawable thumb, boolean cacheOnly) {
setImage(path, null, filter, thumb, null, null, 0, cacheOnly);
public void setImage(TLObject path, String filter, Drawable thumb, String ext, boolean cacheOnly) {
setImage(path, null, filter, thumb, null, null, 0, ext, cacheOnly);
}
public void setImage(TLObject path, String filter, Drawable thumb, int size, boolean cacheOnly) {
setImage(path, null, filter, thumb, null, null, size, cacheOnly);
public void setImage(TLObject path, String filter, Drawable thumb, int size, String ext, boolean cacheOnly) {
setImage(path, null, filter, thumb, null, null, size, ext, cacheOnly);
}
public void setImage(String httpUrl, String filter, Drawable thumb, int size) {
setImage(null, httpUrl, filter, thumb, null, null, size, true);
public void setImage(String httpUrl, String filter, Drawable thumb, String ext, int size) {
setImage(null, httpUrl, filter, thumb, null, null, size, ext, true);
}
public void setImage(TLObject fileLocation, String filter, TLRPC.FileLocation thumbLocation, String thumbFilter, boolean cacheOnly) {
setImage(fileLocation, null, filter, null, thumbLocation, thumbFilter, 0, cacheOnly);
public void setImage(TLObject fileLocation, String filter, TLRPC.FileLocation thumbLocation, String thumbFilter, String ext, boolean cacheOnly) {
setImage(fileLocation, null, filter, null, thumbLocation, thumbFilter, 0, ext, cacheOnly);
}
public void setImage(TLObject fileLocation, String filter, TLRPC.FileLocation thumbLocation, String thumbFilter, int size, boolean cacheOnly) {
setImage(fileLocation, null, filter, null, thumbLocation, thumbFilter, size, cacheOnly);
public void setImage(TLObject fileLocation, String filter, TLRPC.FileLocation thumbLocation, String thumbFilter, int size, String ext, boolean cacheOnly) {
setImage(fileLocation, null, filter, null, thumbLocation, thumbFilter, size, ext, cacheOnly);
}
public void setImage(TLObject fileLocation, String httpUrl, String filter, Drawable thumb, TLRPC.FileLocation thumbLocation, String thumbFilter, int size, boolean cacheOnly) {
public void setImage(TLObject fileLocation, String httpUrl, String filter, Drawable thumb, TLRPC.FileLocation thumbLocation, String thumbFilter, int size, String ext, boolean cacheOnly) {
if (setImageBackup != null) {
setImageBackup.fileLocation = null;
setImageBackup.httpUrl = null;
@ -139,6 +142,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
recycleBitmap(null, false);
recycleBitmap(null, true);
currentKey = null;
currentExt = ext;
currentThumbKey = null;
currentThumbFilter = null;
currentImageLocation = null;
@ -153,7 +157,11 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
bitmapShader = null;
ImageLoader.getInstance().cancelLoadingForImageReceiver(this, 0);
if (parentView != null) {
parentView.invalidate(imageX, imageY, imageX + imageW, imageY + imageH);
if (invalidateAll) {
parentView.invalidate();
} else {
parentView.invalidate(imageX, imageY, imageX + imageW, imageY + imageH);
}
}
if (delegate != null) {
delegate.didSetImage(this, currentImage != null || currentThumb != null || staticThumb != null, currentImage == null);
@ -207,6 +215,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
currentThumbKey = thumbKey;
currentKey = key;
currentExt = ext;
currentImageLocation = fileLocation;
currentHttpUrl = httpUrl;
currentFilter = filter;
@ -224,7 +233,11 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
ImageLoader.getInstance().loadImageForImageReceiver(this);
if (parentView != null) {
parentView.invalidate(imageX, imageY, imageX + imageW, imageY + imageH);
if (invalidateAll) {
parentView.invalidate();
} else {
parentView.invalidate(imageX, imageY, imageX + imageW, imageY + imageH);
}
}
}
@ -249,6 +262,10 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
centerRotation = center;
}
public void setInvalidateAll(boolean value) {
invalidateAll = value;
}
public int getOrientation() {
return orientation;
}
@ -264,6 +281,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
staticThumb = bitmap;
currentThumbLocation = null;
currentKey = null;
currentExt = null;
currentThumbKey = null;
currentImage = null;
currentThumbFilter = null;
@ -284,7 +302,11 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
delegate.didSetImage(this, currentImage != null || currentThumb != null || staticThumb != null, currentImage == null);
}
if (parentView != null) {
parentView.invalidate(imageX, imageY, imageX + imageW, imageY + imageH);
if (invalidateAll) {
parentView.invalidate();
} else {
parentView.invalidate(imageX, imageY, imageX + imageW, imageY + imageH);
}
}
}
@ -309,6 +331,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
setImageBackup.thumbLocation = currentThumbLocation;
setImageBackup.thumbFilter = currentThumbFilter;
setImageBackup.size = currentSize;
setImageBackup.ext = currentExt;
setImageBackup.cacheOnly = currentCacheOnly;
}
NotificationCenter.getInstance().removeObserver(this, NotificationCenter.didReplacedPhotoInMemCache);
@ -318,7 +341,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
public boolean onAttachedToWindow() {
NotificationCenter.getInstance().addObserver(this, NotificationCenter.didReplacedPhotoInMemCache);
if (setImageBackup != null && (setImageBackup.fileLocation != null || setImageBackup.httpUrl != null || setImageBackup.thumbLocation != null || setImageBackup.thumb != null)) {
setImage(setImageBackup.fileLocation, setImageBackup.httpUrl, setImageBackup.filter, setImageBackup.thumb, setImageBackup.thumbLocation, setImageBackup.thumbFilter, setImageBackup.size, setImageBackup.cacheOnly);
setImage(setImageBackup.fileLocation, setImageBackup.httpUrl, setImageBackup.filter, setImageBackup.thumb, setImageBackup.thumbLocation, setImageBackup.thumbFilter, setImageBackup.size, setImageBackup.ext, setImageBackup.cacheOnly);
return true;
}
return false;
@ -332,10 +355,8 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
boolean hasFilter = paint != null && paint.getColorFilter() != null;
if (hasFilter && !isPressed) {
bitmapDrawable.setColorFilter(null);
hasFilter = false;
} else if (!hasFilter && isPressed) {
bitmapDrawable.setColorFilter(new PorterDuffColorFilter(0xffdddddd, PorterDuff.Mode.MULTIPLY));
hasFilter = true;
}
if (colorFilter != null) {
bitmapDrawable.setColorFilter(colorFilter);
@ -353,8 +374,6 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
} else {
int bitmapW;
int bitmapH;
int originalW = bitmapDrawable.getIntrinsicWidth();
int originalH = bitmapDrawable.getIntrinsicHeight();
if (orientation == 90 || orientation == 270) {
bitmapW = bitmapDrawable.getIntrinsicHeight();
bitmapH = bitmapDrawable.getIntrinsicWidth();
@ -383,7 +402,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
ImageLoader.getInstance().removeImage(currentThumbKey);
currentThumbKey = null;
}
setImage(currentImageLocation, currentHttpUrl, currentFilter, currentThumb, currentThumbLocation, currentThumbFilter, currentSize, currentCacheOnly);
setImage(currentImageLocation, currentHttpUrl, currentFilter, currentThumb, currentThumbLocation, currentThumbFilter, currentSize, currentExt, currentCacheOnly);
FileLog.e("tmessages", e);
}
canvas.restore();
@ -402,11 +421,9 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
if (bitmapW / scaleH > imageW) {
bitmapW /= scaleH;
originalW /= scaleH;
drawRegion.set(imageX - (bitmapW - imageW) / 2, imageY, imageX + (bitmapW + imageW) / 2, imageY + imageH);
} else {
bitmapH /= scaleW;
originalH /= scaleW;
drawRegion.set(imageX, imageY - (bitmapH - imageH) / 2, imageX + imageW, imageY + (bitmapH + imageH) / 2);
}
if (orientation == 90 || orientation == 270) {
@ -430,7 +447,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
ImageLoader.getInstance().removeImage(currentThumbKey);
currentThumbKey = null;
}
setImage(currentImageLocation, currentHttpUrl, currentFilter, currentThumb, currentThumbLocation, currentThumbFilter, currentSize, currentCacheOnly);
setImage(currentImageLocation, currentHttpUrl, currentFilter, currentThumb, currentThumbLocation, currentThumbFilter, currentSize, currentExt, currentCacheOnly);
FileLog.e("tmessages", e);
}
}
@ -467,7 +484,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
ImageLoader.getInstance().removeImage(currentThumbKey);
currentThumbKey = null;
}
setImage(currentImageLocation, currentHttpUrl, currentFilter, currentThumb, currentThumbLocation, currentThumbFilter, currentSize, currentCacheOnly);
setImage(currentImageLocation, currentHttpUrl, currentFilter, currentThumb, currentThumbLocation, currentThumbFilter, currentSize, currentExt, currentCacheOnly);
FileLog.e("tmessages", e);
}
}
@ -498,7 +515,11 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
lastUpdateAlphaTime = System.currentTimeMillis();
if (parentView != null) {
parentView.invalidate(imageX, imageY, imageX + imageW, imageY + imageH);
if (invalidateAll) {
parentView.invalidate();
} else {
parentView.invalidate(imageX, imageY, imageX + imageW, imageY + imageH);
}
}
}
}
@ -577,7 +598,11 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
isVisible = value;
if (invalidate && parentView != null) {
parentView.invalidate(imageX, imageY, imageX + imageW, imageY + imageH);
if (invalidateAll) {
parentView.invalidate();
} else {
parentView.invalidate(imageX, imageY, imageX + imageW, imageY + imageH);
}
}
}
@ -636,6 +661,10 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
return imageH;
}
public String getExt() {
return currentExt;
}
public boolean isInsideImage(float x, float y) {
return x >= imageX && x <= imageX + imageW && y >= imageY && y <= imageY + imageH;
}
@ -782,7 +811,11 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
if (parentView != null) {
parentView.invalidate(imageX, imageY, imageX + imageW, imageY + imageH);
if (invalidateAll) {
parentView.invalidate();
} else {
parentView.invalidate(imageX, imageY, imageX + imageW, imageY + imageH);
}
}
} else if (currentThumb == null && (currentImage == null || forcePreview)) {
if (currentThumbKey == null || !key.equals(currentThumbKey)) {
@ -801,7 +834,11 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
if (!(staticThumb instanceof BitmapDrawable) && parentView != null) {
parentView.invalidate(imageX, imageY, imageX + imageW, imageY + imageH);
if (invalidateAll) {
parentView.invalidate();
} else {
parentView.invalidate(imageX, imageY, imageX + imageW, imageY + imageH);
}
}
}
@ -841,7 +878,6 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
if (canDelete) {
bitmap.recycle();
ImageLoader.getInstance().callGC();
}
}
if (thumb) {
@ -866,7 +902,11 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
staticThumb = null;
}
if (parentView != null) {
parentView.invalidate(imageX, imageY, imageX + imageW, imageY + imageH);
if (invalidateAll) {
parentView.invalidate();
} else {
parentView.invalidate(imageX, imageY, imageX + imageW, imageY + imageH);
}
}
}
} else if (id == NotificationCenter.didReplacedPhotoInMemCache) {

View File

@ -23,7 +23,6 @@ import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.messenger.TLRPC;
import org.telegram.messenger.Utilities;
import org.telegram.messenger.ApplicationLoader;
import org.xmlpull.v1.XmlPullParser;
@ -359,7 +358,7 @@ public class LocaleController {
}
File finalFile = new File(ApplicationLoader.applicationContext.getFilesDir(), languageCode + ".xml");
if (!Utilities.copyFile(file, finalFile)) {
if (!AndroidUtilities.copyFile(file, finalFile)) {
return false;
}
@ -494,7 +493,6 @@ public class LocaleController {
try {
if (stream != null) {
stream.close();
stream = null;
}
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -512,7 +510,7 @@ public class LocaleController {
return;
}
try {
Locale newLocale = null;
Locale newLocale;
if (localeInfo.shortName != null) {
String[] args = localeInfo.shortName.split("_");
if (args.length == 1) {
@ -682,50 +680,60 @@ public class LocaleController {
}
public static String formatDate(long date) {
Calendar rightNow = Calendar.getInstance();
int day = rightNow.get(Calendar.DAY_OF_YEAR);
int year = rightNow.get(Calendar.YEAR);
rightNow.setTimeInMillis(date * 1000);
int dateDay = rightNow.get(Calendar.DAY_OF_YEAR);
int dateYear = rightNow.get(Calendar.YEAR);
try {
Calendar rightNow = Calendar.getInstance();
int day = rightNow.get(Calendar.DAY_OF_YEAR);
int year = rightNow.get(Calendar.YEAR);
rightNow.setTimeInMillis(date * 1000);
int dateDay = rightNow.get(Calendar.DAY_OF_YEAR);
int dateYear = rightNow.get(Calendar.YEAR);
if (dateDay == day && year == dateYear) {
return formatterDay.format(new Date(date * 1000));
} else if (dateDay + 1 == day && year == dateYear) {
return getString("Yesterday", R.string.Yesterday);
} else if (year == dateYear) {
return formatterMonth.format(new Date(date * 1000));
} else {
return formatterYear.format(new Date(date * 1000));
if (dateDay == day && year == dateYear) {
return formatterDay.format(new Date(date * 1000));
} else if (dateDay + 1 == day && year == dateYear) {
return getString("Yesterday", R.string.Yesterday);
} else if (year == dateYear) {
return formatterMonth.format(new Date(date * 1000));
} else {
return formatterYear.format(new Date(date * 1000));
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
return "LOC_ERR";
}
public static String formatDateOnline(long date) {
Calendar rightNow = Calendar.getInstance();
int day = rightNow.get(Calendar.DAY_OF_YEAR);
int year = rightNow.get(Calendar.YEAR);
rightNow.setTimeInMillis(date * 1000);
int dateDay = rightNow.get(Calendar.DAY_OF_YEAR);
int dateYear = rightNow.get(Calendar.YEAR);
try {
Calendar rightNow = Calendar.getInstance();
int day = rightNow.get(Calendar.DAY_OF_YEAR);
int year = rightNow.get(Calendar.YEAR);
rightNow.setTimeInMillis(date * 1000);
int dateDay = rightNow.get(Calendar.DAY_OF_YEAR);
int dateYear = rightNow.get(Calendar.YEAR);
if (dateDay == day && year == dateYear) {
return String.format("%s %s %s", LocaleController.getString("LastSeen", R.string.LastSeen), LocaleController.getString("TodayAt", R.string.TodayAt), formatterDay.format(new Date(date * 1000)));
} else if (dateDay + 1 == day && year == dateYear) {
return String.format("%s %s %s", LocaleController.getString("LastSeen", R.string.LastSeen), LocaleController.getString("YesterdayAt", R.string.YesterdayAt), formatterDay.format(new Date(date * 1000)));
} else if (year == dateYear) {
String format = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, formatterMonth.format(new Date(date * 1000)), formatterDay.format(new Date(date * 1000)));
return String.format("%s %s", LocaleController.getString("LastSeenDate", R.string.LastSeenDate), format);
} else {
String format = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, formatterYear.format(new Date(date * 1000)), formatterDay.format(new Date(date * 1000)));
return String.format("%s %s", LocaleController.getString("LastSeenDate", R.string.LastSeenDate), format);
if (dateDay == day && year == dateYear) {
return String.format("%s %s %s", LocaleController.getString("LastSeen", R.string.LastSeen), LocaleController.getString("TodayAt", R.string.TodayAt), formatterDay.format(new Date(date * 1000)));
} else if (dateDay + 1 == day && year == dateYear) {
return String.format("%s %s %s", LocaleController.getString("LastSeen", R.string.LastSeen), LocaleController.getString("YesterdayAt", R.string.YesterdayAt), formatterDay.format(new Date(date * 1000)));
} else if (year == dateYear) {
String format = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, formatterMonth.format(new Date(date * 1000)), formatterDay.format(new Date(date * 1000)));
return String.format("%s %s", LocaleController.getString("LastSeenDate", R.string.LastSeenDate), format);
} else {
String format = LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, formatterYear.format(new Date(date * 1000)), formatterDay.format(new Date(date * 1000)));
return String.format("%s %s", LocaleController.getString("LastSeenDate", R.string.LastSeenDate), format);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
return "LOC_ERR";
}
private FastDateFormat createFormatter(Locale locale, String format, String defaultFormat) {
if (format == null || format.length() == 0) {
format = defaultFormat;
}
FastDateFormat formatter = null;
FastDateFormat formatter;
try {
formatter = FastDateFormat.getInstance(format, locale);
} catch (Exception e) {
@ -758,25 +766,30 @@ public class LocaleController {
}
public static String stringForMessageListDate(long date) {
Calendar rightNow = Calendar.getInstance();
int day = rightNow.get(Calendar.DAY_OF_YEAR);
int year = rightNow.get(Calendar.YEAR);
rightNow.setTimeInMillis(date * 1000);
int dateDay = rightNow.get(Calendar.DAY_OF_YEAR);
int dateYear = rightNow.get(Calendar.YEAR);
try {
Calendar rightNow = Calendar.getInstance();
int day = rightNow.get(Calendar.DAY_OF_YEAR);
int year = rightNow.get(Calendar.YEAR);
rightNow.setTimeInMillis(date * 1000);
int dateDay = rightNow.get(Calendar.DAY_OF_YEAR);
int dateYear = rightNow.get(Calendar.YEAR);
if (year != dateYear) {
return formatterYear.format(new Date(date * 1000));
} else {
int dayDiff = dateDay - day;
if(dayDiff == 0 || dayDiff == -1 && (int)(System.currentTimeMillis() / 1000) - date < 60 * 60 * 8) {
return formatterDay.format(new Date(date * 1000));
} else if(dayDiff > -7 && dayDiff <= -1) {
return formatterWeek.format(new Date(date * 1000));
if (year != dateYear) {
return formatterYear.format(new Date(date * 1000));
} else {
return formatterMonth.format(new Date(date * 1000));
int dayDiff = dateDay - day;
if(dayDiff == 0 || dayDiff == -1 && (int)(System.currentTimeMillis() / 1000) - date < 60 * 60 * 8) {
return formatterDay.format(new Date(date * 1000));
} else if(dayDiff > -7 && dayDiff <= -1) {
return formatterWeek.format(new Date(date * 1000));
} else {
return formatterMonth.format(new Date(date * 1000));
}
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
return "LOC_ERR";
}
public static String formatUserStatus(TLRPC.User user) {

View File

@ -107,7 +107,6 @@ public class LruCache {
if (previous != null) {
entryRemoved(false, key, previous, value);
ImageLoader.getInstance().callGC();
}
trimToSize(maxSize, key);
@ -148,7 +147,6 @@ public class LruCache {
entryRemoved(true, key, value, null);
}
ImageLoader.getInstance().callGC();
}
}
@ -183,7 +181,6 @@ public class LruCache {
}
entryRemoved(false, key, previous, null);
ImageLoader.getInstance().callGC();
}
return previous;

View File

@ -8,6 +8,7 @@
package org.telegram.android;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ProgressDialog;
@ -243,6 +244,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
private Timer progressTimer = null;
private final Object progressTimerSync = new Object();
private boolean useFrontSpeaker;
private int buffersWrited;
private AudioRecord audioRecorder = null;
private TLRPC.TL_audio recordingAudio = null;
@ -271,7 +273,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
@Override
public void run() {
if (audioRecorder != null) {
ByteBuffer buffer = null;
ByteBuffer buffer;
if (!recordBuffers.isEmpty()) {
buffer = recordBuffers.get(0);
recordBuffers.remove(0);
@ -691,7 +693,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
if (downloadObject.object instanceof TLRPC.Audio) {
FileLoader.getInstance().loadFile((TLRPC.Audio)downloadObject.object, false);
} else if (downloadObject.object instanceof TLRPC.PhotoSize) {
FileLoader.getInstance().loadFile((TLRPC.PhotoSize)downloadObject.object, false);
FileLoader.getInstance().loadFile((TLRPC.PhotoSize)downloadObject.object, null, false);
} else if (downloadObject.object instanceof TLRPC.Video) {
FileLoader.getInstance().loadFile((TLRPC.Video)downloadObject.object, false);
} else if (downloadObject.object instanceof TLRPC.Document) {
@ -727,7 +729,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
if (downloadObject != null) {
downloadQueueKeys.remove(fileName);
if (state == 0 || state == 2) {
MessagesStorage.getInstance().removeFromDownloadQueue(downloadObject.id, downloadObject.type, state != 0);
MessagesStorage.getInstance().removeFromDownloadQueue(downloadObject.id, downloadObject.type, false /*state != 0*/);
}
if (downloadObject.type == AUTODOWNLOAD_MASK_PHOTO) {
photoDownloadQueue.remove(downloadObject);
@ -1106,10 +1108,12 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
} catch (Exception e) {
FileLog.e("tmessages", e);
}
buffersWrited++;
if (count > 0) {
final long pcm = buffer.pcmOffset;
final int marker = buffer.finished == 1 ? buffer.size : -1;
final int marker = buffer.finished == 1 ? count : -1;
final int finalBuffersWrited = buffersWrited;
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
@ -1118,6 +1122,9 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
if (audioTrackPlayer != null) {
audioTrackPlayer.setNotificationMarkerPosition(1);
}
if (finalBuffersWrited == 1) {
clenupPlayer(true);
}
}
}
});
@ -1140,12 +1147,17 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
});
}
private boolean isNearToSensor(float value) {
return value < 5.0f && value != proximitySensor.getMaximumRange();
}
@Override
public void onSensorChanged(SensorEvent event) {
if (proximitySensor != null && audioTrackPlayer == null && audioPlayer == null || isPaused || (useFrontSpeaker == (event.values[0] < proximitySensor.getMaximumRange() / 10))) {
FileLog.e("tmessages", "proximity changed to " + event.values[0]);
if (proximitySensor != null && audioTrackPlayer == null && audioPlayer == null || isPaused || (useFrontSpeaker == isNearToSensor(event.values[0]))) {
return;
}
boolean newValue = event.values[0] < proximitySensor.getMaximumRange() / 10;
boolean newValue = isNearToSensor(event.values[0]);
try {
if (newValue && NotificationsController.getInstance().audioManager.isWiredHeadsetOn()) {
return;
@ -1230,6 +1242,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
}
stopProgressTimer();
lastProgress = 0;
buffersWrited = 0;
isPaused = false;
MessageObject lastFile = playingMessageObject;
playingMessageObject.audioProgress = 0.0f;
@ -1464,6 +1477,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
if (audioTrackPlayer == null && audioPlayer == null || messageObject == null || playingMessageObject == null || playingMessageObject != null && playingMessageObject.getId() != messageObject.getId()) {
return false;
}
stopProgressTimer();
try {
if (audioPlayer != null) {
audioPlayer.pause();
@ -1480,11 +1494,12 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
}
public boolean resumeAudio(MessageObject messageObject) {
startProximitySensor();
if (audioTrackPlayer == null && audioPlayer == null || messageObject == null || playingMessageObject == null || playingMessageObject != null && playingMessageObject.getId() != messageObject.getId()) {
return false;
}
startProximitySensor();
try {
startProgressTimer();
if (audioPlayer != null) {
audioPlayer.start();
} else if (audioTrackPlayer != null) {
@ -1706,9 +1721,9 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
try {
File destFile = null;
if (type == 0) {
destFile = Utilities.generatePicturePath();
destFile = AndroidUtilities.generatePicturePath();
} else if (type == 1) {
destFile = Utilities.generateVideoPath();
destFile = AndroidUtilities.generateVideoPath();
} else if (type == 2) {
File f = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
destFile = new File(f, name);
@ -1725,8 +1740,8 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
source = new FileInputStream(sourceFile).getChannel();
destination = new FileOutputStream(destFile).getChannel();
long size = source.size();
for (long a = 0; a < size; a += 1024) {
destination.transferFrom(source, a, Math.min(1024, size - a));
for (long a = 0; a < size; a += 4096) {
destination.transferFrom(source, a, Math.min(4096, size - a));
if (finalProgress != null) {
if (lastProgress <= System.currentTimeMillis() - 500) {
lastProgress = System.currentTimeMillis();
@ -1757,7 +1772,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
}
if (result && (type == 0 || type == 1)) {
Utilities.addMediaToGallery(Uri.fromFile(destFile));
AndroidUtilities.addMediaToGallery(Uri.fromFile(destFile));
}
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -2185,6 +2200,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
}
}
@SuppressLint("NewApi")
public static MediaCodecInfo selectCodec(String mimeType) {
int numCodecs = MediaCodecList.getCodecCount();
MediaCodecInfo lastCodecInfo = null;
@ -2221,6 +2237,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
}
}
@SuppressLint("NewApi")
public static int selectColorFormat(MediaCodecInfo codecInfo, String mimeType) {
MediaCodecInfo.CodecCapabilities capabilities = codecInfo.getCapabilitiesForType(mimeType);
int lastColorFormat = 0;
@ -2373,7 +2390,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
}
private void checkConversionCanceled() throws Exception {
boolean cancelConversion = false;
boolean cancelConversion;
synchronized (videoConvertSync) {
cancelConversion = cancelCurrentVideoConversion;
}
@ -2384,15 +2401,15 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
@TargetApi(16)
private boolean convertVideo(final MessageObject messageObject) {
String videoPath = messageObject.messageOwner.videoEditedInfo.originalPath;
long startTime = messageObject.messageOwner.videoEditedInfo.startTime;
long endTime = messageObject.messageOwner.videoEditedInfo.endTime;
int resultWidth = messageObject.messageOwner.videoEditedInfo.resultWidth;
int resultHeight = messageObject.messageOwner.videoEditedInfo.resultHeight;
int rotationValue = messageObject.messageOwner.videoEditedInfo.rotationValue;
int originalWidth = messageObject.messageOwner.videoEditedInfo.originalWidth;
int originalHeight = messageObject.messageOwner.videoEditedInfo.originalHeight;
int bitrate = messageObject.messageOwner.videoEditedInfo.bitrate;
String videoPath = messageObject.videoEditedInfo.originalPath;
long startTime = messageObject.videoEditedInfo.startTime;
long endTime = messageObject.videoEditedInfo.endTime;
int resultWidth = messageObject.videoEditedInfo.resultWidth;
int resultHeight = messageObject.videoEditedInfo.resultHeight;
int rotationValue = messageObject.videoEditedInfo.rotationValue;
int originalWidth = messageObject.videoEditedInfo.originalWidth;
int originalHeight = messageObject.videoEditedInfo.originalHeight;
int bitrate = messageObject.videoEditedInfo.bitrate;
int rotateRender = 0;
File cacheFile = new File(messageObject.messageOwner.attachPath);
@ -2455,7 +2472,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
checkConversionCanceled();
if (resultWidth != originalWidth || resultHeight != originalHeight) {
int videoIndex = -5;
int videoIndex;
videoIndex = selectTrack(extractor, false);
if (videoIndex >= 0) {
MediaCodec decoder = null;
@ -2471,7 +2488,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
int swapUV = 0;
int videoTrackIndex = -5;
int colorFormat = 0;
int colorFormat;
int processorType = PROCESSOR_TYPE_OTHER;
String manufacturer = Build.MANUFACTURER.toLowerCase();
if (Build.VERSION.SDK_INT < 18) {
@ -2590,7 +2607,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
if (index == videoIndex) {
int inputBufIndex = decoder.dequeueInputBuffer(TIMEOUT_USEC);
if (inputBufIndex >= 0) {
ByteBuffer inputBuf = null;
ByteBuffer inputBuf;
if (Build.VERSION.SDK_INT < 21) {
inputBuf = decoderInputBuffers[inputBufIndex];
} else {
@ -2636,7 +2653,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
} else if (encoderStatus < 0) {
throw new RuntimeException("unexpected result from encoder.dequeueOutputBuffer: " + encoderStatus);
} else {
ByteBuffer encodedData = null;
ByteBuffer encodedData;
if (Build.VERSION.SDK_INT < 21) {
encodedData = encoderOutputBuffers[encoderStatus];
} else {
@ -2698,7 +2715,7 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
} else if (decoderStatus < 0) {
throw new RuntimeException("unexpected result from decoder.dequeueOutputBuffer: " + decoderStatus);
} else {
boolean doRender = false;
boolean doRender;
if (Build.VERSION.SDK_INT >= 18) {
doRender = info.size != 0;
} else {
@ -2775,21 +2792,17 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
if (outputSurface != null) {
outputSurface.release();
outputSurface = null;
}
if (inputSurface != null) {
inputSurface.release();
inputSurface = null;
}
if (decoder != null) {
decoder.stop();
decoder.release();
decoder = null;
}
if (encoder != null) {
encoder.stop();
encoder.release();
encoder = null;
}
checkConversionCanceled();
@ -2809,7 +2822,6 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
} finally {
if (extractor != null) {
extractor.release();
extractor = null;
}
if (mediaMuxer != null) {
try {
@ -2817,7 +2829,6 @@ public class MediaController implements NotificationCenter.NotificationCenterDel
} catch (Exception e) {
FileLog.e("tmessages", e);
}
mediaMuxer = null;
}
FileLog.e("tmessages", "time = " + (System.currentTimeMillis() - time));
}

View File

@ -25,6 +25,7 @@ import org.telegram.messenger.TLRPC;
import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig;
import org.telegram.ui.Components.URLSpanNoUnderline;
import org.telegram.ui.Components.URLSpanNoUnderlineBold;
import java.util.AbstractMap;
import java.util.ArrayList;
@ -48,10 +49,11 @@ public class MessageObject {
public int contentType;
public String dateKey;
public String monthKey;
public boolean deleted = false;
public boolean deleted;
public float audioProgress;
public int audioProgressSec;
public ArrayList<TLRPC.PhotoSize> photoThumbs;
public VideoEditedInfo videoEditedInfo;
public static TextPaint textPaint;
public int lastLineWidth;
@ -147,7 +149,7 @@ public class MessageObject {
if (whoUser != null && fromUser != null) {
if (whoUser.id == fromUser.id) {
if (isOut()) {
messageText = LocaleController.getString("ActionAddUserSelf", R.string.ActionAddUserSelf).replace("un1", LocaleController.getString("FromYou", R.string.FromYou));
messageText = LocaleController.getString("ActionAddUserSelfYou", R.string.ActionAddUserSelfYou);
} else {
messageText = replaceWithLink(LocaleController.getString("ActionAddUserSelf", R.string.ActionAddUserSelf), "un1", fromUser);
}
@ -331,6 +333,9 @@ public class MessageObject {
if (message instanceof TLRPC.TL_message || message instanceof TLRPC.TL_messageForwarded_old2) {
if (isMediaEmpty()) {
contentType = type = 0;
if (messageText.length() == 0) {
messageText = "Empty message";
}
} else if (message.media instanceof TLRPC.TL_messageMediaPhoto) {
contentType = type = 1;
} else if (message.media instanceof TLRPC.TL_messageMediaGeo || message.media instanceof TLRPC.TL_messageMediaVenue) {
@ -351,9 +356,6 @@ public class MessageObject {
type = 8;
} else if (message.media.document.mime_type.equals("image/webp") && isSticker()) {
type = 13;
if (messageOwner.media.document.thumb != null && messageOwner.media.document.thumb.location != null) {
messageOwner.media.document.thumb.location.ext = "webp";
}
} else {
type = 9;
}
@ -393,6 +395,11 @@ public class MessageObject {
monthKey = String.format("%d_%02d", dateYear, dateMonth);
}
if (messageOwner.message != null && messageOwner.id < 0 && messageOwner.message.length() > 6 && messageOwner.media instanceof TLRPC.TL_messageMediaVideo) {
videoEditedInfo = new VideoEditedInfo();
videoEditedInfo.parseString(messageOwner.message);
}
generateCaption();
if (generateLayout) {
generateLayout();
@ -458,7 +465,7 @@ public class MessageObject {
if (messageOwner.media.webpage.photo != null) {
if (!update || photoThumbs == null) {
photoThumbs = new ArrayList<>(messageOwner.media.webpage.photo.sizes);
} else if (photoThumbs != null && !photoThumbs.isEmpty()) {
} else if (!photoThumbs.isEmpty()) {
for (TLRPC.PhotoSize photoObject : photoThumbs) {
for (TLRPC.PhotoSize size : messageOwner.media.webpage.photo.sizes) {
if (size instanceof TLRPC.TL_photoSizeEmpty) {
@ -479,7 +486,7 @@ public class MessageObject {
public CharSequence replaceWithLink(CharSequence source, String param, TLRPC.User user) {
String name = ContactsController.formatName(user.first_name, user.last_name);
int start = TextUtils.indexOf(source, param);
URLSpanNoUnderline span = new URLSpanNoUnderline("" + user.id);
URLSpanNoUnderlineBold span = new URLSpanNoUnderlineBold("" + user.id);
SpannableStringBuilder builder = new SpannableStringBuilder(TextUtils.replace(source, new String[]{param}, new String[]{name}));
builder.setSpan(span, start, start + name.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return builder;
@ -664,7 +671,7 @@ public class MessageObject {
}
}
StaticLayout textLayout = null;
StaticLayout textLayout;
try {
textLayout = new StaticLayout(messageText, textPaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
@ -783,7 +790,6 @@ public class MessageObject {
if (a == blocksCount - 1) {
lastLineWidth = lastLineWidthWithLeft;
}
linesMaxWidth = linesMaxWidthWithLeft;
} else if (a == blocksCount - 1) {
lastLineWidth = linesMaxWidth;
}
@ -939,6 +945,20 @@ public class MessageObject {
return false;
}
public static TLRPC.InputStickerSet getInputStickerSet(TLRPC.Message message) {
if (message.media != null && message.media.document != null) {
for (TLRPC.DocumentAttribute attribute : message.media.document.attributes) {
if (attribute instanceof TLRPC.TL_documentAttributeSticker) {
if (attribute.stickerset instanceof TLRPC.TL_inputStickerSetEmpty) {
return null;
}
return attribute.stickerset;
}
}
}
return null;
}
public String getStrickerChar() {
if (messageOwner.media != null && messageOwner.media.document != null) {
for (TLRPC.DocumentAttribute attribute : messageOwner.media.document.attributes) {
@ -991,8 +1011,8 @@ public class MessageObject {
}
return photoHeight + AndroidUtilities.dp(14);
} else {
int photoHeight = 0;
int photoWidth = 0;
int photoHeight;
int photoWidth;
if (AndroidUtilities.isTablet()) {
photoWidth = (int) (AndroidUtilities.getMinTabletSide() * 0.7f);
@ -1010,35 +1030,22 @@ public class MessageObject {
if (currentPhotoObject != null) {
float scale = (float) currentPhotoObject.w / (float) photoWidth;
int w = (int) (currentPhotoObject.w / scale);
int h = (int) (currentPhotoObject.h / scale);
if (w == 0) {
w = AndroidUtilities.dp(100);
}
if (h == 0) {
h = AndroidUtilities.dp(100);
}
if (h > photoHeight) {
float scale2 = h;
h = photoHeight;
scale2 /= h;
w = (int) (w / scale2);
} else if (h < AndroidUtilities.dp(120)) {
h = AndroidUtilities.dp(120);
float hScale = (float) currentPhotoObject.h / h;
if (currentPhotoObject.w / hScale < photoWidth) {
w = (int) (currentPhotoObject.w / hScale);
}
}
if (isSecretPhoto()) {
if (AndroidUtilities.isTablet()) {
w = h = (int) (AndroidUtilities.getMinTabletSide() * 0.5f);
h = (int) (AndroidUtilities.getMinTabletSide() * 0.5f);
} else {
w = h = (int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.5f);
h = (int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.5f);
}
}
photoWidth = w;
photoHeight = h;
}
return photoHeight + AndroidUtilities.dp(14);
@ -1049,6 +1056,10 @@ public class MessageObject {
return isStickerMessage(messageOwner);
}
public TLRPC.InputStickerSet getInputStickerSet() {
return getInputStickerSet(messageOwner);
}
public boolean isForwarded() {
return (messageOwner.flags & TLRPC.MESSAGE_FLAG_FWD) != 0;
}

View File

@ -10,9 +10,12 @@ package org.telegram.android;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.os.Build;
import android.os.Bundle;
import android.util.Base64;
import android.util.SparseArray;
@ -28,6 +31,8 @@ import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ChatActivity;
import org.telegram.ui.ProfileActivity;
import java.util.ArrayList;
import java.util.Collections;
@ -129,6 +134,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
private static volatile MessagesController Instance = null;
public static MessagesController getInstance() {
MessagesController localInstance = Instance;
if (localInstance == null) {
@ -200,7 +206,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
disabledFeature.serializeToStream(data);
}
String string = Base64.encodeToString(data.toByteArray(), Base64.DEFAULT);
if (string != null && string.length() != 0) {
if (string.length() != 0) {
editor.putString("disabledFeatures", string);
}
} catch (Exception e) {
@ -223,7 +229,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
builder.setTitle("Oops!");
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null);
builder.setMessage(disabledFeature.description);
fragment.showAlertDialog(builder);
fragment.showDialog(builder.create());
}
return false;
}
@ -255,7 +261,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
if (user == null) {
return null;
}
TLRPC.InputUser inputUser = null;
TLRPC.InputUser inputUser;
if (user.id == UserConfig.getClientUserId()) {
inputUser = new TLRPC.TL_inputUserSelf();
} else if (user instanceof TLRPC.TL_userForeign || user instanceof TLRPC.TL_userRequest) {
@ -272,9 +278,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter
@Override
public void didReceivedNotification(int id, Object... args) {
if (id == NotificationCenter.FileDidUpload) {
final String location = (String)args[0];
final TLRPC.InputFile file = (TLRPC.InputFile)args[1];
final TLRPC.InputEncryptedFile encryptedFile = (TLRPC.InputEncryptedFile)args[2];
final String location = (String) args[0];
final TLRPC.InputFile file = (TLRPC.InputFile) args[1];
if (uploadingAvatar != null && uploadingAvatar.equals(location)) {
TLRPC.TL_photos_uploadProfilePhoto req = new TLRPC.TL_photos_uploadProfilePhoto();
@ -327,16 +332,14 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
} else if (id == NotificationCenter.FileDidFailUpload) {
final String location = (String) args[0];
final boolean enc = (Boolean) args[1];
if (uploadingAvatar != null && uploadingAvatar.equals(location)) {
uploadingAvatar = null;
}
} else if (id == NotificationCenter.messageReceivedByServer) {
Integer msgId = (Integer)args[0];
Integer msgId = (Integer) args[0];
MessageObject obj = dialogMessage.get(msgId);
if (obj != null) {
Integer newMsgId = (Integer)args[1];
Integer newMsgId = (Integer) args[1];
dialogMessage.remove(msgId);
dialogMessage.put(newMsgId, obj);
obj.messageOwner.id = newMsgId;
@ -360,9 +363,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
}
} else {
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidLoaded);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidFailedLoad);
}
}
@ -431,7 +431,10 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
public TLRPC.User getUser(String username) {
return usersByUsernames.get(username);
if (username == null || username.length() == 0) {
return null;
}
return usersByUsernames.get(username.toLowerCase());
}
public ConcurrentHashMap<Integer, TLRPC.User> getUsers() {
@ -458,8 +461,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter
FileLog.e("tmessages", e);
}
if (result.size() == 2) {
chat = (TLRPC.EncryptedChat)result.get(0);
TLRPC.User user = (TLRPC.User)result.get(1);
chat = (TLRPC.EncryptedChat) result.get(0);
TLRPC.User user = (TLRPC.User) result.get(1);
putEncryptedChat(chat, false);
putUser(user, true);
}
@ -471,10 +474,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
return exportedChats.get(chat_id);
}
public void putExportedInvite(int chat_id, TLRPC.TL_chatInviteExported invite) {
exportedChats.put(chat_id, invite);
}
public boolean putUser(TLRPC.User user, boolean fromCache) {
if (user == null) {
return false;
@ -485,7 +484,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
usersByUsernames.remove(oldUser.username);
}
if (user.username != null && user.username.length() > 0) {
usersByUsernames.put(user.username, user);
usersByUsernames.put(user.username.toLowerCase(), user);
}
if (!fromCache) {
users.put(user.id, user);
@ -637,7 +636,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
loadingFullUsers.remove((Integer) user.id);
loadedFullUsers.add(user.id);
String names = user.first_name + user.last_name + user.username;
TLRPC.TL_userFull userFull = (TLRPC.TL_userFull)response;
TLRPC.TL_userFull userFull = (TLRPC.TL_userFull) response;
ArrayList<TLRPC.User> users = new ArrayList<>();
users.add(userFull.user);
putUsers(users, false);
@ -651,7 +650,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
loadingFullUsers.remove((Integer)user.id);
loadingFullUsers.remove((Integer) user.id);
}
});
}
@ -710,7 +709,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
MessagesStorage.lastPtsValue = pts;
MessagesStorage.getInstance().saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue);
} else if (MessagesStorage.lastPtsValue != pts) {
if (gettingDifference || updatesStartWaitTimePts == 0 || updatesStartWaitTimePts != 0 && updatesStartWaitTimePts + 1500 > System.currentTimeMillis()) {
if (gettingDifference || updatesStartWaitTimePts == 0 || updatesStartWaitTimePts + 1500 > System.currentTimeMillis()) {
FileLog.e("tmessages", "ADD UPDATE TO QUEUE pts = " + pts + " pts_count = " + pts_count);
if (updatesStartWaitTimePts == 0) {
updatesStartWaitTimePts = System.currentTimeMillis();
@ -733,7 +732,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
MessagesStorage.getInstance().saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue);
} else if (MessagesStorage.lastSeqValue != seq) {
if (gettingDifference || updatesStartWaitTimeSeq == 0 || updatesStartWaitTimeSeq != 0 && updatesStartWaitTimeSeq + 1500 > System.currentTimeMillis()) {
if (gettingDifference || updatesStartWaitTimeSeq == 0 || updatesStartWaitTimeSeq + 1500 > System.currentTimeMillis()) {
FileLog.e("tmessages", "ADD UPDATE TO QUEUE seq = " + seq);
if (updatesStartWaitTimeSeq == 0) {
updatesStartWaitTimeSeq = System.currentTimeMillis();
@ -826,7 +825,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
};
int currentServerTime = ConnectionsManager.getInstance().getCurrentTime();
Utilities.stageQueue.postRunnable(currentDeleteTaskRunnable, (long)Math.abs(currentServerTime - currentDeletingTaskTime) * 1000);
Utilities.stageQueue.postRunnable(currentDeleteTaskRunnable, (long) Math.abs(currentServerTime - currentDeletingTaskTime) * 1000);
}
} else {
currentDeletingTaskTime = 0;
@ -847,14 +846,14 @@ public class MessagesController implements NotificationCenter.NotificationCenter
TLRPC.TL_photos_getUserPhotos req = new TLRPC.TL_photos_getUserPhotos();
req.limit = count;
req.offset = offset;
req.max_id = (int)max_id;
req.max_id = (int) max_id;
req.user_id = getInputUser(user);
long reqId = ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() {
@Override
public void run(TLObject response, TLRPC.TL_error error) {
if (error == null) {
TLRPC.photos_Photos res = (TLRPC.photos_Photos) response;
processLoadedUserPhotos(res, uid, offset, count, max_id, fromCache, classGuid);
processLoadedUserPhotos(res, uid, offset, count, max_id, false, classGuid);
}
}
});
@ -917,7 +916,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
ArrayList<Integer> blocked = new ArrayList<>();
ArrayList<TLRPC.User> users = null;
if (error == null) {
final TLRPC.contacts_Blocked res = (TLRPC.contacts_Blocked)response;
final TLRPC.contacts_Blocked res = (TLRPC.contacts_Blocked) response;
for (TLRPC.TL_contactBlocked contactBlocked : res.blocked) {
blocked.add(contactBlocked.user_id);
}
@ -965,9 +964,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
if (user == null) {
return;
}
if (user != null) {
user.photo = UserConfig.getCurrentUser().photo;
}
user.photo = UserConfig.getCurrentUser().photo;
NotificationCenter.getInstance().postNotificationName(NotificationCenter.mainUserInfoChanged);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.updateInterfaces, MessagesController.UPDATE_MASK_ALL);
ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() {
@ -1077,8 +1074,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
public void deleteDialog(final long did, int offset, final boolean onlyHistory) {
int lower_part = (int)did;
int high_id = (int)(did >> 32);
int lower_part = (int) did;
int high_id = (int) (did >> 32);
if (offset == 0) {
TLRPC.TL_dialog dialog = dialogs_dict.get(did);
@ -1414,8 +1411,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter
typings = new HashMap<>();
sendingTypings.put(action, typings);
}
int lower_part = (int)dialog_id;
int high_id = (int)(dialog_id >> 32);
int lower_part = (int) dialog_id;
int high_id = (int) (dialog_id >> 32);
if (lower_part != 0) {
if (high_id == 1) {
return;
@ -1505,7 +1502,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
public void loadMessages(final long dialog_id, final int count, final int max_id, boolean fromCache, int midDate, final int classGuid, final int load_type, final int last_message_id, final int first_message_id, final boolean allowCache) {
int lower_part = (int)dialog_id;
int lower_part = (int) dialog_id;
if (fromCache || lower_part == 0) {
MessagesStorage.getInstance().getMessages(dialog_id, count, max_id, midDate, classGuid, load_type);
} else {
@ -1515,6 +1512,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter
req.peer.chat_id = -lower_part;
} else {
TLRPC.User user = getUser(lower_part);
if (user == null) {
return;
}
if (user instanceof TLRPC.TL_userForeign || user instanceof TLRPC.TL_userRequest) {
req.peer = new TLRPC.TL_inputPeerForeign();
req.peer.user_id = user.id;
@ -1785,7 +1785,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
putUsers(dialogsRes.users, isCache);
putUsers(dialogsRes.users, true);
loadingDialogs = false;
if (resetEnd) {
dialogsEndReached = false;
@ -1936,8 +1936,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter
if (random_id == 0 || dialog_id == 0 || ttl <= 0) {
return;
}
int lower_part = (int)dialog_id;
int high_id = (int)(dialog_id >> 32);
int lower_part = (int) dialog_id;
int high_id = (int) (dialog_id >> 32);
if (lower_part != 0) {
return;
}
@ -1953,8 +1953,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
public void markDialogAsRead(final long dialog_id, final int max_id, final int max_positive_id, final int offset, final int max_date, final boolean was, final boolean popup) {
int lower_part = (int)dialog_id;
int high_id = (int)(dialog_id >> 32);
int lower_part = (int) dialog_id;
int high_id = (int) (dialog_id >> 32);
if (lower_part != 0) {
if (max_positive_id == 0 && offset == 0 || high_id == 1) {
@ -2079,7 +2079,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
chat.title = title;
chat.photo = new TLRPC.TL_chatPhotoEmpty();
chat.participants_count = selectedContacts.size();
chat.date = (int)(System.currentTimeMillis() / 1000);
chat.date = (int) (System.currentTimeMillis() / 1000);
chat.left = false;
chat.version = 1;
UserConfig.lastBroadcastId--;
@ -2096,7 +2096,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
TLRPC.TL_chatParticipant participant = new TLRPC.TL_chatParticipant();
participant.user_id = id;
participant.inviter_id = UserConfig.getClientUserId();
participant.date = (int)(System.currentTimeMillis() / 1000);
participant.date = (int) (System.currentTimeMillis() / 1000);
participants.participants.add(participant);
}
MessagesStorage.getInstance().updateChatInfo(chat.id, participants, false);
@ -2246,20 +2246,18 @@ public class MessagesController implements NotificationCenter.NotificationCenter
MessagesStorage.getInstance().putUsersAndChats(null, chatArrayList, true, true);
boolean changed = false;
if (info != null) {
for (int a = 0; a < info.participants.size(); a++) {
TLRPC.TL_chatParticipant p = info.participants.get(a);
if (p.user_id == user.id) {
info.participants.remove(a);
changed = true;
break;
}
}
if (changed) {
MessagesStorage.getInstance().updateChatInfo(info.chat_id, info, true);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatInfoDidLoaded, info.chat_id, info);
for (int a = 0; a < info.participants.size(); a++) {
TLRPC.TL_chatParticipant p = info.participants.get(a);
if (p.user_id == user.id) {
info.participants.remove(a);
changed = true;
break;
}
}
if (changed) {
MessagesStorage.getInstance().updateChatInfo(info.chat_id, info, true);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.chatInfoDidLoaded, info.chat_id, info);
}
NotificationCenter.getInstance().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_CHAT_MEMBERS);
}
}
@ -2325,14 +2323,27 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
}
public void logOut() {
TLRPC.TL_auth_logOut req = new TLRPC.TL_auth_logOut();
ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() {
@Override
public void run(TLObject response, TLRPC.TL_error error) {
ConnectionsManager.getInstance().cleanUp();
}
});
public void performLogout(boolean byUser) {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.clear().commit();
if (byUser) {
unregistedPush();
TLRPC.TL_auth_logOut req = new TLRPC.TL_auth_logOut();
ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() {
@Override
public void run(TLObject response, TLRPC.TL_error error) {
ConnectionsManager.getInstance().cleanUp();
}
});
} else {
ConnectionsManager.getInstance().cleanUp();
}
UserConfig.clearConfig();
NotificationCenter.getInstance().postNotificationName(NotificationCenter.appDidLogout);
MessagesStorage.getInstance().cleanUp(false);
cleanUp();
ContactsController.getInstance().deleteAllAppAccounts();
}
public void generateUpdateMessage() {
@ -2343,6 +2354,9 @@ public class MessagesController implements NotificationCenter.NotificationCenter
String build = LocaleController.getString("updateBuild", R.string.updateBuild);
if (build != null) {
int version = Utilities.parseInt(build);
if (version == 0) {
version = 524;
}
if (version <= UserConfig.lastUpdateVersion) {
return;
}
@ -2378,20 +2392,13 @@ public class MessagesController implements NotificationCenter.NotificationCenter
req.app_sandbox = false;
try {
req.lang_code = LocaleController.getLocaleString(LocaleController.getInstance().getSystemDefaultLocale());
if (req.lang_code == null || req.lang_code.length() == 0) {
if (req.lang_code.length() == 0) {
req.lang_code = "en";
}
req.device_model = Build.MANUFACTURER + Build.MODEL;
if (req.device_model == null) {
req.device_model = "Android unknown";
}
req.system_version = "SDK " + Build.VERSION.SDK_INT;
PackageInfo pInfo = ApplicationLoader.applicationContext.getPackageManager().getPackageInfo(ApplicationLoader.applicationContext.getPackageName(), 0);
req.app_version = pInfo.versionName + " (" + pInfo.versionCode + ")";
if (req.app_version == null) {
req.app_version = "App version unknown";
}
} catch (Exception e) {
FileLog.e("tmessages", e);
req.lang_code = "en";
@ -2505,15 +2512,15 @@ public class MessagesController implements NotificationCenter.NotificationCenter
} else if (type == 1) {
if (updates.pts <= MessagesStorage.lastPtsValue) {
return 2;
} else if (MessagesStorage.lastPtsValue + updates.pts_count == updates.pts) {
} else if (MessagesStorage.lastPtsValue + updates.pts_count == updates.pts) {
return 0;
} else {
return 1;
}
} else if (type == 2) {
if (updates.qts <= MessagesStorage.lastQtsValue) {
if (updates.pts <= MessagesStorage.lastQtsValue) {
return 2;
} else if (MessagesStorage.lastQtsValue + updates.updates.size() == updates.qts) {
} else if (MessagesStorage.lastQtsValue + updates.updates.size() == updates.pts) {
return 0;
} else {
return 1;
@ -2545,11 +2552,11 @@ public class MessagesController implements NotificationCenter.NotificationCenter
Collections.sort(updatesQueue, new Comparator<TLRPC.Updates>() {
@Override
public int compare(TLRPC.Updates updates, TLRPC.Updates updates2) {
return AndroidUtilities.compare(updates.qts, updates2.qts);
return AndroidUtilities.compare(updates.pts, updates2.pts);
}
});
}
if (!updatesQueue.isEmpty()) {
if (updatesQueue != null && !updatesQueue.isEmpty()) {
boolean anyProceed = false;
if (state == 2) {
TLRPC.Updates updates = updatesQueue.get(0);
@ -2557,8 +2564,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter
MessagesStorage.lastSeqValue = getUpdateSeq(updates);
} else if (type == 1) {
MessagesStorage.lastPtsValue = updates.pts;
} else if (type == 2) {
MessagesStorage.lastQtsValue = updates.qts;
} else {
MessagesStorage.lastQtsValue = updates.pts;
}
}
for (int a = 0; a < updatesQueue.size(); a++) {
@ -2707,15 +2714,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
for (TLRPC.Message message : res.new_messages) {
MessageObject obj = new MessageObject(message, usersDict, true);
long dialog_id = obj.messageOwner.dialog_id;
if (dialog_id == 0) {
if (obj.messageOwner.to_id.chat_id != 0) {
dialog_id = -obj.messageOwner.to_id.chat_id;
} else {
dialog_id = obj.messageOwner.to_id.user_id;
}
}
if (!obj.isOut() && obj.isUnread()) {
pushMessages.add(obj);
}
@ -2773,7 +2771,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
SecretChatHelper.getInstance().processPendingEncMessages();
}
if (res != null && !res.other_updates.isEmpty()) {
if (!res.other_updates.isEmpty()) {
processUpdateArray(res.other_updates, res.users, res.chats);
}
@ -2886,7 +2884,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
needFwdUser = true;
}
boolean missingData = false;
boolean missingData;
if (updates instanceof TLRPC.TL_updateShortMessage) {
missingData = user == null || needFwdUser && user2 == null;
} else {
@ -2985,7 +2983,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
MessagesStorage.getInstance().putMessages(arr, false, true, false, 0);
} else if (MessagesStorage.lastPtsValue != updates.pts) {
FileLog.e("tmessages", "need get diff short message, pts: " + MessagesStorage.lastPtsValue + " " + updates.pts + " count = " + updates.pts_count);
if (gettingDifference || updatesStartWaitTimePts == 0 || updatesStartWaitTimePts != 0 && updatesStartWaitTimePts + 1500 > System.currentTimeMillis()) {
if (gettingDifference || updatesStartWaitTimePts == 0 || updatesStartWaitTimePts + 1500 > System.currentTimeMillis()) {
if (updatesStartWaitTimePts == 0) {
updatesStartWaitTimePts = System.currentTimeMillis();
}
@ -3054,24 +3052,24 @@ public class MessagesController implements NotificationCenter.NotificationCenter
} else if (getUpdateType(update) == 1) {
TLRPC.TL_updates updatesNew = new TLRPC.TL_updates();
updatesNew.updates.add(update);
updatesNew.qts = update.qts;
updatesNew.pts = update.qts;
for (int b = a + 1; b < updates.updates.size(); b++) {
TLRPC.Update update2 = updates.updates.get(b);
if (getUpdateType(update2) == 1 && updatesNew.qts + 1 == update2.qts) {
if (getUpdateType(update2) == 1 && updatesNew.pts + 1 == update2.qts) {
updatesNew.updates.add(update2);
updatesNew.qts = update2.qts;
updatesNew.pts = update2.qts;
updates.updates.remove(b);
b--;
} else {
break;
}
}
if (MessagesStorage.lastQtsValue == 0 || MessagesStorage.lastQtsValue + updatesNew.updates.size() == updatesNew.qts) {
if (MessagesStorage.lastQtsValue == 0 || MessagesStorage.lastQtsValue + updatesNew.updates.size() == updatesNew.pts) {
processUpdateArray(updatesNew.updates, updates.users, updates.chats);
MessagesStorage.lastQtsValue = updatesNew.qts;
MessagesStorage.lastQtsValue = updatesNew.pts;
needReceivedQueue = true;
} else if (MessagesStorage.lastPtsValue != updatesNew.qts) {
FileLog.e("tmessages", update + " need get diff, qts: " + MessagesStorage.lastQtsValue + " " + updatesNew.qts);
} else if (MessagesStorage.lastPtsValue != updatesNew.pts) {
FileLog.e("tmessages", update + " need get diff, qts: " + MessagesStorage.lastQtsValue + " " + updatesNew.pts);
if (gettingDifference || updatesStartWaitTimeQts == 0 || updatesStartWaitTimeQts != 0 && updatesStartWaitTimeQts + 1500 > System.currentTimeMillis()) {
if (updatesStartWaitTimeQts == 0) {
updatesStartWaitTimeQts = System.currentTimeMillis();
@ -3089,7 +3087,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
a--;
}
boolean processUpdate = false;
boolean processUpdate;
if (updates instanceof TLRPC.TL_updatesCombined) {
processUpdate = MessagesStorage.lastSeqValue + 1 == updates.seq_start || MessagesStorage.lastSeqValue == updates.seq_start;
} else {
@ -3110,7 +3108,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
FileLog.e("tmessages", "need get diff TL_updates, seq: " + MessagesStorage.lastSeqValue + " " + updates.seq);
}
if (gettingDifference || updatesStartWaitTimeSeq == 0 || updatesStartWaitTimeSeq != 0 && updatesStartWaitTimeSeq + 1500 > System.currentTimeMillis()) {
if (gettingDifference || updatesStartWaitTimeSeq == 0 || updatesStartWaitTimeSeq + 1500 > System.currentTimeMillis()) {
if (updatesStartWaitTimeSeq == 0) {
updatesStartWaitTimeSeq = System.currentTimeMillis();
}
@ -3142,7 +3140,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
} else if (a == 2) {
updatesQueue = updatesQueueQts;
}
if (!updatesQueue.isEmpty()) {
if (updatesQueue != null && !updatesQueue.isEmpty()) {
processUpdatesQueue(a, 0);
}
}
@ -3226,7 +3224,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
for (TLRPC.Update update : updates) {
if (update instanceof TLRPC.TL_updateNewMessage) {
TLRPC.TL_updateNewMessage upd = (TLRPC.TL_updateNewMessage)update;
TLRPC.TL_updateNewMessage upd = (TLRPC.TL_updateNewMessage) update;
if (checkForUsers) {
TLRPC.User user = getUser(upd.message.from_id);
if (usersDict.get(upd.message.from_id) == null && user == null || upd.message.to_id.chat_id != 0 && chatsDict.get(upd.message.to_id.chat_id) == null && getChat(upd.message.to_id.chat_id) == null) {
@ -3419,7 +3417,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
} else if (update instanceof TLRPC.TL_updateNewEncryptedMessage) {
ArrayList<TLRPC.Message> decryptedMessages = SecretChatHelper.getInstance().decryptMessage(((TLRPC.TL_updateNewEncryptedMessage) update).message);
if (decryptedMessages != null && !decryptedMessages.isEmpty()) {
int cid = ((TLRPC.TL_updateNewEncryptedMessage)update).message.chat_id;
int cid = ((TLRPC.TL_updateNewEncryptedMessage) update).message.chat_id;
long uid = ((long) cid) << 32;
ArrayList<MessageObject> arr = messages.get(uid);
if (arr == null) {
@ -3475,7 +3473,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
} else if (update instanceof TLRPC.TL_updateEncryption) {
SecretChatHelper.getInstance().processUpdateEncryption((TLRPC.TL_updateEncryption) update, usersDict);
} else if (update instanceof TLRPC.TL_updateUserBlocked) {
final TLRPC.TL_updateUserBlocked finalUpdate = (TLRPC.TL_updateUserBlocked)update;
final TLRPC.TL_updateUserBlocked finalUpdate = (TLRPC.TL_updateUserBlocked) update;
if (finalUpdate.blocked) {
ArrayList<Integer> ids = new ArrayList<>();
ids.add(finalUpdate.user_id);
@ -3514,7 +3512,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
newMessage.to_id.user_id = UserConfig.getClientUserId();
newMessage.dialog_id = 777000;
newMessage.media = update.media;
newMessage.message = ((TLRPC.TL_updateServiceNotification)update).message;
newMessage.message = ((TLRPC.TL_updateServiceNotification) update).message;
messagesArr.add(newMessage);
MessageObject obj = new MessageObject(newMessage, usersDict, true);
@ -3575,7 +3573,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
public void run() {
int updateMask = interfaceUpdateMaskFinal;
boolean avatarsUpdate = false;
if (!updatesOnMainThread.isEmpty()) {
ArrayList<TLRPC.User> dbUsers = new ArrayList<>();
ArrayList<TLRPC.User> dbUsersStatus = new ArrayList<>();
@ -3627,7 +3624,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
if (currentUser != null) {
currentUser.photo = update.photo;
}
avatarsUpdate = true;
toDbUser.photo = update.photo;
dbUsers.add(toDbUser);
} else if (update instanceof TLRPC.TL_updateUserPhone) {
@ -3643,14 +3639,15 @@ public class MessagesController implements NotificationCenter.NotificationCenter
toDbUser.phone = update.phone;
dbUsers.add(toDbUser);
} else if (update instanceof TLRPC.TL_updateNotifySettings) {
if (update.notify_settings instanceof TLRPC.TL_peerNotifySettings && update.peer instanceof TLRPC.TL_notifyPeer) {
TLRPC.TL_updateNotifySettings updateNotifySettings = (TLRPC.TL_updateNotifySettings) update;
if (update.notify_settings instanceof TLRPC.TL_peerNotifySettings && updateNotifySettings.peer instanceof TLRPC.TL_notifyPeer) {
if (editor == null) {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE);
editor = preferences.edit();
}
long dialog_id = update.peer.peer.user_id;
long dialog_id = updateNotifySettings.peer.peer.user_id;
if (dialog_id == 0) {
dialog_id = -update.peer.peer.chat_id;
dialog_id = -updateNotifySettings.peer.peer.chat_id;
}
TLRPC.TL_dialog dialog = dialogs_dict.get(dialog_id);
if (dialog != null) {
@ -3671,7 +3668,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
dialog.notify_settings.mute_until = until;
}
}
MessagesStorage.getInstance().setDialogFlags(dialog_id, ((long)until << 32) | 1);
MessagesStorage.getInstance().setDialogFlags(dialog_id, ((long) until << 32) | 1);
} else {
if (dialog != null) {
dialog.notify_settings.mute_until = 0;
@ -3888,19 +3885,25 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
protected void updateInterfaceWithMessages(final long uid, final ArrayList<MessageObject> messages, boolean isBroadcast) {
if (messages == null || messages.isEmpty()) {
return;
}
boolean isEncryptedChat = ((int) uid) == 0;
MessageObject lastMessage = null;
TLRPC.TL_dialog dialog = dialogs_dict.get(uid);
boolean isEncryptedChat = ((int)uid) == 0;
NotificationCenter.getInstance().postNotificationName(NotificationCenter.didReceivedNewMessages, uid, messages);
for (MessageObject message : messages) {
if (lastMessage == null || (!isEncryptedChat && message.getId() > lastMessage.getId() || (isEncryptedChat || message.getId() < 0 && lastMessage.getId() < 0) && message.getId() < lastMessage.getId()) || message.messageOwner.date > lastMessage.messageOwner.date) {
lastMessage = message;
}
}
TLRPC.TL_dialog dialog = dialogs_dict.get(uid);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.didReceivedNewMessages, uid, messages);
if (lastMessage == null) {
return;
}
boolean changed = false;
if (dialog == null) {
@ -3958,13 +3961,88 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
});
for (TLRPC.TL_dialog d : dialogs) {
int high_id = (int)(d.id >> 32);
if ((int)d.id != 0 && high_id != 1) {
int high_id = (int) (d.id >> 32);
if ((int) d.id != 0 && high_id != 1) {
dialogsServerOnly.add(d);
}
}
}
}
public static void openByUserName(String username, final BaseFragment fragment, final int type) {
if (username == null || fragment == null) {
return;
}
TLRPC.User user = MessagesController.getInstance().getUser(username);
if (user != null) {
Bundle args = new Bundle();
args.putInt("user_id", user.id);
if (type == 0) {
fragment.presentFragment(new ProfileActivity(args));
} else {
fragment.presentFragment(new ChatActivity(args));
}
} else {
if (fragment.getParentActivity() == null) {
return;
}
final ProgressDialog progressDialog = new ProgressDialog(fragment.getParentActivity());
progressDialog.setMessage(LocaleController.getString("Loading", R.string.Loading));
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setCancelable(false);
TLRPC.TL_contacts_resolveUsername req = new TLRPC.TL_contacts_resolveUsername();
req.username = username;
final long 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() {
try {
progressDialog.dismiss();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
if (fragment != null) {
fragment.setVisibleDialog(null);
}
if (error == null) {
TLRPC.User user = (TLRPC.User) response;
MessagesController.getInstance().putUser(user, false);
ArrayList<TLRPC.User> users = new ArrayList<>();
users.add(user);
MessagesStorage.getInstance().putUsersAndChats(users, null, false, true);
Bundle args = new Bundle();
args.putInt("user_id", user.id);
if (fragment != null) {
if (type == 0) {
fragment.presentFragment(new ProfileActivity(args));
} else if (type == 1) {
fragment.presentFragment(new ChatActivity(args));
}
}
}
}
});
}
});
progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, LocaleController.getString("Cancel", R.string.Cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ConnectionsManager.getInstance().cancelRpc(reqId, true);
try {
dialog.dismiss();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
if (fragment != null) {
fragment.setVisibleDialog(null);
}
}
});
fragment.setVisibleDialog(progressDialog);
progressDialog.show();
}
}
}

View File

@ -282,7 +282,7 @@ public class MessagesStorage {
database.executeFast("PRAGMA user_version = 4").stepThis().dispose();
version = 4;
}
if (version == 4 && version < 6) {
if (version == 4) {
database.executeFast("CREATE TABLE IF NOT EXISTS enc_tasks_v2(mid INTEGER PRIMARY KEY, date INTEGER)").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS date_idx_enc_tasks_v2 ON enc_tasks_v2(date);").stepThis().dispose();
database.beginTransaction();
@ -290,7 +290,7 @@ public class MessagesStorage {
SQLitePreparedStatement state = database.executeFast("REPLACE INTO enc_tasks_v2 VALUES(?, ?)");
if (cursor.next()) {
int date = cursor.intValue(0);
int length = 0;
int length;
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(1));
if ((length = cursor.byteBufferValue(1, data.buffer)) != 0) {
for (int a = 0; a < length / 4; a++) {
@ -313,7 +313,7 @@ public class MessagesStorage {
database.executeFast("PRAGMA user_version = 6").stepThis().dispose();
version = 6;
}
if (version == 6 && version < 7) {
if (version == 6) {
database.executeFast("CREATE TABLE IF NOT EXISTS messages_seq(mid INTEGER PRIMARY KEY, seq_in INTEGER, seq_out INTEGER);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS seq_idx_messages_seq ON messages_seq(seq_in, seq_out);").stepThis().dispose();
database.executeFast("ALTER TABLE enc_chats ADD COLUMN layer INTEGER default 0").stepThis().dispose();
@ -333,7 +333,7 @@ public class MessagesStorage {
database.executeFast("PRAGMA user_version = 9").stepThis().dispose();
version = 9;
}*/
if ((version == 7 || version == 8 || version == 9) && version < 10) {
if (version == 7 || version == 8 || version == 9) {
database.executeFast("ALTER TABLE enc_chats ADD COLUMN use_count INTEGER default 0").stepThis().dispose();
database.executeFast("ALTER TABLE enc_chats ADD COLUMN exchange_id INTEGER default 0").stepThis().dispose();
database.executeFast("ALTER TABLE enc_chats ADD COLUMN key_date INTEGER default 0").stepThis().dispose();
@ -343,17 +343,17 @@ public class MessagesStorage {
database.executeFast("PRAGMA user_version = 10").stepThis().dispose();
version = 10;
}
if (version == 10 && version < 11) {
if (version == 10) {
database.executeFast("CREATE TABLE IF NOT EXISTS web_recent_v3(id TEXT, type INTEGER, image_url TEXT, thumb_url TEXT, local_url TEXT, width INTEGER, height INTEGER, size INTEGER, date INTEGER, PRIMARY KEY (id, type));").stepThis().dispose();
database.executeFast("PRAGMA user_version = 11").stepThis().dispose();
version = 11;
}
if (version == 11 && version < 12) {
if (version == 11) {
database.executeFast("CREATE TABLE IF NOT EXISTS stickers(id INTEGER PRIMARY KEY, data BLOB, date INTEGER);").stepThis().dispose();
database.executeFast("PRAGMA user_version = 12").stepThis().dispose();
version = 12;
}
if (version == 12 && version < 13) {
if (version == 12) {
database.executeFast("DROP INDEX IF EXISTS uid_mid_idx_media;").stepThis().dispose();
database.executeFast("DROP INDEX IF EXISTS mid_idx_media;").stepThis().dispose();
database.executeFast("DROP INDEX IF EXISTS uid_date_mid_idx_media;").stepThis().dispose();
@ -370,26 +370,26 @@ public class MessagesStorage {
database.executeFast("PRAGMA user_version = 13").stepThis().dispose();
version = 13;
}
if (version == 13 && version < 14) {
if (version == 13) {
database.executeFast("ALTER TABLE messages ADD COLUMN replydata BLOB default NULL").stepThis().dispose();
database.executeFast("PRAGMA user_version = 14").stepThis().dispose();
version = 14;
}
if (version == 14 && version < 15) {
if (version == 14) {
database.executeFast("CREATE TABLE IF NOT EXISTS hashtag_recent_v2(id TEXT PRIMARY KEY, date INTEGER);").stepThis().dispose();
database.executeFast("PRAGMA user_version = 15").stepThis().dispose();
version = 15;
}
if (version == 15 && version < 16) {
if (version == 15) {
database.executeFast("CREATE TABLE IF NOT EXISTS webpage_pending(id INTEGER, mid INTEGER, PRIMARY KEY (id, mid));").stepThis().dispose();
database.executeFast("PRAGMA user_version = 16").stepThis().dispose();
version = 16;
}
if (version == 16 && version < 17) {
if (version == 16) {
database.executeFast("ALTER TABLE dialogs ADD COLUMN inbox_max INTEGER default 0").stepThis().dispose();
database.executeFast("ALTER TABLE dialogs ADD COLUMN outbox_max INTEGER default 0").stepThis().dispose();
database.executeFast("PRAGMA user_version = 17").stepThis().dispose();
version = 17;
//version = 17;
}
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -764,7 +764,7 @@ public class MessagesStorage {
public void run() {
try {
SQLiteCursor cursor = database.queryFinalized("SELECT data FROM wallpapers WHERE 1");
ArrayList<TLRPC.WallPaper> wallPapers = new ArrayList<>();
final ArrayList<TLRPC.WallPaper> wallPapers = new ArrayList<>();
while (cursor.next()) {
ByteBufferDesc data = buffersStorage.getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
@ -774,7 +774,12 @@ public class MessagesStorage {
buffersStorage.reuseFreeBuffer(data);
}
cursor.dispose();
NotificationCenter.getInstance().postNotificationName(NotificationCenter.wallpapersDidLoaded, wallPapers);
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.wallpapersDidLoaded, wallPapers);
}
});
} catch (Exception e) {
FileLog.e("tmessages", e);
}
@ -1069,7 +1074,7 @@ public class MessagesStorage {
int minDate = Integer.MAX_VALUE;
SparseArray<ArrayList<Integer>> messages = new SparseArray<>();
StringBuilder mids = new StringBuilder();
SQLiteCursor cursor = null;
SQLiteCursor cursor;
if (random_ids == null) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT mid, ttl FROM messages WHERE uid = %d AND out = %d AND read_state != 0 AND ttl > 0 AND date <= %d AND send_state = 0 AND media != 1", ((long) chat_id) << 32, isOut, time));
} else {
@ -1763,7 +1768,7 @@ public class MessagesStorage {
ArrayList<Integer> replyMessages = new ArrayList<>();
HashMap<Integer, ArrayList<TLRPC.Message>> replyMessageOwners = new HashMap<>();
SQLiteCursor cursor = null;
SQLiteCursor cursor;
int lower_id = (int)dialog_id;
if (lower_id != 0) {
@ -3241,7 +3246,6 @@ public class MessagesStorage {
} finally {
if (state != null) {
state.dispose();
state = null;
}
}
@ -3351,12 +3355,12 @@ public class MessagesStorage {
try {
if (inbox != null) {
for (HashMap.Entry<Integer, Integer> entry : inbox.entrySet()) {
database.executeFast(String.format(Locale.US, "UPDATE messages SET read_state = read_state | 1 WHERE uid = %d AND mid <= %d AND read_state IN(0,2) AND out = 0", entry.getKey(), entry.getValue())).stepThis().dispose();
database.executeFast(String.format(Locale.US, "UPDATE messages SET read_state = read_state | 1 WHERE uid = %d AND mid > 0 AND mid <= %d AND read_state IN(0,2) AND out = 0", entry.getKey(), entry.getValue())).stepThis().dispose();
}
}
if (outbox != null) {
for (HashMap.Entry<Integer, Integer> entry : outbox.entrySet()) {
database.executeFast(String.format(Locale.US, "UPDATE messages SET read_state = read_state | 1 WHERE uid = %d AND mid <= %d AND read_state IN(0,2) AND out = 1", entry.getKey(), entry.getValue())).stepThis().dispose();
database.executeFast(String.format(Locale.US, "UPDATE messages SET read_state = read_state | 1 WHERE uid = %d AND mid > 0 AND mid <= %d AND read_state IN(0,2) AND out = 1", entry.getKey(), entry.getValue())).stepThis().dispose();
}
}
if (encryptedMessages != null && !encryptedMessages.isEmpty()) {

View File

@ -8,6 +8,10 @@
package org.telegram.android;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.FileLog;
import java.util.ArrayList;
import java.util.HashMap;
@ -51,7 +55,6 @@ public class NotificationCenter {
public static final int didSetPasscode = totalEvents++;
public static final int didSetTwoStepPassword = totalEvents++;
public static final int screenStateChanged = totalEvents++;
public static final int appSwitchedToForeground = totalEvents++;
public static final int didLoadedReplyMessages = totalEvents++;
public static final int newSessionReceived = totalEvents++;
public static final int didReceivedWebpages = totalEvents++;
@ -94,14 +97,31 @@ public class NotificationCenter {
public static final int audioDidStarted = totalEvents++;
public static final int audioRouteChanged = totalEvents++;
final private HashMap<Integer, ArrayList<Object>> observers = new HashMap<>();
final private HashMap<Integer, Object> removeAfterBroadcast = new HashMap<>();
final private HashMap<Integer, Object> addAfterBroadcast = new HashMap<>();
private HashMap<Integer, ArrayList<Object>> observers = new HashMap<>();
private HashMap<Integer, Object> removeAfterBroadcast = new HashMap<>();
private HashMap<Integer, Object> addAfterBroadcast = new HashMap<>();
private ArrayList<DelayedPost> delayedPosts = new ArrayList<>(10);
private int broadcasting = 0;
private boolean animationInProgress;
public interface NotificationCenterDelegate {
void didReceivedNotification(int id, Object... args);
}
private class DelayedPost {
private DelayedPost(int id, Object[] args) {
this.id = id;
this.args = args;
}
private int id;
private Object[] args;
}
private static volatile NotificationCenter Instance = null;
public static NotificationCenter getInstance() {
NotificationCenter localInstance = Instance;
if (localInstance == null) {
@ -115,66 +135,97 @@ public class NotificationCenter {
return localInstance;
}
public interface NotificationCenterDelegate {
void didReceivedNotification(int id, Object... args);
public void setAnimationInProgress(boolean value) {
animationInProgress = value;
if (!animationInProgress && !delayedPosts.isEmpty()) {
for (DelayedPost delayedPost : delayedPosts) {
postNotificationNameInternal(delayedPost.id, true, delayedPost.args);
}
delayedPosts.clear();
}
}
public void postNotificationName(int id, Object... args) {
synchronized (observers) {
broadcasting++;
ArrayList<Object> objects = observers.get(id);
if (objects != null) {
for (Object obj : objects) {
((NotificationCenterDelegate)obj).didReceivedNotification(id, args);
}
boolean allowDuringAnimation = false;
if (id == dialogsNeedReload || id == closeChats || id == messagesDidLoaded || id == mediaCountDidLoaded || id == mediaDidLoaded) {
allowDuringAnimation = true;
}
postNotificationNameInternal(id, allowDuringAnimation, args);
}
public void postNotificationNameInternal(int id, boolean allowDuringAnimation, Object... args) {
if (BuildVars.DEBUG_VERSION) {
if (Thread.currentThread() != ApplicationLoader.applicationHandler.getLooper().getThread()) {
throw new RuntimeException("postNotificationName allowed only from MAIN thread");
}
broadcasting--;
if (broadcasting == 0) {
if (!removeAfterBroadcast.isEmpty()) {
for (HashMap.Entry<Integer, Object> entry : removeAfterBroadcast.entrySet()) {
removeObserver(entry.getValue(), entry.getKey());
}
removeAfterBroadcast.clear();
}
if (!allowDuringAnimation && animationInProgress) {
DelayedPost delayedPost = new DelayedPost(id, args);
delayedPosts.add(delayedPost);
if (BuildVars.DEBUG_VERSION) {
FileLog.e("tmessages", "delay post notification " + id + " with args count = " + args.length);
}
return;
}
broadcasting++;
ArrayList<Object> objects = observers.get(id);
if (objects != null) {
for (Object obj : objects) {
((NotificationCenterDelegate) obj).didReceivedNotification(id, args);
}
}
broadcasting--;
if (broadcasting == 0) {
if (!removeAfterBroadcast.isEmpty()) {
for (HashMap.Entry<Integer, Object> entry : removeAfterBroadcast.entrySet()) {
removeObserver(entry.getValue(), entry.getKey());
}
if (!addAfterBroadcast.isEmpty()) {
for (HashMap.Entry<Integer, Object> entry : addAfterBroadcast.entrySet()) {
addObserver(entry.getValue(), entry.getKey());
}
addAfterBroadcast.clear();
removeAfterBroadcast.clear();
}
if (!addAfterBroadcast.isEmpty()) {
for (HashMap.Entry<Integer, Object> entry : addAfterBroadcast.entrySet()) {
addObserver(entry.getValue(), entry.getKey());
}
addAfterBroadcast.clear();
}
}
}
public void addObserver(Object observer, int id) {
synchronized (observers) {
if (broadcasting != 0) {
addAfterBroadcast.put(id, observer);
return;
if (BuildVars.DEBUG_VERSION) {
if (Thread.currentThread() != ApplicationLoader.applicationHandler.getLooper().getThread()) {
throw new RuntimeException("addObserver allowed only from MAIN thread");
}
ArrayList<Object> objects = observers.get(id);
if (objects == null) {
observers.put(id, (objects = new ArrayList<>()));
}
if (objects.contains(observer)) {
return;
}
objects.add(observer);
}
if (broadcasting != 0) {
addAfterBroadcast.put(id, observer);
return;
}
ArrayList<Object> objects = observers.get(id);
if (objects == null) {
observers.put(id, (objects = new ArrayList<>()));
}
if (objects.contains(observer)) {
return;
}
objects.add(observer);
}
public void removeObserver(Object observer, int id) {
synchronized (observers) {
if (broadcasting != 0) {
removeAfterBroadcast.put(id, observer);
return;
if (BuildVars.DEBUG_VERSION) {
if (Thread.currentThread() != ApplicationLoader.applicationHandler.getLooper().getThread()) {
throw new RuntimeException("removeObserver allowed only from MAIN thread");
}
ArrayList<Object> objects = observers.get(id);
if (objects != null) {
objects.remove(observer);
if (objects.size() == 0) {
observers.remove(id);
}
}
if (broadcasting != 0) {
removeAfterBroadcast.put(id, observer);
return;
}
ArrayList<Object> objects = observers.get(id);
if (objects != null) {
objects.remove(observer);
if (objects.size() == 0) {
observers.remove(id);
}
}
}

View File

@ -8,6 +8,7 @@
package org.telegram.android;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
@ -59,9 +60,11 @@ public class NotificationsController {
private HashMap<Long, Point> smartNotificationsDialogs = new HashMap<>();
private NotificationManagerCompat notificationManager = null;
private HashMap<Long, Integer> pushDialogs = new HashMap<>();
private HashMap<Long, Integer> wearNoticationsIds = new HashMap<>();
private HashMap<Long, Integer> wearNotificationsIds = new HashMap<>();
private HashMap<Long, Integer> autoNotificationsIds = new HashMap<>();
private HashMap<Long, Integer> pushDialogsOverrideMention = new HashMap<>();
private int wearNotificationId = 10000;
private int autoNotificationId = 20000;
public ArrayList<MessageObject> popupMessages = new ArrayList<>();
private long openned_dialog_id = 0;
private int total_unread_count = 0;
@ -70,10 +73,10 @@ public class NotificationsController {
private int lastOnlineFromOtherDevice = 0;
private boolean inChatSoundEnabled = true;
private int lastBadgeCount;
private String launcherClassName;
private long lastSoundPlay;
//private MediaPlayer mediaPlayerIn;
//private MediaPlayer mediaPlayerOut;
private long lastSoundOutPlay;
private SoundPool soundPool;
private int soundIn;
private int soundOut;
@ -100,7 +103,6 @@ public class NotificationsController {
try {
audioManager = (AudioManager) ApplicationLoader.applicationContext.getSystemService(Context.AUDIO_SERVICE);
//mediaPlayer = new MediaPlayer();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
@ -114,7 +116,8 @@ public class NotificationsController {
pushMessagesDict.clear();
pushDialogs.clear();
popupMessages.clear();
wearNoticationsIds.clear();
wearNotificationsIds.clear();
autoNotificationsIds.clear();
notifyCheck = false;
lastBadgeCount = 0;
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Context.MODE_PRIVATE);
@ -376,13 +379,13 @@ public class NotificationsController {
int needVibrate = 0;
String choosenSoundPath = null;
int ledColor = 0xff00ff00;
boolean inAppSounds = false;
boolean inAppVibrate = false;
boolean inAppSounds;
boolean inAppVibrate;
boolean inAppPreview = false;
boolean inAppPriority = false;
boolean inAppPriority;
int priority = 0;
int priorityOverride = 0;
int vibrateOverride = 0;
int priorityOverride;
int vibrateOverride;
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Context.MODE_PRIVATE);
int notifyOverride = getNotifyOverride(preferences, override_dialog_id);
@ -517,7 +520,7 @@ public class NotificationsController {
}
PendingIntent contentIntent = PendingIntent.getActivity(ApplicationLoader.applicationContext, 0, intent, PendingIntent.FLAG_ONE_SHOT);
String name = null;
String name;
boolean replace = true;
if ((int)dialog_id == 0 || pushDialogs.size() > 1 || AndroidUtilities.needShowPasscode(false) || UserConfig.isWaitingForPasscodeEnter) {
name = LocaleController.getString("AppName", R.string.AppName);
@ -530,7 +533,7 @@ public class NotificationsController {
}
}
String detailText = null;
String detailText;
if (pushDialogs.size() == 1) {
detailText = LocaleController.formatPluralString("NewMessages", total_unread_count);
} else {
@ -547,12 +550,16 @@ public class NotificationsController {
.setGroupSummary(true)
.setColor(0xff2ca5e0);
if (priority == 0) {
mBuilder.setPriority(NotificationCompat.PRIORITY_DEFAULT);
} else if (priority == 1) {
mBuilder.setPriority(NotificationCompat.PRIORITY_HIGH);
} else if (priority == 2) {
mBuilder.setPriority(NotificationCompat.PRIORITY_MAX);
if (!notifyAboutLast) {
mBuilder.setPriority(NotificationCompat.PRIORITY_LOW);
} else {
if (priority == 0) {
mBuilder.setPriority(NotificationCompat.PRIORITY_DEFAULT);
} else if (priority == 1) {
mBuilder.setPriority(NotificationCompat.PRIORITY_HIGH);
} else if (priority == 2) {
mBuilder.setPriority(NotificationCompat.PRIORITY_MAX);
}
}
mBuilder.setCategory(NotificationCompat.CATEGORY_MESSAGE);
@ -649,18 +656,20 @@ public class NotificationsController {
mBuilder.setVibrate(new long[]{0, 0});
}
showExtraNotifications(mBuilder, notifyAboutLast);
notificationManager.notify(1, mBuilder.build());
if (preferences.getBoolean("EnablePebbleNotifications", false)) {
sendAlertToPebble(lastMessageFull);
}
showWearNotifications(notifyAboutLast);
scheduleNotificationRepeat();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
public void showWearNotifications(boolean notifyAboutLast) {
@SuppressLint("InlinedApi")
public void showExtraNotifications(NotificationCompat.Builder notificationBuilder, boolean notifyAboutLast) {
if (Build.VERSION.SDK_INT < 19) {
return;
}
@ -681,16 +690,21 @@ public class NotificationsController {
arrayList.add(messageObject);
}
HashMap<Long, Integer> oldIds = new HashMap<>();
oldIds.putAll(wearNoticationsIds);
wearNoticationsIds.clear();
HashMap<Long, Integer> oldIdsWear = new HashMap<>();
oldIdsWear.putAll(wearNotificationsIds);
wearNotificationsIds.clear();
HashMap<Long, Integer> oldIdsAuto = new HashMap<>();
oldIdsAuto.putAll(autoNotificationsIds);
autoNotificationsIds.clear();
for (long dialog_id : sortedDialogs) {
ArrayList<MessageObject> messageObjects = messagesByDialogs.get(dialog_id);
int max_id = messageObjects.get(0).getId();
int max_date = messageObjects.get(0).messageOwner.date;
TLRPC.Chat chat = null;
TLRPC.User user = null;
String name = null;
String name;
if (dialog_id > 0) {
user = MessagesController.getInstance().getUser((int)dialog_id);
if (user == null) {
@ -708,28 +722,56 @@ public class NotificationsController {
name = ContactsController.formatName(user.first_name, user.last_name);
}
Integer notificationId = oldIds.get(dialog_id);
if (notificationId == null) {
notificationId = wearNotificationId++;
Integer notificationIdWear = oldIdsWear.get(dialog_id);
if (notificationIdWear == null) {
notificationIdWear = wearNotificationId++;
} else {
oldIds.remove(dialog_id);
oldIdsWear.remove(dialog_id);
}
Integer notificationIdAuto = oldIdsAuto.get(dialog_id);
if (notificationIdAuto == null) {
notificationIdAuto = autoNotificationId++;
} else {
oldIdsAuto.remove(dialog_id);
}
Intent replyIntent = new Intent(ApplicationLoader.applicationContext, WearReplyReceiver.class);
replyIntent.putExtra("dialog_id", dialog_id);
replyIntent.putExtra("max_id", max_id);
PendingIntent replyPendingIntent = PendingIntent.getBroadcast(ApplicationLoader.applicationContext, notificationId, replyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY).setLabel(LocaleController.getString("Reply", R.string.Reply)).build();
PendingIntent replyPendingIntent = PendingIntent.getBroadcast(ApplicationLoader.applicationContext, notificationIdWear, replyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
RemoteInput remoteInputWear = new RemoteInput.Builder(EXTRA_VOICE_REPLY).setLabel(LocaleController.getString("Reply", R.string.Reply)).build();
String replyToString;
if (chat != null) {
replyToString = LocaleController.formatString("ReplyToGroup", R.string.ReplyToGroup, name);
} else {
replyToString = LocaleController.formatString("ReplyToUser", R.string.ReplyToUser, name);
}
NotificationCompat.Action action = new NotificationCompat.Action.Builder(R.drawable.ic_reply_icon, replyToString, replyPendingIntent).addRemoteInput(remoteInput).build();
NotificationCompat.Action action = new NotificationCompat.Action.Builder(R.drawable.ic_reply_icon, replyToString, replyPendingIntent).addRemoteInput(remoteInputWear).build();
Intent msgHeardIntent = new Intent();
msgHeardIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
msgHeardIntent.setAction("org.telegram.messenger.ACTION_MESSAGE_HEARD");
msgHeardIntent.putExtra("dialog_id", dialog_id);
msgHeardIntent.putExtra("max_id", max_id);
PendingIntent msgHeardPendingIntent = PendingIntent.getBroadcast(ApplicationLoader.applicationContext, notificationIdAuto, msgHeardIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Intent msgReplyIntent = new Intent();
msgReplyIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
msgReplyIntent.setAction("org.telegram.messenger.ACTION_MESSAGE_REPLY");
msgReplyIntent.putExtra("dialog_id", dialog_id);
msgReplyIntent.putExtra("max_id", max_id);
PendingIntent msgReplyPendingIntent = PendingIntent.getBroadcast(ApplicationLoader.applicationContext, notificationIdAuto, msgReplyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
RemoteInput remoteInputAuto = new RemoteInput.Builder(NotificationsController.EXTRA_VOICE_REPLY).setLabel(LocaleController.getString("Reply", R.string.Reply)).build();
NotificationCompat.CarExtender.UnreadConversation.Builder unreadConvBuilder = new NotificationCompat.CarExtender.UnreadConversation.Builder(name)
.setReadPendingIntent(msgHeardPendingIntent)
.setReplyAction(msgReplyPendingIntent, remoteInputAuto)
.setLatestTimestamp((long) max_date * 1000);
String text = "";
for (MessageObject messageObject : messageObjects) {
for (int a = messageObjects.size() - 1; a >= 0; a--) {
MessageObject messageObject = messageObjects.get(a);
String message = getStringForMessage(messageObject, false);
if (message == null) {
continue;
@ -743,8 +785,40 @@ public class NotificationsController {
text += "\n\n";
}
text += message;
unreadConvBuilder.addMessage(message);
}
TLRPC.FileLocation photoPath = null;
if (chat != null) {
if (chat.photo != null && chat.photo.photo_small != null && chat.photo.photo_small.volume_id != 0 && chat.photo.photo_small.local_id != 0) {
photoPath = chat.photo.photo_small;
}
} else {
if (user.photo != null && user.photo.photo_small != null && user.photo.photo_small.volume_id != 0 && user.photo.photo_small.local_id != 0) {
photoPath = user.photo.photo_small;
}
}
//notificationBuilder.extend(new NotificationCompat.CarExtender().setUnreadConversation(unreadConvBuilder.build()));
NotificationCompat.Builder builderAuto = new NotificationCompat.Builder(ApplicationLoader.applicationContext)
.setSmallIcon(R.drawable.notification)
.setColor(0xff2ca5e0)
.setGroup("messages")
.setLocalOnly(true)
//.setGroupSummary(false)
//.setCategory(NotificationCompat.CATEGORY_MESSAGE)
.extend(new NotificationCompat.CarExtender().setUnreadConversation(unreadConvBuilder.build()));
if (photoPath != null) {
BitmapDrawable img = ImageLoader.getInstance().getImageFromMemory(photoPath, null, "50_50");
if (img != null) {
builderAuto.setLargeIcon(img.getBitmap());
}
}
notificationManager.notify("android_auto", notificationIdAuto, builderAuto.build());
autoNotificationsIds.put(dialog_id, notificationIdAuto);
Intent intent = new Intent(ApplicationLoader.applicationContext, LaunchActivity.class);
intent.setAction("com.tmessages.openchat" + Math.random() + Integer.MAX_VALUE);
intent.setFlags(32768);
@ -760,20 +834,30 @@ public class NotificationsController {
.setSmallIcon(R.drawable.notification)
.setGroup("messages")
.setContentText(text)
.setColor(0xff2ca5e0)
.setGroupSummary(false)
.setContentIntent(contentIntent)
.extend(new NotificationCompat.WearableExtender().addAction(action))
.setCategory(NotificationCompat.CATEGORY_MESSAGE);
if (photoPath != null) {
BitmapDrawable img = ImageLoader.getInstance().getImageFromMemory(photoPath, null, "50_50");
if (img != null) {
builder.setLargeIcon(img.getBitmap());
}
}
if (chat == null && user != null && user.phone != null && user.phone.length() > 0) {
builder.addPerson("tel:+" + user.phone);
}
notificationManager.notify(notificationId, builder.build());
wearNoticationsIds.put(dialog_id, notificationId);
notificationManager.notify(notificationIdWear, builder.build());
wearNotificationsIds.put(dialog_id, notificationIdWear);
}
for (HashMap.Entry<Long, Integer> entry : oldIds.entrySet()) {
for (HashMap.Entry<Long, Integer> entry : oldIdsAuto.entrySet()) {
notificationManager.cancel(entry.getValue());
}
for (HashMap.Entry<Long, Integer> entry : oldIdsWear.entrySet()) {
notificationManager.cancel(entry.getValue());
}
}
@ -783,6 +867,14 @@ public class NotificationsController {
notificationManager.cancel(1);
pushMessages.clear();
pushMessagesDict.clear();
for (HashMap.Entry<Long, Integer> entry : autoNotificationsIds.entrySet()) {
notificationManager.cancel(entry.getValue());
}
autoNotificationsIds.clear();
for (HashMap.Entry<Long, Integer> entry : wearNotificationsIds.entrySet()) {
notificationManager.cancel(entry.getValue());
}
wearNotificationsIds.clear();
NotificationCenter.getInstance().postNotificationName(NotificationCenter.pushMessagesUpdated);
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -893,29 +985,19 @@ public class NotificationsController {
try {
if (soundPool == null) {
soundPool = new SoundPool(4, AudioManager.STREAM_SYSTEM, 0);
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
@Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
if (status == 0) {
soundPool.play(sampleId, 1.0f, 1.0f, 1, 0, 1.0f);
}
}
});
}
if (soundIn == 0) {
soundIn = soundPool.load(ApplicationLoader.applicationContext, R.raw.sound_in, 1);
}
soundPool.play(soundIn, 1.0f, 1.0f, 1, 0, 1.0f);
/*if (mediaPlayerIn == null) {
AssetFileDescriptor assetFileDescriptor = ApplicationLoader.applicationContext.getResources().openRawResourceFd(R.raw.sound_in);
if (assetFileDescriptor != null) {
mediaPlayerIn = new MediaPlayer();
mediaPlayerIn.setAudioStreamType(AudioManager.STREAM_SYSTEM);
mediaPlayerIn.setDataSource(assetFileDescriptor.getFileDescriptor(), assetFileDescriptor.getStartOffset(), assetFileDescriptor.getLength());
mediaPlayerIn.setLooping(false);
assetFileDescriptor.close();
mediaPlayerIn.prepare();
}
}
try {
mediaPlayerIn.pause();
mediaPlayerIn.seekTo(0);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
mediaPlayerIn.start();*/
} catch (Exception e) {
FileLog.e("tmessages", e);
}
@ -941,31 +1023,25 @@ public class NotificationsController {
@Override
public void run() {
try {
if (lastSoundOutPlay > System.currentTimeMillis() - 100) {
return;
}
lastSoundOutPlay = System.currentTimeMillis();
if (soundPool == null) {
soundPool = new SoundPool(4, AudioManager.STREAM_SYSTEM, 0);
soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
@Override
public void onLoadComplete(SoundPool soundPool, int sampleId, int status) {
if (status == 0) {
soundPool.play(sampleId, 1.0f, 1.0f, 1, 0, 1.0f);
}
}
});
}
if (soundOut == 0) {
soundOut = soundPool.load(ApplicationLoader.applicationContext, R.raw.sound_out, 1);
}
soundPool.play(soundOut, 1.0f, 1.0f, 1, 0, 1.0f);
/*if (mediaPlayerOut == null) {
AssetFileDescriptor assetFileDescriptor = ApplicationLoader.applicationContext.getResources().openRawResourceFd(R.raw.sound_out);
if (assetFileDescriptor != null) {
mediaPlayerOut = new MediaPlayer();
mediaPlayerOut.setAudioStreamType(AudioManager.STREAM_SYSTEM);
mediaPlayerOut.setDataSource(assetFileDescriptor.getFileDescriptor(), assetFileDescriptor.getStartOffset(), assetFileDescriptor.getLength());
mediaPlayerOut.setLooping(false);
assetFileDescriptor.close();
mediaPlayerOut.prepare();
}
}
try {
mediaPlayerOut.pause();
mediaPlayerOut.seekTo(0);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
mediaPlayerOut.start();*/
} catch (Exception e) {
FileLog.e("tmessages", e);
}
@ -1109,13 +1185,9 @@ public class NotificationsController {
delayedPushMessages.clear();
showOrUpdateNotification(notifyCheck);
} else {
showOrUpdateNotification(false);
scheduleNotificationDelay(lastOnlineFromOtherDevice > ConnectionsManager.getInstance().getCurrentTime());
}
}
/*if (old_unread_count != total_unread_count) {
showOrUpdateNotification(notifyCheck);
}*/
notifyCheck = false;
if (preferences.getBoolean("badgeNumber", true)) {
setBadge(ApplicationLoader.applicationContext, total_unread_count);
@ -1217,15 +1289,24 @@ public class NotificationsController {
//ignore
}
try {
String launcherClassName = getLauncherClassName(context);
launcherClassName = getLauncherClassName(context);
if (launcherClassName == null) {
return;
}
Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
intent.putExtra("badge_count", count);
intent.putExtra("badge_count_package_name", context.getPackageName());
intent.putExtra("badge_count_class_name", launcherClassName);
context.sendBroadcast(intent);
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
try {
Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
intent.putExtra("badge_count", count);
intent.putExtra("badge_count_package_name", context.getPackageName());
intent.putExtra("badge_count_class_name", launcherClassName);
context.sendBroadcast(intent);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
} catch (Throwable e) {
FileLog.e("tmessages", e);
}

View File

@ -17,6 +17,7 @@ import org.telegram.messenger.FileLog;
import org.telegram.messenger.ApplicationLoader;
public class ScreenReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {

View File

@ -48,6 +48,7 @@ public class SecretChatHelper {
private boolean startingSecretChat = false;
private static volatile SecretChatHelper Instance = null;
public static SecretChatHelper getInstance() {
SecretChatHelper localInstance = Instance;
if (localInstance == null) {
@ -87,7 +88,7 @@ public class SecretChatHelper {
newMsg.local_id = newMsg.id = UserConfig.getNewMessageId();
newMsg.from_id = UserConfig.getClientUserId();
newMsg.flags = TLRPC.MESSAGE_FLAG_UNREAD | TLRPC.MESSAGE_FLAG_OUT;
newMsg.dialog_id = ((long)encryptedChat.id) << 32;
newMsg.dialog_id = ((long) encryptedChat.id) << 32;
newMsg.to_id = new TLRPC.TL_peerUser();
newMsg.send_state = MessageObject.MESSAGE_SEND_STATE_SENDING;
if (encryptedChat.participant_id == UserConfig.getClientUserId()) {
@ -114,7 +115,7 @@ public class SecretChatHelper {
if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) {
return;
}
TLRPC.TL_decryptedMessageService reqSend = null;
TLRPC.TL_decryptedMessageService reqSend;
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
reqSend = new TLRPC.TL_decryptedMessageService();
} else {
@ -123,7 +124,7 @@ public class SecretChatHelper {
Utilities.random.nextBytes(reqSend.random_bytes);
}
TLRPC.Message message = null;
TLRPC.Message message;
if (resendMessage != null) {
message = resendMessage;
@ -140,7 +141,7 @@ public class SecretChatHelper {
protected void processUpdateEncryption(TLRPC.TL_updateEncryption update, ConcurrentHashMap<Integer, TLRPC.User> usersDict) {
final TLRPC.EncryptedChat newChat = update.chat;
long dialog_id = ((long)newChat.id) << 32;
long dialog_id = ((long) newChat.id) << 32;
TLRPC.EncryptedChat existingChat = MessagesController.getInstance().getEncryptedChatDB(newChat.id);
if (newChat instanceof TLRPC.TL_encryptedChatRequested && existingChat == null) {
@ -219,7 +220,7 @@ public class SecretChatHelper {
if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) {
return;
}
TLRPC.TL_decryptedMessageService reqSend = null;
TLRPC.TL_decryptedMessageService reqSend;
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
reqSend = new TLRPC.TL_decryptedMessageService();
} else {
@ -228,7 +229,7 @@ public class SecretChatHelper {
Utilities.random.nextBytes(reqSend.random_bytes);
}
TLRPC.Message message = null;
TLRPC.Message message;
if (resendMessage != null) {
message = resendMessage;
@ -247,7 +248,7 @@ public class SecretChatHelper {
if (!(encryptedChat instanceof TLRPC.TL_encryptedChat)) {
return;
}
TLRPC.TL_decryptedMessageService reqSend = null;
TLRPC.TL_decryptedMessageService reqSend;
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
reqSend = new TLRPC.TL_decryptedMessageService();
} else {
@ -256,7 +257,7 @@ public class SecretChatHelper {
Utilities.random.nextBytes(reqSend.random_bytes);
}
TLRPC.Message message = null;
TLRPC.Message message;
if (resendMessage != null) {
message = resendMessage;
@ -278,7 +279,7 @@ public class SecretChatHelper {
return;
}
sendingNotifyLayer.add(encryptedChat.id);
TLRPC.TL_decryptedMessageService reqSend = null;
TLRPC.TL_decryptedMessageService reqSend;
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
reqSend = new TLRPC.TL_decryptedMessageService();
} else {
@ -287,7 +288,7 @@ public class SecretChatHelper {
Utilities.random.nextBytes(reqSend.random_bytes);
}
TLRPC.Message message = null;
TLRPC.Message message;
if (resendMessage != null) {
message = resendMessage;
@ -307,7 +308,7 @@ public class SecretChatHelper {
return;
}
TLRPC.TL_decryptedMessageService reqSend = null;
TLRPC.TL_decryptedMessageService reqSend;
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
reqSend = new TLRPC.TL_decryptedMessageService();
} else {
@ -316,7 +317,7 @@ public class SecretChatHelper {
Utilities.random.nextBytes(reqSend.random_bytes);
}
TLRPC.Message message = null;
TLRPC.Message message;
if (resendMessage != null) {
message = resendMessage;
@ -338,7 +339,7 @@ public class SecretChatHelper {
return;
}
TLRPC.TL_decryptedMessageService reqSend = null;
TLRPC.TL_decryptedMessageService reqSend;
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
reqSend = new TLRPC.TL_decryptedMessageService();
} else {
@ -347,7 +348,7 @@ public class SecretChatHelper {
Utilities.random.nextBytes(reqSend.random_bytes);
}
TLRPC.Message message = null;
TLRPC.Message message;
if (resendMessage != null) {
message = resendMessage;
@ -370,7 +371,7 @@ public class SecretChatHelper {
return;
}
TLRPC.TL_decryptedMessageService reqSend = null;
TLRPC.TL_decryptedMessageService reqSend;
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
reqSend = new TLRPC.TL_decryptedMessageService();
} else {
@ -379,7 +380,7 @@ public class SecretChatHelper {
Utilities.random.nextBytes(reqSend.random_bytes);
}
TLRPC.Message message = null;
TLRPC.Message message;
if (resendMessage != null) {
message = resendMessage;
@ -401,7 +402,7 @@ public class SecretChatHelper {
return;
}
TLRPC.TL_decryptedMessageService reqSend = null;
TLRPC.TL_decryptedMessageService reqSend;
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
reqSend = new TLRPC.TL_decryptedMessageService();
} else {
@ -410,7 +411,7 @@ public class SecretChatHelper {
Utilities.random.nextBytes(reqSend.random_bytes);
}
TLRPC.Message message = null;
TLRPC.Message message;
if (resendMessage != null) {
message = resendMessage;
@ -431,7 +432,7 @@ public class SecretChatHelper {
return;
}
TLRPC.TL_decryptedMessageService reqSend = null;
TLRPC.TL_decryptedMessageService reqSend;
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
reqSend = new TLRPC.TL_decryptedMessageService();
} else {
@ -440,7 +441,7 @@ public class SecretChatHelper {
Utilities.random.nextBytes(reqSend.random_bytes);
}
TLRPC.Message message = null;
TLRPC.Message message;
if (resendMessage != null) {
message = resendMessage;
@ -459,7 +460,7 @@ public class SecretChatHelper {
return;
}
TLRPC.TL_decryptedMessageService reqSend = null;
TLRPC.TL_decryptedMessageService reqSend;
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
reqSend = new TLRPC.TL_decryptedMessageService();
} else {
@ -468,7 +469,7 @@ public class SecretChatHelper {
Utilities.random.nextBytes(reqSend.random_bytes);
}
TLRPC.Message message = null;
TLRPC.Message message;
if (resendMessage != null) {
message = resendMessage;
@ -495,7 +496,7 @@ public class SecretChatHelper {
return;
}
TLRPC.TL_decryptedMessageService reqSend = null;
TLRPC.TL_decryptedMessageService reqSend;
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
reqSend = new TLRPC.TL_decryptedMessageService();
} else {
@ -504,7 +505,7 @@ public class SecretChatHelper {
Utilities.random.nextBytes(reqSend.random_bytes);
}
TLRPC.Message message = null;
TLRPC.Message message;
if (resendMessage != null) {
message = resendMessage;
@ -654,7 +655,7 @@ public class SecretChatHelper {
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
TLObject toEncryptObject = null;
TLObject toEncryptObject;
if (AndroidUtilities.getPeerLayerVersion(chat.layer) >= 17) {
TLRPC.TL_decryptedMessageLayer layer = new TLRPC.TL_decryptedMessageLayer();
int myLayer = Math.max(17, AndroidUtilities.getMyLayerVersion(chat.layer));
@ -710,7 +711,7 @@ public class SecretChatHelper {
byte[] messageKey = new byte[16];
System.arraycopy(messageKeyFull, messageKeyFull.length - 16, messageKey, 0, 16);
MessageKeyData keyData = Utilities.generateMessageKeyData(chat.auth_key, messageKey, false);
MessageKeyData keyData = MessageKeyData.generateMessageKeyData(chat.auth_key, messageKey, false);
len = toEncrypt.length();
int extraLen = len % 16 != 0 ? 16 - len % 16 : 0;
@ -734,7 +735,7 @@ public class SecretChatHelper {
BuffersStorage.getInstance().reuseFreeBuffer(dataForEncryption);
data.position(0);
TLObject reqToSend = null;
TLObject reqToSend;
if (encryptedFile == null) {
if (req instanceof TLRPC.TL_decryptedMessageService) {
@ -770,7 +771,7 @@ public class SecretChatHelper {
if (error == null) {
if (req.action instanceof TLRPC.TL_decryptedMessageActionNotifyLayer) {
TLRPC.EncryptedChat currentChat = MessagesController.getInstance().getEncryptedChat(chat.id);
sendingNotifyLayer.remove((Integer)currentChat.id);
sendingNotifyLayer.remove((Integer) currentChat.id);
currentChat.layer = AndroidUtilities.setMyLayerVersion(currentChat.layer, CURRENT_SECRET_CHAT_LAYER);
MessagesStorage.getInstance().updateEncryptedChatLayer(currentChat);
}
@ -857,8 +858,8 @@ public class SecretChatHelper {
}
if (object instanceof TLRPC.TL_decryptedMessage) {
TLRPC.TL_decryptedMessage decryptedMessage = (TLRPC.TL_decryptedMessage)object;
TLRPC.TL_message newMessage = null;
TLRPC.TL_decryptedMessage decryptedMessage = (TLRPC.TL_decryptedMessage) object;
TLRPC.TL_message newMessage;
if (AndroidUtilities.getPeerLayerVersion(chat.layer) >= 17) {
newMessage = new TLRPC.TL_message_secret();
newMessage.ttl = decryptedMessage.ttl;
@ -875,7 +876,7 @@ public class SecretChatHelper {
newMessage.random_id = random_id;
newMessage.to_id.user_id = UserConfig.getClientUserId();
newMessage.flags = TLRPC.MESSAGE_FLAG_UNREAD;
newMessage.dialog_id = ((long)chat.id) << 32;
newMessage.dialog_id = ((long) chat.id) << 32;
if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaEmpty) {
newMessage.media = new TLRPC.TL_messageMediaEmpty();
} else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaContact) {
@ -899,11 +900,12 @@ public class SecretChatHelper {
newMessage.media.photo.user_id = newMessage.from_id;
newMessage.media.photo.date = newMessage.date;
newMessage.media.photo.geo = new TLRPC.TL_geoPointEmpty();
if (decryptedMessage.media.thumb.length != 0 && decryptedMessage.media.thumb.length <= 6000 && decryptedMessage.media.thumb_w <= 100 && decryptedMessage.media.thumb_h <= 100) {
byte[] thumb = ((TLRPC.TL_decryptedMessageMediaPhoto) decryptedMessage.media).thumb;
if (thumb != null && thumb.length != 0 && thumb.length <= 6000 && decryptedMessage.media.thumb_w <= 100 && decryptedMessage.media.thumb_h <= 100) {
TLRPC.TL_photoCachedSize small = new TLRPC.TL_photoCachedSize();
small.w = decryptedMessage.media.thumb_w;
small.h = decryptedMessage.media.thumb_h;
small.bytes = decryptedMessage.media.thumb;
small.bytes = thumb;
small.type = "s";
small.location = new TLRPC.TL_fileLocationUnavailable();
newMessage.media.photo.sizes.add(small);
@ -929,9 +931,10 @@ public class SecretChatHelper {
newMessage.media = new TLRPC.TL_messageMediaVideo();
newMessage.media.caption = "";
newMessage.media.video = new TLRPC.TL_videoEncrypted();
if (decryptedMessage.media.thumb.length != 0 && decryptedMessage.media.thumb.length <= 6000 && decryptedMessage.media.thumb_w <= 100 && decryptedMessage.media.thumb_h <= 100) {
byte[] thumb = ((TLRPC.TL_decryptedMessageMediaVideo) decryptedMessage.media).thumb;
if (thumb != null && thumb.length != 0 && thumb.length <= 6000 && decryptedMessage.media.thumb_w <= 100 && decryptedMessage.media.thumb_h <= 100) {
newMessage.media.video.thumb = new TLRPC.TL_photoCachedSize();
newMessage.media.video.thumb.bytes = decryptedMessage.media.thumb;
newMessage.media.video.thumb.bytes = thumb;
newMessage.media.video.thumb.w = decryptedMessage.media.thumb_w;
newMessage.media.video.thumb.h = decryptedMessage.media.thumb_h;
newMessage.media.video.thumb.type = "s";
@ -975,9 +978,10 @@ public class SecretChatHelper {
newMessage.media.document.size = file.size;
newMessage.media.document.key = decryptedMessage.media.key;
newMessage.media.document.iv = decryptedMessage.media.iv;
if (decryptedMessage.media.thumb.length != 0 && decryptedMessage.media.thumb.length <= 6000 && decryptedMessage.media.thumb_w <= 100 && decryptedMessage.media.thumb_h <= 100) {
byte[] thumb = ((TLRPC.TL_decryptedMessageMediaDocument) decryptedMessage.media).thumb;
if (thumb != null && thumb.length != 0 && thumb.length <= 6000 && decryptedMessage.media.thumb_w <= 100 && decryptedMessage.media.thumb_h <= 100) {
newMessage.media.document.thumb = new TLRPC.TL_photoCachedSize();
newMessage.media.document.thumb.bytes = decryptedMessage.media.thumb;
newMessage.media.document.thumb.bytes = thumb;
newMessage.media.document.thumb.w = decryptedMessage.media.thumb_w;
newMessage.media.document.thumb.h = decryptedMessage.media.thumb_h;
newMessage.media.document.thumb.type = "s";
@ -997,7 +1001,7 @@ public class SecretChatHelper {
newMessage.media.document.mime_type = decryptedMessage.media.mime_type;
newMessage.media.document.dc_id = decryptedMessage.media.dc_id;
newMessage.media.document.size = decryptedMessage.media.size;
newMessage.media.document.thumb = decryptedMessage.media.thumbImage;
newMessage.media.document.thumb = ((TLRPC.TL_decryptedMessageMediaExternalDocument) decryptedMessage.media).thumb;
} else if (decryptedMessage.media instanceof TLRPC.TL_decryptedMessageMediaAudio) {
if (decryptedMessage.media.key == null || decryptedMessage.media.key.length != 32 || decryptedMessage.media.iv == null || decryptedMessage.media.iv.length != 32) {
return null;
@ -1025,7 +1029,7 @@ public class SecretChatHelper {
}
return newMessage;
} else if (object instanceof TLRPC.TL_decryptedMessageService) {
final TLRPC.TL_decryptedMessageService serviceMessage = (TLRPC.TL_decryptedMessageService)object;
final TLRPC.TL_decryptedMessageService serviceMessage = (TLRPC.TL_decryptedMessageService) object;
if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL || serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages) {
TLRPC.TL_messageService newMessage = new TLRPC.TL_messageService();
if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL) {
@ -1047,10 +1051,10 @@ public class SecretChatHelper {
newMessage.from_id = from_id;
newMessage.to_id = new TLRPC.TL_peerUser();
newMessage.to_id.user_id = UserConfig.getClientUserId();
newMessage.dialog_id = ((long)chat.id) << 32;
newMessage.dialog_id = ((long) chat.id) << 32;
return newMessage;
} else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionFlushHistory) {
final long did = ((long)chat.id) << 32;
final long did = ((long) chat.id) << 32;
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
@ -1314,7 +1318,7 @@ public class SecretChatHelper {
if (keyToDecrypt != null) {
byte[] messageKey = is.readData(16, false);
MessageKeyData keyData = Utilities.generateMessageKeyData(keyToDecrypt, messageKey, false);
MessageKeyData keyData = MessageKeyData.generateMessageKeyData(keyToDecrypt, messageKey, false);
Utilities.aesIgeEncryption(is.buffer, keyData.aesKey, keyData.aesIv, false, false, 24, is.limit() - 24);
@ -1327,19 +1331,14 @@ public class SecretChatHelper {
return null;
}
TLObject object = null;
try {
object = TLClassStore.Instance().TLdeserialize(is, is.readInt32(true), true);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
TLObject object = TLClassStore.Instance().TLdeserialize(is, is.readInt32(false), false);
BuffersStorage.getInstance().reuseFreeBuffer(is);
if (!new_key_used && AndroidUtilities.getPeerLayerVersion(chat.layer) >= 20) {
chat.key_use_count_in++;
}
if (object instanceof TLRPC.TL_decryptedMessageLayer) {
final TLRPC.TL_decryptedMessageLayer layer = (TLRPC.TL_decryptedMessageLayer)object;
final TLRPC.TL_decryptedMessageLayer layer = (TLRPC.TL_decryptedMessageLayer) object;
if (chat.seq_in == 0 && chat.seq_out == 0) {
if (chat.admin_id == UserConfig.getClientUserId()) {
chat.seq_out = 1;

View File

@ -56,9 +56,11 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
public String httpLocation;
public MessageObject obj;
public TLRPC.EncryptedChat encryptedChat;
public VideoEditedInfo videoEditedInfo;
}
private static volatile SendMessagesHelper Instance = null;
public static SendMessagesHelper getInstance() {
SendMessagesHelper localInstance = Instance;
if (localInstance == null) {
@ -94,113 +96,100 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
@Override
public void didReceivedNotification(int id, Object... args) {
public void didReceivedNotification(int id, final Object... args) {
if (id == NotificationCenter.FileDidUpload) {
final String location = (String)args[0];
final TLRPC.InputFile file = (TLRPC.InputFile)args[1];
final TLRPC.InputEncryptedFile encryptedFile = (TLRPC.InputEncryptedFile)args[2];
final String location = (String) args[0];
final TLRPC.InputFile file = (TLRPC.InputFile) args[1];
final TLRPC.InputEncryptedFile encryptedFile = (TLRPC.InputEncryptedFile) args[2];
ArrayList<DelayedMessage> arr = delayedMessages.get(location);
if (arr != null) {
for (int a = 0; a < arr.size(); a++) {
DelayedMessage message = arr.get(a);
TLRPC.InputMedia media = null;
if (message.sendRequest instanceof TLRPC.TL_messages_sendMedia) {
media = ((TLRPC.TL_messages_sendMedia) message.sendRequest).media;
} else if (message.sendRequest instanceof TLRPC.TL_messages_sendBroadcast) {
media = ((TLRPC.TL_messages_sendBroadcast) message.sendRequest).media;
}
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
ArrayList<DelayedMessage> arr = delayedMessages.get(location);
if (arr != null) {
for (int a = 0; a < arr.size(); a++) {
DelayedMessage message = arr.get(a);
TLRPC.InputMedia media = null;
if (message.sendRequest instanceof TLRPC.TL_messages_sendMedia) {
media = ((TLRPC.TL_messages_sendMedia)message.sendRequest).media;
} else if (message.sendRequest instanceof TLRPC.TL_messages_sendBroadcast) {
media = ((TLRPC.TL_messages_sendBroadcast)message.sendRequest).media;
}
if (file != null && media != null) {
if (message.type == 0) {
media.file = file;
performSendMessageRequest(message.sendRequest, message.obj.messageOwner, message.originalPath);
} else if (message.type == 1) {
if (media.file == null) {
media.file = file;
if (media.thumb == null && message.location != null) {
performSendDelayedMessage(message);
} else {
performSendMessageRequest(message.sendRequest, message.obj.messageOwner, message.originalPath);
}
} else {
media.thumb = file;
performSendMessageRequest(message.sendRequest, message.obj.messageOwner, message.originalPath);
}
} else if (message.type == 2) {
if (media.file == null) {
media.file = file;
if (media.thumb == null && message.location != null) {
performSendDelayedMessage(message);
} else {
performSendMessageRequest(message.sendRequest, message.obj.messageOwner, message.originalPath);
}
} else {
media.thumb = file;
performSendMessageRequest(message.sendRequest, message.obj.messageOwner, message.originalPath);
}
} else if (message.type == 3) {
media.file = file;
if (file != null && media != null) {
if (message.type == 0) {
media.file = file;
performSendMessageRequest(message.sendRequest, message.obj.messageOwner, message.originalPath);
} else if (message.type == 1) {
if (media.file == null) {
media.file = file;
if (media.thumb == null && message.location != null) {
performSendDelayedMessage(message);
} else {
performSendMessageRequest(message.sendRequest, message.obj.messageOwner, message.originalPath);
}
arr.remove(a);
a--;
} else if (encryptedFile != null && message.sendEncryptedRequest != null) {
message.sendEncryptedRequest.media.key = encryptedFile.key;
message.sendEncryptedRequest.media.iv = encryptedFile.iv;
SecretChatHelper.getInstance().performSendEncryptedRequest(message.sendEncryptedRequest, message.obj.messageOwner, message.encryptedChat, encryptedFile, message.originalPath);
arr.remove(a);
a--;
} else {
media.thumb = file;
performSendMessageRequest(message.sendRequest, message.obj.messageOwner, message.originalPath);
}
} else if (message.type == 2) {
if (media.file == null) {
media.file = file;
if (media.thumb == null && message.location != null) {
performSendDelayedMessage(message);
} else {
performSendMessageRequest(message.sendRequest, message.obj.messageOwner, message.originalPath);
}
} else {
media.thumb = file;
performSendMessageRequest(message.sendRequest, message.obj.messageOwner, message.originalPath);
}
} else if (message.type == 3) {
media.file = file;
performSendMessageRequest(message.sendRequest, message.obj.messageOwner, message.originalPath);
}
if (arr.isEmpty()) {
delayedMessages.remove(location);
}
arr.remove(a);
a--;
} else if (encryptedFile != null && message.sendEncryptedRequest != null) {
message.sendEncryptedRequest.media.key = (byte[]) args[3];
message.sendEncryptedRequest.media.iv = (byte[]) args[4];
SecretChatHelper.getInstance().performSendEncryptedRequest(message.sendEncryptedRequest, message.obj.messageOwner, message.encryptedChat, encryptedFile, message.originalPath);
arr.remove(a);
a--;
}
}
});
if (arr.isEmpty()) {
delayedMessages.remove(location);
}
}
} else if (id == NotificationCenter.FileDidFailUpload) {
final String location = (String) args[0];
final boolean enc = (Boolean) args[1];
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
ArrayList<DelayedMessage> arr = delayedMessages.get(location);
if (arr != null) {
for (int a = 0; a < arr.size(); a++) {
DelayedMessage obj = arr.get(a);
if (enc && obj.sendEncryptedRequest != null || !enc && obj.sendRequest != null) {
MessagesStorage.getInstance().markMessageAsSendError(obj.obj.getId());
obj.obj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR;
arr.remove(a);
a--;
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, obj.obj.getId());
processSentMessage(obj.obj.getId());
}
}
if (arr.isEmpty()) {
delayedMessages.remove(location);
}
ArrayList<DelayedMessage> arr = delayedMessages.get(location);
if (arr != null) {
for (int a = 0; a < arr.size(); a++) {
DelayedMessage obj = arr.get(a);
if (enc && obj.sendEncryptedRequest != null || !enc && obj.sendRequest != null) {
MessagesStorage.getInstance().markMessageAsSendError(obj.obj.getId());
obj.obj.messageOwner.send_state = MessageObject.MESSAGE_SEND_STATE_SEND_ERROR;
arr.remove(a);
a--;
NotificationCenter.getInstance().postNotificationName(NotificationCenter.messageSendError, obj.obj.getId());
processSentMessage(obj.obj.getId());
}
}
});
if (arr.isEmpty()) {
delayedMessages.remove(location);
}
}
} else if (id == NotificationCenter.FilePreparingStarted) {
MessageObject messageObject = (MessageObject)args[0];
String finalPath = (String)args[1];
MessageObject messageObject = (MessageObject) args[0];
String finalPath = (String) args[1];
ArrayList<DelayedMessage> arr = delayedMessages.get(messageObject.messageOwner.attachPath);
if (arr != null) {
for (int a = 0; a < arr.size(); a++) {
DelayedMessage message = arr.get(a);
if (message.obj == messageObject) {
message.videoLocation.videoEditedInfo = null;
message.videoEditedInfo = null;
performSendDelayedMessage(message);
arr.remove(a);
a--;
break;
}
}
@ -209,19 +198,19 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
}
} else if (id == NotificationCenter.FileNewChunkAvailable) {
MessageObject messageObject = (MessageObject)args[0];
String finalPath = (String)args[1];
long finalSize = (Long)args[2];
boolean isEncrypted = ((int)messageObject.getDialogId()) == 0;
MessageObject messageObject = (MessageObject) args[0];
String finalPath = (String) args[1];
long finalSize = (Long) args[2];
boolean isEncrypted = ((int) messageObject.getDialogId()) == 0;
FileLoader.getInstance().checkUploadNewDataAvailable(finalPath, isEncrypted, finalSize);
if (finalSize != 0) {
ArrayList<DelayedMessage> arr = delayedMessages.get(messageObject.messageOwner.attachPath);
if (arr != null) {
for (DelayedMessage message : arr) {
if (message.obj == messageObject) {
message.obj.messageOwner.videoEditedInfo = null;
message.obj.videoEditedInfo = null;
message.obj.messageOwner.message = "-1";
message.obj.messageOwner.media.video.size = (int)finalSize;
message.obj.messageOwner.media.video.size = (int) finalSize;
ArrayList<TLRPC.Message> messages = new ArrayList<>();
messages.add(message.obj.messageOwner);
@ -235,8 +224,8 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
}
} else if (id == NotificationCenter.FilePreparingFailed) {
MessageObject messageObject = (MessageObject)args[0];
String finalPath = (String)args[1];
MessageObject messageObject = (MessageObject) args[0];
String finalPath = (String) args[1];
stopVideoService(messageObject.messageOwner.attachPath);
ArrayList<DelayedMessage> arr = delayedMessages.get(finalPath);
@ -257,8 +246,8 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
}
} else if (id == NotificationCenter.httpFileDidLoaded) {
String path = (String)args[0];
String file = (String)args[1];
String path = (String) args[0];
String file = (String) args[1];
ArrayList<DelayedMessage> arr = delayedMessages.get(path);
if (arr != null) {
for (final DelayedMessage message : arr) {
@ -334,7 +323,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
delayedMessages.remove(path);
}
} else if (id == NotificationCenter.httpFileDidFailedLoad) {
String path = (String)args[0];
String path = (String) args[0];
ArrayList<DelayedMessage> arr = delayedMessages.get(path);
if (arr != null) {
@ -454,8 +443,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
sendMessage((TLRPC.TL_audio) messageObject.messageOwner.media.audio, messageObject.messageOwner.attachPath, did, messageObject.replyMessageObject);
} else if (messageObject.messageOwner.media.video instanceof TLRPC.TL_video) {
TLRPC.TL_video video = (TLRPC.TL_video) messageObject.messageOwner.media.video;
video.videoEditedInfo = messageObject.messageOwner.videoEditedInfo;
sendMessage(video, null, messageObject.messageOwner.attachPath, did, messageObject.replyMessageObject);
sendMessage(video, messageObject.videoEditedInfo, null, messageObject.messageOwner.attachPath, did, messageObject.replyMessageObject);
} else if (messageObject.messageOwner.media.document instanceof TLRPC.TL_document) {
sendMessage((TLRPC.TL_document) messageObject.messageOwner.media.document, null, messageObject.messageOwner.attachPath, did, messageObject.replyMessageObject);
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaVenue || messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGeo) {
@ -527,7 +515,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
public void sendMessage(TLRPC.User user, long peer, MessageObject reply_to_msg) {
sendMessage(null, null, null, null, null, user, null, null, null, peer, false, null, reply_to_msg, null, true);
sendMessage(null, null, null, null, null, null, user, null, null, null, peer, false, null, reply_to_msg, null, true);
}
public void sendMessage(ArrayList<MessageObject> messages, long peer) {
@ -703,38 +691,38 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
public void sendMessage(MessageObject message) {
sendMessage(null, null, null, null, message, null, null, null, null, message.getDialogId(), true, message.messageOwner.attachPath, null, null, true);
sendMessage(null, null, null, null, null, message, null, null, null, null, message.getDialogId(), true, message.messageOwner.attachPath, null, null, true);
}
public void sendMessage(MessageObject message, long peer) {
sendMessage(null, null, null, null, message, null, null, null, null, peer, false, message.messageOwner.attachPath, null, null, true);
sendMessage(null, null, null, null, null, message, null, null, null, null, peer, false, message.messageOwner.attachPath, null, null, true);
}
public void sendMessage(TLRPC.TL_document document, String originalPath, String path, long peer, MessageObject reply_to_msg) {
sendMessage(null, null, null, null, null, null, document, null, originalPath, peer, false, path, reply_to_msg, null, true);
sendMessage(null, null, null, null, null, null, null, document, null, originalPath, peer, false, path, reply_to_msg, null, true);
}
public void sendMessage(String message, long peer, MessageObject reply_to_msg, TLRPC.WebPage webPage, boolean searchLinks) {
sendMessage(message, null, null, null, null, null, null, null, null, peer, false, null, reply_to_msg, webPage, searchLinks);
sendMessage(message, null, null, null, null, null, null, null, null, null, peer, false, null, reply_to_msg, webPage, searchLinks);
}
public void sendMessage(TLRPC.MessageMedia location, long peer, MessageObject reply_to_msg) {
sendMessage(null, location, null, null, null, null, null, null, null, peer, false, null, reply_to_msg, null, true);
sendMessage(null, location, null, null, null, null, null, null, null, null, peer, false, null, reply_to_msg, null, true);
}
public void sendMessage(TLRPC.TL_photo photo, String originalPath, String path, long peer, MessageObject reply_to_msg) {
sendMessage(null, null, photo, null, null, null, null, null, originalPath, peer, false, path, reply_to_msg, null, true);
sendMessage(null, null, photo, null, null, null, null, null, null, originalPath, peer, false, path, reply_to_msg, null, true);
}
public void sendMessage(TLRPC.TL_video video, String originalPath, String path, long peer, MessageObject reply_to_msg) {
sendMessage(null, null, null, video, null, null, null, null, originalPath, peer, false, path, reply_to_msg, null, true);
public void sendMessage(TLRPC.TL_video video, VideoEditedInfo videoEditedInfo, String originalPath, String path, long peer, MessageObject reply_to_msg) {
sendMessage(null, null, null, video, videoEditedInfo, null, null, null, null, originalPath, peer, false, path, reply_to_msg, null, true);
}
public void sendMessage(TLRPC.TL_audio audio, String path, long peer, MessageObject reply_to_msg) {
sendMessage(null, null, null, null, null, null, null, audio, null, peer, false, path, reply_to_msg, null, true);
sendMessage(null, null, null, null, null, null, null, null, audio, null, peer, false, path, reply_to_msg, null, true);
}
private void sendMessage(String message, TLRPC.MessageMedia location, TLRPC.TL_photo photo, TLRPC.TL_video video, MessageObject msgObj, TLRPC.User user, TLRPC.TL_document document, TLRPC.TL_audio audio, String originalPath, long peer, boolean retry, String path, MessageObject reply_to_msg, TLRPC.WebPage webPage, boolean searchLinks) {
private void sendMessage(String message, TLRPC.MessageMedia location, TLRPC.TL_photo photo, TLRPC.TL_video video, VideoEditedInfo videoEditedInfo, MessageObject msgObj, TLRPC.User user, TLRPC.TL_document document, TLRPC.TL_audio audio, String originalPath, long peer, boolean retry, String path, MessageObject reply_to_msg, TLRPC.WebPage webPage, boolean searchLinks) {
if (peer == 0) {
return;
}
@ -776,7 +764,6 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
} else {
type = 3;
video = (TLRPC.TL_video) newMsg.media.video;
video.videoEditedInfo = newMsg.videoEditedInfo;
}
} else if (msgObj.type == 12) {
user = new TLRPC.TL_userRequest();
@ -842,12 +829,11 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
newMsg.media = new TLRPC.TL_messageMediaVideo();
newMsg.media.caption = video.caption != null ? video.caption : "";
newMsg.media.video = video;
newMsg.videoEditedInfo = video.videoEditedInfo;
type = 3;
if (video.videoEditedInfo == null) {
if (videoEditedInfo == null) {
newMsg.message = "-1";
} else {
newMsg.message = video.videoEditedInfo.getString();
newMsg.message = videoEditedInfo.getString();
}
newMsg.attachPath = path;
} else if (msgObj != null) {
@ -1093,6 +1079,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
delayedMessage.obj = newMsgObj;
delayedMessage.location = video.thumb.location;
delayedMessage.videoLocation = video;
delayedMessage.videoEditedInfo = videoEditedInfo;
} else {
TLRPC.TL_inputMediaVideo media = new TLRPC.TL_inputMediaVideo();
media.id = new TLRPC.TL_inputVideo();
@ -1149,7 +1136,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
}
TLObject reqSend = null;
TLObject reqSend;
if (sendToPeers != null) {
TLRPC.TL_messages_sendBroadcast request = new TLRPC.TL_messages_sendBroadcast();
@ -1229,7 +1216,12 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
TLRPC.PhotoSize small = photo.sizes.get(0);
TLRPC.PhotoSize big = photo.sizes.get(photo.sizes.size() - 1);
reqSend.media = new TLRPC.TL_decryptedMessageMediaPhoto();
reqSend.media.thumb = small.bytes;
ImageLoader.fillPhotoSizeWithBytes(small);
if (small.bytes != null) {
((TLRPC.TL_decryptedMessageMediaPhoto) reqSend.media).thumb = small.bytes;
} else {
((TLRPC.TL_decryptedMessageMediaPhoto) reqSend.media).thumb = new byte[0];
}
reqSend.media.thumb_h = small.h;
reqSend.media.thumb_w = small.w;
reqSend.media.w = big.w;
@ -1257,16 +1249,26 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
SecretChatHelper.getInstance().performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, encryptedFile, null);
}
} else if (type == 3) {
ImageLoader.fillPhotoSizeWithBytes(video.thumb);
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
reqSend.media = new TLRPC.TL_decryptedMessageMediaVideo();
if (video.thumb != null && video.thumb.bytes != null) {
((TLRPC.TL_decryptedMessageMediaVideo) reqSend.media).thumb = video.thumb.bytes;
} else {
((TLRPC.TL_decryptedMessageMediaVideo) reqSend.media).thumb = new byte[0];
}
} else {
reqSend.media = new TLRPC.TL_decryptedMessageMediaVideo_old();
if (video.thumb != null && video.thumb.bytes != null) {
((TLRPC.TL_decryptedMessageMediaVideo_old) reqSend.media).thumb = video.thumb.bytes;
} else {
((TLRPC.TL_decryptedMessageMediaVideo_old) reqSend.media).thumb = new byte[0];
}
}
reqSend.media.duration = video.duration;
reqSend.media.size = video.size;
reqSend.media.w = video.w;
reqSend.media.h = video.h;
reqSend.media.thumb = video.thumb.bytes;
reqSend.media.thumb_h = video.thumb.h;
reqSend.media.thumb_w = video.thumb.w;
reqSend.media.mime_type = "video/mp4";
@ -1278,6 +1280,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
delayedMessage.obj = newMsgObj;
delayedMessage.encryptedChat = encryptedChat;
delayedMessage.videoLocation = video;
delayedMessage.videoEditedInfo = videoEditedInfo;
performSendDelayedMessage(delayedMessage);
} else {
TLRPC.TL_inputEncryptedFile encryptedFile = new TLRPC.TL_inputEncryptedFile();
@ -1305,21 +1308,27 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
reqSend.media = new TLRPC.TL_decryptedMessageMediaExternalDocument();
reqSend.media.id = document.id;
reqSend.media.date = document.date;
reqSend.media.access_hash = document.access_hash;
reqSend.media.mime_type = document.mime_type;
reqSend.media.size = document.size;
((TLRPC.TL_decryptedMessageMediaExternalDocument) reqSend.media).thumbImage = document.thumb;
reqSend.media.dc_id = document.dc_id;
reqSend.media.attributes = document.attributes;
if (document.thumb == null) {
((TLRPC.TL_decryptedMessageMediaExternalDocument) reqSend.media).thumb = new TLRPC.TL_photoSizeEmpty();
} else {
((TLRPC.TL_decryptedMessageMediaExternalDocument) reqSend.media).thumb = document.thumb;
}
SecretChatHelper.getInstance().performSendEncryptedRequest(reqSend, newMsgObj.messageOwner, encryptedChat, null, null);
} else {
ImageLoader.fillPhotoSizeWithBytes(document.thumb);
reqSend.media = new TLRPC.TL_decryptedMessageMediaDocument();
reqSend.media.size = document.size;
if (!(document.thumb instanceof TLRPC.TL_photoSizeEmpty)) {
reqSend.media.thumb = document.thumb.bytes;
if (document.thumb != null && document.thumb.bytes != null) {
((TLRPC.TL_decryptedMessageMediaDocument) reqSend.media).thumb = document.thumb.bytes;
reqSend.media.thumb_h = document.thumb.h;
reqSend.media.thumb_w = document.thumb.w;
} else {
reqSend.media.thumb = new byte[0];
((TLRPC.TL_decryptedMessageMediaDocument) reqSend.media).thumb = new byte[0];
reqSend.media.thumb_h = 0;
reqSend.media.thumb_w = 0;
}
@ -1401,7 +1410,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
}
} else if (message.type == 1) {
if (message.videoLocation.videoEditedInfo != null) {
if (message.videoEditedInfo != null) {
String location = message.obj.messageOwner.attachPath;
if (location == null) {
location = FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE) + "/" + message.videoLocation.id + ".mp4";
@ -1410,10 +1419,10 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
MediaController.getInstance().scheduleVideoConvert(message.obj);
} else {
if (message.sendRequest != null) {
TLRPC.InputMedia media = null;
TLRPC.InputMedia media;
if (message.sendRequest instanceof TLRPC.TL_messages_sendMedia) {
media = ((TLRPC.TL_messages_sendMedia) message.sendRequest).media;
} else if (message.sendRequest instanceof TLRPC.TL_messages_sendBroadcast) {
} else {
media = ((TLRPC.TL_messages_sendBroadcast) message.sendRequest).media;
}
if (media.file == null) {
@ -1422,7 +1431,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
location = FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE) + "/" + message.videoLocation.id + ".mp4";
}
putToDelayedMessages(location, message);
if (message.obj.messageOwner.videoEditedInfo != null) {
if (message.obj.videoEditedInfo != null) {
FileLoader.getInstance().uploadFile(location, false, false, message.videoLocation.size);
} else {
FileLoader.getInstance().uploadFile(location, false, false);
@ -1438,7 +1447,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
location = FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE) + "/" + message.videoLocation.id + ".mp4";
}
putToDelayedMessages(location, message);
if (message.obj.messageOwner.videoEditedInfo != null) {
if (message.obj.videoEditedInfo != null) {
FileLoader.getInstance().uploadFile(location, true, false, message.videoLocation.size);
} else {
FileLoader.getInstance().uploadFile(location, true, false);
@ -1451,10 +1460,10 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
ImageLoader.getInstance().loadHttpFile(message.httpLocation, "gif");
} else {
if (message.sendRequest != null) {
TLRPC.InputMedia media = null;
TLRPC.InputMedia media;
if (message.sendRequest instanceof TLRPC.TL_messages_sendMedia) {
media = ((TLRPC.TL_messages_sendMedia) message.sendRequest).media;
} else if (message.sendRequest instanceof TLRPC.TL_messages_sendBroadcast) {
} else {
media = ((TLRPC.TL_messages_sendBroadcast) message.sendRequest).media;
}
if (media.file == null) {
@ -1575,7 +1584,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
ArrayList<MessageObject> arr = new ArrayList<>();
MessageObject messageObject = new MessageObject(message, null, false);
arr.add(messageObject);
MessagesController.getInstance().updateInterfaceWithMessages(messageObject.getDialogId(), arr, isBroadcast);
MessagesController.getInstance().updateInterfaceWithMessages(messageObject.getDialogId(), arr, true);
}
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
}
@ -1632,18 +1641,21 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
MessagesStorage.getInstance().putSentFile(originalPath, sentMessage.media.photo, 0);
for (TLRPC.PhotoSize size : sentMessage.media.photo.sizes) {
if (size instanceof TLRPC.TL_photoSizeEmpty) {
if (size == null || size instanceof TLRPC.TL_photoSizeEmpty || size.type == null) {
continue;
}
for (TLRPC.PhotoSize size2 : newMsg.media.photo.sizes) {
if (size2.location != null && size2.location.volume_id == Integer.MIN_VALUE && size.type.equals(size2.type) || size.w == size2.w && size.h == size2.h) {
if (size2 == null || size2.location == null || size2.type == null) {
continue;
}
if (size2.location.volume_id == Integer.MIN_VALUE && size.type.equals(size2.type) || size.w == size2.w && size.h == size2.h) {
String fileName = size2.location.volume_id + "_" + size2.location.local_id;
String fileName2 = size.location.volume_id + "_" + size.location.local_id;
if (fileName.equals(fileName2)) {
break;
}
File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName + ".jpg");
File cacheFile2 = null;
File cacheFile2;
if (sentMessage.media.photo.sizes.size() == 1 || size.w > 90 || size.h > 90) {
cacheFile2 = FileLoader.getPathToAttach(size);
} else {
@ -1842,13 +1854,10 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
return false;
}
boolean isEncrypted = (int)dialog_id == 0;
boolean isEncrypted = (int) dialog_id == 0;
boolean allowSticker = !isEncrypted;
String name = f.getName();
if (name == null) {
name = "noname";
}
String ext = "";
int idx = path.lastIndexOf(".");
if (idx != -1) {
@ -1872,7 +1881,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
TLRPC.TL_documentAttributeFilename fileName = new TLRPC.TL_documentAttributeFilename();
fileName.file_name = name;
document.attributes.add(fileName);
document.size = (int)f.length();
document.size = (int) f.length();
document.dc_id = 0;
if (ext.length() != 0) {
if (ext.toLowerCase().equals("webp")) {
@ -1911,12 +1920,13 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
FileLog.e("tmessages", e);
}
if (bmOptions.outWidth != 0 && bmOptions.outHeight != 0 && bmOptions.outWidth <= 800 && bmOptions.outHeight <= 800) {
TLRPC.TL_documentAttributeSticker attributeSticker = null;
TLRPC.TL_documentAttributeSticker attributeSticker;
if (isEncrypted) {
attributeSticker = new TLRPC.TL_documentAttributeSticker_old();
} else {
attributeSticker = new TLRPC.TL_documentAttributeSticker();
attributeSticker.alt = "";
attributeSticker.stickerset = new TLRPC.TL_inputStickerSetEmpty();
}
document.attributes.add(attributeSticker);
TLRPC.TL_documentAttributeImageSize attributeImageSize = new TLRPC.TL_documentAttributeImageSize();
@ -2023,7 +2033,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
new Thread(new Runnable() {
@Override
public void run() {
boolean isEncrypted = (int)dialog_id == 0;
boolean isEncrypted = (int) dialog_id == 0;
for (int a = 0; a < photos.size(); a++) {
final MediaController.SearchImage searchImage = photos.get(a);
if (searchImage.type == 1) {
@ -2034,7 +2044,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
String md5 = Utilities.MD5(searchImage.imageUrl) + "." + ImageLoader.getHttpUrlExtension(searchImage.imageUrl);
File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), md5);
if (document == null) {
File thumbFile = null;
File thumbFile;
document = new TLRPC.TL_document();
document.id = 0;
document.date = ConnectionsManager.getInstance().getCurrentTime();
@ -2091,15 +2101,19 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
if (photo == null) {
String md5 = Utilities.MD5(searchImage.imageUrl) + "." + ImageLoader.getHttpUrlExtension(searchImage.imageUrl);
File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), md5);
if (cacheFile.exists()) {
if (cacheFile.exists() && cacheFile.length() != 0) {
photo = SendMessagesHelper.getInstance().generatePhotoSizes(cacheFile.toString(), null);
needDownloadHttp = false;
} else {
if (photo != null) {
needDownloadHttp = false;
}
}
if (photo == null) {
md5 = Utilities.MD5(searchImage.thumbUrl) + "." + ImageLoader.getHttpUrlExtension(searchImage.thumbUrl);
cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), md5);
if (cacheFile.exists()) {
photo = SendMessagesHelper.getInstance().generatePhotoSizes(cacheFile.toString(), null);
} else {
}
if (photo == null) {
photo = new TLRPC.TL_photo();
photo.user_id = UserConfig.getClientUserId();
photo.date = ConnectionsManager.getInstance().getCurrentTime();
@ -2174,7 +2188,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
new Thread(new Runnable() {
@Override
public void run() {
boolean isEncrypted = (int)dialog_id == 0;
boolean isEncrypted = (int) dialog_id == 0;
ArrayList<String> sendAsDocuments = null;
ArrayList<String> sendAsDocumentsOriginal = null;
@ -2192,7 +2206,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
String originalPath = path;
String tempPath = path;
if (tempPath == null && uri != null) {
tempPath = Utilities.getPath(uri);
tempPath = AndroidUtilities.getPath(uri);
originalPath = uri.toString();
}
@ -2236,7 +2250,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
if (!isEncrypted) {
photo = (TLRPC.TL_photo) MessagesStorage.getInstance().getSentFile(originalPath, !isEncrypted ? 0 : 3);
if (photo == null && uri != null) {
photo = (TLRPC.TL_photo) MessagesStorage.getInstance().getSentFile(Utilities.getPath(uri), !isEncrypted ? 0 : 3);
photo = (TLRPC.TL_photo) MessagesStorage.getInstance().getSentFile(AndroidUtilities.getPath(uri), !isEncrypted ? 0 : 3);
}
}
if (photo == null) {
@ -2266,7 +2280,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}).start();
}
public static void prepareSendingVideo(final String videoPath, final long estimatedSize, final long duration, final int width, final int height, final TLRPC.VideoEditedInfo videoEditedInfo, final long dialog_id, final MessageObject reply_to_msg) {
public static void prepareSendingVideo(final String videoPath, final long estimatedSize, final long duration, final int width, final int height, final VideoEditedInfo videoEditedInfo, final long dialog_id, final MessageObject reply_to_msg) {
if (videoPath == null || videoPath.length() == 0) {
return;
}
@ -2274,7 +2288,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
@Override
public void run() {
boolean isEncrypted = (int)dialog_id == 0;
boolean isEncrypted = (int) dialog_id == 0;
if (videoEditedInfo != null || videoPath.endsWith("mp4")) {
String path = videoPath;
@ -2316,14 +2330,13 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
video.h = height;
}
video.size = (int) estimatedSize;
video.videoEditedInfo = videoEditedInfo;
String fileName = Integer.MIN_VALUE + "_" + UserConfig.lastLocalId + ".mp4";
UserConfig.lastLocalId--;
File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName);
UserConfig.saveConfig(false);
path = cacheFile.getAbsolutePath();
} else {
if (temp != null && temp.exists()) {
if (temp.exists()) {
video.size = (int) temp.length();
}
boolean infoObtained = false;
@ -2351,7 +2364,6 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
try {
if (mediaMetadataRetriever != null) {
mediaMetadataRetriever.release();
mediaMetadataRetriever = null;
}
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -2379,7 +2391,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
SendMessagesHelper.getInstance().sendMessage(videoFinal, originalPathFinal, finalPath, dialog_id, reply_to_msg);
SendMessagesHelper.getInstance().sendMessage(videoFinal, videoEditedInfo, originalPathFinal, finalPath, dialog_id, reply_to_msg);
}
});
} else {

View File

@ -44,11 +44,16 @@ public class SmsListener extends BroadcastReceiver {
try {
Pattern pattern = Pattern.compile("[0-9]+");
Matcher matcher = pattern.matcher(wholeString);
final Matcher matcher = pattern.matcher(wholeString);
if (matcher.find()) {
String str = matcher.group(0);
if (str.length() >= 3) {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.didReceiveSmsCode, matcher.group(0));
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.didReceiveSmsCode, matcher.group(0));
}
});
}
}
} catch (Throwable e) {

View File

@ -0,0 +1,51 @@
/*
* This is the source code of Telegram for Android v. 2.x.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.android;
import java.util.Locale;
public class VideoEditedInfo {
public long startTime;
public long endTime;
public int rotationValue;
public int originalWidth;
public int originalHeight;
public int resultWidth;
public int resultHeight;
public int bitrate;
public String originalPath;
public String getString() {
return String.format(Locale.US, "-1_%d_%d_%d_%d_%d_%d_%d_%d_%s", startTime, endTime, rotationValue, originalWidth, originalHeight, bitrate, resultWidth, resultHeight, originalPath);
}
public void parseString(String string) {
if (string.length() < 6) {
return;
}
String args[] = string.split("_");
if (args.length >= 10) {
startTime = Long.parseLong(args[1]);
endTime = Long.parseLong(args[2]);
rotationValue = Integer.parseInt(args[3]);
originalWidth = Integer.parseInt(args[4]);
originalHeight = Integer.parseInt(args[5]);
bitrate = Integer.parseInt(args[6]);
resultWidth = Integer.parseInt(args[7]);
resultHeight = Integer.parseInt(args[8]);
for (int a = 9; a < args.length; a++) {
if (originalPath == null) {
originalPath = args[a];
} else {
originalPath += "_" + args[a];
}
}
}
}
}

View File

@ -8,20 +8,33 @@
package org.telegram.android.query;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Message;
import android.widget.Toast;
import org.telegram.SQLite.SQLiteCursor;
import org.telegram.SQLite.SQLitePreparedStatement;
import org.telegram.android.AndroidUtilities;
import org.telegram.android.LocaleController;
import org.telegram.android.MessagesStorage;
import org.telegram.android.NotificationCenter;
import org.telegram.messenger.ByteBufferDesc;
import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.messenger.RPCRequest;
import org.telegram.messenger.TLObject;
import org.telegram.messenger.TLRPC;
import org.telegram.messenger.Utilities;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.Components.StickersAlert;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
public class StickersQuery {
@ -30,19 +43,54 @@ public class StickersQuery {
private static int loadDate;
private static ArrayList<TLRPC.Document> stickers = new ArrayList<>();
private static HashMap<String, ArrayList<TLRPC.Document>> allStickers = new HashMap<>();
private static ArrayList<TLRPC.TL_stickerPack> stickerPacks = new ArrayList<>();
private static ArrayList<TLRPC.TL_stickerSet> stickerSets = new ArrayList<>();
private static HashMap<Long, ArrayList<TLRPC.Document>> stickersBySets = new HashMap<>();
private static HashMap<Long, String> stickersByEmoji = new HashMap<>();
private static boolean loadingStickers;
private static boolean stickersLoaded;
private static boolean hideMainStickersPack;
public static void checkStickers() {
if (!loadingStickers && (allStickers.isEmpty() || loadDate < (System.currentTimeMillis() / 1000 - 60 * 60))) {
loadStickers(true);
if (!loadingStickers && (!stickersLoaded || loadDate < (System.currentTimeMillis() / 1000 - 60 * 60))) {
loadStickers(true, false);
}
}
public static boolean isLoadingStickers() {
return loadingStickers;
}
public static HashMap<String, ArrayList<TLRPC.Document>> getAllStickers() {
return allStickers;
}
public static ArrayList<TLRPC.Document> getStickersForSet(long id) {
return stickersBySets.get(id);
}
public static ArrayList<TLRPC.TL_stickerPack> getStickerPacks() {
return stickerPacks;
}
public static ArrayList<TLRPC.Document> getStickers() {
return stickers;
}
private static void loadStickers(boolean cache) {
public static ArrayList<TLRPC.TL_stickerSet> getStickerSets() {
return stickerSets;
}
public static boolean isStickerPackInstalled(long id) {
return stickersBySets.containsKey(id);
}
public static String getEmojiForSticker(long id) {
String value = stickersByEmoji.get(id);
return value != null ? value : "";
}
public static void loadStickers(boolean cache, boolean force) {
if (loadingStickers) {
return;
}
@ -54,7 +102,14 @@ public class StickersQuery {
TLRPC.messages_AllStickers result = null;
int date = 0;
try {
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT data, date FROM stickers WHERE 1");
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT value FROM keyvalue WHERE id = 'hide_stickers'");
if (cursor.next()) {
int value = Utilities.parseInt(cursor.stringValue(0));
hideMainStickersPack = value == 1;
}
cursor.dispose();
cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT data, date FROM stickers WHERE 1");
ArrayList<TLRPC.User> loadedUsers = new ArrayList<>();
if (cursor.next()) {
ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0));
@ -73,10 +128,7 @@ public class StickersQuery {
});
} else {
TLRPC.TL_messages_getAllStickers req = new TLRPC.TL_messages_getAllStickers();
req.hash = hash;
if (req.hash == null) {
req.hash = "";
}
req.hash = hash == null || force ? "" : hash;
ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() {
@Override
public void run(final TLObject response, final TLRPC.TL_error error) {
@ -113,11 +165,24 @@ public class StickersQuery {
});
}
private static long getStickerSetId(TLRPC.Document document) {
for (TLRPC.DocumentAttribute attribute : document.attributes) {
if (attribute instanceof TLRPC.TL_documentAttributeSticker) {
if (attribute.stickerset instanceof TLRPC.TL_inputStickerSetID) {
return attribute.stickerset.id;
}
break;
}
}
return -1;
}
private static void processLoadedStickers(final TLRPC.messages_AllStickers res, final boolean cache, final int date) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
loadingStickers = false;
stickersLoaded = true;
}
});
Utilities.stageQueue.postRunnable(new Runnable() {
@ -127,7 +192,7 @@ public class StickersQuery {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
loadStickers(false);
loadStickers(false, false);
}
});
if (res == null) {
@ -135,18 +200,41 @@ public class StickersQuery {
}
}
if (res instanceof TLRPC.TL_messages_allStickers) {
if (!cache) {
putStickersToCache((TLRPC.TL_messages_allStickers) res);
}
HashMap<Long, TLRPC.Document> documents = new HashMap<>();
final HashMap<Long, ArrayList<TLRPC.Document>> sets = new HashMap<>();
final ArrayList<TLRPC.Document> allDocuments = new ArrayList<>();
final HashMap<Long, String> stickersEmoji = new HashMap<>();
for (TLRPC.Document document : res.documents) {
if (document == null) {
continue;
}
documents.put(document.id, document);
if (document.thumb != null && document.thumb.location != null) {
document.thumb.location.ext = "webp";
long setId = getStickerSetId(document);
if (setId != -1 || setId == -1 && !hideMainStickersPack) {
allDocuments.add(document);
}
ArrayList<TLRPC.Document> docs = sets.get(setId);
if (docs == null) {
docs = new ArrayList<>();
sets.put(setId, docs);
if (setId == -1) {
boolean contain = false;
for (TLRPC.TL_stickerSet set : res.sets) {
if (set.id == setId) {
contain = true;
break;
}
}
if (!contain) {
TLRPC.TL_stickerSet set = new TLRPC.TL_stickerSet();
set.title = set.short_name = "";
set.id = -1;
res.sets.add(0, set);
}
}
}
docs.add(document);
}
final HashMap<String, ArrayList<TLRPC.Document>> result = new HashMap<>();
for (TLRPC.TL_stickerPack stickerPack : res.packs) {
@ -154,8 +242,16 @@ public class StickersQuery {
stickerPack.emoticon = stickerPack.emoticon.replace("\uFE0F", "");
ArrayList<TLRPC.Document> arrayList = result.get(stickerPack.emoticon);
for (Long id : stickerPack.documents) {
if (!stickersEmoji.containsKey(id)) {
stickersEmoji.put(id, stickerPack.emoticon);
}
TLRPC.Document document = documents.get(id);
if (document != null) {
long setId = getStickerSetId(document);
if (setId == -1 && hideMainStickersPack) {
continue;
}
if (arrayList == null) {
arrayList = new ArrayList<>();
result.put(stickerPack.emoticon, arrayList);
@ -165,11 +261,30 @@ public class StickersQuery {
}
}
}
Collections.sort(allDocuments, new Comparator<TLRPC.Document>() {
@Override
public int compare(TLRPC.Document lhs, TLRPC.Document rhs) {
long lid = getStickerSetId(lhs);
long rid = getStickerSetId(rhs);
if (lid < rid) {
return -1;
} else if (lid > rid) {
return 1;
}
return 0;
}
});
if (!cache) {
putStickersToCache((TLRPC.TL_messages_allStickers) res);
}
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
stickerSets = res.sets;
allStickers = result;
stickers = res.documents;
stickers = allDocuments;
stickersBySets = sets;
stickersByEmoji = stickersEmoji;
hash = res.hash;
loadDate = date;
NotificationCenter.getInstance().postNotificationName(NotificationCenter.stickersDidLoaded);
@ -179,4 +294,144 @@ public class StickersQuery {
}
});
}
public static void loadStickers(final BaseFragment fragment, final TLRPC.InputStickerSet stickerSet) {
if (fragment == null || stickerSet == null) {
return;
}
final ProgressDialog progressDialog = new ProgressDialog(fragment.getParentActivity());
progressDialog.setMessage(LocaleController.getString("Loading", R.string.Loading));
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setCancelable(false);
TLRPC.TL_messages_getStickerSet req = new TLRPC.TL_messages_getStickerSet();
req.stickerset = stickerSet;
final long 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() {
try {
progressDialog.dismiss();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
if (fragment != null && fragment.getParentActivity() != null && !fragment.getParentActivity().isFinishing()) {
if (error == null) {
final TLRPC.TL_messages_stickerSet res = (TLRPC.TL_messages_stickerSet) response;
StickersAlert alert = new StickersAlert(fragment.getParentActivity(), res.set, res.documents);
if (res.set == null || !StickersQuery.isStickerPackInstalled(res.set.id)) {
alert.setButton(AlertDialog.BUTTON_POSITIVE, LocaleController.getString("AddStickers", R.string.AddStickers), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
TLRPC.TL_messages_installStickerSet req = new TLRPC.TL_messages_installStickerSet();
req.stickerset = stickerSet;
ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() {
@Override
public void run(TLObject response, final TLRPC.TL_error error) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
if (fragment != null && fragment.getParentActivity() != null) {
if (error == null) {
Toast.makeText(fragment.getParentActivity(), LocaleController.getString("AddStickersInstalled", R.string.AddStickersInstalled), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(fragment.getParentActivity(), LocaleController.getString("ErrorOccurred", R.string.ErrorOccurred), Toast.LENGTH_SHORT).show();
}
}
loadStickers(false, true);
}
});
}
});
}
});
} else {
alert.setButton(AlertDialog.BUTTON_NEUTRAL, LocaleController.getString("StickersRemove", R.string.StickersRemove), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
removeStickersSet(fragment.getParentActivity(), res.set);
}
});
}
alert.setButton(AlertDialog.BUTTON_NEGATIVE, LocaleController.getString("Close", R.string.Close), (Message) null);
fragment.setVisibleDialog(alert);
alert.show();
} else {
Toast.makeText(fragment.getParentActivity(), LocaleController.getString("AddStickersNotFound", R.string.AddStickersNotFound), Toast.LENGTH_SHORT).show();
}
}
}
});
}
});
progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, LocaleController.getString("Cancel", R.string.Cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ConnectionsManager.getInstance().cancelRpc(reqId, true);
try {
dialog.dismiss();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
fragment.setVisibleDialog(progressDialog);
progressDialog.show();
}
public static void setHideMainStickersPack(final boolean value) {
hideMainStickersPack = value;
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
try {
SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO keyvalue VALUES(?, ?)");
state.requery();
state.bindString(1, "hide_stickers");
state.bindString(2, value ? "1" : "0");
state.step();
state.dispose();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
}
public static void removeStickersSet(final Context context, TLRPC.TL_stickerSet stickerSet) {
TLRPC.TL_messages_uninstallStickerSet req = new TLRPC.TL_messages_uninstallStickerSet();
req.stickerset = new TLRPC.TL_inputStickerSetID();
req.stickerset.access_hash = stickerSet.access_hash;
req.stickerset.id = stickerSet.id;
ConnectionsManager.getInstance().performRpc(req, new RPCRequest.RPCRequestDelegate() {
@Override
public void run(TLObject response, final TLRPC.TL_error error) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
try {
if (error == null) {
Toast.makeText(context, LocaleController.getString("StickersRemoved", R.string.StickersRemoved), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, LocaleController.getString("ErrorOccurred", R.string.ErrorOccurred), Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
loadStickers(false, true);
}
});
}
});
}
public static boolean getHideMainStickersPack() {
return hideMainStickersPack;
}
}

View File

@ -58,6 +58,8 @@ import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.Interpolator;
import org.telegram.android.AndroidUtilities;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

View File

@ -1,9 +1,9 @@
/*
* This is the source code of Telegram for Android v. 1.3.x.
* This is the source code of Telegram for Android v. 2.x.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.
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.messenger;

View File

@ -1,9 +1,9 @@
/*
* This is the source code of Telegram for Android v. 1.3.2.
* This is the source code of Telegram for Android v. 2.x.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.
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.messenger;

View File

@ -1,9 +1,9 @@
/*
* This is the source code of Telegram for Android v. 1.3.2.
* This is the source code of Telegram for Android v. 2.x.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.
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.messenger;
@ -157,6 +157,7 @@ public class ApplicationLoader extends Application {
}
UserConfig.loadConfig();
MessagesController.getInstance();
if (UserConfig.getCurrentUser() != null) {
MessagesController.getInstance().putUser(UserConfig.getCurrentUser(), true);
ConnectionsManager.getInstance().applyCountryPortNumber(UserConfig.getCurrentUser().phone);

View File

@ -1,9 +1,9 @@
/*
* This is the source code of Telegram for Android v. 1.3.x.
* This is the source code of Telegram for Android v. 2.x.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.
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.messenger;
@ -37,12 +37,12 @@ public class BuffersStorage {
public BuffersStorage(boolean threadSafe) {
isThreadSafe = threadSafe;
freeBuffers128 = new ArrayList<ByteBufferDesc>();
freeBuffers1024 = new ArrayList<ByteBufferDesc>();
freeBuffers4096 = new ArrayList<ByteBufferDesc>();
freeBuffers16384 = new ArrayList<ByteBufferDesc>();
freeBuffers32768 = new ArrayList<ByteBufferDesc>();
freeBuffersBig = new ArrayList<ByteBufferDesc>();
freeBuffers128 = new ArrayList<>();
freeBuffers1024 = new ArrayList<>();
freeBuffers4096 = new ArrayList<>();
freeBuffers16384 = new ArrayList<>();
freeBuffers32768 = new ArrayList<>();
freeBuffersBig = new ArrayList<>();
for (int a = 0; a < 5; a++) {
freeBuffers128.add(new ByteBufferDesc(128));

View File

@ -10,7 +10,7 @@ package org.telegram.messenger;
public class BuildVars {
public static boolean DEBUG_VERSION = false;
public static int BUILD_VERSION = 521;
public static int BUILD_VERSION = 541;
public static int APP_ID = 0; //obtain your own APP_ID at https://core.telegram.org/api/obtaining_api_id
public static String APP_HASH = ""; //obtain your own APP_HASH at https://core.telegram.org/api/obtaining_api_id
public static String HOCKEY_APP_HASH = "your-hockeyapp-api-key-here";

View File

@ -1,5 +1,5 @@
/*
* This is the source code of Telegram for Android v. 2.x
* This is the source code of Telegram for Android v. 2.x.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).
*

View File

@ -1,9 +1,9 @@
/*
* This is the source code of Telegram for Android v. 1.3.x.
* This is the source code of Telegram for Android v. 2.x.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.
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.messenger;

View File

@ -1,9 +1,9 @@
/*
* This is the source code of Telegram for Android v. 1.4.x.
* This is the source code of Telegram for Android v. 2.x.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.
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.messenger;

View File

@ -1,13 +1,14 @@
/*
* This is the source code of Telegram for Android v. 1.3.2.
* This is the source code of Telegram for Android v. 2.x.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.
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.messenger;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
@ -24,7 +25,13 @@ import org.telegram.android.MessagesController;
import org.telegram.android.NotificationCenter;
import java.io.File;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;
@ -444,67 +451,117 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
if (isTestBackend == 0) {
Datacenter datacenter = new Datacenter();
datacenter.datacenterId = 1;
datacenter.addAddressAndPort("149.154.175.50", 443);
datacenter.addAddressAndPort("149.154.175.50", 443, 0);
datacenter.addAddressAndPort("2001:b28:f23d:f001:0000:0000:0000:000a", 443, 1);
datacenters.put(datacenter.datacenterId, datacenter);
datacenter = new Datacenter();
datacenter.datacenterId = 2;
datacenter.addAddressAndPort("149.154.167.51", 443);
datacenter.addAddressAndPort("149.154.167.51", 443, 0);
datacenter.addAddressAndPort("2001:67c:4e8:f002:0000:0000:0000:000a", 443, 1);
datacenters.put(datacenter.datacenterId, datacenter);
datacenter = new Datacenter();
datacenter.datacenterId = 3;
datacenter.addAddressAndPort("149.154.175.100", 443);
datacenter.addAddressAndPort("149.154.175.100", 443, 0);
datacenter.addAddressAndPort("2001:b28:f23d:f003:0000:0000:0000:000a", 443, 1);
datacenters.put(datacenter.datacenterId, datacenter);
datacenter = new Datacenter();
datacenter.datacenterId = 4;
datacenter.addAddressAndPort("149.154.167.91", 443);
datacenter.addAddressAndPort("149.154.167.91", 443, 0);
datacenter.addAddressAndPort("2001:67c:4e8:f004:0000:0000:0000:000a", 443, 1);
datacenters.put(datacenter.datacenterId, datacenter);
datacenter = new Datacenter();
datacenter.datacenterId = 5;
datacenter.addAddressAndPort("149.154.171.5", 443);
datacenter.addAddressAndPort("149.154.171.5", 443, 0);
datacenter.addAddressAndPort("2001:b28:f23f:f005:0000:0000:0000:000a", 443, 1);
datacenters.put(datacenter.datacenterId, datacenter);
} else {
Datacenter datacenter = new Datacenter();
datacenter.datacenterId = 1;
datacenter.addAddressAndPort("149.154.175.10", 443);
datacenter.addAddressAndPort("149.154.175.10", 443, 0);
datacenter.addAddressAndPort("2001:b28:f23d:f001:0000:0000:0000:000e", 443, 1);
datacenters.put(datacenter.datacenterId, datacenter);
datacenter = new Datacenter();
datacenter.datacenterId = 2;
datacenter.addAddressAndPort("149.154.167.40", 443);
datacenter.addAddressAndPort("149.154.167.40", 443, 0);
datacenter.addAddressAndPort("2001:67c:4e8:f002:0000:0000:0000:000e", 443, 1);
datacenters.put(datacenter.datacenterId, datacenter);
datacenter = new Datacenter();
datacenter.datacenterId = 3;
datacenter.addAddressAndPort("149.154.175.117", 443);
datacenter.addAddressAndPort("149.154.175.117", 443, 0);
datacenter.addAddressAndPort("2001:b28:f23d:f003:0000:0000:0000:000e", 443, 1);
datacenters.put(datacenter.datacenterId, datacenter);
}
} else if (datacenters.size() == 1) {
Datacenter datacenter = new Datacenter();
datacenter.datacenterId = 2;
datacenter.addAddressAndPort("149.154.167.51", 443);
datacenter.addAddressAndPort("149.154.167.51", 443, 0);
datacenter.addAddressAndPort("2001:67c:4e8:f002:0000:0000:0000:000a", 443, 1);
datacenters.put(datacenter.datacenterId, datacenter);
datacenter = new Datacenter();
datacenter.datacenterId = 3;
datacenter.addAddressAndPort("149.154.175.100", 443);
datacenter.addAddressAndPort("149.154.175.100", 443, 0);
datacenter.addAddressAndPort("2001:b28:f23d:f003:0000:0000:0000:000a", 443, 1);
datacenters.put(datacenter.datacenterId, datacenter);
datacenter = new Datacenter();
datacenter.datacenterId = 4;
datacenter.addAddressAndPort("149.154.167.91", 443);
datacenter.addAddressAndPort("149.154.167.91", 443, 0);
datacenter.addAddressAndPort("2001:67c:4e8:f004:0000:0000:0000:000a", 443, 1);
datacenters.put(datacenter.datacenterId, datacenter);
datacenter = new Datacenter();
datacenter.datacenterId = 5;
datacenter.addAddressAndPort("149.154.171.5", 443);
datacenter.addAddressAndPort("149.154.171.5", 443, 0);
datacenter.addAddressAndPort("2001:b28:f23f:f005:0000:0000:0000:000a", 443, 1);
datacenters.put(datacenter.datacenterId, datacenter);
}
}
@SuppressLint("NewApi")
protected static boolean useIpv6Address() {
if (Build.VERSION.SDK_INT < 19) {
return false;
}
try {
NetworkInterface networkInterface;
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
while (networkInterfaces.hasMoreElements()) {
networkInterface = networkInterfaces.nextElement();
if (!networkInterface.isUp() || networkInterface.isLoopback()) {
continue;
}
boolean hasIpv4 = false;
boolean hasIpv6 = false;
for (InterfaceAddress address : networkInterface.getInterfaceAddresses()) {
InetAddress inetAddress = address.getAddress();
if (inetAddress.isLinkLocalAddress() || inetAddress.isLoopbackAddress() || inetAddress.isMulticastAddress()) {
continue;
}
if (inetAddress instanceof Inet6Address) {
hasIpv6 = true;
} else if (inetAddress instanceof Inet4Address) {
hasIpv4 = true;
}
}
if (!hasIpv4 && hasIpv6) {
return true;
}
}
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
return false;
}
private void saveSession() {
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
@ -698,7 +755,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
HashMap<String, Integer> ports = new HashMap<>();
addresses.add(ip_address);
ports.put(ip_address, port);
exist.replaceAddressesAndPorts(addresses, ports);
exist.replaceAddressesAndPorts(addresses, ports, 0);
exist.suspendConnections();
updateDcSettings(dc);
}
@ -783,7 +840,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
datacentersArr.add(existing);
datacenterMap.put(existing.datacenterId, existing);
}
existing.addAddressAndPort(datacenterDesc.ip_address, datacenterDesc.port);
existing.addAddressAndPort(datacenterDesc.ip_address, datacenterDesc.port, datacenterDesc.flags);
}
if (!datacentersArr.isEmpty()) {
@ -792,7 +849,10 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
if (exist == null) {
datacenters.put(datacenter.datacenterId, datacenter);
} else {
exist.replaceAddressesAndPorts(datacenter.addresses, datacenter.ports);
exist.replaceAddressesAndPorts(datacenter.addressesIpv4, datacenter.ports, 0);
exist.replaceAddressesAndPorts(datacenter.addressesIpv6, datacenter.ports, 1);
exist.replaceAddressesAndPorts(datacenter.addressesIpv4Download, datacenter.ports, 2);
exist.replaceAddressesAndPorts(datacenter.addressesIpv6Download, datacenter.ports, 3);
}
if (datacenter.datacenterId == movingToDatacenterId) {
movingToDatacenterId = DEFAULT_DATACENTER_ID;
@ -821,18 +881,12 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
invoke.api_id = BuildVars.APP_ID;
try {
invoke.lang_code = LocaleController.getLocaleString(LocaleController.getInstance().getSystemDefaultLocale());
if (invoke.lang_code == null || invoke.lang_code.length() == 0) {
if (invoke.lang_code.length() == 0) {
invoke.lang_code = "en";
}
invoke.device_model = Build.MANUFACTURER + Build.MODEL;
if (invoke.device_model == null) {
invoke.device_model = "Android unknown";
}
PackageInfo pInfo = ApplicationLoader.applicationContext.getPackageManager().getPackageInfo(ApplicationLoader.applicationContext.getPackageName(), 0);
invoke.app_version = pInfo.versionName + " (" + pInfo.versionCode + ")";
if (invoke.app_version == null) {
invoke.app_version = "App version unknown";
}
invoke.system_version = "SDK " + Build.VERSION.SDK_INT;
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -1729,7 +1783,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
data.cleanup();
}
MessageKeyData keyData = Utilities.generateMessageKeyData(datacenter.authKey, messageKey, false);
MessageKeyData keyData = MessageKeyData.generateMessageKeyData(datacenter.authKey, messageKey, false);
int zeroCount = 0;
if (innerOs.limit() % 16 != 0) {
@ -1841,20 +1895,13 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
req.app_sandbox = false;
try {
req.lang_code = LocaleController.getLocaleString(LocaleController.getInstance().getSystemDefaultLocale());
if (req.lang_code == null || req.lang_code.length() == 0) {
if (req.lang_code.length() == 0) {
req.lang_code = "en";
}
req.device_model = Build.MANUFACTURER + Build.MODEL;
if (req.device_model == null) {
req.device_model = "Android unknown";
}
req.system_version = "SDK " + Build.VERSION.SDK_INT;
PackageInfo pInfo = ApplicationLoader.applicationContext.getPackageManager().getPackageInfo(ApplicationLoader.applicationContext.getPackageName(), 0);
req.app_version = pInfo.versionName + " (" + pInfo.versionCode + ")";
if (req.app_version == null) {
req.app_version = "App version unknown";
}
} catch (Exception e) {
FileLog.e("tmessages", e);
req.lang_code = "en";
@ -2191,7 +2238,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.appDidLogout);
MessagesController.getInstance().performLogout(false);
}
});
}
@ -2428,13 +2475,13 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
}
void generatePing(Datacenter datacenter, boolean push) {
TcpConnection connection = null;
TcpConnection connection;
if (push) {
connection = datacenter.pushConnection;
} else {
connection = datacenter.connection;
}
if (connection != null && (push || !push && connection.channelToken != 0)) {
if (connection != null && (push || connection.channelToken != 0)) {
ByteBufferDesc transportData = generatePingData(connection);
if (transportData != null) {
if (push) {
@ -2607,7 +2654,7 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
}
byte[] messageKey = data.readData(16, false);
MessageKeyData keyData = Utilities.generateMessageKeyData(datacenter.authKey, messageKey, true);
MessageKeyData keyData = MessageKeyData.generateMessageKeyData(datacenter.authKey, messageKey, true);
Utilities.aesIgeEncryption(data.buffer, keyData.aesKey, keyData.aesIv, false, false, data.position(), length - 24);
@ -2671,10 +2718,15 @@ public class ConnectionsManager implements Action.ActionDelegate, TcpConnection.
}
protected TLObject deserialize(TLObject request, AbsSerializedData data, boolean exception) {
int constructor = data.readInt32(exception);
int constructor = 0;
try {
constructor = data.readInt32(exception);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
TLObject message = null;
try {
message = TLClassStore.Instance().TLdeserialize(data, constructor, request, exception);
message = TLClassStore.Instance().TLdeserialize(data, constructor, exception);
} catch (Exception e) {
FileLog.e("tmessages", e);
}

View File

@ -1,9 +1,9 @@
/*
* This is the source code of Telegram for Android v. 1.3.2.
* This is the source code of Telegram for Android v. 2.x.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.
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.messenger;
@ -17,10 +17,13 @@ import java.util.Comparator;
import java.util.HashMap;
public class Datacenter {
private static final int DATA_VERSION = 4;
private static final int DATA_VERSION = 5;
public int datacenterId;
public ArrayList<String> addresses = new ArrayList<>();
public ArrayList<String> addressesIpv4 = new ArrayList<>();
public ArrayList<String> addressesIpv6 = new ArrayList<>();
public ArrayList<String> addressesIpv4Download = new ArrayList<>();
public ArrayList<String> addressesIpv6Download = new ArrayList<>();
public HashMap<String, Integer> ports = new HashMap<>();
public int[] defaultPorts = new int[] {-1, 80, -1, 443, -1, 443, -1, 80, -1, 443, -1};
public int[] defaultPorts8888 = new int[] {-1, 8888, -1, 443, -1, 8888, -1, 80, -1, 8888, -1};
@ -29,8 +32,15 @@ public class Datacenter {
public long authKeyId;
public int lastInitVersion = 0;
public int overridePort = -1;
private volatile int currentPortNum = 0;
private volatile int currentAddressNum = 0;
private volatile int currentPortNumIpv4 = 0;
private volatile int currentAddressNumIpv4 = 0;
private volatile int currentPortNumIpv6 = 0;
private volatile int currentAddressNumIpv6 = 0;
private volatile int currentPortNumIpv4Download = 0;
private volatile int currentAddressNumIpv4Download = 0;
private volatile int currentPortNumIpv6Download = 0;
private volatile int currentAddressNumIpv6Download = 0;
public TcpConnection connection;
private TcpConnection downloadConnection;
@ -47,7 +57,7 @@ public class Datacenter {
if (version == 0) {
datacenterId = data.readInt32(false);
String address = data.readString(false);
addresses.add(address);
addressesIpv4.add(address);
int port = data.readInt32(false);
ports.put(address, port);
int len = data.readInt32(false);
@ -72,7 +82,7 @@ public class Datacenter {
}
} else if (version == 1) {
int currentVersion = data.readInt32(false);
if (currentVersion == 2 || currentVersion == 3 || currentVersion == 4) {
if (currentVersion >= 2 && currentVersion <= 5) {
datacenterId = data.readInt32(false);
if (currentVersion >= 3) {
lastInitVersion = data.readInt32(false);
@ -80,15 +90,35 @@ public class Datacenter {
int len = data.readInt32(false);
for (int a = 0; a < len; a++) {
String address = data.readString(false);
addresses.add(address);
addressesIpv4.add(address);
ports.put(address, data.readInt32(false));
}
if (currentVersion >= 5) {
len = data.readInt32(false);
for (int a = 0; a < len; a++) {
String address = data.readString(false);
addressesIpv6.add(address);
ports.put(address, data.readInt32(false));
}
len = data.readInt32(false);
for (int a = 0; a < len; a++) {
String address = data.readString(false);
addressesIpv4Download.add(address);
ports.put(address, data.readInt32(false));
}
len = data.readInt32(false);
for (int a = 0; a < len; a++) {
String address = data.readString(false);
addressesIpv6Download.add(address);
ports.put(address, data.readInt32(false));
}
}
len = data.readInt32(false);
if (len != 0) {
authKey = data.readData(len, false);
}
if (currentVersion == 4) {
if (currentVersion >= 4) {
authKeyId = data.readInt64(false);
} else {
len = data.readInt32(false);
@ -116,26 +146,79 @@ public class Datacenter {
}
public void switchTo443Port() {
for (int a = 0; a < addresses.size(); a++) {
if (ports.get(addresses.get(a)) == 443) {
currentAddressNum = a;
currentPortNum = 0;
for (int a = 0; a < addressesIpv4.size(); a++) {
if (ports.get(addressesIpv4.get(a)) == 443) {
currentAddressNumIpv4 = a;
currentPortNumIpv4 = 0;
break;
}
}
for (int a = 0; a < addressesIpv6.size(); a++) {
if (ports.get(addressesIpv6.get(a)) == 443) {
currentAddressNumIpv6 = a;
currentPortNumIpv6 = 0;
break;
}
}
for (int a = 0; a < addressesIpv4Download.size(); a++) {
if (ports.get(addressesIpv4Download.get(a)) == 443) {
currentAddressNumIpv4Download = a;
currentPortNumIpv4Download = 0;
break;
}
}
for (int a = 0; a < addressesIpv6Download.size(); a++) {
if (ports.get(addressesIpv6Download.get(a)) == 443) {
currentAddressNumIpv6Download = a;
currentPortNumIpv6Download = 0;
break;
}
}
}
public String getCurrentAddress() {
public String getCurrentAddress(int flags) {
int currentAddressNum;
ArrayList<String> addresses;
if ((flags & 2) != 0) {
if ((flags & 1) != 0) {
currentAddressNum = currentAddressNumIpv6Download;
addresses = addressesIpv6Download;
} else {
currentAddressNum = currentAddressNumIpv4Download;
addresses = addressesIpv4Download;
}
} else {
if ((flags & 1) != 0) {
currentAddressNum = currentAddressNumIpv6;
addresses = addressesIpv6;
} else {
currentAddressNum = currentAddressNumIpv4;
addresses = addressesIpv4;
}
}
if (addresses.isEmpty()) {
return null;
}
if (currentAddressNum >= addresses.size()) {
currentAddressNum = 0;
if ((flags & 2) != 0) {
if ((flags & 1) != 0) {
currentAddressNumIpv6Download = currentAddressNum;
} else {
currentAddressNumIpv4Download = currentAddressNum;
}
} else {
if ((flags & 1) != 0) {
currentAddressNumIpv6 = currentAddressNum;
} else {
currentAddressNumIpv4 = currentAddressNum;
}
}
}
return addresses.get(currentAddressNum);
}
public int getCurrentPort() {
public int getCurrentPort(int flags) {
if (ports.isEmpty()) {
return overridePort == -1 ? 443 : overridePort;
}
@ -146,21 +229,64 @@ public class Datacenter {
portsArray = defaultPorts8888;
}
int currentPortNum;
ArrayList<String> addresses;
if ((flags & 2) != 0) {
if ((flags & 1) != 0) {
currentPortNum = currentPortNumIpv6Download;
} else {
currentPortNum = currentPortNumIpv4Download;
}
} else {
if ((flags & 1) != 0) {
currentPortNum = currentPortNumIpv6;
} else {
currentPortNum = currentPortNumIpv4;
}
}
if (currentPortNum >= defaultPorts.length) {
currentPortNum = 0;
if ((flags & 2) != 0) {
if ((flags & 1) != 0) {
currentPortNumIpv6Download = currentPortNum;
} else {
currentPortNumIpv4Download = currentPortNum;
}
} else {
if ((flags & 1) != 0) {
currentPortNumIpv6 = currentPortNum;
} else {
currentPortNumIpv4 = currentPortNum;
}
}
}
int port = portsArray[currentPortNum];
if (port == -1) {
if (overridePort != -1) {
return overridePort;
}
String address = getCurrentAddress();
String address = getCurrentAddress(flags);
return ports.get(address);
}
return port;
}
public void addAddressAndPort(String address, int port) {
public void addAddressAndPort(String address, int port, int flags) {
ArrayList<String> addresses;
if ((flags & 2) != 0) {
if ((flags & 1) != 0) {
addresses = addressesIpv6Download;
} else {
addresses = addressesIpv4Download;
}
} else {
if ((flags & 1) != 0) {
addresses = addressesIpv6;
} else {
addresses = addressesIpv4;
}
}
if (addresses.contains(address)) {
return;
}
@ -168,7 +294,31 @@ public class Datacenter {
ports.put(address, port);
}
public void nextAddressOrPort() {
public void nextAddressOrPort(int flags) {
int currentPortNum;
int currentAddressNum;
ArrayList<String> addresses;
if ((flags & 2) != 0) {
if ((flags & 1) != 0) {
currentPortNum = currentPortNumIpv6Download;
currentAddressNum = currentAddressNumIpv6Download;
addresses = addressesIpv6Download;
} else {
currentPortNum = currentPortNumIpv4Download;
currentAddressNum = currentAddressNumIpv4Download;
addresses = addressesIpv4Download;
}
} else {
if ((flags & 1) != 0) {
currentPortNum = currentPortNumIpv6;
currentAddressNum = currentAddressNumIpv6;
addresses = addressesIpv6;
} else {
currentPortNum = currentPortNumIpv4;
currentAddressNum = currentAddressNumIpv4;
addresses = addressesIpv4;
}
}
if (currentPortNum + 1 < defaultPorts.length) {
currentPortNum++;
} else {
@ -179,6 +329,23 @@ public class Datacenter {
}
currentPortNum = 0;
}
if ((flags & 2) != 0) {
if ((flags & 1) != 0) {
currentPortNumIpv6Download = currentPortNum;
currentAddressNumIpv6Download = currentAddressNum;
} else {
currentPortNumIpv4Download = currentPortNum;
currentAddressNumIpv4Download = currentAddressNum;
}
} else {
if ((flags & 1) != 0) {
currentPortNumIpv6 = currentPortNum;
currentAddressNumIpv6 = currentAddressNum;
} else {
currentPortNumIpv4 = currentPortNum;
currentAddressNumIpv4 = currentAddressNum;
}
}
}
public void storeCurrentAddressAndPortNum() {
@ -187,8 +354,14 @@ public class Datacenter {
public void run() {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("dataconfig", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("dc" + datacenterId + "port", currentPortNum);
editor.putInt("dc" + datacenterId + "address", currentAddressNum);
editor.putInt("dc" + datacenterId + "port", currentPortNumIpv4);
editor.putInt("dc" + datacenterId + "address", currentAddressNumIpv4);
editor.putInt("dc" + datacenterId + "port6", currentPortNumIpv6);
editor.putInt("dc" + datacenterId + "address6", currentAddressNumIpv6);
editor.putInt("dc" + datacenterId + "portD", currentPortNumIpv4Download);
editor.putInt("dc" + datacenterId + "addressD", currentAddressNumIpv4Download);
editor.putInt("dc" + datacenterId + "port6D", currentPortNumIpv6Download);
editor.putInt("dc" + datacenterId + "address6D", currentAddressNumIpv6Download);
editor.commit();
}
});
@ -196,21 +369,71 @@ public class Datacenter {
private void readCurrentAddressAndPortNum() {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("dataconfig", Context.MODE_PRIVATE);
currentPortNum = preferences.getInt("dc" + datacenterId + "port", 0);
currentAddressNum = preferences.getInt("dc" + datacenterId + "address", 0);
currentPortNumIpv4 = preferences.getInt("dc" + datacenterId + "port", 0);
currentAddressNumIpv4 = preferences.getInt("dc" + datacenterId + "address", 0);
currentPortNumIpv6 = preferences.getInt("dc" + datacenterId + "port6", 0);
currentAddressNumIpv6 = preferences.getInt("dc" + datacenterId + "address6", 0);
currentPortNumIpv4Download = preferences.getInt("dc" + datacenterId + "portD", 0);
currentAddressNumIpv4Download = preferences.getInt("dc" + datacenterId + "addressD", 0);
currentPortNumIpv6Download = preferences.getInt("dc" + datacenterId + "port6D", 0);
currentAddressNumIpv6Download = preferences.getInt("dc" + datacenterId + "address6D", 0);
}
public void replaceAddressesAndPorts(ArrayList<String> newAddresses, HashMap<String, Integer> newPorts) {
addresses = newAddresses;
ports = newPorts;
public void replaceAddressesAndPorts(ArrayList<String> newAddresses, HashMap<String, Integer> newPorts, int flags) {
ArrayList<String> addresses;
if ((flags & 2) != 0) {
if ((flags & 1) != 0) {
addresses = addressesIpv6Download;
} else {
addresses = addressesIpv4Download;
}
} else {
if ((flags & 1) != 0) {
addresses = addressesIpv6;
} else {
addresses = addressesIpv4;
}
}
for (String address : addresses) {
ports.remove(address);
}
if ((flags & 2) != 0) {
if ((flags & 1) != 0) {
addressesIpv6Download = newAddresses;
} else {
addressesIpv4Download = newAddresses;
}
} else {
if ((flags & 1) != 0) {
addressesIpv6 = newAddresses;
} else {
addressesIpv4 = newAddresses;
}
}
ports.putAll(newPorts);
}
public void SerializeToStream(SerializedData stream) {
stream.writeInt32(DATA_VERSION);
stream.writeInt32(datacenterId);
stream.writeInt32(lastInitVersion);
stream.writeInt32(addresses.size());
for (String address : addresses) {
stream.writeInt32(addressesIpv4.size());
for (String address : addressesIpv4) {
stream.writeString(address);
stream.writeInt32(ports.get(address));
}
stream.writeInt32(addressesIpv6.size());
for (String address : addressesIpv6) {
stream.writeString(address);
stream.writeInt32(ports.get(address));
}
stream.writeInt32(addressesIpv4Download.size());
for (String address : addressesIpv4Download) {
stream.writeString(address);
stream.writeInt32(ports.get(address));
}
stream.writeInt32(addressesIpv6Download.size());
for (String address : addressesIpv6Download) {
stream.writeString(address);
stream.writeInt32(ports.get(address));
}

View File

@ -1,9 +1,9 @@
/*
* This is the source code of Telegram for Android v. 1.3.2.
* This is the source code of Telegram for Android v. 2.x.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.
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.messenger;

View File

@ -1,9 +1,9 @@
/*
* This is the source code of Telegram for Android v. 1.3.2.
* This is the source code of Telegram for Android v. 2.x.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.
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.messenger;

View File

@ -1,9 +1,9 @@
/*
* This is the source code of Telegram for Android v. 1.3.2.
* This is the source code of Telegram for Android v. 2.x.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.
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.messenger;
@ -60,7 +60,7 @@ public class FileLoadOperation {
void didChangedLoadProgress(FileLoadOperation operation, float progress);
}
public FileLoadOperation(TLRPC.FileLocation photoLocation, int size) {
public FileLoadOperation(TLRPC.FileLocation photoLocation, String extension, int size) {
if (photoLocation instanceof TLRPC.TL_fileEncryptedLocation) {
location = new TLRPC.TL_inputEncryptedFileLocation();
location.id = photoLocation.volume_id;
@ -79,10 +79,7 @@ public class FileLoadOperation {
datacenter_id = photoLocation.dc_id;
}
totalBytesCount = size;
ext = photoLocation.ext;
if (ext == null) {
ext = "jpg";
}
ext = extension != null ? extension : "jpg";
}
public FileLoadOperation(TLRPC.Video videoLocation) {
@ -140,7 +137,7 @@ public class FileLoadOperation {
}
totalBytesCount = documentLocation.size;
ext = FileLoader.getDocumentFileName(documentLocation);
int idx = -1;
int idx;
if (ext == null || (idx = ext.lastIndexOf(".")) == -1) {
ext = "";
} else {
@ -179,8 +176,8 @@ public class FileLoadOperation {
return;
}
Long mediaId = null;
String fileNameFinal = null;
String fileNameTemp = null;
String fileNameFinal;
String fileNameTemp;
String fileNameIv = null;
if (location.volume_id != 0 && location.local_id != 0) {
fileNameTemp = location.volume_id + "_" + location.local_id + "_temp." + ext;
@ -219,7 +216,6 @@ public class FileLoadOperation {
cacheFileFinal = new File(storePath, fileNameFinal);
boolean exist = cacheFileFinal.exists();
if (exist && totalBytesCount != 0 && totalBytesCount != cacheFileFinal.length()) {
exist = false;
cacheFileFinal.delete();
}
@ -388,7 +384,6 @@ public class FileLoadOperation {
processRequestResult(delayedRequestInfo, null);
delayedRequestInfo.response.disableFree = false;
delayedRequestInfo.response.freeResources();
delayedRequestInfo = null;
break;
}
}

View File

@ -1,9 +1,9 @@
/*
* This is the source code of Telegram for Android v. 1.3.2.
* This is the source code of Telegram for Android v. 2.x.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.
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.messenger;
@ -21,10 +21,15 @@ public class FileLoader {
public interface FileLoaderDelegate {
void fileUploadProgressChanged(String location, float progress, boolean isEncrypted);
void fileDidUploaded(String location, TLRPC.InputFile inputFile, TLRPC.InputEncryptedFile inputEncryptedFile);
void fileDidUploaded(String location, TLRPC.InputFile inputFile, TLRPC.InputEncryptedFile inputEncryptedFile, byte[] key, byte[] iv);
void fileDidFailedUpload(String location, boolean isEncrypted);
void fileDidLoaded(String location, File finalFile, int type);
void fileDidFailedLoad(String location, int state);
void fileLoadProgressChanged(String location, float progress);
}
@ -56,6 +61,7 @@ public class FileLoader {
private int currentUploadSmallOperationsCount = 0;
private static volatile FileLoader Instance = null;
public static FileLoader getInstance() {
FileLoader localInstance = Instance;
if (localInstance == null) {
@ -92,7 +98,7 @@ public class FileLoader {
fileLoaderQueue.postRunnable(new Runnable() {
@Override
public void run() {
FileUploadOperation operation = null;
FileUploadOperation operation;
if (!enc) {
operation = uploadOperationPaths.get(location);
} else {
@ -112,7 +118,7 @@ public class FileLoader {
fileLoaderQueue.postRunnable(new Runnable() {
@Override
public void run() {
FileUploadOperation operation = null;
FileUploadOperation operation;
if (encrypted) {
operation = uploadOperationPathsEnc.get(location);
} else {
@ -163,7 +169,7 @@ public class FileLoader {
}
operation.delegate = new FileUploadOperation.FileUploadOperationDelegate() {
@Override
public void didFinishUploadingFile(FileUploadOperation operation, final TLRPC.InputFile inputFile, final TLRPC.InputEncryptedFile inputEncryptedFile) {
public void didFinishUploadingFile(FileUploadOperation operation, final TLRPC.InputFile inputFile, final TLRPC.InputEncryptedFile inputEncryptedFile, final byte[] key, final byte[] iv) {
fileLoaderQueue.postRunnable(new Runnable() {
@Override
public void run() {
@ -192,7 +198,7 @@ public class FileLoader {
}
}
if (delegate != null) {
delegate.fileDidUploaded(location, inputFile, inputEncryptedFile);
delegate.fileDidUploaded(location, inputFile, inputEncryptedFile, key, iv);
}
}
});
@ -261,26 +267,26 @@ public class FileLoader {
}
public void cancelLoadFile(TLRPC.Video video) {
cancelLoadFile(video, null, null, null);
cancelLoadFile(video, null, null, null, null);
}
public void cancelLoadFile(TLRPC.Document document) {
cancelLoadFile(null, document, null, null);
cancelLoadFile(null, document, null, null, null);
}
public void cancelLoadFile(TLRPC.Audio audio) {
cancelLoadFile(null, null, audio, null);
cancelLoadFile(null, null, audio, null, null);
}
public void cancelLoadFile(TLRPC.PhotoSize photo) {
cancelLoadFile(null, null, null, photo.location);
cancelLoadFile(null, null, null, photo.location, null);
}
public void cancelLoadFile(TLRPC.FileLocation location) {
cancelLoadFile(null, null, null, location);
public void cancelLoadFile(TLRPC.FileLocation location, String ext) {
cancelLoadFile(null, null, null, location, ext);
}
private void cancelLoadFile(final TLRPC.Video video, final TLRPC.Document document, final TLRPC.Audio audio, final TLRPC.FileLocation location) {
private void cancelLoadFile(final TLRPC.Video video, final TLRPC.Document document, final TLRPC.Audio audio, final TLRPC.FileLocation location, final String locationExt) {
if (video == null && location == null && document == null && audio == null) {
return;
}
@ -291,7 +297,7 @@ public class FileLoader {
if (video != null) {
fileName = getAttachFileName(video);
} else if (location != null) {
fileName = getAttachFileName(location);
fileName = getAttachFileName(location, locationExt);
} else if (document != null) {
fileName = getAttachFileName(document);
} else if (audio != null) {
@ -335,26 +341,26 @@ public class FileLoader {
}
public void loadFile(TLRPC.Video video, boolean force) {
loadFile(video, null, null, null, 0, force, video != null && video.key != null);
loadFile(video, null, null, null, null, 0, force, video != null && video.key != null);
}
public void loadFile(TLRPC.PhotoSize photo, boolean cacheOnly) {
loadFile(null, null, null, photo.location, photo.size, false, cacheOnly || (photo != null && photo.size == 0 || photo.location.key != null));
public void loadFile(TLRPC.PhotoSize photo, String ext, boolean cacheOnly) {
loadFile(null, null, null, photo.location, ext, photo.size, false, cacheOnly || (photo != null && photo.size == 0 || photo.location.key != null));
}
public void loadFile(TLRPC.Document document, boolean force, boolean cacheOnly) {
loadFile(null, document, null, null, 0, force, cacheOnly || document != null && document.key != null);
loadFile(null, document, null, null, null, 0, force, cacheOnly || document != null && document.key != null);
}
public void loadFile(TLRPC.Audio audio, boolean force) {
loadFile(null, null, audio, null, 0, false, audio != null && audio.key != null);
loadFile(null, null, audio, null, null, 0, false, audio != null && audio.key != null);
}
public void loadFile(TLRPC.FileLocation location, int size, boolean cacheOnly) {
loadFile(null, null, null, location, size, true, cacheOnly || size == 0 || (location != null && location.key != null));
public void loadFile(TLRPC.FileLocation location, String ext, int size, boolean cacheOnly) {
loadFile(null, null, null, location, ext, size, true, cacheOnly || size == 0 || (location != null && location.key != null));
}
private void loadFile(final TLRPC.Video video, final TLRPC.Document document, final TLRPC.Audio audio, final TLRPC.FileLocation location, final int locationSize, final boolean force, final boolean cacheOnly) {
private void loadFile(final TLRPC.Video video, final TLRPC.Document document, final TLRPC.Audio audio, final TLRPC.FileLocation location, final String locationExt, final int locationSize, final boolean force, final boolean cacheOnly) {
fileLoaderQueue.postRunnable(new Runnable() {
@Override
public void run() {
@ -362,7 +368,7 @@ public class FileLoader {
if (video != null) {
fileName = getAttachFileName(video);
} else if (location != null) {
fileName = getAttachFileName(location);
fileName = getAttachFileName(location, locationExt);
} else if (document != null) {
fileName = getAttachFileName(document);
} else if (audio != null) {
@ -372,11 +378,11 @@ public class FileLoader {
return;
}
FileLoadOperation operation = null;
FileLoadOperation operation;
operation = loadOperationPaths.get(fileName);
if (operation != null) {
if (force) {
LinkedList<FileLoadOperation> downloadQueue = null;
LinkedList<FileLoadOperation> downloadQueue;
if (audio != null) {
downloadQueue = audioLoadOperationQueue;
} else if (location != null) {
@ -404,7 +410,7 @@ public class FileLoader {
operation = new FileLoadOperation(video);
type = MEDIA_DIR_VIDEO;
} else if (location != null) {
operation = new FileLoadOperation(location, locationSize);
operation = new FileLoadOperation(location, locationExt, locationSize);
type = MEDIA_DIR_IMAGE;
} else if (document != null) {
operation = new FileLoadOperation(document);
@ -489,7 +495,7 @@ public class FileLoader {
@Override
public void run() {
loadOperationPaths.remove(arg1);
FileLoadOperation operation = null;
FileLoadOperation operation;
if (audio != null) {
currentAudioLoadOperationsCount--;
if (!audioLoadOperationQueue.isEmpty()) {
@ -583,51 +589,59 @@ public class FileLoader {
}
public static File getPathToAttach(TLObject attach) {
return getPathToAttach(attach, false);
return getPathToAttach(attach, null, false);
}
public static File getPathToAttach(TLObject attach, boolean forceCache) {
return getPathToAttach(attach, null, forceCache);
}
public static File getPathToAttach(TLObject attach, String ext, boolean forceCache) {
File dir = null;
if (attach instanceof TLRPC.Video) {
TLRPC.Video video = (TLRPC.Video)attach;
if (forceCache || video.key != null) {
dir = getInstance().getDirectory(MEDIA_DIR_CACHE);
} else {
dir = getInstance().getDirectory(MEDIA_DIR_VIDEO);
}
} else if (attach instanceof TLRPC.Document) {
TLRPC.Document document = (TLRPC.Document)attach;
if (forceCache || document.key != null) {
dir = getInstance().getDirectory(MEDIA_DIR_CACHE);
} else {
dir = getInstance().getDirectory(MEDIA_DIR_DOCUMENT);
}
} else if (attach instanceof TLRPC.PhotoSize) {
TLRPC.PhotoSize photoSize = (TLRPC.PhotoSize)attach;
if (forceCache || photoSize.location == null || photoSize.location.key != null || photoSize.location.volume_id == Integer.MIN_VALUE && photoSize.location.local_id < 0) {
dir = getInstance().getDirectory(MEDIA_DIR_CACHE);
} else {
dir = getInstance().getDirectory(MEDIA_DIR_IMAGE);
}
} else if (attach instanceof TLRPC.Audio) {
TLRPC.Audio audio = (TLRPC.Audio)attach;
if (forceCache || audio.key != null) {
dir = getInstance().getDirectory(MEDIA_DIR_CACHE);
} else {
dir = getInstance().getDirectory(MEDIA_DIR_AUDIO);
}
} else if (attach instanceof TLRPC.FileLocation) {
TLRPC.FileLocation fileLocation = (TLRPC.FileLocation)attach;
if (forceCache || fileLocation.key != null || fileLocation.volume_id == Integer.MIN_VALUE && fileLocation.local_id < 0) {
dir = getInstance().getDirectory(MEDIA_DIR_CACHE);
} else {
dir = getInstance().getDirectory(MEDIA_DIR_IMAGE);
if (forceCache) {
dir = getInstance().getDirectory(MEDIA_DIR_CACHE);
} else {
if (attach instanceof TLRPC.Video) {
TLRPC.Video video = (TLRPC.Video) attach;
if (video.key != null) {
dir = getInstance().getDirectory(MEDIA_DIR_CACHE);
} else {
dir = getInstance().getDirectory(MEDIA_DIR_VIDEO);
}
} else if (attach instanceof TLRPC.Document) {
TLRPC.Document document = (TLRPC.Document) attach;
if (document.key != null) {
dir = getInstance().getDirectory(MEDIA_DIR_CACHE);
} else {
dir = getInstance().getDirectory(MEDIA_DIR_DOCUMENT);
}
} else if (attach instanceof TLRPC.PhotoSize) {
TLRPC.PhotoSize photoSize = (TLRPC.PhotoSize) attach;
if (photoSize.location == null || photoSize.location.key != null || photoSize.location.volume_id == Integer.MIN_VALUE && photoSize.location.local_id < 0) {
dir = getInstance().getDirectory(MEDIA_DIR_CACHE);
} else {
dir = getInstance().getDirectory(MEDIA_DIR_IMAGE);
}
} else if (attach instanceof TLRPC.Audio) {
TLRPC.Audio audio = (TLRPC.Audio) attach;
if (audio.key != null) {
dir = getInstance().getDirectory(MEDIA_DIR_CACHE);
} else {
dir = getInstance().getDirectory(MEDIA_DIR_AUDIO);
}
} else if (attach instanceof TLRPC.FileLocation) {
TLRPC.FileLocation fileLocation = (TLRPC.FileLocation) attach;
if (fileLocation.key != null || fileLocation.volume_id == Integer.MIN_VALUE && fileLocation.local_id < 0) {
dir = getInstance().getDirectory(MEDIA_DIR_CACHE);
} else {
dir = getInstance().getDirectory(MEDIA_DIR_IMAGE);
}
}
}
if (dir == null) {
return new File("");
}
return new File(dir, getAttachFileName(attach));
return new File(dir, getAttachFileName(attach, ext));
}
public static TLRPC.PhotoSize getClosestPhotoSizeWithSize(ArrayList<TLRPC.PhotoSize> sizes, int side) {
@ -663,6 +677,9 @@ public class FileLoader {
public static String getDocumentFileName(TLRPC.Document document) {
if (document != null) {
if (document.file_name != null) {
return document.file_name;
}
for (TLRPC.DocumentAttribute documentAttribute : document.attributes) {
if (documentAttribute instanceof TLRPC.TL_documentAttributeFilename) {
return documentAttribute.file_name;
@ -673,35 +690,39 @@ public class FileLoader {
}
public static String getAttachFileName(TLObject attach) {
return getAttachFileName(attach, null);
}
public static String getAttachFileName(TLObject attach, String ext) {
if (attach instanceof TLRPC.Video) {
TLRPC.Video video = (TLRPC.Video)attach;
return video.dc_id + "_" + video.id + ".mp4";
TLRPC.Video video = (TLRPC.Video) attach;
return video.dc_id + "_" + video.id + "." + (ext != null ? ext : "mp4");
} else if (attach instanceof TLRPC.Document) {
TLRPC.Document document = (TLRPC.Document)attach;
String ext = getDocumentFileName(document);
int idx = -1;
if (ext == null || (idx = ext.lastIndexOf(".")) == -1) {
ext = "";
TLRPC.Document document = (TLRPC.Document) attach;
String docExt = getDocumentFileName(document);
int idx;
if (docExt == null || (idx = docExt.lastIndexOf(".")) == -1) {
docExt = "";
} else {
ext = ext.substring(idx);
docExt = docExt.substring(idx);
}
if (ext.length() > 1) {
return document.dc_id + "_" + document.id + ext;
if (docExt.length() > 1) {
return document.dc_id + "_" + document.id + docExt;
} else {
return document.dc_id + "_" + document.id;
}
} else if (attach instanceof TLRPC.PhotoSize) {
TLRPC.PhotoSize photo = (TLRPC.PhotoSize)attach;
TLRPC.PhotoSize photo = (TLRPC.PhotoSize) attach;
if (photo.location == null) {
return "";
}
return photo.location.volume_id + "_" + photo.location.local_id + "." + (photo.location.ext != null ? photo.location.ext : "jpg");
return photo.location.volume_id + "_" + photo.location.local_id + "." + (ext != null ? ext : "jpg");
} else if (attach instanceof TLRPC.Audio) {
TLRPC.Audio audio = (TLRPC.Audio)attach;
return audio.dc_id + "_" + audio.id + ".ogg";
TLRPC.Audio audio = (TLRPC.Audio) attach;
return audio.dc_id + "_" + audio.id + "." + (ext != null ? ext : "ogg");
} else if (attach instanceof TLRPC.FileLocation) {
TLRPC.FileLocation location = (TLRPC.FileLocation)attach;
return location.volume_id + "_" + location.local_id + "." + (location.ext != null ? location.ext : "jpg");
TLRPC.FileLocation location = (TLRPC.FileLocation) attach;
return location.volume_id + "_" + location.local_id + "." + (ext != null ? ext : "jpg");
}
return "";
}

View File

@ -1,14 +1,13 @@
/*
* This is the source code of Telegram for Android v. 1.3.2.
* This is the source code of Telegram for Android v. 2.x.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.
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.messenger;
import android.net.Uri;
import android.util.Log;
import org.telegram.android.time.FastDateFormat;
@ -16,7 +15,6 @@ import org.telegram.android.time.FastDateFormat;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Locale;
public class FileLog {
@ -50,14 +48,8 @@ public class FileLog {
return;
}
File dir = new File(sdCard.getAbsolutePath() + "/logs");
if (dir == null) {
return;
}
dir.mkdirs();
currentFile = new File(dir, dateFormat.format(System.currentTimeMillis()) + ".txt");
if (currentFile == null) {
return;
}
} catch (Exception e) {
e.printStackTrace();
}
@ -181,7 +173,6 @@ public class FileLog {
}
public static void cleanupLogs() {
ArrayList<Uri> uris = new ArrayList<>();
File sdCard = ApplicationLoader.applicationContext.getExternalFilesDir(null);
File dir = new File (sdCard.getAbsolutePath() + "/logs");
File[] files = dir.listFiles();

View File

@ -1,9 +1,9 @@
/*
* This is the source code of Telegram for Android v. 1.3.2.
* This is the source code of Telegram for Android v. 2.x.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.
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.messenger;
@ -46,7 +46,7 @@ public class FileUploadOperation {
private boolean started = false;
public interface FileUploadOperationDelegate {
void didFinishUploadingFile(FileUploadOperation operation, TLRPC.InputFile inputFile, TLRPC.InputEncryptedFile inputEncryptedFile);
void didFinishUploadingFile(FileUploadOperation operation, TLRPC.InputFile inputFile, TLRPC.InputEncryptedFile inputEncryptedFile, byte[] key, byte[] iv);
void didFailedUploadingFile(FileUploadOperation operation);
void didChangedUploadProgress(FileUploadOperation operation, float progress);
}
@ -190,8 +190,12 @@ public class FileUploadOperation {
if (ivString != null && keyString != null) {
key = Utilities.hexToBytes(keyString);
iv = Utilities.hexToBytes(ivString);
ivChange = new byte[32];
System.arraycopy(iv, 0, ivChange, 0, 32);
if (key != null && iv != null && key.length == 32 && iv.length == 32) {
ivChange = new byte[32];
System.arraycopy(iv, 0, ivChange, 0, 32);
} else {
rewrite = true;
}
} else {
rewrite = true;
}
@ -234,6 +238,11 @@ public class FileUploadOperation {
String ivcString = preferences.getString(fileKey + "_ivc", null);
if (ivcString != null) {
ivChange = Utilities.hexToBytes(ivcString);
if (ivChange == null || ivChange.length != 32) {
rewrite = true;
currentUploaded = 0;
currentPartNum = 0;
}
} else {
rewrite = true;
currentUploaded = 0;
@ -369,7 +378,7 @@ public class FileUploadOperation {
result.parts = currentPartNum;
result.id = currentFileId;
result.name = uploadingFilePath.substring(uploadingFilePath.lastIndexOf("/") + 1);
delegate.didFinishUploadingFile(FileUploadOperation.this, result, null);
delegate.didFinishUploadingFile(FileUploadOperation.this, result, null, null, null);
cleanup();
} else {
TLRPC.InputEncryptedFile result;
@ -382,9 +391,7 @@ public class FileUploadOperation {
result.parts = currentPartNum;
result.id = currentFileId;
result.key_fingerprint = fingerprint;
result.iv = iv;
result.key = key;
delegate.didFinishUploadingFile(FileUploadOperation.this, null, result);
delegate.didFinishUploadingFile(FileUploadOperation.this, null, result, key, iv);
cleanup();
}
} else {

View File

@ -1,9 +1,9 @@
/*
* This is the source code of Telegram for Android v. 1.3.2.
* This is the source code of Telegram for Android v. 2.x.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.
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.messenger;

View File

@ -1,14 +1,68 @@
/*
* This is the source code of Telegram for Android v. 1.3.2.
* This is the source code of Telegram for Android v. 2.x.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.
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.messenger;
public class MessageKeyData {
public byte[] aesKey;
public byte[] aesIv;
public static MessageKeyData generateMessageKeyData(byte[] authKey, byte[] messageKey, boolean incoming) {
MessageKeyData keyData = new MessageKeyData();
if (authKey == null || authKey.length == 0) {
keyData.aesIv = null;
keyData.aesKey = null;
return keyData;
}
int x = incoming ? 8 : 0;
SerializedData data = new SerializedData();
data.writeRaw(messageKey);
data.writeRaw(authKey, x, 32);
byte[] sha1_a = Utilities.computeSHA1(data.toByteArray());
data.cleanup();
data = new SerializedData();
data.writeRaw(authKey, 32 + x, 16);
data.writeRaw(messageKey);
data.writeRaw(authKey, 48 + x, 16);
byte[] sha1_b = Utilities.computeSHA1(data.toByteArray());
data.cleanup();
data = new SerializedData();
data.writeRaw(authKey, 64 + x, 32);
data.writeRaw(messageKey);
byte[] sha1_c = Utilities.computeSHA1(data.toByteArray());
data.cleanup();
data = new SerializedData();
data.writeRaw(messageKey);
data.writeRaw(authKey, 96 + x, 32);
byte[] sha1_d = Utilities.computeSHA1(data.toByteArray());
data.cleanup();
data = new SerializedData();
data.writeRaw(sha1_a, 0, 8);
data.writeRaw(sha1_b, 8, 12);
data.writeRaw(sha1_c, 4, 12);
keyData.aesKey = data.toByteArray();
data.cleanup();
data = new SerializedData();
data.writeRaw(sha1_a, 8, 12);
data.writeRaw(sha1_b, 0, 8);
data.writeRaw(sha1_c, 16, 4);
data.writeRaw(sha1_d, 0, 8);
keyData.aesIv = data.toByteArray();
data.cleanup();
return keyData;
}
}

View File

@ -1,9 +1,9 @@
/*
* This is the source code of Telegram for Android v. 1.3.2.
* This is the source code of Telegram for Android v. 2.x.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.
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.messenger;

View File

@ -1,9 +1,9 @@
/*
* This is the source code of Telegram for Android v. 1.3.2.
* This is the source code of Telegram for Android v. 2.x.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.
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.messenger;

View File

@ -1,9 +1,9 @@
/*
* This is the source code of Telegram for Android v. 1.3.2.
* This is the source code of Telegram for Android v. 2.x.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.
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.messenger;

View File

@ -1,9 +1,9 @@
/*
* This is the source code of Telegram for Android v. 1.3.2.
* This is the source code of Telegram for Android v. 2.x.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.
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.messenger;

View File

@ -1,9 +1,9 @@
/*
* This is the source code of Telegram for Android v. 1.3.2.
* This is the source code of Telegram for Android v. 2.x.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.
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.messenger;
@ -13,7 +13,7 @@ import java.util.HashMap;
public class TLClassStore {
private HashMap<Integer, Class> classStore;
public TLClassStore () {
public TLClassStore() {
classStore = new HashMap<>();
classStore.put(TLRPC.TL_futuresalts.constructor, TLRPC.TL_futuresalts.class);
@ -108,26 +108,18 @@ public class TLClassStore {
}
public TLObject TLdeserialize(AbsSerializedData stream, int constructor, boolean exception) {
try {
return TLdeserialize(stream, constructor, null, exception);
} catch (Exception e) {
return null;
}
}
public TLObject TLdeserialize(AbsSerializedData stream, int constructor, TLObject request, boolean exception) {
Class objClass = classStore.get(constructor);
if (objClass != null) {
TLObject response;
try {
TLObject response = (TLObject)objClass.newInstance();
response.readParams(stream, exception);
return response;
response = (TLObject) objClass.newInstance();
} catch (Throwable e) {
FileLog.e("tmessages", "can't create class");
FileLog.e("tmessages", e);
return null;
}
} else {
return null;
response.readParams(stream, exception);
return response;
}
return null;
}
}

View File

@ -1,14 +1,15 @@
/*
* This is the source code of Telegram for Android v. 1.3.2.
* This is the source code of Telegram for Android v. 2.x.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.
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.messenger;
public class TLObject {
public boolean disableFree = false;
public TLObject() {
@ -19,10 +20,6 @@ public class TLObject {
}
public byte[] serialize() {
return null;
}
public void serializeToStream(AbsSerializedData stream) {
}

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
/*
* This is the source code of Telegram for Android v. 1.3.2.
* This is the source code of Telegram for Android v. 2.x.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.
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.messenger;
@ -20,6 +20,7 @@ import jawnae.pyronet.PyroClient;
import jawnae.pyronet.PyroSelector;
public class TcpConnection extends ConnectionContext {
public enum TcpConnectionState {
TcpConnectionStageIdle,
TcpConnectionStageConnecting,
@ -30,8 +31,11 @@ public class TcpConnection extends ConnectionContext {
public interface TcpConnectionDelegate {
void tcpConnectionClosed(TcpConnection connection);
void tcpConnectionConnected(TcpConnection connection);
void tcpConnectionQuiackAckReceived(TcpConnection connection, int ack);
void tcpConnectionReceivedData(TcpConnection connection, ByteBufferDesc data, int length);
}
@ -41,6 +45,7 @@ public class TcpConnection extends ConnectionContext {
public volatile int channelToken = 0;
private String hostAddress;
private int hostPort;
private int currentAddressFlag;
private int datacenterId;
private int failedConnectionCount;
public TcpConnectionDelegate delegate;
@ -62,13 +67,14 @@ public class TcpConnection extends ConnectionContext {
if (selector == null) {
selector = new PyroSelector();
selector.spawnNetworkThread("network thread");
BuffersStorage storage = BuffersStorage.getInstance();
BuffersStorage.getInstance();
}
datacenterId = did;
connectionState = TcpConnectionState.TcpConnectionStageIdle;
}
static volatile Integer nextChannelToken = 1;
static int generateChannelToken() {
return nextChannelToken++;
}
@ -101,8 +107,27 @@ public class TcpConnection extends ConnectionContext {
connectionState = TcpConnectionState.TcpConnectionStageConnecting;
try {
Datacenter datacenter = ConnectionsManager.getInstance().datacenterWithId(datacenterId);
hostAddress = datacenter.getCurrentAddress();
hostPort = datacenter.getCurrentPort();
if (transportRequestClass == RPCRequest.RPCRequestClassDownloadMedia) {
currentAddressFlag = 2;
if (ConnectionsManager.useIpv6Address()) {
currentAddressFlag |= 1;
}
hostAddress = datacenter.getCurrentAddress(currentAddressFlag);
if (hostAddress == null) {
currentAddressFlag = 0;
if (ConnectionsManager.useIpv6Address()) {
currentAddressFlag |= 1;
}
hostAddress = datacenter.getCurrentAddress(currentAddressFlag);
}
} else {
currentAddressFlag = 0;
if (ConnectionsManager.useIpv6Address()) {
currentAddressFlag |= 1;
}
hostAddress = datacenter.getCurrentAddress(currentAddressFlag);
}
hostPort = datacenter.getCurrentPort(currentAddressFlag);
try {
synchronized (timerSync) {
@ -163,7 +188,7 @@ public class TcpConnection extends ConnectionContext {
} catch (Exception e2) {
FileLog.e("tmessages", e2);
}
connectionState = TcpConnectionState.TcpConnectionStageReconnecting;
connectionState = TcpConnectionState.TcpConnectionStageReconnecting;
if (delegate != null) {
final TcpConnectionDelegate finalDelegate = delegate;
Utilities.stageQueue.postRunnable(new Runnable() {
@ -186,7 +211,7 @@ public class TcpConnection extends ConnectionContext {
isNextPort = true;
if (failedConnectionCount > willRetryConnectCount) {
Datacenter datacenter = ConnectionsManager.getInstance().datacenterWithId(datacenterId);
datacenter.nextAddressOrPort();
datacenter.nextAddressOrPort(currentAddressFlag);
failedConnectionCount = 0;
}
}
@ -319,7 +344,7 @@ public class TcpConnection extends ConnectionContext {
ByteBufferDesc buffer = BuffersStorage.getInstance().getFreeBuffer(bufferLen);
if (firstPacket) {
buffer.writeByte((byte)0xef);
buffer.writeByte((byte) 0xef);
firstPacket = false;
}
if (packetLength < 0x7f) {
@ -354,12 +379,10 @@ public class TcpConnection extends ConnectionContext {
ByteBuffer parseLaterBuffer = null;
if (restOfTheData != null) {
if (lastPacketLength == 0) {
//FileLog.e("tmessages", this + " write addition data to restOfTheData");
if (restOfTheData.capacity() - restOfTheData.position() >= buffer.limit()) {
restOfTheData.limit(restOfTheData.position() + buffer.limit());
restOfTheData.put(buffer);
buffer = restOfTheData.buffer;
//FileLog.e("tmessages", this + " no need to recreate buffer");
} else {
ByteBufferDesc newBuffer = BuffersStorage.getInstance().getFreeBuffer(restOfTheData.limit() + buffer.limit());
restOfTheData.rewind();
@ -368,30 +391,23 @@ public class TcpConnection extends ConnectionContext {
buffer = newBuffer.buffer;
BuffersStorage.getInstance().reuseFreeBuffer(restOfTheData);
restOfTheData = newBuffer;
//FileLog.e("tmessages", this + " NEED to recreate buffer");
}
} else {
//FileLog.e("tmessages", this + " write buffer to restOfTheData buffer of len = " + lastPacketLength);
int len = 0;
int len;
if (lastPacketLength - restOfTheData.position() <= buffer.limit()) {
len = lastPacketLength - restOfTheData.position();
//FileLog.e("tmessages", this + " received buffer - OK!");
} else {
len = buffer.limit();
//FileLog.e("tmessages", this + " received buffer less than need");
}
int oldLimit = buffer.limit();
buffer.limit(len);
restOfTheData.put(buffer);
buffer.limit(oldLimit);
if (restOfTheData.position() != lastPacketLength) {
//FileLog.e("tmessages", this + " don't get much data to restOfTheData");
return;
} else {
//FileLog.e("tmessages", this + " get much data to restOfTheData - OK!");
if (buffer.hasRemaining()) {
parseLaterBuffer = buffer;
//FileLog.e("tmessages", this + " something remain in the received buffer");
} else {
parseLaterBuffer = null;
}
@ -427,10 +443,8 @@ public class TcpConnection extends ConnectionContext {
restOfTheData.put(buffer);
restOfTheData.limit(restOfTheData.position());
lastPacketLength = 0;
//FileLog.e("tmessages", this + " 1 - size less than 4 bytes - write to free buffer");
if (reuseLater != null) {
BuffersStorage.getInstance().reuseFreeBuffer(reuseLater);
//FileLog.e("tmessages", this + " 1 - reuse later buffer1");
}
break;
}
@ -450,11 +464,10 @@ public class TcpConnection extends ConnectionContext {
}
if (fByte != 0x7f) {
currentPacketLength = ((int)fByte) * 4;
currentPacketLength = ((int) fByte) * 4;
} else {
buffer.reset();
if (buffer.remaining() < 4) {
//FileLog.e("tmessages", this + " 2 - size less than 4 bytes - write to free buffer");
if (restOfTheData == null || restOfTheData != null && restOfTheData.position() != 0) {
ByteBufferDesc reuseLater = restOfTheData;
restOfTheData = BuffersStorage.getInstance().getFreeBuffer(16384);
@ -463,7 +476,6 @@ public class TcpConnection extends ConnectionContext {
lastPacketLength = 0;
if (reuseLater != null) {
BuffersStorage.getInstance().reuseFreeBuffer(reuseLater);
//FileLog.e("tmessages", this + " 2 - reuse later buffer1");
}
} else {
restOfTheData.position(restOfTheData.limit());
@ -491,10 +503,8 @@ public class TcpConnection extends ConnectionContext {
if (restOfTheData != null && restOfTheData.capacity() < len) {
reuseLater = restOfTheData;
restOfTheData = null;
//FileLog.e("tmessages", this + " not enough space for len, recreate buffer = " + len);
}
if (restOfTheData == null) {
//FileLog.e("tmessages", this + " write to restOfTheData, get buffer len = " + len);
buffer.reset();
restOfTheData = BuffersStorage.getInstance().getFreeBuffer(len);
restOfTheData.put(buffer);
@ -505,7 +515,6 @@ public class TcpConnection extends ConnectionContext {
lastPacketLength = len;
if (reuseLater != null) {
BuffersStorage.getInstance().reuseFreeBuffer(reuseLater);
//FileLog.e("tmessages", this + " 3 - reuse later buffer1");
}
return;
}
@ -533,17 +542,14 @@ public class TcpConnection extends ConnectionContext {
if (lastPacketLength != 0 && restOfTheData.position() == lastPacketLength || lastPacketLength == 0 && !restOfTheData.hasRemaining()) {
BuffersStorage.getInstance().reuseFreeBuffer(restOfTheData);
restOfTheData = null;
//FileLog.e("tmessages", this + " restOfTheData parsed null it");
} else {
restOfTheData.compact();
restOfTheData.limit(restOfTheData.position());
restOfTheData.position(0);
//FileLog.e("tmessages", this + " restOfTheData NOT parsed, compact");
}
}
if (parseLaterBuffer != null) {
//FileLog.e("tmessages", this + " there is parseLaterBuffer");
buffer = parseLaterBuffer;
parseLaterBuffer = null;
}
@ -597,7 +603,7 @@ public class TcpConnection extends ConnectionContext {
isNextPort = true;
if (failedConnectionCount > willRetryConnectCount || switchToNextPort) {
Datacenter datacenter = ConnectionsManager.getInstance().datacenterWithId(datacenterId);
datacenter.nextAddressOrPort();
datacenter.nextAddressOrPort(currentAddressFlag);
failedConnectionCount = 0;
}
}

View File

@ -1,9 +1,9 @@
/*
* This is the source code of Telegram for Android v. 1.3.2.
* This is the source code of Telegram for Android v. 2.x.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.
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.messenger;
@ -17,6 +17,7 @@ import org.telegram.android.MessagesStorage;
import java.io.File;
public class UserConfig {
private static TLRPC.User currentUser;
public static boolean registeredForPush = false;
public static boolean registeredForInternalPush = false;
@ -31,6 +32,7 @@ public class UserConfig {
public static boolean saveIncomingPhotos = false;
public static int contactsVersion = 1;
public static String passcodeHash = "";
public static byte[] passcodeSalt = new byte[0];
public static boolean appLocked = false;
public static int passcodeType = 0;
public static int autoLockIn = 60 * 60;
@ -68,6 +70,7 @@ public class UserConfig {
editor.putBoolean("registeredForInternalPush", registeredForInternalPush);
editor.putBoolean("blockedUsersLoaded", blockedUsersLoaded);
editor.putString("passcodeHash1", passcodeHash);
editor.putString("passcodeSalt", passcodeSalt.length > 0 ? Base64.encodeToString(passcodeSalt, Base64.DEFAULT) : "");
editor.putBoolean("appLocked", appLocked);
editor.putInt("passcodeType", passcodeType);
editor.putInt("autoLockIn", autoLockIn);
@ -85,6 +88,7 @@ public class UserConfig {
} else {
editor.remove("user");
}
editor.commit();
if (oldFile != null) {
oldFile.delete();
@ -211,10 +215,51 @@ public class UserConfig {
data.cleanup();
}
}
String passcodeSaltString = preferences.getString("passcodeSalt", "");
if (passcodeSaltString.length() > 0) {
passcodeSalt = Base64.decode(passcodeSaltString, Base64.DEFAULT);
} else {
passcodeSalt = new byte[0];
}
}
}
}
public static boolean checkPasscode(String passcode) {
if (passcodeSalt.length == 0) {
boolean result = Utilities.MD5(passcode).equals(passcodeHash);
if (result) {
try {
passcodeSalt = new byte[16];
Utilities.random.nextBytes(passcodeSalt);
byte[] passcodeBytes = passcode.getBytes("UTF-8");
byte[] bytes = new byte[32 + passcodeBytes.length];
System.arraycopy(passcodeSalt, 0, bytes, 0, 16);
System.arraycopy(passcodeBytes, 0, bytes, 16, passcodeBytes.length);
System.arraycopy(passcodeSalt, 0, bytes, passcodeBytes.length + 16, 16);
passcodeHash = Utilities.bytesToHex(Utilities.computeSHA256(bytes, 0, bytes.length));
saveConfig(false);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
return result;
} else {
try {
byte[] passcodeBytes = passcode.getBytes("UTF-8");
byte[] bytes = new byte[32 + passcodeBytes.length];
System.arraycopy(passcodeSalt, 0, bytes, 0, 16);
System.arraycopy(passcodeBytes, 0, bytes, 16, passcodeBytes.length);
System.arraycopy(passcodeSalt, 0, bytes, passcodeBytes.length + 16, 16);
String hash = Utilities.bytesToHex(Utilities.computeSHA256(bytes, 0, bytes.length));
return passcodeHash.equals(hash);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
return false;
}
public static void clearConfig() {
currentUser = null;
registeredForInternalPush = false;
@ -229,6 +274,7 @@ public class UserConfig {
appLocked = false;
passcodeType = 0;
passcodeHash = "";
passcodeSalt = new byte[0];
autoLockIn = 60 * 60;
lastPauseTime = 0;
isWaitingForPasscodeEnter = false;

View File

@ -1,43 +1,24 @@
/*
* This is the source code of Telegram for Android v. 1.3.2.
* This is the source code of Telegram for Android v. 2.x.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.
* Copyright Nikolai Kudashov, 2013-2015.
*/
package org.telegram.messenger;
import android.app.Activity;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.text.SpannableStringBuilder;
import android.util.Base64;
import net.hockeyapp.android.CrashManager;
import net.hockeyapp.android.CrashManagerListener;
import net.hockeyapp.android.UpdateManager;
import org.telegram.android.AndroidUtilities;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.security.KeyFactory;
@ -45,9 +26,7 @@ import java.security.MessageDigest;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.spec.RSAPublicKeySpec;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;
@ -56,6 +35,7 @@ import java.util.zip.GZIPOutputStream;
import javax.crypto.Cipher;
public class Utilities {
public static Pattern pattern = Pattern.compile("[0-9]+");
public static SecureRandom random = new SecureRandom();
@ -111,13 +91,19 @@ public class Utilities {
}
public native static long doPQNative(long _what);
public native static void loadBitmap(String path, Bitmap bitmap, int scale, int width, int height, int stride);
public native static int pinBitmap(Bitmap bitmap);
public native static void blurBitmap(Object bitmap, int radius, int unpin);
public native static void calcCDT(ByteBuffer hsvBuffer, int width, int height, ByteBuffer buffer);
public native static Bitmap loadWebpImage(ByteBuffer buffer, int len, BitmapFactory.Options options);
public native static Bitmap loadBpgImage(ByteBuffer buffer, int len, BitmapFactory.Options options);
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);
public static void aesIgeEncryption(ByteBuffer buffer, byte[] key, byte[] iv, boolean encrypt, boolean changeIv, int offset, int length) {
@ -287,12 +273,13 @@ public class Utilities {
if (arr1 == null || arr2 == null || arr1.length - offset1 != arr2.length - offset2 || arr1.length - offset1 < 0) {
return false;
}
boolean result = true;
for (int a = offset1; a < arr1.length; a++) {
if (arr1[a + offset1] != arr2[a + offset2]) {
return false;
result = false;
}
}
return true;
return result;
}
public static byte[] computeSHA1(byte[] convertme, int offset, int len) {
@ -321,7 +308,7 @@ public class Utilities {
convertme.limit(oldl);
convertme.position(oldp);
}
return null;
return new byte[0];
}
public static byte[] computeSHA1(ByteBuffer convertme) {
@ -362,59 +349,6 @@ public class Utilities {
+ (((long) bytes[3] & 0xFF) << 24) + (((long) bytes[2] & 0xFF) << 16) + (((long) bytes[1] & 0xFF) << 8) + ((long) bytes[0] & 0xFF);
}
public static MessageKeyData generateMessageKeyData(byte[] authKey, byte[] messageKey, boolean incoming) {
MessageKeyData keyData = new MessageKeyData();
if (authKey == null || authKey.length == 0) {
keyData.aesIv = null;
keyData.aesKey = null;
return keyData;
}
int x = incoming ? 8 : 0;
SerializedData data = new SerializedData();
data.writeRaw(messageKey);
data.writeRaw(authKey, x, 32);
byte[] sha1_a = Utilities.computeSHA1(data.toByteArray());
data.cleanup();
data = new SerializedData();
data.writeRaw(authKey, 32 + x, 16);
data.writeRaw(messageKey);
data.writeRaw(authKey, 48 + x, 16);
byte[] sha1_b = Utilities.computeSHA1(data.toByteArray());
data.cleanup();
data = new SerializedData();
data.writeRaw(authKey, 64 + x, 32);
data.writeRaw(messageKey);
byte[] sha1_c = Utilities.computeSHA1(data.toByteArray());
data.cleanup();
data = new SerializedData();
data.writeRaw(messageKey);
data.writeRaw(authKey, 96 + x, 32);
byte[] sha1_d = Utilities.computeSHA1(data.toByteArray());
data.cleanup();
data = new SerializedData();
data.writeRaw(sha1_a, 0, 8);
data.writeRaw(sha1_b, 8, 12);
data.writeRaw(sha1_c, 4, 12);
keyData.aesKey = data.toByteArray();
data.cleanup();
data = new SerializedData();
data.writeRaw(sha1_a, 8, 12);
data.writeRaw(sha1_b, 0, 8);
data.writeRaw(sha1_c, 16, 4);
data.writeRaw(sha1_d, 0, 8);
keyData.aesIv = data.toByteArray();
data.cleanup();
return keyData;
}
public static TLObject decompress(byte[] data, TLObject parentObject, boolean exception) {
final int BUFFER_SIZE = 16384;
ByteArrayInputStream is = new ByteArrayInputStream(data);
@ -477,42 +411,6 @@ public class Utilities {
return packedData;
}
public static boolean copyFile(InputStream sourceFile, File destFile) throws IOException {
OutputStream out = new FileOutputStream(destFile);
byte[] buf = new byte[4096];
int len;
while ((len = sourceFile.read(buf)) > 0) {
Thread.yield();
out.write(buf, 0, len);
}
out.close();
return true;
}
public static boolean copyFile(File sourceFile, File destFile) throws IOException {
if (!destFile.exists()) {
destFile.createNewFile();
}
FileInputStream source = null;
FileOutputStream destination = null;
try {
source = new FileInputStream(sourceFile);
destination = new FileOutputStream(destFile);
destination.getChannel().transferFrom(source.getChannel(), 0, source.getChannel().size());
} catch (Exception e) {
FileLog.e("tmessages", e);
return false;
} finally {
if (source != null) {
source.close();
}
if (destination != null) {
destination.close();
}
}
return true;
}
public static String MD5(String md5) {
if (md5 == null) {
return null;
@ -530,249 +428,4 @@ public class Utilities {
}
return null;
}
public static void addMediaToGallery(String fromPath) {
if (fromPath == null) {
return;
}
File f = new File(fromPath);
Uri contentUri = Uri.fromFile(f);
addMediaToGallery(contentUri);
}
public static void addMediaToGallery(Uri uri) {
if (uri == null) {
return;
}
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mediaScanIntent.setData(uri);
ApplicationLoader.applicationContext.sendBroadcast(mediaScanIntent);
}
private static File getAlbumDir() {
File storageDir = null;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
storageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "Telegram");
if (storageDir != null) {
if (!storageDir.mkdirs()) {
if (!storageDir.exists()){
FileLog.d("tmessages", "failed to create directory");
return null;
}
}
}
} else {
FileLog.d("tmessages", "External storage is not mounted READ/WRITE.");
}
return storageDir;
}
public static String getPath(final Uri uri) {
try {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
if (isKitKat && DocumentsContract.isDocumentUri(ApplicationLoader.applicationContext, uri)) {
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
} else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(ApplicationLoader.applicationContext, contentUri, null, null);
} else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
switch (type) {
case "image":
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
break;
case "video":
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
break;
case "audio":
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
break;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[] {
split[1]
};
return getDataColumn(ApplicationLoader.applicationContext, contentUri, selection, selectionArgs);
}
} else if ("content".equalsIgnoreCase(uri.getScheme())) {
return getDataColumn(ApplicationLoader.applicationContext, uri, null, null);
} else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
return null;
}
public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {
column
};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
} finally {
if (cursor != null) {
cursor.close();
}
}
return null;
}
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
public static File generatePicturePath() {
try {
File storageDir = getAlbumDir();
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
return new File(storageDir, "IMG_" + timeStamp + ".jpg");
} catch (Exception e) {
FileLog.e("tmessages", e);
}
return null;
}
public static CharSequence generateSearchName(String name, String name2, String q) {
if (name == null && name2 == null) {
return "";
}
SpannableStringBuilder builder = new SpannableStringBuilder();
String wholeString = name;
if (wholeString == null || wholeString.length() == 0) {
wholeString = name2;
} else if (name2 != null && name2.length() != 0) {
wholeString += " " + name2;
}
wholeString = wholeString.trim();
String lower = " " + wholeString.toLowerCase();
int index = -1;
int lastIndex = 0;
while ((index = lower.indexOf(" " + q, lastIndex)) != -1) {
int idx = index - (index == 0 ? 0 : 1);
int end = q.length() + (index == 0 ? 0 : 1) + idx;
if (lastIndex != 0 && lastIndex != idx + 1) {
builder.append(wholeString.substring(lastIndex, idx));
} else if (lastIndex == 0 && idx != 0) {
builder.append(wholeString.substring(0, idx));
}
String query = wholeString.substring(idx, end);
if (query.startsWith(" ")) {
builder.append(" ");
}
query = query.trim();
builder.append(AndroidUtilities.replaceTags("<c#ff4d83b3>" + query + "</c>"));
lastIndex = end;
}
if (lastIndex != -1 && lastIndex != wholeString.length()) {
builder.append(wholeString.substring(lastIndex, wholeString.length()));
}
return builder;
}
public static File generateVideoPath() {
try {
File storageDir = getAlbumDir();
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
return new File(storageDir, "VID_" + timeStamp + ".mp4");
} catch (Exception e) {
FileLog.e("tmessages", e);
}
return null;
}
public static String formatFileSize(long size) {
if (size < 1024) {
return String.format("%d B", size);
} else if (size < 1024 * 1024) {
return String.format("%.1f KB", size / 1024.0f);
} else if (size < 1024 * 1024 * 1024) {
return String.format("%.1f MB", size / 1024.0f / 1024.0f);
} else {
return String.format("%.1f GB", size / 1024.0f / 1024.0f / 1024.0f);
}
}
public static byte[] decodeQuotedPrintable(final byte[] bytes) {
if (bytes == null) {
return null;
}
final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
for (int i = 0; i < bytes.length; i++) {
final int b = bytes[i];
if (b == '=') {
try {
final int u = Character.digit((char) bytes[++i], 16);
final int l = Character.digit((char) bytes[++i], 16);
buffer.write((char) ((u << 4) + l));
} catch (Exception e) {
FileLog.e("tmessages", e);
return null;
}
} else {
buffer.write(b);
}
}
byte[] array = buffer.toByteArray();
try {
buffer.close();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
return array;
}
public static void checkForCrashes(Activity context) {
CrashManager.register(context, BuildVars.HOCKEY_APP_HASH, new CrashManagerListener() {
@Override
public boolean includeDeviceData() {
return true;
}
});
}
public static void checkForUpdates(Activity context) {
if (BuildVars.DEBUG_VERSION) {
UpdateManager.register(context, BuildVars.HOCKEY_APP_HASH);
}
}
}

View File

@ -88,7 +88,7 @@ public class ActionBar extends FrameLayout {
}
int maxTextWidth = 0;
LayoutParams layoutParams = null;
LayoutParams layoutParams;
if (titleTextView != null && titleTextView.getVisibility() == VISIBLE) {
if (!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
@ -121,7 +121,7 @@ public class ActionBar extends FrameLayout {
maxTextWidth = Math.max(maxTextWidth, subTitleTextView.getMeasuredWidth());
}
int x = 0;
int x;
if (backButtonImageView != null && backButtonImageView.getVisibility() == VISIBLE) {
x = AndroidUtilities.dp(AndroidUtilities.isTablet() ? 80 : 72);
} else {

View File

@ -71,7 +71,7 @@ public class ActionBarLayout extends FrameLayout {
if (view instanceof ActionBar && view.getVisibility() == VISIBLE) {
if (((ActionBar) view).getCastShadows()) {
actionBarHeight = view.getMeasuredHeight();
wasActionBar = true;
//wasActionBar = true;
}
break;
}
@ -424,7 +424,7 @@ public class ActionBarLayout extends FrameLayout {
float velX = velocityTracker.getXVelocity();
float velY = velocityTracker.getYVelocity();
final boolean backAnimation = x < containerView.getMeasuredWidth() / 3.0f && (velX < 3500 || velX < velY);
float distToMove = 0;
float distToMove;
if (!backAnimation) {
distToMove = containerView.getMeasuredWidth() - x;
animatorSet.playTogether(
@ -674,6 +674,7 @@ public class ActionBarLayout extends FrameLayout {
animators.add(ObjectAnimatorProxy.ofFloat(backgroundView, "alpha", 0.0f, 1.0f));
}
fragment.onOpenAnimationStart();
currentAnimation = new AnimatorSetProxy();
currentAnimation.playTogether(animators);
currentAnimation.setInterpolator(accelerateDecelerateInterpolator);
@ -703,6 +704,7 @@ public class ActionBarLayout extends FrameLayout {
};
ViewProxy.setAlpha(containerView, 0.0f);
ViewProxy.setTranslationX(containerView, 48.0f);
fragment.onOpenAnimationStart();
startLayoutAnimation(true, true);
/*currentAnimation = new AnimatorSetProxy();
currentAnimation.playTogether(
@ -733,6 +735,7 @@ public class ActionBarLayout extends FrameLayout {
ViewProxy.setAlpha(backgroundView, 1.0f);
backgroundView.setVisibility(VISIBLE);
}
fragment.onOpenAnimationStart();
fragment.onOpenAnimationEnd();
}
return true;

View File

@ -10,7 +10,6 @@ package org.telegram.ui.ActionBar;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
@ -32,14 +31,6 @@ public class ActionBarMenu extends LinearLayout {
super(context);
}
public ActionBarMenu(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ActionBarMenu(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public View addItemResource(int id, int resourceId) {
LayoutInflater li = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = li.inflate(resourceId, null);

View File

@ -42,10 +42,22 @@ import java.lang.reflect.Field;
public class ActionBarMenuItem extends FrameLayoutFixed {
public static class ActionBarMenuItemSearchListener {
public void onSearchExpand() { }
public boolean onSearchCollapse() { return true; }
public void onTextChanged(EditText editText) { }
public void onSearchPressed(EditText editText) { }
public void onSearchExpand() {
}
public boolean onSearchCollapse() {
return true;
}
public void onTextChanged(EditText editText) {
}
public void onSearchPressed(EditText editText) {
}
}
public interface ActionBarMenuItemDelegate {
void onItemClick(int id);
}
private ActionBarPopupWindow.ActionBarPopupWindowLayout popupLayout;
@ -63,8 +75,8 @@ public class ActionBarMenuItem extends FrameLayoutFixed {
private Runnable showMenuRunnable;
private boolean showFromBottom;
private int menuHeight = AndroidUtilities.dp(16);
private boolean needOffset = Build.VERSION.SDK_INT >= 21;
private int subMenuOpenSide = 0;
private ActionBarMenuItemDelegate delegate;
public ActionBarMenuItem(Context context, ActionBarMenu menu, int background) {
super(context);
@ -115,8 +127,8 @@ public class ActionBarMenuItem extends FrameLayoutFixed {
for (int a = 0; a < popupLayout.getChildCount(); a++) {
View child = popupLayout.getChildAt(a);
child.getHitRect(rect);
if ((Integer)child.getTag() < 100) {
if (!rect.contains((int)x, (int)y)) {
if ((Integer) child.getTag() < 100) {
if (!rect.contains((int) x, (int) y)) {
child.setPressed(false);
child.setSelected(false);
if (Build.VERSION.SDK_INT >= 21) {
@ -137,7 +149,11 @@ public class ActionBarMenuItem extends FrameLayoutFixed {
} else if (popupWindow != null && popupWindow.isShowing() && event.getActionMasked() == MotionEvent.ACTION_UP) {
if (selectedMenuView != null) {
selectedMenuView.setSelected(false);
parentMenu.onItemClick((Integer) selectedMenuView.getTag());
if (parentMenu != null) {
parentMenu.onItemClick((Integer) selectedMenuView.getTag());
} else if (delegate != null) {
delegate.onItemClick((Integer) selectedMenuView.getTag());
}
}
popupWindow.dismiss();
} else {
@ -149,12 +165,12 @@ public class ActionBarMenuItem extends FrameLayoutFixed {
return super.onTouchEvent(event);
}
public void setShowFromBottom(boolean value) {
showFromBottom = value;
public void setDelegate(ActionBarMenuItemDelegate delegate) {
this.delegate = delegate;
}
public void setNeedOffset(boolean value) {
needOffset = Build.VERSION.SDK_INT >= 21 && value;
public void setShowFromBottom(boolean value) {
showFromBottom = value;
}
public void setSubMenuOpenSide(int side) {
@ -174,7 +190,7 @@ public class ActionBarMenuItem extends FrameLayoutFixed {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
if (popupWindow != null && popupWindow.isShowing()) {
v.getHitRect(rect);
if (!rect.contains((int)event.getX(), (int)event.getY())) {
if (!rect.contains((int) event.getX(), (int) event.getY())) {
popupWindow.dismiss();
}
}
@ -213,7 +229,7 @@ public class ActionBarMenuItem extends FrameLayoutFixed {
}
}
popupLayout.addView(textView);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams)textView.getLayoutParams();
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) textView.getLayoutParams();
if (LocaleController.isRTL) {
layoutParams.gravity = Gravity.RIGHT;
}
@ -223,7 +239,11 @@ public class ActionBarMenuItem extends FrameLayoutFixed {
textView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
parentMenu.onItemClick((Integer) view.getTag());
if (parentMenu != null) {
parentMenu.onItemClick((Integer) view.getTag());
} else if (delegate != null) {
delegate.onItemClick((Integer) view.getTag());
}
if (popupWindow != null && popupWindow.isShowing()) {
popupWindow.dismiss();
}
@ -262,7 +282,7 @@ public class ActionBarMenuItem extends FrameLayoutFixed {
popupWindow.getContentView().setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU && event.getRepeatCount() == 0 && event.getAction() == KeyEvent.ACTION_UP && popupWindow != null && popupWindow.isShowing()) {
if (keyCode == KeyEvent.KEYCODE_MENU && event.getRepeatCount() == 0 && event.getAction() == KeyEvent.ACTION_UP && popupWindow != null && popupWindow.isShowing()) {
popupWindow.dismiss();
return true;
}
@ -277,8 +297,14 @@ public class ActionBarMenuItem extends FrameLayoutFixed {
popupWindow.showAsDropDown(this, -popupLayout.getMeasuredWidth() + getMeasuredWidth(), getOffsetY());
popupWindow.update(this, -popupLayout.getMeasuredWidth() + getMeasuredWidth(), getOffsetY(), -1, -1);
} else {
popupWindow.showAsDropDown(this, parentMenu.parentActionBar.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parentMenu.getLeft(), getOffsetY());
popupWindow.update(this, parentMenu.parentActionBar.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parentMenu.getLeft(), getOffsetY(), -1, -1);
if (parentMenu != null) {
popupWindow.showAsDropDown(this, parentMenu.parentActionBar.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parentMenu.getLeft(), getOffsetY());
popupWindow.update(this, parentMenu.parentActionBar.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parentMenu.getLeft(), getOffsetY(), -1, -1);
} else if (getParent() != null) {
View parent = (View) getParent();
popupWindow.showAsDropDown(this, parent.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parent.getLeft(), getOffsetY());
popupWindow.update(this, parent.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parent.getLeft(), getOffsetY(), -1, -1);
}
}
} else {
popupWindow.showAsDropDown(this, -AndroidUtilities.dp(8), getOffsetY());
@ -289,7 +315,12 @@ public class ActionBarMenuItem extends FrameLayoutFixed {
if (showFromBottom) {
popupWindow.showAsDropDown(this, -popupLayout.getMeasuredWidth() + getMeasuredWidth(), getOffsetY());
} else {
popupWindow.showAsDropDown(this, parentMenu.parentActionBar.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parentMenu.getLeft(), getOffsetY());
if (parentMenu != null) {
popupWindow.showAsDropDown(this, parentMenu.parentActionBar.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parentMenu.getLeft(), getOffsetY());
} else {
View parent = (View) getParent();
popupWindow.showAsDropDown(this, parent.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parent.getLeft(), getOffsetY());
}
}
} else {
popupWindow.showAsDropDown(this, -AndroidUtilities.dp(8), getOffsetY());
@ -305,14 +336,14 @@ public class ActionBarMenuItem extends FrameLayoutFixed {
if (diff < 0) {
y -= diff;
}
return y - (needOffset ? AndroidUtilities.statusBarHeight : 0);
return y;
} else {
return -getMeasuredHeight() - (needOffset ? AndroidUtilities.statusBarHeight : 0);
return -getMeasuredHeight();
}
}
public void openSearch() {
if (searchContainer == null || searchContainer.getVisibility() == VISIBLE) {
if (searchContainer == null || searchContainer.getVisibility() == VISIBLE || parentMenu == null) {
return;
}
parentMenu.parentActionBar.onSearchFieldVisibilityChanged(toggleSearch());
@ -357,10 +388,13 @@ public class ActionBarMenuItem extends FrameLayoutFixed {
}
public ActionBarMenuItem setIsSearchField(boolean value) {
if (parentMenu == null) {
return this;
}
if (value && searchContainer == null) {
searchContainer = new FrameLayout(getContext());
parentMenu.addView(searchContainer, 0);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams)searchContainer.getLayoutParams();
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) searchContainer.getLayoutParams();
layoutParams.weight = 1;
layoutParams.width = 0;
layoutParams.height = LayoutHelper.MATCH_PARENT;
@ -491,7 +525,12 @@ public class ActionBarMenuItem extends FrameLayoutFixed {
if (showFromBottom) {
popupWindow.update(this, -popupLayout.getMeasuredWidth() + getMeasuredWidth(), getOffsetY(), -1, -1);
} else {
popupWindow.update(this, parentMenu.parentActionBar.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parentMenu.getLeft(), getOffsetY(), -1, -1);
if (parentMenu != null) {
popupWindow.update(this, parentMenu.parentActionBar.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parentMenu.getLeft(), getOffsetY(), -1, -1);
} else {
View parent = (View) getParent();
popupWindow.update(this, parent.getMeasuredWidth() - popupLayout.getMeasuredWidth() - getLeft() - parent.getLeft(), getOffsetY(), -1, -1);
}
}
} else {
popupWindow.update(this, -AndroidUtilities.dp(8), getOffsetY(), -1, -1);

View File

@ -11,12 +11,9 @@
package org.telegram.ui.ActionBar;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
@ -60,14 +57,6 @@ public class ActionBarPopupWindow extends PopupWindow {
super(context);
}
public ActionBarPopupWindowLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ActionBarPopupWindowLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void setDispatchKeyEventListener(OnDispatchKeyEventListener listener) {
mOnDispatchKeyEventListener = listener;
}
@ -91,21 +80,6 @@ public class ActionBarPopupWindow extends PopupWindow {
init();
}
public ActionBarPopupWindow(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ActionBarPopupWindow(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public ActionBarPopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
public ActionBarPopupWindow(int width, int height) {
super(width, height);
init();
@ -135,15 +109,15 @@ public class ActionBarPopupWindow extends PopupWindow {
mSuperScrollListener = null;
}
}
if (Build.VERSION.SDK_INT >= 21) {
/*if (Build.VERSION.SDK_INT >= 21) {
try {
Field field = PopupWindow.class.getDeclaredField("mWindowLayoutType");
field.setAccessible(true);
field.set(this, WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
} catch (Exception e) {
/* ignored */
//ignored
}
}
}*/
}
private void unregisterListener() {

View File

@ -9,7 +9,7 @@
package org.telegram.ui.ActionBar;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
@ -23,8 +23,9 @@ import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
public class BaseFragment {
private boolean isFinished = false;
protected AlertDialog visibleDialog = null;
protected Dialog visibleDialog = null;
protected View fragmentView;
protected ActionBarLayout parentLayout;
@ -191,7 +192,11 @@ public class BaseFragment {
}
}
public void onOpenAnimationEnd() {
protected void onOpenAnimationEnd() {
}
protected void onOpenAnimationStart() {
}
@ -203,7 +208,7 @@ public class BaseFragment {
return true;
}
public AlertDialog showAlertDialog(AlertDialog.Builder builder) {
public Dialog showDialog(Dialog dialog) {
if (parentLayout == null || parentLayout.animationInProgress || parentLayout.startedTracking || parentLayout.checkTransitionAnimation()) {
return null;
}
@ -216,7 +221,7 @@ public class BaseFragment {
FileLog.e("tmessages", e);
}
try {
visibleDialog = builder.show();
visibleDialog = dialog;
visibleDialog.setCanceledOnTouchOutside(true);
visibleDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
@ -225,6 +230,7 @@ public class BaseFragment {
onDialogDismiss();
}
});
visibleDialog.show();
return visibleDialog;
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -235,4 +241,8 @@ public class BaseFragment {
protected void onDialogDismiss() {
}
public void setVisibleDialog(Dialog dialog) {
visibleDialog = dialog;
}
}

View File

@ -0,0 +1,301 @@
/*
* This is the source code of Telegram for Android v. 2.x.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-2015.
*/
package org.telegram.ui.ActionBar;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Build;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.telegram.android.AndroidUtilities;
import org.telegram.android.AnimationCompat.AnimatorListenerAdapterProxy;
import org.telegram.android.AnimationCompat.AnimatorSetProxy;
import org.telegram.android.AnimationCompat.ObjectAnimatorProxy;
import org.telegram.android.LocaleController;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.ui.Components.LayoutHelper;
public class BottomSheet extends Dialog {
private LinearLayout linearLayout;
private FrameLayout container;
private boolean dismissed;
private DialogInterface.OnClickListener onClickListener;
private CharSequence[] items;
private View customView;
private boolean overrideTabletWidth = true;
private BottomSheetDelegate delegate;
public interface BottomSheetDelegate {
void onOpenAnimationEnd();
}
private static class BottomSheetRow extends FrameLayout {
private TextView textView;
public BottomSheetRow(Context context) {
super(context);
setBackgroundResource(R.drawable.list_selector);
setPadding(AndroidUtilities.dp(16), 0, AndroidUtilities.dp(16), 0);
textView = new TextView(context);
textView.setTextColor(0xff212121);
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL));
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(48), MeasureSpec.EXACTLY));
}
}
public BottomSheet(Context context) {
super(context);
container = new FrameLayout(getContext());
container.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
dismiss();
return false;
}
});
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/*
<item name="android:windowFrame">@null</item>
<item name="android:textColor">@null</item>
<item name="android:layout_width">fill_parent</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowAnimationStyle">@style/BottomSheet.Animation</item>
<item name="android:textColorPrimary">#DD000000</item>
<item name="android:textColorSecondary">#8A000000</item>
<item name="android:textColorHint">#42000000</item>
*/
Window window = getWindow();
window.setBackgroundDrawableResource(R.drawable.transparent);
window.requestFeature(Window.FEATURE_NO_TITLE);
setContentView(container);
linearLayout = new LinearLayout(getContext());
linearLayout.setOrientation(LinearLayout.VERTICAL);
if (AndroidUtilities.isTablet() && !overrideTabletWidth) {
container.addView(linearLayout, 0, LayoutHelper.createFrame(320, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL));
} else {
container.addView(linearLayout, 0, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM));
}
View shadow = new View(getContext());
shadow.setBackgroundResource(R.drawable.header_shadow_reverse);
linearLayout.addView(shadow, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 3));
LinearLayout containerView = new LinearLayout(getContext());
containerView.setBackgroundColor(0xffffffff);
containerView.setOrientation(LinearLayout.VERTICAL);
containerView.setPadding(0, AndroidUtilities.dp(8), 0, AndroidUtilities.dp(8));
linearLayout.addView(containerView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
if (items != null) {
for (int a = 0; a < items.length; a++) {
CharSequence charSequence = items[a];
BottomSheetRow row = new BottomSheetRow(getContext());
row.textView.setText(charSequence);
containerView.addView(row, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48));
row.setTag(a);
row.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismissWithButtonClick((Integer) v.getTag());
}
});
}
}
if (customView != null) {
containerView.addView(customView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
}
WindowManager.LayoutParams params = getWindow().getAttributes();
params.height = ViewGroup.LayoutParams.MATCH_PARENT;
params.width = ViewGroup.LayoutParams.MATCH_PARENT;
params.gravity = Gravity.TOP | Gravity.LEFT;
params.dimAmount = 0.2f;
params.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
if (Build.VERSION.SDK_INT >= 21) {
params.flags |= WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ERROR;
}
getWindow().setAttributes(params);
setOnShowListener(new OnShowListener() {
@Override
public void onShow(DialogInterface dialog) {
AnimatorSetProxy animatorSetProxy = new AnimatorSetProxy();
animatorSetProxy.playTogether(
ObjectAnimatorProxy.ofFloat(linearLayout, "translationY", linearLayout.getHeight(), 0));
animatorSetProxy.setDuration(180);
animatorSetProxy.setInterpolator(new DecelerateInterpolator());
animatorSetProxy.addListener(new AnimatorListenerAdapterProxy() {
@Override
public void onAnimationEnd(Object animation) {
if (delegate != null) {
delegate.onOpenAnimationEnd();
}
}
});
animatorSetProxy.start();
}
});
}
public void setDelegate(BottomSheetDelegate delegate) {
this.delegate = delegate;
}
public FrameLayout getContainer() {
return container;
}
public LinearLayout getSheetContainer() {
return linearLayout;
}
private void dismissWithButtonClick(final int item) {
if (dismissed) {
return;
}
AnimatorSetProxy animatorSetProxy = new AnimatorSetProxy();
animatorSetProxy.playTogether(
ObjectAnimatorProxy.ofFloat(linearLayout, "translationY", linearLayout.getHeight() + AndroidUtilities.dp(10))
);
animatorSetProxy.setDuration(180);
animatorSetProxy.setInterpolator(new AccelerateInterpolator());
animatorSetProxy.addListener(new AnimatorListenerAdapterProxy() {
@Override
public void onAnimationEnd(Object animation) {
if (onClickListener != null) {
onClickListener.onClick(BottomSheet.this, item);
}
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
try {
BottomSheet.super.dismiss();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
}
@Override
public void onAnimationCancel(Object animation) {
onAnimationEnd(animation);
}
});
animatorSetProxy.start();
}
@Override
public void dismiss() {
if (dismissed) {
return;
}
dismissed = true;
AnimatorSetProxy animatorSetProxy = new AnimatorSetProxy();
animatorSetProxy.playTogether(
ObjectAnimatorProxy.ofFloat(linearLayout, "translationY", linearLayout.getHeight() + AndroidUtilities.dp(10))
);
animatorSetProxy.setDuration(180);
animatorSetProxy.setInterpolator(new AccelerateInterpolator());
animatorSetProxy.addListener(new AnimatorListenerAdapterProxy() {
@Override
public void onAnimationEnd(Object animation) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
try {
BottomSheet.super.dismiss();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
}
@Override
public void onAnimationCancel(Object animation) {
onAnimationEnd(animation);
}
});
animatorSetProxy.start();
}
public static class Builder {
private BottomSheet bottomSheet;
public Builder(Context context) {
bottomSheet = new BottomSheet(context);
}
public Builder setItems(CharSequence[] items, final OnClickListener onClickListener) {
bottomSheet.items = items;
bottomSheet.onClickListener = onClickListener;
return this;
}
public Builder setCustomView(View view) {
bottomSheet.customView = view;
return this;
}
public BottomSheet create() {
return bottomSheet;
}
public BottomSheet show() {
bottomSheet.show();
return bottomSheet;
}
public BottomSheet setOverrideTabletWidth(boolean value) {
bottomSheet.overrideTabletWidth = value;
return bottomSheet;
}
}
}

View File

@ -0,0 +1,210 @@
/*
* This is the source code of Telegram for Android v. 2.x.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-2015.
*/
package org.telegram.ui.Adapters;
import org.telegram.SQLite.SQLiteCursor;
import org.telegram.SQLite.SQLitePreparedStatement;
import org.telegram.android.AndroidUtilities;
import org.telegram.android.MessagesStorage;
import org.telegram.android.support.widget.RecyclerView;
import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.RPCRequest;
import org.telegram.messenger.TLObject;
import org.telegram.messenger.TLRPC;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public abstract class BaseSearchAdapterRecycler extends RecyclerView.Adapter {
protected static class HashtagObject {
String hashtag;
int date;
}
protected ArrayList<TLRPC.User> globalSearch = new ArrayList<>();
private long reqId = 0;
private int lastReqId;
protected String lastFoundUsername = null;
protected ArrayList<HashtagObject> hashtags;
protected HashMap<String, HashtagObject> hashtagsByText;
protected boolean hashtagsLoadedFromDb = false;
public void queryServerSearch(final String query) {
if (reqId != 0) {
ConnectionsManager.getInstance().cancelRpc(reqId, true);
reqId = 0;
}
if (query == null || query.length() < 5) {
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);
}
public void loadRecentHashtags() {
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
try {
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT id, date FROM hashtag_recent_v2 WHERE 1");
final ArrayList<HashtagObject> arrayList = new ArrayList<>();
final HashMap<String, HashtagObject> hashMap = new HashMap<>();
while (cursor.next()) {
HashtagObject hashtagObject = new HashtagObject();
hashtagObject.hashtag = cursor.stringValue(0);
hashtagObject.date = cursor.intValue(1);
arrayList.add(hashtagObject);
hashMap.put(hashtagObject.hashtag, hashtagObject);
}
cursor.dispose();
Collections.sort(arrayList, new Comparator<HashtagObject>() {
@Override
public int compare(HashtagObject lhs, HashtagObject rhs) {
if (lhs.date < rhs.date) {
return 1;
} else if (lhs.date > rhs.date) {
return -1;
} else {
return 0;
}
}
});
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
setHashtags(arrayList, hashMap);
}
});
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
}
public void addHashtagsFromMessage(String message) {
if (message == null) {
return;
}
boolean changed = false;
Pattern pattern = Pattern.compile("(^|\\s)#[\\w@\\.]+");
Matcher matcher = pattern.matcher(message);
while (matcher.find()) {
int start = matcher.start();
int end = matcher.end();
if (message.charAt(start) != '@' && message.charAt(start) != '#') {
start++;
}
String hashtag = message.substring(start, end);
if (hashtagsByText == null) {
hashtagsByText = new HashMap<>();
hashtags = new ArrayList<>();
}
HashtagObject hashtagObject = hashtagsByText.get(hashtag);
if (hashtagObject == null) {
hashtagObject = new HashtagObject();
hashtagObject.hashtag = hashtag;
hashtagsByText.put(hashtagObject.hashtag, hashtagObject);
} else {
hashtags.remove(hashtagObject);
}
hashtagObject.date = (int) (System.currentTimeMillis() / 1000);
hashtags.add(0, hashtagObject);
changed = true;
}
if (changed) {
putRecentHashtags(hashtags);
}
}
private void putRecentHashtags(final ArrayList<HashtagObject> arrayList) {
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
try {
MessagesStorage.getInstance().getDatabase().beginTransaction();
SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO hashtag_recent_v2 VALUES(?, ?)");
for (int a = 0; a < arrayList.size(); a++) {
if (a == 100) {
break;
}
HashtagObject hashtagObject = arrayList.get(a);
state.requery();
state.bindString(1, hashtagObject.hashtag);
state.bindInteger(2, hashtagObject.date);
state.step();
}
state.dispose();
MessagesStorage.getInstance().getDatabase().commitTransaction();
if (arrayList.size() >= 100) {
MessagesStorage.getInstance().getDatabase().beginTransaction();
for (int a = 100; a < arrayList.size(); a++) {
MessagesStorage.getInstance().getDatabase().executeFast("DELETE FROM hashtag_recent_v2 WHERE id = '" + arrayList.get(a).hashtag + "'").stepThis().dispose();
}
MessagesStorage.getInstance().getDatabase().commitTransaction();
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
}
public void clearRecentHashtags() {
hashtags = new ArrayList<>();
hashtagsByText = new HashMap<>();
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
try {
MessagesStorage.getInstance().getDatabase().executeFast("DELETE FROM hashtag_recent_v2 WHERE 1").stepThis().dispose();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
}
protected void setHashtags(ArrayList<HashtagObject> arrayList, HashMap<String, HashtagObject> hashMap) {
hashtags = arrayList;
hashtagsByText = hashMap;
hashtagsLoadedFromDb = true;
}
}

View File

@ -294,7 +294,7 @@ public class ChatActivityAdapter {
}
}
);
showAlertDialog(builder);
showDialog(builder.create());
}
});
}

View File

@ -14,17 +14,25 @@ import android.view.ViewGroup;
import org.telegram.android.AndroidUtilities;
import org.telegram.android.MessagesController;
import org.telegram.android.support.widget.RecyclerView;
import org.telegram.messenger.TLRPC;
import org.telegram.ui.Cells.DialogCell;
import org.telegram.ui.Cells.LoadingCell;
public class DialogsAdapter extends BaseFragmentAdapter {
public class DialogsAdapter extends RecyclerView.Adapter {
private Context mContext;
private boolean serverOnly;
private long openedDialogId;
private int currentCount;
private class Holder extends RecyclerView.ViewHolder {
public Holder(View itemView) {
super(itemView);
}
}
public DialogsAdapter(Context context, boolean onlyFromServer) {
mContext = context;
serverOnly = onlyFromServer;
@ -36,21 +44,11 @@ public class DialogsAdapter extends BaseFragmentAdapter {
public boolean isDataSetChanged() {
int current = currentCount;
return current != getCount();
return current != getItemCount();
}
@Override
public boolean areAllItemsEnabled() {
return true;
}
@Override
public boolean isEnabled(int i) {
return true;
}
@Override
public int getCount() {
public int getItemCount() {
int count;
if (serverOnly) {
count = MessagesController.getInstance().dialogsServerOnly.size();
@ -67,7 +65,6 @@ public class DialogsAdapter extends BaseFragmentAdapter {
return count;
}
@Override
public TLRPC.TL_dialog getItem(int i) {
if (serverOnly) {
if (i < 0 || i >= MessagesController.getInstance().dialogsServerOnly.size()) {
@ -88,41 +85,32 @@ public class DialogsAdapter extends BaseFragmentAdapter {
}
@Override
public boolean hasStableIds() {
return true;
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View view = null;
if (viewType == 0) {
view = new DialogCell(mContext);
} else if (viewType == 1) {
view = new LoadingCell(mContext);
}
return new Holder(view);
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
int type = getItemViewType(i);
if (type == 1) {
if (view == null) {
view = new LoadingCell(mContext);
}
} else if (type == 0) {
if (view == null) {
view = new DialogCell(mContext);
}
if (view instanceof DialogCell) { //TODO finally i need to find this crash
((DialogCell) view).useSeparator = (i != getCount() - 1);
TLRPC.TL_dialog dialog = null;
if (serverOnly) {
dialog = MessagesController.getInstance().dialogsServerOnly.get(i);
} else {
dialog = MessagesController.getInstance().dialogs.get(i);
if (AndroidUtilities.isTablet()) {
if (dialog.id == openedDialogId) {
view.setBackgroundColor(0x0f000000);
} else {
view.setBackgroundColor(0);
}
}
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) {
if (viewHolder.getItemViewType() == 0) {
DialogCell cell = (DialogCell) viewHolder.itemView;
cell.useSeparator = (i != getItemCount() - 1);
TLRPC.TL_dialog dialog;
if (serverOnly) {
dialog = MessagesController.getInstance().dialogsServerOnly.get(i);
} else {
dialog = MessagesController.getInstance().dialogs.get(i);
if (AndroidUtilities.isTablet()) {
cell.setDialogSelected(dialog.id == openedDialogId);
}
((DialogCell) view).setDialog(dialog, i, serverOnly);
}
cell.setDialog(dialog, i, serverOnly);
}
return view;
}
@Override
@ -132,26 +120,4 @@ public class DialogsAdapter extends BaseFragmentAdapter {
}
return 0;
}
@Override
public int getViewTypeCount() {
return 2;
}
@Override
public boolean isEmpty() {
int count;
if (serverOnly) {
count = MessagesController.getInstance().dialogsServerOnly.size();
} else {
count = MessagesController.getInstance().dialogs.size();
}
if (count == 0 && MessagesController.getInstance().loadingDialogs) {
return true;
}
if (!MessagesController.getInstance().dialogsEndReached) {
count++;
}
return count == 0;
}
}

View File

@ -20,6 +20,7 @@ import org.telegram.android.LocaleController;
import org.telegram.android.MessageObject;
import org.telegram.android.MessagesController;
import org.telegram.android.MessagesStorage;
import org.telegram.android.support.widget.RecyclerView;
import org.telegram.messenger.ByteBufferDesc;
import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.FileLog;
@ -27,7 +28,6 @@ import org.telegram.messenger.R;
import org.telegram.messenger.RPCRequest;
import org.telegram.messenger.TLObject;
import org.telegram.messenger.TLRPC;
import org.telegram.messenger.Utilities;
import org.telegram.ui.Cells.DialogCell;
import org.telegram.ui.Cells.GreySectionCell;
import org.telegram.ui.Cells.HashtagSearchCell;
@ -42,7 +42,7 @@ import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
public class DialogsSearchAdapter extends BaseSearchAdapter {
public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
private Context mContext;
private Timer searchTimer;
@ -59,6 +59,13 @@ public class DialogsSearchAdapter extends BaseSearchAdapter {
private String lastMessagesSearchString;
private int lastSearchId = 0;
private class Holder extends RecyclerView.ViewHolder {
public Holder(View itemView) {
super(itemView);
}
}
private class DialogSearchResult {
public TLObject object;
public int date;
@ -246,9 +253,9 @@ public class DialogsSearchAdapter extends BaseSearchAdapter {
user.status.expires = cursor.intValue(1);
}
if (found == 1) {
dialogSearchResult.name = Utilities.generateSearchName(user.first_name, user.last_name, q);
dialogSearchResult.name = AndroidUtilities.generateSearchName(user.first_name, user.last_name, q);
} else {
dialogSearchResult.name = Utilities.generateSearchName("@" + user.username, null, "@" + q);
dialogSearchResult.name = AndroidUtilities.generateSearchName("@" + user.username, null, "@" + q);
}
dialogSearchResult.object = user;
resultCount++;
@ -281,7 +288,7 @@ public class DialogsSearchAdapter extends BaseSearchAdapter {
dialog_id = AndroidUtilities.makeBroadcastId(chat.id);
}
DialogSearchResult dialogSearchResult = dialogsResult.get(dialog_id);
dialogSearchResult.name = Utilities.generateSearchName(chat.title, null, q);
dialogSearchResult.name = AndroidUtilities.generateSearchName(chat.title, null, q);
dialogSearchResult.object = chat;
resultCount++;
}
@ -345,7 +352,7 @@ public class DialogsSearchAdapter extends BaseSearchAdapter {
if (found == 1) {
dialogSearchResult.name = AndroidUtilities.replaceTags("<c#ff00a60e>" + ContactsController.formatName(user.first_name, user.last_name) + "</c>");
} else {
dialogSearchResult.name = Utilities.generateSearchName("@" + user.username, null, "@" + q);
dialogSearchResult.name = AndroidUtilities.generateSearchName("@" + user.username, null, "@" + q);
}
dialogSearchResult.object = chat;
encUsers.add(user);
@ -418,9 +425,9 @@ public class DialogsSearchAdapter extends BaseSearchAdapter {
user.status.expires = cursor.intValue(1);
}
if (found == 1) {
resultArrayNames.add(Utilities.generateSearchName(user.first_name, user.last_name, q));
resultArrayNames.add(AndroidUtilities.generateSearchName(user.first_name, user.last_name, q));
} else {
resultArrayNames.add(Utilities.generateSearchName("@" + user.username, null, "@" + q));
resultArrayNames.add(AndroidUtilities.generateSearchName("@" + user.username, null, "@" + q));
}
resultArray.add(user);
}
@ -567,30 +574,7 @@ public class DialogsSearchAdapter extends BaseSearchAdapter {
}
@Override
public boolean areAllItemsEnabled() {
return false;
}
@Override
public boolean isEnabled(int i) {
if (!searchResultHashtags.isEmpty()) {
return i != 0;
}
int localCount = searchResult.size();
int globalCount = globalSearch.isEmpty() ? 0 : globalSearch.size() + 1;
int messagesCount = searchResultMessages.isEmpty() ? 0 : searchResultMessages.size() + 1;
if (i >= 0 && i < localCount || i > localCount && i < globalCount + localCount) {
return true;
} else if (i > globalCount + localCount && i < globalCount + localCount + messagesCount) {
return true;
} else if (messagesCount != 0 && i == globalCount + localCount + messagesCount) {
return true;
}
return false;
}
@Override
public int getCount() {
public int getItemCount() {
if (!searchResultHashtags.isEmpty()) {
return searchResultHashtags.size() + 1;
}
@ -606,7 +590,6 @@ public class DialogsSearchAdapter extends BaseSearchAdapter {
return count;
}
@Override
public Object getItem(int i) {
if (!searchResultHashtags.isEmpty()) {
return searchResultHashtags.get(i - 1);
@ -630,96 +613,107 @@ public class DialogsSearchAdapter extends BaseSearchAdapter {
}
@Override
public boolean hasStableIds() {
return true;
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = null;
switch (viewType) {
case 0:
view = new ProfileSearchCell(mContext);
view.setBackgroundResource(R.drawable.list_selector);
break;
case 1:
view = new GreySectionCell(mContext);
break;
case 2:
view = new DialogCell(mContext);
break;
case 3:
view = new LoadingCell(mContext);
break;
case 4:
view = new HashtagSearchCell(mContext);
break;
}
return new Holder(view);
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
int type = getItemViewType(i);
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case 0: {
ProfileSearchCell cell = (ProfileSearchCell) holder.itemView;
if (type == 1) {
if (view == null) {
view = new GreySectionCell(mContext);
}
if (!searchResultHashtags.isEmpty()) {
((GreySectionCell) view).setText(LocaleController.getString("Hashtags", R.string.Hashtags).toUpperCase());
} else if (!globalSearch.isEmpty() && i == searchResult.size()) {
((GreySectionCell) view).setText(LocaleController.getString("GlobalSearch", R.string.GlobalSearch));
} else {
((GreySectionCell) view).setText(LocaleController.getString("SearchMessages", R.string.SearchMessages));
}
} else if (type == 0) {
if (view == null) {
view = new ProfileSearchCell(mContext);
}
TLRPC.User user = null;
TLRPC.Chat chat = null;
TLRPC.EncryptedChat encryptedChat = null;
TLRPC.User user = null;
TLRPC.Chat chat = null;
TLRPC.EncryptedChat encryptedChat = null;
int localCount = searchResult.size();
int globalCount = globalSearch.isEmpty() ? 0 : globalSearch.size() + 1;
int localCount = searchResult.size();
int globalCount = globalSearch.isEmpty() ? 0 : globalSearch.size() + 1;
((ProfileSearchCell) view).useSeparator = (i != getCount() - 1 && i != localCount - 1 && i != localCount + globalCount - 1);
Object obj = getItem(i);
if (obj instanceof TLRPC.User) {
/*user = MessagesController.getInstance().getUser(((TLRPC.User) obj).id);
if (user == null) {
cell.useSeparator = (position != getItemCount() - 1 && position != localCount - 1 && position != localCount + globalCount - 1);
Object obj = getItem(position);
if (obj instanceof TLRPC.User) {
user = (TLRPC.User) obj;
}*/
user = (TLRPC.User) obj;
} else if (obj instanceof TLRPC.Chat) {
chat = MessagesController.getInstance().getChat(((TLRPC.Chat) obj).id);
} else if (obj instanceof TLRPC.EncryptedChat) {
encryptedChat = MessagesController.getInstance().getEncryptedChat(((TLRPC.EncryptedChat) obj).id);
user = MessagesController.getInstance().getUser(encryptedChat.user_id);
}
} else if (obj instanceof TLRPC.Chat) {
chat = MessagesController.getInstance().getChat(((TLRPC.Chat) obj).id);
} else if (obj instanceof TLRPC.EncryptedChat) {
encryptedChat = MessagesController.getInstance().getEncryptedChat(((TLRPC.EncryptedChat) obj).id);
user = MessagesController.getInstance().getUser(encryptedChat.user_id);
}
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;
CharSequence username = null;
CharSequence name = null;
if (position < searchResult.size()) {
name = searchResultNames.get(position);
if (name != null && user != null && user.username != null && user.username.length() > 0) {
if (name.toString().startsWith("@" + user.username)) {
username = name;
name = null;
}
}
} else if (position > searchResult.size() && user != null && user.username != null) {
String foundUserName = lastFoundUsername;
if (foundUserName.startsWith("@")) {
foundUserName = foundUserName.substring(1);
}
try {
username = AndroidUtilities.replaceTags(String.format("<c#ff4d83b3>@%s</c>%s", user.username.substring(0, foundUserName.length()), user.username.substring(foundUserName.length())));
} catch (Exception e) {
username = user.username;
FileLog.e("tmessages", e);
}
}
} else if (i > searchResult.size() && user != null && user.username != null) {
String foundUserName = lastFoundUsername;
if (foundUserName.startsWith("@")) {
foundUserName = foundUserName.substring(1);
}
try {
username = AndroidUtilities.replaceTags(String.format("<c#ff4d83b3>@%s</c>%s", user.username.substring(0, foundUserName.length()), user.username.substring(foundUserName.length())));
} catch (Exception e) {
username = user.username;
FileLog.e("tmessages", e);
}
}
((ProfileSearchCell) view).setData(user, chat, encryptedChat, name, username);
} else if (type == 2) {
if (view == null) {
view = new DialogCell(mContext);
cell.setData(user, chat, encryptedChat, name, username);
break;
}
((DialogCell) view).useSeparator = (i != getCount() - 1);
MessageObject messageObject = (MessageObject)getItem(i);
((DialogCell) view).setDialog(messageObject.getDialogId(), messageObject, messageObject.messageOwner.date);
} else if (type == 3) {
if (view == null) {
view = new LoadingCell(mContext);
case 1: {
GreySectionCell cell = (GreySectionCell) holder.itemView;
if (!searchResultHashtags.isEmpty()) {
cell.setText(LocaleController.getString("Hashtags", R.string.Hashtags).toUpperCase());
} else if (!globalSearch.isEmpty() && position == searchResult.size()) {
cell.setText(LocaleController.getString("GlobalSearch", R.string.GlobalSearch));
} else {
cell.setText(LocaleController.getString("SearchMessages", R.string.SearchMessages));
}
break;
}
} else if (type == 4) {
if (view == null) {
view = new HashtagSearchCell(mContext);
case 2: {
DialogCell cell = (DialogCell) holder.itemView;
cell.useSeparator = (position != getItemCount() - 1);
MessageObject messageObject = (MessageObject)getItem(position);
cell.setDialog(messageObject.getDialogId(), messageObject, messageObject.messageOwner.date);
break;
}
case 3: {
break;
}
case 4: {
HashtagSearchCell cell = (HashtagSearchCell) holder.itemView;
cell.setText(searchResultHashtags.get(position - 1));
cell.setNeedDivider(position != searchResultHashtags.size());
break;
}
((HashtagSearchCell) view).setText(searchResultHashtags.get(i - 1));
((HashtagSearchCell) view).setNeedDivider(i != searchResultHashtags.size());
}
return view;
}
@Override
@ -739,14 +733,4 @@ public class DialogsSearchAdapter extends BaseSearchAdapter {
}
return 1;
}
@Override
public int getViewTypeCount() {
return 5;
}
@Override
public boolean isEmpty() {
return searchResult.isEmpty() && globalSearch.isEmpty() && searchResultMessages.isEmpty() && searchResultHashtags.isEmpty();
}
}

View File

@ -138,9 +138,9 @@ public class SearchAdapter extends BaseSearchAdapter {
if (found != 0) {
if (found == 1) {
resultArrayNames.add(Utilities.generateSearchName(user.first_name, user.last_name, q));
resultArrayNames.add(AndroidUtilities.generateSearchName(user.first_name, user.last_name, q));
} else {
resultArrayNames.add(Utilities.generateSearchName("@" + user.username, null, "@" + q));
resultArrayNames.add(AndroidUtilities.generateSearchName("@" + user.username, null, "@" + q));
}
resultArray.add(user);
break;

View File

@ -12,20 +12,11 @@ import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import org.telegram.SQLite.SQLiteCursor;
import org.telegram.SQLite.SQLitePreparedStatement;
import org.telegram.android.AndroidUtilities;
import org.telegram.android.MessagesStorage;
import org.telegram.android.NotificationCenter;
import org.telegram.android.query.StickersQuery;
import org.telegram.android.support.widget.RecyclerView;
import org.telegram.messenger.ByteBufferDesc;
import org.telegram.messenger.ConnectionsManager;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.RPCRequest;
import org.telegram.messenger.TLObject;
import org.telegram.messenger.TLRPC;
import org.telegram.messenger.Utilities;
import org.telegram.ui.Cells.StickerCell;
import java.io.File;
@ -34,11 +25,6 @@ import java.util.HashMap;
public class StickersAdapter extends RecyclerView.Adapter implements NotificationCenter.NotificationCenterDelegate {
private static boolean loadingStickers;
private static String hash = "";
private static int loadDate = 0;
private static HashMap<String, ArrayList<TLRPC.Document>> allStickers;
private Context mContext;
private ArrayList<TLRPC.Document> stickers;
private ArrayList<String> stickersToLoad = new ArrayList<>();
@ -60,9 +46,7 @@ public class StickersAdapter extends RecyclerView.Adapter implements Notificatio
public StickersAdapter(Context context, StickersAdapterDelegate delegate) {
mContext = context;
this.delegate = delegate;
if (!loadingStickers && (allStickers == null || loadDate < (System.currentTimeMillis() / 1000 - 60 * 60))) {
loadStickers(true);
}
StickersQuery.checkStickers();
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidLoaded);
NotificationCenter.getInstance().addObserver(this, NotificationCenter.FileDidFailedLoad);
}
@ -75,64 +59,13 @@ public class StickersAdapter extends RecyclerView.Adapter implements Notificatio
@Override
public void didReceivedNotification(int id, final Object... args) {
if (id == NotificationCenter.FileDidLoaded || id == NotificationCenter.FileDidFailedLoad) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
if (stickers != null && !stickers.isEmpty() && !stickersToLoad.isEmpty() && visible) {
String fileName = (String) args[0];
stickersToLoad.remove(fileName);
if (stickersToLoad.isEmpty()) {
delegate.needChangePanelVisibility(stickers != null && !stickers.isEmpty() && stickersToLoad.isEmpty());
}
}
if (stickers != null && !stickers.isEmpty() && !stickersToLoad.isEmpty() && visible) {
String fileName = (String) args[0];
stickersToLoad.remove(fileName);
if (stickersToLoad.isEmpty()) {
delegate.needChangePanelVisibility(stickers != null && !stickers.isEmpty() && stickersToLoad.isEmpty());
}
});
}
}
private void loadStickers(boolean cache) {
if (loadingStickers) {
return;
}
loadingStickers = true;
if (cache) {
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
TLRPC.messages_AllStickers result = null;
int date = 0;
try {
SQLiteCursor cursor = MessagesStorage.getInstance().getDatabase().queryFinalized("SELECT data, date FROM stickers WHERE 1");
ArrayList<TLRPC.User> loadedUsers = new ArrayList<>();
if (cursor.next()) {
ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data.buffer) != 0) {
result = TLRPC.messages_AllStickers.TLdeserialize(data, data.readInt32(false), false);
}
date = cursor.intValue(1);
MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data);
}
cursor.dispose();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
processLoadedStickers(result, true, date);
}
});
} else {
TLRPC.TL_messages_getAllStickers req = new TLRPC.TL_messages_getAllStickers();
req.hash = hash;
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() {
processLoadedStickers((TLRPC.messages_AllStickers) response, false, (int)(System.currentTimeMillis() / 1000));
}
});
}
});
}
}
}
@ -144,109 +77,20 @@ public class StickersAdapter extends RecyclerView.Adapter implements Notificatio
int size = Math.min(10, stickers.size());
for (int a = 0; a < size; a++) {
TLRPC.Document document = stickers.get(a);
File f = FileLoader.getPathToAttach(document.thumb, true);
File f = FileLoader.getPathToAttach(document.thumb, "webp", true);
if (!f.exists()) {
stickersToLoad.add(FileLoader.getAttachFileName(document.thumb));
FileLoader.getInstance().loadFile(document.thumb.location, 0, true);
stickersToLoad.add(FileLoader.getAttachFileName(document.thumb, "webp"));
FileLoader.getInstance().loadFile(document.thumb.location, "webp", 0, true);
}
}
return stickersToLoad.isEmpty();
}
private void putStickersToCache(final TLRPC.TL_messages_allStickers stickers) {
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
try {
SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO stickers VALUES(?, ?, ?)");
state.requery();
ByteBufferDesc data = MessagesStorage.getInstance().getBuffersStorage().getFreeBuffer(stickers.getObjectSize());
stickers.serializeToStream(data);
state.bindInteger(1, 1);
state.bindByteBuffer(2, data.buffer);
state.bindInteger(3, (int) (System.currentTimeMillis() / 1000));
state.step();
MessagesStorage.getInstance().getBuffersStorage().reuseFreeBuffer(data);
state.dispose();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
}
private void processLoadedStickers(final TLRPC.messages_AllStickers res, final boolean cache, final int date) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
loadingStickers = false;
}
});
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
if ((res == null || date < (int) (System.currentTimeMillis() / 1000 - 60 * 60)) && cache) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
loadStickers(false);
}
});
if (res == null) {
return;
}
}
if (res instanceof TLRPC.TL_messages_allStickers) {
if (!cache) {
putStickersToCache((TLRPC.TL_messages_allStickers) res);
}
HashMap<Long, TLRPC.Document> documents = new HashMap<>();
for (TLRPC.Document document : res.documents) {
if (document == null) {
continue;
}
documents.put(document.id, document);
if (document.thumb != null && document.thumb.location != null) {
document.thumb.location.ext = "webp";
}
}
final HashMap<String, ArrayList<TLRPC.Document>> result = new HashMap<>();
for (TLRPC.TL_stickerPack stickerPack : res.packs) {
if (stickerPack != null && stickerPack.emoticon != null) {
stickerPack.emoticon = stickerPack.emoticon.replace("\uFE0F", "");
ArrayList<TLRPC.Document> arrayList = result.get(stickerPack.emoticon);
for (Long id : stickerPack.documents) {
TLRPC.Document document = documents.get(id);
if (document != null) {
if (arrayList == null) {
arrayList = new ArrayList<>();
result.put(stickerPack.emoticon, arrayList);
}
arrayList.add(document);
}
}
}
}
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
allStickers = result;
hash = res.hash;
loadDate = date;
if (lastSticker != null) {
loadStikersForEmoji(lastSticker);
}
}
});
}
}
});
}
public void loadStikersForEmoji(CharSequence emoji) {
boolean search = emoji != null && emoji.length() != 0 && emoji.length() <= 2;
if (search) {
lastSticker = emoji.toString();
HashMap<String, ArrayList<TLRPC.Document>> allStickers = StickersQuery.getAllStickers();
if (allStickers != null) {
ArrayList<TLRPC.Document> newStickers = allStickers.get(lastSticker);
if (stickers != null && newStickers == null) {

View File

@ -98,12 +98,7 @@ public class BlockedUsersActivity extends BaseFragment implements NotificationCe
emptyTextView.setGravity(Gravity.CENTER);
emptyTextView.setVisibility(View.INVISIBLE);
emptyTextView.setText(LocaleController.getString("NoBlocked", R.string.NoBlocked));
frameLayout.addView(emptyTextView);
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) emptyTextView.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
layoutParams.gravity = Gravity.TOP;
emptyTextView.setLayoutParams(layoutParams);
frameLayout.addView(emptyTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT));
emptyTextView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
@ -112,19 +107,10 @@ public class BlockedUsersActivity extends BaseFragment implements NotificationCe
});
progressView = new FrameLayout(context);
frameLayout.addView(progressView);
layoutParams = (FrameLayout.LayoutParams) progressView.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
progressView.setLayoutParams(layoutParams);
frameLayout.addView(progressView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
ProgressBar progressBar = new ProgressBar(context);
progressView.addView(progressBar);
layoutParams = (FrameLayout.LayoutParams) progressView.getLayoutParams();
layoutParams.width = LayoutHelper.WRAP_CONTENT;
layoutParams.height = LayoutHelper.WRAP_CONTENT;
layoutParams.gravity = Gravity.CENTER;
progressView.setLayoutParams(layoutParams);
progressView.addView(progressBar, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER));
listView = new ListView(context);
listView.setEmptyView(emptyTextView);
@ -135,11 +121,7 @@ public class BlockedUsersActivity extends BaseFragment implements NotificationCe
if (Build.VERSION.SDK_INT >= 11) {
listView.setVerticalScrollbarPosition(LocaleController.isRTL ? ListView.SCROLLBAR_POSITION_LEFT : ListView.SCROLLBAR_POSITION_RIGHT);
}
frameLayout.addView(listView);
layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
listView.setLayoutParams(layoutParams);
frameLayout.addView(listView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
@ -170,7 +152,7 @@ public class BlockedUsersActivity extends BaseFragment implements NotificationCe
}
}
});
showAlertDialog(builder);
showDialog(builder.create());
return true;
}

View File

@ -98,11 +98,11 @@ public class ChatActionCell extends BaseCell {
}
avatarDrawable.setInfo(id, null, null, false);
if (currentMessageObject.messageOwner.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) {
imageReceiver.setImage(currentMessageObject.messageOwner.action.newUserPhoto.photo_small, "50_50", avatarDrawable, false);
imageReceiver.setImage(currentMessageObject.messageOwner.action.newUserPhoto.photo_small, "50_50", avatarDrawable, null, false);
} else {
TLRPC.PhotoSize photo = FileLoader.getClosestPhotoSizeWithSize(currentMessageObject.photoThumbs, AndroidUtilities.dp(64));
if (photo != null) {
imageReceiver.setImage(photo.location, "50_50", avatarDrawable, false);
imageReceiver.setImage(photo.location, "50_50", avatarDrawable, null, false);
} else {
imageReceiver.setImageBitmap(avatarDrawable);
}
@ -225,7 +225,7 @@ public class ChatActionCell extends BaseCell {
try {
int linesCount = textLayout.getLineCount();
for (int a = 0; a < linesCount; a++) {
float lineWidth = 0;
float lineWidth;
float lineLeft = 0;
try {
lineWidth = textLayout.getLineWidth(a);
@ -257,7 +257,7 @@ public class ChatActionCell extends BaseCell {
return;
}
Drawable backgroundDrawable = null;
Drawable backgroundDrawable;
if (ApplicationLoader.isCustomTheme()) {
backgroundDrawable = ResourceLoader.backgroundBlack;
} else {

View File

@ -165,7 +165,7 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
seekBar.setProgress(currentMessageObject.audioProgress);
}
int duration = 0;
int duration;
if (!MediaController.getInstance().isPlayingAudio(currentMessageObject)) {
duration = currentMessageObject.messageOwner.media.audio.duration;
} else {
@ -307,11 +307,6 @@ public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelega
backgroundWidth = Math.min(AndroidUtilities.displaySize.x - AndroidUtilities.dp(isChat ? 102 : 50), AndroidUtilities.dp(300));
}
int uid = messageObject.messageOwner.media.audio.user_id;
if (uid == 0) {
uid = messageObject.messageOwner.from_id;
}
if (messageObject.isOut()) {
seekBar.type = 0;
progressView.setProgressColors(0xffb4e396, 0xff6ac453);

View File

@ -47,6 +47,7 @@ public class ChatBaseCell extends BaseCell {
void didLongPressed(ChatBaseCell cell);
void didPressReplyMessage(ChatBaseCell cell, int id);
void didPressUrl(String url);
void needOpenWebView(String url, String title, String originalUrl, int w, int h);
boolean canPerformActions();
}
@ -196,6 +197,9 @@ public class ChatBaseCell extends BaseCell {
replyTextPaint.linkColor = 0xff316f9f;
replyLinePaint = new Paint();
urlPaint = new Paint();
urlPaint.setColor(0x33316f9f);
}
avatarImage = new ImageReceiver(this);
avatarImage.setRoundRadius(AndroidUtilities.dp(21));
@ -347,7 +351,7 @@ public class ChatBaseCell extends BaseCell {
currentPhoto = null;
avatarDrawable.setInfo(messageObject.messageOwner.from_id, null, null, false);
}
avatarImage.setImage(currentPhoto, "50_50", avatarDrawable, false);
avatarImage.setImage(currentPhoto, "50_50", avatarDrawable, null, false);
}
if (!media) {
@ -461,7 +465,7 @@ public class ChatBaseCell extends BaseCell {
needReplyImage = false;
} else {
currentReplyPhoto = photoSize.location;
replyImageReceiver.setImage(photoSize.location, "50_50", null, true);
replyImageReceiver.setImage(photoSize.location, "50_50", null, null, true);
needReplyImage = true;
maxWidth -= AndroidUtilities.dp(44);
}
@ -653,7 +657,7 @@ public class ChatBaseCell extends BaseCell {
avatarImage.draw(canvas);
}
Drawable currentBackgroundDrawable = null;
Drawable currentBackgroundDrawable;
if (currentMessageObject.isOut()) {
if (isPressed() && isCheckPressed || !isCheckPressed && isPressed || isHighlighted) {
if (!media) {

View File

@ -195,7 +195,7 @@ public class ChatContactCell extends ChatBaseCell {
currentPhoto = null;
avatarDrawable.setInfo(uid, null, null, false);
}
avatarImage.setImage(currentPhoto, "50_50", avatarDrawable, false);
avatarImage.setImage(currentPhoto, "50_50", avatarDrawable, null, false);
String currentNameString = ContactsController.formatName(messageObject.messageOwner.media.first_name, messageObject.messageOwner.media.last_name);
int nameWidth = Math.min((int) Math.ceil(namePaint.measureText(currentNameString)), maxWidth);

View File

@ -34,7 +34,6 @@ import org.telegram.android.MediaController;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.messenger.TLRPC;
import org.telegram.messenger.Utilities;
import org.telegram.android.MessageObject;
import org.telegram.ui.Components.RadialProgress;
import org.telegram.ui.Components.ResourceLoader;
@ -407,7 +406,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
cancelLoading = false;
radialProgress.setProgress(0, false);
if (currentMessageObject.type == 1) {
photoImage.setImage(currentPhotoObject.location, currentPhotoFilter, currentPhotoObjectThumb != null ? currentPhotoObjectThumb.location : null, currentPhotoFilter, currentPhotoObject.size, false);
photoImage.setImage(currentPhotoObject.location, currentPhotoFilter, currentPhotoObjectThumb != null ? currentPhotoObjectThumb.location : null, currentPhotoFilter, currentPhotoObject.size, null, false);
} else if (currentMessageObject.type == 8 || currentMessageObject.type == 9) {
FileLoader.getInstance().loadFile(currentMessageObject.messageOwner.media.document, true, false);
lastDownloadedGifMessage = currentMessageObject;
@ -527,7 +526,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
}
ext = ext.toUpperCase();
String str = Utilities.formatFileSize(messageObject.messageOwner.media.document.size) + " " + ext;
String str = AndroidUtilities.formatFileSize(messageObject.messageOwner.media.document.size) + " " + ext;
if (currentInfoString == null || !currentInfoString.equals(str)) {
currentInfoString = str;
@ -539,7 +538,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
} else if (messageObject.type == 8) {
gifDrawable = MediaController.getInstance().getGifDrawable(this, false);
String str = Utilities.formatFileSize(messageObject.messageOwner.media.document.size);
String str = AndroidUtilities.formatFileSize(messageObject.messageOwner.media.document.size);
if (currentInfoString == null || !currentInfoString.equals(str)) {
currentInfoString = str;
infoOffset = 0;
@ -552,7 +551,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
int duration = messageObject.messageOwner.media.video.duration;
int minutes = duration / 60;
int seconds = duration - minutes * 60;
String str = String.format("%d:%02d, %s", minutes, seconds, Utilities.formatFileSize(messageObject.messageOwner.media.video.size));
String str = String.format("%d:%02d, %s", minutes, seconds, AndroidUtilities.formatFileSize(messageObject.messageOwner.media.video.size));
if (currentInfoString == null || !currentInfoString.equals(str)) {
currentInfoString = str;
infoOffset = ResourceLoader.videoIconDrawable.getIntrinsicWidth() + AndroidUtilities.dp(4);
@ -578,7 +577,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
photoImage.setParentMessageObject(messageObject);
if (currentPhotoObject != null) {
currentPhotoFilter = String.format(Locale.US, "%d_%d_b", photoWidth, photoHeight);
photoImage.setImage(null, null, null, null, currentPhotoObject.location, currentPhotoFilter, 0, true);
photoImage.setImage(null, null, null, null, currentPhotoObject.location, currentPhotoFilter, 0, null, true);
} else {
photoImage.setImageBitmap((BitmapDrawable) null);
}
@ -605,7 +604,6 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
maxWidth = (int) Math.max(maxWidth, nameLayout.getLineWidth(a) + AndroidUtilities.dp(16));
}
if (infoLayout != null) {
lineCount = infoLayout.getLineCount();
for (int a = 0; a < infoLayout.getLineCount(); a++) {
maxWidth = (int) Math.max(maxWidth, infoLayout.getLineWidth(a) + AndroidUtilities.dp(16));
}
@ -622,7 +620,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
photoImage.setNeedsQualityThumb(false);
photoImage.setShouldGenerateQualityThumb(false);
photoImage.setParentMessageObject(null);
photoImage.setImage(currentUrl, null, messageObject.isOut() ? ResourceLoader.geoOutDrawable : ResourceLoader.geoInDrawable, 0);
photoImage.setImage(currentUrl, null, messageObject.isOut() ? ResourceLoader.geoOutDrawable : ResourceLoader.geoInDrawable, null, 0);
} else if (messageObject.type == 13) { //webp
drawBackground = false;
for (TLRPC.DocumentAttribute attribute : messageObject.messageOwner.media.document.attributes) {
@ -664,7 +662,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
null,
currentPhotoObjectThumb != null ? currentPhotoObjectThumb.location : null,
"b1",
messageObject.messageOwner.media.document.size, true);
messageObject.messageOwner.media.document.size, "webp", true);
}
} else if (messageObject.messageOwner.media.document.id != 0) {
photoImage.setImage(messageObject.messageOwner.media.document, null,
@ -672,7 +670,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
null,
currentPhotoObjectThumb != null ? currentPhotoObjectThumb.location : null,
"b1",
messageObject.messageOwner.media.document.size, true);
messageObject.messageOwner.media.document.size, "webp", true);
}
} else {
if (AndroidUtilities.isTablet()) {
@ -803,22 +801,22 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
if (photoExist || MediaController.getInstance().canDownloadMedia(MediaController.AUTODOWNLOAD_MASK_PHOTO) || FileLoader.getInstance().isLoadingFile(fileName)) {
if (allowedToSetPhoto || ImageLoader.getInstance().getImageFromMemory(currentPhotoObject.location, null, currentPhotoFilter) != null) {
allowedToSetPhoto = true;
photoImage.setImage(currentPhotoObject.location, currentPhotoFilter, currentPhotoObjectThumb != null ? currentPhotoObjectThumb.location : null, currentPhotoFilter, noSize ? 0 : currentPhotoObject.size, false);
photoImage.setImage(currentPhotoObject.location, currentPhotoFilter, currentPhotoObjectThumb != null ? currentPhotoObjectThumb.location : null, currentPhotoFilter, noSize ? 0 : currentPhotoObject.size, null, false);
} else if (currentPhotoObjectThumb != null) {
photoImage.setImage(null, null, currentPhotoObjectThumb.location, currentPhotoFilter, 0, false);
photoImage.setImage(null, null, currentPhotoObjectThumb.location, currentPhotoFilter, 0, null, false);
} else {
photoImage.setImageBitmap((Drawable) null);
}
} else {
photoNotSet = true;
if (currentPhotoObjectThumb != null) {
photoImage.setImage(null, null, currentPhotoObjectThumb.location, currentPhotoFilter, 0, false);
photoImage.setImage(null, null, currentPhotoObjectThumb.location, currentPhotoFilter, 0, null, false);
} else {
photoImage.setImageBitmap((Drawable) null);
}
}
} else {
photoImage.setImage(null, null, currentPhotoObject.location, currentPhotoFilter, 0, false);
photoImage.setImage(null, null, currentPhotoObject.location, currentPhotoFilter, 0, null, false);
}
} else {
photoImage.setImageBitmap((Bitmap) null);
@ -998,7 +996,7 @@ public class ChatMediaCell extends ChatBaseCell implements MediaController.FileD
radialProgress.setHideCurrentDrawable(false);
if (currentMessageObject.type == 9) {
Drawable menuDrawable = null;
Drawable menuDrawable;
if (currentMessageObject.isOut()) {
infoPaint.setColor(0xff70b15c);
docBackPaint.setColor(0xffdaf5c3);

View File

@ -14,6 +14,7 @@ import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.provider.Browser;
import android.text.Layout;
import android.text.Spannable;
@ -36,6 +37,7 @@ import org.telegram.ui.Components.ResourceLoader;
import org.telegram.ui.Components.StaticLayoutEx;
import org.telegram.ui.Components.URLSpanNoUnderline;
import java.io.File;
import java.util.Locale;
public class ChatMessageCell extends ChatBaseCell {
@ -56,6 +58,9 @@ public class ChatMessageCell extends ChatBaseCell {
private boolean isInstagram;
private int descriptionY;
private int durationWidth;
private int descriptionX;
private int titleX;
private int authorX;
private StaticLayout siteNameLayout;
private StaticLayout titleLayout;
private StaticLayout descriptionLayout;
@ -69,10 +74,6 @@ public class ChatMessageCell extends ChatBaseCell {
super(context);
drawForwardedName = true;
linkImageView = new ImageReceiver(this);
if (urlPaint == null) {
urlPaint = new Paint();
urlPaint.setColor(0x33316f9f);
}
}
@Override
@ -152,7 +153,7 @@ public class ChatMessageCell extends ChatBaseCell {
} else {
if (descriptionLayout != null && y >= descriptionY) {
try {
x -= textX + AndroidUtilities.dp(10);
x -= textX + AndroidUtilities.dp(10) + descriptionX;
y -= descriptionY;
final int line = descriptionLayout.getLineForVertical(y);
final int off = descriptionLayout.getOffsetForHorizontal(line, x);
@ -191,10 +192,15 @@ public class ChatMessageCell extends ChatBaseCell {
if (pressedLink != null) {
pressedLink.onClick(this);
} else {
Uri uri = Uri.parse(currentMessageObject.messageOwner.media.webpage.url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.putExtra(Browser.EXTRA_APPLICATION_ID, getContext().getPackageName());
getContext().startActivity(intent);
TLRPC.WebPage webPage = currentMessageObject.messageOwner.media.webpage;
if (Build.VERSION.SDK_INT >= 16 && webPage.embed_url != null && webPage.embed_url.length() != 0) {
delegate.needOpenWebView(webPage.embed_url, webPage.site_name, webPage.url, webPage.embed_width, webPage.embed_height);
} else {
Uri uri = Uri.parse(webPage.url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.putExtra(Browser.EXTRA_APPLICATION_ID, getContext().getPackageName());
getContext().startActivity(intent);
}
}
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -260,6 +266,9 @@ public class ChatMessageCell extends ChatBaseCell {
int addedChars = 0;
StaticLayout layout = new StaticLayout(text, paint, smallWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
for (int a = 0; a < linesCount; a++) {
if (layout.getLineLeft(a) != 0) {
maxWidth = smallWidth;
}
int pos = layout.getLineEnd(a);
if (pos == text.length()) {
break;
@ -348,6 +357,7 @@ public class ChatMessageCell extends ChatBaseCell {
maxChildWidth = Math.max(maxChildWidth, forwardedNameWidth);
maxChildWidth = Math.max(maxChildWidth, replyNameWidth);
maxChildWidth = Math.max(maxChildWidth, replyTextWidth);
int maxWebWidth = 0;
int timeMore = timeWidth + AndroidUtilities.dp(6);
if (messageObject.isOut()) {
@ -387,9 +397,7 @@ public class ChatMessageCell extends ChatBaseCell {
currentMessageObject.generateThumbs(true);
}
if (MediaController.getInstance().canDownloadMedia(MediaController.AUTODOWNLOAD_MASK_PHOTO)) {
isSmallImage = webPage.description != null && webPage.type != null && (webPage.type.equals("app") || webPage.type.equals("profile") || webPage.type.equals("article")) && currentMessageObject.photoThumbs != null;
}
isSmallImage = webPage.description != null && webPage.type != null && (webPage.type.equals("app") || webPage.type.equals("profile") || webPage.type.equals("article")) && currentMessageObject.photoThumbs != null;
if (webPage.site_name != null) {
try {
@ -399,35 +407,54 @@ public class ChatMessageCell extends ChatBaseCell {
linkPreviewHeight += height;
totalHeight += height;
additionalHeight += height;
width = siteNameLayout.getWidth();
maxChildWidth = Math.max(maxChildWidth, width + additinalWidth);
maxWebWidth = Math.max(maxWebWidth, width + additinalWidth);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
boolean titleIsRTL = false;
if (webPage.title != null) {
try {
titleX = 0;
if (linkPreviewHeight != 0) {
linkPreviewHeight += AndroidUtilities.dp(2);
totalHeight += AndroidUtilities.dp(2);
}
int restLines = 0;
if (!isSmallImage || webPage.description == null) {
titleLayout = StaticLayoutEx.createStaticLayout(webPage.title, replyNamePaint, linkPreviewMaxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, AndroidUtilities.dp(1), false, TextUtils.TruncateAt.END, linkPreviewMaxWidth, 2);
titleLayout = StaticLayoutEx.createStaticLayout(webPage.title, replyNamePaint, linkPreviewMaxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, AndroidUtilities.dp(1), false, TextUtils.TruncateAt.END, linkPreviewMaxWidth, 4);
} else {
restLines = restLinesCount;
titleLayout = generateStaticLayout(webPage.title, replyNamePaint, linkPreviewMaxWidth, linkPreviewMaxWidth - AndroidUtilities.dp(48 + 2), restLinesCount, 2);
titleLayout = generateStaticLayout(webPage.title, replyNamePaint, linkPreviewMaxWidth, linkPreviewMaxWidth - AndroidUtilities.dp(48 + 2), restLinesCount, 4);
restLinesCount -= titleLayout.getLineCount();
}
int height = titleLayout.getLineBottom(titleLayout.getLineCount() - 1);
linkPreviewHeight += height;
totalHeight += height;
for (int a = 0; a < titleLayout.getLineCount(); a++) {
int width = (int) Math.ceil(titleLayout.getLineWidth(a));
if (a < restLines) {
int lineLeft = (int) titleLayout.getLineLeft(a);
if (lineLeft != 0) {
titleIsRTL = true;
if (titleX == 0) {
titleX = -lineLeft;
} else {
titleX = Math.max(titleX, -lineLeft);
}
}
int width;
if (lineLeft != 0) {
width = titleLayout.getWidth() - lineLeft;
} else {
width = (int) Math.ceil(titleLayout.getLineWidth(a));
}
if (a < restLines || lineLeft != 0 && isSmallImage) {
width += AndroidUtilities.dp(48 + 2);
}
maxChildWidth = Math.max(maxChildWidth, width + additinalWidth);
maxWebWidth = Math.max(maxWebWidth, width + additinalWidth);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -450,7 +477,10 @@ public class ChatMessageCell extends ChatBaseCell {
int height = authorLayout.getLineBottom(authorLayout.getLineCount() - 1);
linkPreviewHeight += height;
totalHeight += height;
int lineLeft = (int) authorLayout.getLineLeft(0);
authorX = -lineLeft;
maxChildWidth = Math.max(maxChildWidth, width + additinalWidth);
maxWebWidth = Math.max(maxWebWidth, width + additinalWidth);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
@ -458,6 +488,7 @@ public class ChatMessageCell extends ChatBaseCell {
if (webPage.description != null) {
try {
descriptionX = 0;
currentMessageObject.generateLinkDescription();
if (linkPreviewHeight != 0) {
linkPreviewHeight += AndroidUtilities.dp(2);
@ -474,10 +505,28 @@ public class ChatMessageCell extends ChatBaseCell {
linkPreviewHeight += height;
totalHeight += height;
for (int a = 0; a < descriptionLayout.getLineCount(); a++) {
int width = (int) Math.ceil(descriptionLayout.getLineWidth(a));
if (a < restLines) {
int lineLeft = (int) Math.ceil(descriptionLayout.getLineLeft(a));
if (descriptionX == 0) {
descriptionX = -lineLeft;
} else {
descriptionX = Math.max(descriptionX, -lineLeft);
}
int width;
if (lineLeft != 0) {
width = descriptionLayout.getWidth() - lineLeft;
} else {
width = (int) Math.ceil(descriptionLayout.getLineWidth(a));
}
if (a < restLines || lineLeft != 0 && isSmallImage) {
width += AndroidUtilities.dp(48 + 2);
}
if (maxWebWidth < width + additinalWidth) {
if (titleIsRTL) {
titleX += (width + additinalWidth - maxWebWidth);
}
maxWebWidth = width + additinalWidth;
}
maxChildWidth = Math.max(maxChildWidth, width + additinalWidth);
}
} catch (Exception e) {
@ -485,7 +534,7 @@ public class ChatMessageCell extends ChatBaseCell {
}
}
if (webPage.photo != null && MediaController.getInstance().canDownloadMedia(MediaController.AUTODOWNLOAD_MASK_PHOTO)) {
if (webPage.photo != null) {
boolean smallImage = webPage.type != null && (webPage.type.equals("app") || webPage.type.equals("profile") || webPage.type.equals("article"));
if (smallImage && descriptionLayout != null && descriptionLayout.getLineCount() == 1) {
smallImage = false;
@ -537,7 +586,26 @@ public class ChatMessageCell extends ChatBaseCell {
}
linkImageView.setImageCoords(0, 0, width, height);
linkImageView.setImage(currentPhotoObject.location, String.format(Locale.US, "%d_%d", width, height), currentPhotoObjectThumb != null ? currentPhotoObjectThumb.location : null, String.format(Locale.US, "%d_%d_b", width, height), 0, false);
String fileName = FileLoader.getAttachFileName(currentPhotoObject);
boolean photoExist = true;
File cacheFile = FileLoader.getPathToAttach(currentPhotoObject, true);
if (!cacheFile.exists()) {
photoExist = false;
}
String filter = String.format(Locale.US, "%d_%d", width, height);
if (photoExist || MediaController.getInstance().canDownloadMedia(MediaController.AUTODOWNLOAD_MASK_PHOTO) || FileLoader.getInstance().isLoadingFile(fileName)) {
linkImageView.setImage(currentPhotoObject.location, filter, currentPhotoObjectThumb != null ? currentPhotoObjectThumb.location : null, String.format(Locale.US, "%d_%d_b", width, height), 0, null, false);
} else {
if (currentPhotoObjectThumb != null) {
linkImageView.setImage(null, null, currentPhotoObjectThumb.location, String.format(Locale.US, "%d_%d_b", width, height), 0, null, false);
} else {
linkImageView.setImageBitmap((Drawable) null);
}
}
drawLinkImageView = true;
if (webPage.site_name != null) {
@ -659,7 +727,7 @@ public class ChatMessageCell extends ChatBaseCell {
replyNamePaint.setColor(0xff000000);
smallImageStartY = linkPreviewY - AndroidUtilities.dp(1);
canvas.save();
canvas.translate(textX + AndroidUtilities.dp(10), linkPreviewY - AndroidUtilities.dp(3));
canvas.translate(textX + AndroidUtilities.dp(10) + titleX, linkPreviewY - AndroidUtilities.dp(3));
titleLayout.draw(canvas);
canvas.restore();
linkPreviewY += titleLayout.getLineBottom(titleLayout.getLineCount() - 1);
@ -674,7 +742,7 @@ public class ChatMessageCell extends ChatBaseCell {
}
replyNamePaint.setColor(0xff000000);
canvas.save();
canvas.translate(textX + AndroidUtilities.dp(10), linkPreviewY - AndroidUtilities.dp(3));
canvas.translate(textX + AndroidUtilities.dp(10) + authorX, linkPreviewY - AndroidUtilities.dp(3));
authorLayout.draw(canvas);
canvas.restore();
linkPreviewY += authorLayout.getLineBottom(authorLayout.getLineCount() - 1);
@ -690,7 +758,7 @@ public class ChatMessageCell extends ChatBaseCell {
replyTextPaint.setColor(0xff000000);
descriptionY = linkPreviewY - AndroidUtilities.dp(3);
canvas.save();
canvas.translate(textX + AndroidUtilities.dp(10), descriptionY);
canvas.translate(textX + AndroidUtilities.dp(10) + descriptionX, descriptionY);
if (pressedLink != null && linkBlockNum == -10) {
canvas.drawPath(urlPath, urlPaint);
}

View File

@ -12,10 +12,12 @@ import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.view.MotionEvent;
import org.telegram.android.AndroidUtilities;
import org.telegram.PhoneFormat.PhoneFormat;
@ -52,6 +54,7 @@ public class DialogCell extends BaseCell {
private static Drawable muteDrawable;
private static Paint linePaint;
private static Paint backPaint;
private long currentDialogId;
private boolean isDialogCell;
@ -74,7 +77,6 @@ public class DialogCell extends BaseCell {
public boolean useSeparator = false;
private int nameLeft;
private StaticLayout nameLayout;
private boolean drawNameLock;
@ -111,7 +113,11 @@ public class DialogCell extends BaseCell {
private int avatarTop = AndroidUtilities.dp(10);
private void init() {
private boolean isSelected;
public DialogCell(Context context) {
super(context);
if (namePaint == null) {
namePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
namePaint.setTextSize(AndroidUtilities.dp(17));
@ -136,6 +142,9 @@ public class DialogCell extends BaseCell {
linePaint = new Paint();
linePaint.setColor(0xffdcdcdc);
backPaint = new Paint();
backPaint.setColor(0x0f000000);
messagePrintingPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
messagePrintingPaint.setTextSize(AndroidUtilities.dp(16));
messagePrintingPaint.setColor(0xff4d83b3);
@ -159,11 +168,9 @@ public class DialogCell extends BaseCell {
broadcastDrawable = getResources().getDrawable(R.drawable.list_broadcast);
muteDrawable = getResources().getDrawable(R.drawable.mute_grey);
}
}
public DialogCell(Context context) {
super(context);
init();
setBackgroundResource(R.drawable.list_selector);
avatarImage = new ImageReceiver(this);
avatarImage.setRoundRadius(AndroidUtilities.dp(26));
avatarDrawable = new AvatarDrawable();
@ -208,7 +215,7 @@ public class DialogCell extends BaseCell {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), AndroidUtilities.dp(72));
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), AndroidUtilities.dp(72) + (useSeparator ? 1 : 0));
}
@Override
@ -222,6 +229,16 @@ public class DialogCell extends BaseCell {
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (Build.VERSION.SDK_INT >= 21 && getBackground() != null) {
if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) {
getBackground().setHotspot(event.getX(), event.getY());
}
}
return super.onTouchEvent(event);
}
public void buildLayout() {
String nameString = "";
String timeString = "";
@ -568,8 +585,8 @@ public class DialogCell extends BaseCell {
FileLog.e("tmessages", e);
}
double widthpx = 0;
float left = 0;
double widthpx;
float left;
if (LocaleController.isRTL) {
if (nameLayout != null && nameLayout.getLineCount() > 0) {
left = nameLayout.getLineLeft(0);
@ -617,6 +634,13 @@ public class DialogCell extends BaseCell {
}
}
public void setDialogSelected(boolean value) {
if (isSelected != value) {
invalidate();
}
isSelected = value;
}
public void checkCurrentDialogIndex() {
TLRPC.TL_dialog dialog = null;
if (isServerOnly) {
@ -740,7 +764,7 @@ public class DialogCell extends BaseCell {
}
avatarDrawable.setInfo(chat);
}
avatarImage.setImage(photo, "50_50", avatarDrawable, false);
avatarImage.setImage(photo, "50_50", avatarDrawable, null, false);
if (getMeasuredWidth() != 0 || getMeasuredHeight() != 0) {
buildLayout();
@ -757,6 +781,10 @@ public class DialogCell extends BaseCell {
return;
}
if (isSelected) {
canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), backPaint);
}
if (drawNameLock) {
setDrawableBounds(lockDrawable, nameLockLeft, nameLockTop);
lockDrawable.draw(canvas);

View File

@ -33,14 +33,7 @@ public class DrawerActionCell extends FrameLayout {
textView.setSingleLine(true);
textView.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
textView.setCompoundDrawablePadding(AndroidUtilities.dp(34));
addView(textView);
LayoutParams layoutParams = (LayoutParams) textView.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
layoutParams.gravity = Gravity.LEFT;
layoutParams.leftMargin = AndroidUtilities.dp(14);
layoutParams.rightMargin = AndroidUtilities.dp(16);
textView.setLayoutParams(layoutParams);
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 14, 0, 16, 0));
}
@Override

View File

@ -27,6 +27,7 @@ import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.android.AndroidUtilities;
import org.telegram.android.ContactsController;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.messenger.TLRPC;
import org.telegram.ui.Components.AvatarDrawable;
@ -51,23 +52,11 @@ public class DrawerProfileCell extends FrameLayout {
shadowView.setVisibility(INVISIBLE);
shadowView.setScaleType(ImageView.ScaleType.FIT_XY);
shadowView.setImageResource(R.drawable.bottom_shadow);
addView(shadowView);
LayoutParams layoutParams = (FrameLayout.LayoutParams) shadowView.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = AndroidUtilities.dp(70);
layoutParams.gravity = Gravity.LEFT | Gravity.BOTTOM;
shadowView.setLayoutParams(layoutParams);
addView(shadowView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 70, Gravity.LEFT | Gravity.BOTTOM));
avatarImageView = new BackupImageView(context);
avatarImageView.getImageReceiver().setRoundRadius(AndroidUtilities.dp(32));
addView(avatarImageView);
layoutParams = (LayoutParams) avatarImageView.getLayoutParams();
layoutParams.width = AndroidUtilities.dp(64);
layoutParams.height = AndroidUtilities.dp(64);
layoutParams.gravity = Gravity.LEFT | Gravity.BOTTOM;
layoutParams.leftMargin = AndroidUtilities.dp(16);
layoutParams.bottomMargin = AndroidUtilities.dp(67);
avatarImageView.setLayoutParams(layoutParams);
addView(avatarImageView, LayoutHelper.createFrame(64, 64, Gravity.LEFT | Gravity.BOTTOM, 16, 0, 0, 67));
nameTextView = new TextView(context);
nameTextView.setTextColor(0xffffffff);
@ -77,15 +66,7 @@ public class DrawerProfileCell extends FrameLayout {
nameTextView.setMaxLines(1);
nameTextView.setSingleLine(true);
nameTextView.setGravity(Gravity.LEFT);
addView(nameTextView);
layoutParams = (FrameLayout.LayoutParams) nameTextView.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.WRAP_CONTENT;
layoutParams.gravity = Gravity.LEFT | Gravity.BOTTOM;
layoutParams.leftMargin = AndroidUtilities.dp(16);
layoutParams.bottomMargin = AndroidUtilities.dp(28);
layoutParams.rightMargin = AndroidUtilities.dp(16);
nameTextView.setLayoutParams(layoutParams);
addView(nameTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.BOTTOM, 16, 0, 16, 28));
phoneTextView = new TextView(context);
phoneTextView.setTextColor(0xffc2e5ff);
@ -94,15 +75,7 @@ public class DrawerProfileCell extends FrameLayout {
phoneTextView.setMaxLines(1);
phoneTextView.setSingleLine(true);
phoneTextView.setGravity(Gravity.LEFT);
addView(phoneTextView);
layoutParams = (FrameLayout.LayoutParams) phoneTextView.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.WRAP_CONTENT;
layoutParams.gravity = Gravity.LEFT | Gravity.BOTTOM;
layoutParams.leftMargin = AndroidUtilities.dp(16);
layoutParams.bottomMargin = AndroidUtilities.dp(9);
layoutParams.rightMargin = AndroidUtilities.dp(16);
phoneTextView.setLayoutParams(layoutParams);
addView(phoneTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.BOTTOM, 16, 0, 16, 9));
}
@Override
@ -110,7 +83,11 @@ public class DrawerProfileCell extends FrameLayout {
if (Build.VERSION.SDK_INT >= 21) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(148) + AndroidUtilities.statusBarHeight, MeasureSpec.EXACTLY));
} else {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(148), MeasureSpec.EXACTLY));
try {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(148), MeasureSpec.EXACTLY));
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
}

View File

@ -31,19 +31,12 @@ public class GreySectionCell extends FrameLayout {
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
textView.setTextColor(0xff8a8a8a);
textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
addView(textView);
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams)textView.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
layoutParams.leftMargin = AndroidUtilities.dp(16);
layoutParams.rightMargin = AndroidUtilities.dp(16);
layoutParams.gravity = LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT;
textView.setLayoutParams(layoutParams);
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 16, 0, 16, 0));
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(36), MeasureSpec.EXACTLY));
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(36), MeasureSpec.EXACTLY));
}
public void setText(String text) {

View File

@ -11,11 +11,14 @@ package org.telegram.ui.Cells;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Build;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.widget.TextView;
import org.telegram.android.AndroidUtilities;
import org.telegram.messenger.R;
public class HashtagSearchCell extends TextView {
@ -32,6 +35,18 @@ public class HashtagSearchCell extends TextView {
paint = new Paint();
paint.setColor(0xffdcdcdc);
}
setBackgroundResource(R.drawable.list_selector);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (Build.VERSION.SDK_INT >= 21 && getBackground() != null) {
if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) {
getBackground().setHotspot(event.getX(), event.getY());
}
}
return super.onTouchEvent(event);
}
public void setNeedDivider(boolean value) {

View File

@ -9,7 +9,6 @@
package org.telegram.ui.Cells;
import android.content.Context;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.widget.FrameLayout;
@ -23,41 +22,15 @@ public class HeaderCell extends FrameLayout {
private TextView textView;
private void init() {
public HeaderCell(Context context) {
super(context);
textView = new TextView(getContext());
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
textView.setTextColor(0xff3e90cf);
textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
addView(textView);
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams)textView.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
layoutParams.leftMargin = AndroidUtilities.dp(17);
layoutParams.rightMargin = AndroidUtilities.dp(17);
layoutParams.topMargin = AndroidUtilities.dp(15);
layoutParams.gravity = LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT;
textView.setLayoutParams(layoutParams);
}
public HeaderCell(Context context) {
super(context);
init();
}
public HeaderCell(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public HeaderCell(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public HeaderCell(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 17, 15, 17, 0));
}
@Override

View File

@ -31,11 +31,7 @@ public class LetterSectionCell extends FrameLayout {
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
textView.setTextColor(0xff808080);
textView.setGravity(Gravity.CENTER);
addView(textView);
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams)textView.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
textView.setLayoutParams(layoutParams);
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
}
public void setLetter(String letter) {

View File

@ -22,16 +22,11 @@ public class LoadingCell extends FrameLayout {
super(context);
ProgressBar progressBar = new ProgressBar(context);
addView(progressBar);
LayoutParams layoutParams = (FrameLayout.LayoutParams) progressBar.getLayoutParams();
layoutParams.width = LayoutHelper.WRAP_CONTENT;
layoutParams.height = LayoutHelper.WRAP_CONTENT;
layoutParams.gravity = Gravity.CENTER;
progressBar.setLayoutParams(layoutParams);
addView(progressBar, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER));
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(54), MeasureSpec.EXACTLY));
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(54), MeasureSpec.EXACTLY));
}
}

View File

@ -39,13 +39,7 @@ public class MentionCell extends LinearLayout {
imageView = new BackupImageView(context);
imageView.setRoundRadius(AndroidUtilities.dp(14));
addView(imageView);
LayoutParams layoutParams = (LayoutParams) imageView.getLayoutParams();
layoutParams.leftMargin = AndroidUtilities.dp(12);
layoutParams.topMargin = AndroidUtilities.dp(4);
layoutParams.width = AndroidUtilities.dp(28);
layoutParams.height = AndroidUtilities.dp(28);
imageView.setLayoutParams(layoutParams);
addView(imageView, LayoutHelper.createLinear(28, 28, 12, 4, 0, 0));
nameTextView = new TextView(context);
nameTextView.setTextColor(0xff000000);
@ -53,13 +47,7 @@ public class MentionCell extends LinearLayout {
nameTextView.setSingleLine(true);
nameTextView.setGravity(Gravity.LEFT);
nameTextView.setEllipsize(TextUtils.TruncateAt.END);
addView(nameTextView);
layoutParams = (LayoutParams) nameTextView.getLayoutParams();
layoutParams.leftMargin = AndroidUtilities.dp(12);
layoutParams.width = LayoutHelper.WRAP_CONTENT;
layoutParams.height = LayoutHelper.WRAP_CONTENT;
layoutParams.gravity = Gravity.CENTER_VERTICAL;
nameTextView.setLayoutParams(layoutParams);
addView(nameTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL, 12, 0, 0, 0));
usernameTextView = new TextView(context);
usernameTextView.setTextColor(0xff999999);
@ -67,13 +55,7 @@ public class MentionCell extends LinearLayout {
usernameTextView.setSingleLine(true);
usernameTextView.setGravity(Gravity.LEFT);
usernameTextView.setEllipsize(TextUtils.TruncateAt.END);
addView(usernameTextView);
layoutParams = (LayoutParams) usernameTextView.getLayoutParams();
layoutParams.leftMargin = AndroidUtilities.dp(12);
layoutParams.width = LayoutHelper.WRAP_CONTENT;
layoutParams.height = LayoutHelper.WRAP_CONTENT;
layoutParams.gravity = Gravity.CENTER_VERTICAL;
usernameTextView.setLayoutParams(layoutParams);
addView(usernameTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL, 12, 0, 0, 0));
}
@Override

View File

@ -30,12 +30,7 @@ public class PhotoEditToolCell extends FrameLayoutFixed {
iconImage = new ImageView(context);
iconImage.setScaleType(ImageView.ScaleType.CENTER);
addView(iconImage);
LayoutParams layoutParams = (LayoutParams) iconImage.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
layoutParams.bottomMargin = AndroidUtilities.dp(12);
iconImage.setLayoutParams(layoutParams);
addView(iconImage, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT, 0, 0, 0, 12));
nameTextView = new TextView(context);
nameTextView.setGravity(Gravity.CENTER);
@ -45,27 +40,13 @@ public class PhotoEditToolCell extends FrameLayoutFixed {
nameTextView.setMaxLines(1);
nameTextView.setSingleLine(true);
nameTextView.setEllipsize(TextUtils.TruncateAt.END);
addView(nameTextView);
layoutParams = (LayoutParams) nameTextView.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.WRAP_CONTENT;
layoutParams.gravity = Gravity.LEFT | Gravity.BOTTOM;
layoutParams.leftMargin = AndroidUtilities.dp(4);
layoutParams.rightMargin = AndroidUtilities.dp(4);
nameTextView.setLayoutParams(layoutParams);
addView(nameTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.BOTTOM, 4, 0, 4, 0));
valueTextView = new TextView(context);
valueTextView.setTextColor(0xff6cc3ff);
valueTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 11);
valueTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
addView(valueTextView);
layoutParams = (LayoutParams) valueTextView.getLayoutParams();
layoutParams.width = LayoutHelper.WRAP_CONTENT;
layoutParams.height = LayoutHelper.WRAP_CONTENT;
layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
layoutParams.leftMargin = AndroidUtilities.dp(57);
layoutParams.topMargin = AndroidUtilities.dp(3);
valueTextView.setLayoutParams(layoutParams);
addView(valueTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 57, 3, 0, 0));
}
@Override

View File

@ -47,21 +47,12 @@ public class PhotoPickerAlbumsCell extends FrameLayoutFixed {
super(context);
imageView = new BackupImageView(context);
addView(imageView);
LayoutParams layoutParams = (LayoutParams) imageView.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
imageView.setLayoutParams(layoutParams);
addView(imageView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
LinearLayout linearLayout = new LinearLayout(context);
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
linearLayout.setBackgroundColor(0x7f000000);
addView(linearLayout);
layoutParams = (LayoutParams) linearLayout.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = AndroidUtilities.dp(28);
layoutParams.gravity = Gravity.BOTTOM;
linearLayout.setLayoutParams(layoutParams);
addView(linearLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 28, Gravity.LEFT | Gravity.BOTTOM));
nameTextView = new TextView(context);
nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
@ -70,13 +61,7 @@ public class PhotoPickerAlbumsCell extends FrameLayoutFixed {
nameTextView.setEllipsize(TextUtils.TruncateAt.END);
nameTextView.setMaxLines(1);
nameTextView.setGravity(Gravity.CENTER_VERTICAL);
linearLayout.addView(nameTextView);
LinearLayout.LayoutParams layoutParams1 = (LinearLayout.LayoutParams) nameTextView.getLayoutParams();
layoutParams1.width = 0;
layoutParams1.height = LayoutHelper.MATCH_PARENT;
layoutParams1.leftMargin = AndroidUtilities.dp(8);
layoutParams1.weight = 1;
nameTextView.setLayoutParams(layoutParams1);
linearLayout.addView(nameTextView, LayoutHelper.createLinear(0, LayoutHelper.MATCH_PARENT, 1.0f, 8, 0, 0, 0));
countTextView = new TextView(context);
countTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
@ -85,21 +70,11 @@ public class PhotoPickerAlbumsCell extends FrameLayoutFixed {
countTextView.setEllipsize(TextUtils.TruncateAt.END);
countTextView.setMaxLines(1);
countTextView.setGravity(Gravity.CENTER_VERTICAL);
linearLayout.addView(countTextView);
layoutParams1 = (LinearLayout.LayoutParams) countTextView.getLayoutParams();
layoutParams1.width = LayoutHelper.WRAP_CONTENT;
layoutParams1.height = LayoutHelper.MATCH_PARENT;
layoutParams1.leftMargin = AndroidUtilities.dp(4);
layoutParams1.rightMargin = AndroidUtilities.dp(4);
countTextView.setLayoutParams(layoutParams1);
linearLayout.addView(countTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, 4, 0, 4, 0));
selector = new View(context);
selector.setBackgroundResource(R.drawable.list_selector);
addView(selector);
layoutParams = (LayoutParams) selector.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
selector.setLayoutParams(layoutParams);
addView(selector, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
}
@Override

View File

@ -29,33 +29,17 @@ public class PhotoPickerPhotoCell extends FrameLayout {
super(context);
photoImage = new BackupImageView(context);
addView(photoImage);
LayoutParams layoutParams = (LayoutParams) photoImage.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
photoImage.setLayoutParams(layoutParams);
addView(photoImage, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
checkFrame = new FrameLayout(context);
addView(checkFrame);
layoutParams = (LayoutParams) checkFrame.getLayoutParams();
layoutParams.width = AndroidUtilities.dp(42);
layoutParams.height = AndroidUtilities.dp(42);
layoutParams.gravity = Gravity.RIGHT | Gravity.TOP;
checkFrame.setLayoutParams(layoutParams);
addView(checkFrame, LayoutHelper.createFrame(42, 42, Gravity.RIGHT | Gravity.TOP));
checkBox = new CheckBox(context, R.drawable.checkbig);
checkBox.setSize(30);
checkBox.setCheckOffset(AndroidUtilities.dp(1));
checkBox.setDrawBackground(true);
checkBox.setColor(0xff3ccaef);
addView(checkBox);
layoutParams = (LayoutParams) checkBox.getLayoutParams();
layoutParams.width = AndroidUtilities.dp(30);
layoutParams.height = AndroidUtilities.dp(30);
layoutParams.gravity = Gravity.RIGHT | Gravity.TOP;
layoutParams.topMargin = AndroidUtilities.dp(6);
layoutParams.rightMargin = AndroidUtilities.dp(6);
checkBox.setLayoutParams(layoutParams);
addView(checkBox, LayoutHelper.createFrame(30, 30, Gravity.RIGHT | Gravity.TOP, 0, 6, 6, 0));
}
@Override

View File

@ -45,20 +45,11 @@ public class PhotoPickerSearchCell extends LinearLayout {
selector = new View(context);
selector.setBackgroundResource(R.drawable.list_selector);
addView(selector);
FrameLayout.LayoutParams layoutParams1 = (FrameLayout.LayoutParams) selector.getLayoutParams();
layoutParams1.width = LayoutHelper.MATCH_PARENT;
layoutParams1.height = LayoutHelper.MATCH_PARENT;
selector.setLayoutParams(layoutParams1);
addView(selector, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
imageView = new ImageView(context);
imageView.setScaleType(ImageView.ScaleType.CENTER);
addView(imageView);
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) imageView.getLayoutParams();
layoutParams.height = AndroidUtilities.dp(48);
layoutParams.width = AndroidUtilities.dp(48);
layoutParams1.gravity = Gravity.LEFT | Gravity.TOP;
imageView.setLayoutParams(layoutParams);
addView(imageView, LayoutHelper.createFrame(48, 48, Gravity.LEFT | Gravity.TOP));
textView1 = new TextView(context);
textView1.setGravity(Gravity.CENTER_VERTICAL);
@ -67,15 +58,7 @@ public class PhotoPickerSearchCell extends LinearLayout {
textView1.setTextColor(0xffffffff);
textView1.setSingleLine(true);
textView1.setEllipsize(TextUtils.TruncateAt.END);
addView(textView1);
layoutParams1 = (FrameLayout.LayoutParams) textView1.getLayoutParams();
layoutParams1.width = LayoutHelper.MATCH_PARENT;
layoutParams1.height = LayoutHelper.WRAP_CONTENT;
layoutParams1.gravity = Gravity.TOP | Gravity.LEFT;
layoutParams1.rightMargin = AndroidUtilities.dp(4);
layoutParams1.leftMargin = AndroidUtilities.dp(51);
layoutParams1.topMargin = AndroidUtilities.dp(8);
textView1.setLayoutParams(layoutParams1);
addView(textView1, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.LEFT, 51, 8, 4, 0));
textView2 = new TextView(context);
textView2.setGravity(Gravity.CENTER_VERTICAL);
@ -84,15 +67,7 @@ public class PhotoPickerSearchCell extends LinearLayout {
textView2.setTextColor(0xff666666);
textView2.setSingleLine(true);
textView2.setEllipsize(TextUtils.TruncateAt.END);
addView(textView2);
layoutParams1 = (FrameLayout.LayoutParams) textView2.getLayoutParams();
layoutParams1.width = LayoutHelper.MATCH_PARENT;
layoutParams1.height = LayoutHelper.WRAP_CONTENT;
layoutParams1.gravity = Gravity.TOP | Gravity.LEFT;
layoutParams1.leftMargin = AndroidUtilities.dp(51);
layoutParams1.rightMargin = AndroidUtilities.dp(4);
layoutParams1.topMargin = AndroidUtilities.dp(26);
textView2.setLayoutParams(layoutParams1);
addView(textView2, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.LEFT, 51, 26, 4, 0));
}
@Override

View File

@ -12,10 +12,12 @@ import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.view.MotionEvent;
import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.android.AndroidUtilities;
@ -70,13 +72,7 @@ public class ProfileSearchCell extends BaseCell {
public ProfileSearchCell(Context context) {
super(context);
init();
avatarImage = new ImageReceiver(this);
avatarImage.setRoundRadius(AndroidUtilities.dp(26));
avatarDrawable = new AvatarDrawable();
}
private void init() {
if (namePaint == null) {
namePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
namePaint.setTextSize(AndroidUtilities.dp(17));
@ -103,6 +99,20 @@ public class ProfileSearchCell extends BaseCell {
lockDrawable = getResources().getDrawable(R.drawable.list_secret);
groupDrawable = getResources().getDrawable(R.drawable.list_group);
}
avatarImage = new ImageReceiver(this);
avatarImage.setRoundRadius(AndroidUtilities.dp(26));
avatarDrawable = new AvatarDrawable();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (Build.VERSION.SDK_INT >= 21 && getBackground() != null) {
if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) {
getBackground().setHotspot(event.getX(), event.getY());
}
}
return super.onTouchEvent(event);
}
public void setData(TLRPC.User u, TLRPC.Chat c, TLRPC.EncryptedChat ec, CharSequence n, CharSequence s) {
@ -143,7 +153,7 @@ public class ProfileSearchCell extends BaseCell {
}
public void buildLayout() {
CharSequence nameString = "";
CharSequence nameString;
TextPaint currentNamePaint;
drawNameBroadcast = false;
@ -235,7 +245,7 @@ public class ProfileSearchCell extends BaseCell {
onlineLeft = AndroidUtilities.dp(11);
}
CharSequence onlineString = "";
CharSequence onlineString;
TextPaint currentOnlinePaint = offlinePaint;
if (subLabel != null) {
@ -265,8 +275,8 @@ public class ProfileSearchCell extends BaseCell {
avatarImage.setImageCoords(avatarLeft, AndroidUtilities.dp(10), AndroidUtilities.dp(52), AndroidUtilities.dp(52));
double widthpx = 0;
float left = 0;
double widthpx;
float left;
if (LocaleController.isRTL) {
if (nameLayout.getLineCount() > 0) {
left = nameLayout.getLineLeft(0);
@ -370,7 +380,7 @@ public class ProfileSearchCell extends BaseCell {
lastAvatar = photo;
avatarImage.setImage(photo, "50_50", avatarDrawable, false);
avatarImage.setImage(photo, "50_50", avatarDrawable, null, false);
if (getMeasuredWidth() != 0 || getMeasuredHeight() != 0) {
buildLayout();

View File

@ -47,15 +47,7 @@ public class SessionCell extends FrameLayout {
LinearLayout linearLayout = new LinearLayout(context);
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
linearLayout.setWeightSum(1);
addView(linearLayout);
LayoutParams layoutParams = (LayoutParams) linearLayout.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = AndroidUtilities.dp(30);
layoutParams.leftMargin = AndroidUtilities.dp(17);
layoutParams.rightMargin = AndroidUtilities.dp(17);
layoutParams.topMargin = AndroidUtilities.dp(11);
layoutParams.gravity = LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT;
linearLayout.setLayoutParams(layoutParams);
addView(linearLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 30, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 17, 11, 11, 0));
nameTextView = new TextView(context);
nameTextView.setTextColor(0xff212121);
@ -72,32 +64,13 @@ public class SessionCell extends FrameLayout {
onlineTextView.setGravity((LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.TOP);
if (LocaleController.isRTL) {
linearLayout.addView(onlineTextView);
linearLayout.addView(nameTextView);
linearLayout.addView(onlineTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 0, 2, 0, 0));
linearLayout.addView(nameTextView, LayoutHelper.createLinear(0, LayoutHelper.MATCH_PARENT, 1.0f, Gravity.RIGHT | Gravity.TOP, 10, 0, 0, 0));
} else {
linearLayout.addView(nameTextView);
linearLayout.addView(onlineTextView);
linearLayout.addView(nameTextView, LayoutHelper.createLinear(0, LayoutHelper.MATCH_PARENT, 1.0f, Gravity.LEFT | Gravity.TOP, 0, 0, 10, 0));
linearLayout.addView(onlineTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, Gravity.RIGHT | Gravity.TOP, 0, 2, 0, 0));
}
LinearLayout.LayoutParams layoutParams2 = (LinearLayout.LayoutParams) nameTextView.getLayoutParams();
layoutParams2.width = 0;
layoutParams2.height = LayoutHelper.MATCH_PARENT;
layoutParams2.weight = 1;
if (LocaleController.isRTL) {
layoutParams2.leftMargin = AndroidUtilities.dp(10);
} else {
layoutParams2.rightMargin = AndroidUtilities.dp(10);
}
layoutParams2.gravity = LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT;
nameTextView.setLayoutParams(layoutParams2);
layoutParams2 = (LinearLayout.LayoutParams) onlineTextView.getLayoutParams();
layoutParams2.width = LayoutHelper.WRAP_CONTENT;
layoutParams2.height = LayoutHelper.MATCH_PARENT;
layoutParams2.topMargin = AndroidUtilities.dp(2);
layoutParams2.gravity = (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.TOP;
onlineTextView.setLayoutParams(layoutParams2);
detailTextView = new TextView(context);
detailTextView.setTextColor(0xff212121);
detailTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
@ -106,15 +79,7 @@ public class SessionCell extends FrameLayout {
detailTextView.setSingleLine(true);
detailTextView.setEllipsize(TextUtils.TruncateAt.END);
detailTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
addView(detailTextView);
layoutParams = (LayoutParams) detailTextView.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.WRAP_CONTENT;
layoutParams.leftMargin = AndroidUtilities.dp(17);
layoutParams.rightMargin = AndroidUtilities.dp(17);
layoutParams.topMargin = AndroidUtilities.dp(36);
layoutParams.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP;
detailTextView.setLayoutParams(layoutParams);
addView(detailTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 17, 36, 17, 0));
detailExTextView = new TextView(context);
detailExTextView.setTextColor(0xff999999);
@ -124,15 +89,7 @@ public class SessionCell extends FrameLayout {
detailExTextView.setSingleLine(true);
detailExTextView.setEllipsize(TextUtils.TruncateAt.END);
detailExTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
addView(detailExTextView);
layoutParams = (LayoutParams) detailExTextView.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.WRAP_CONTENT;
layoutParams.leftMargin = AndroidUtilities.dp(17);
layoutParams.rightMargin = AndroidUtilities.dp(17);
layoutParams.topMargin = AndroidUtilities.dp(59);
layoutParams.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP;
detailExTextView.setLayoutParams(layoutParams);
addView(detailExTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 17, 59, 17, 0));
}
@Override

View File

@ -9,7 +9,6 @@
package org.telegram.ui.Cells;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import org.telegram.android.AndroidUtilities;
@ -17,28 +16,9 @@ import org.telegram.messenger.R;
public class ShadowBottomSectionCell extends View {
private void init() {
setBackgroundResource(R.drawable.greydivider_bottom);
}
public ShadowBottomSectionCell(Context context) {
super(context);
init();
}
public ShadowBottomSectionCell(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ShadowBottomSectionCell(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public ShadowBottomSectionCell(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
setBackgroundResource(R.drawable.greydivider_bottom);
}
@Override

View File

@ -9,7 +9,6 @@
package org.telegram.ui.Cells;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import org.telegram.android.AndroidUtilities;
@ -17,28 +16,9 @@ import org.telegram.messenger.R;
public class ShadowSectionCell extends View {
private void init() {
setBackgroundResource(R.drawable.greydivider);
}
public ShadowSectionCell(Context context) {
super(context);
init();
}
public ShadowSectionCell(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public ShadowSectionCell(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public ShadowSectionCell(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
setBackgroundResource(R.drawable.greydivider);
}
@Override

View File

@ -28,7 +28,6 @@ import org.telegram.android.MessageObject;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.R;
import org.telegram.messenger.TLRPC;
import org.telegram.messenger.Utilities;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.CheckBox;
import org.telegram.ui.Components.LayoutHelper;
@ -77,15 +76,7 @@ public class SharedDocumentCell extends FrameLayout implements MediaController.F
TAG = MediaController.getInstance().generateObserverTag();
placeholderImabeView = new ImageView(context);
addView(placeholderImabeView);
LayoutParams layoutParams = (LayoutParams) placeholderImabeView.getLayoutParams();
layoutParams.width = AndroidUtilities.dp(40);
layoutParams.height = AndroidUtilities.dp(40);
layoutParams.leftMargin = LocaleController.isRTL ? 0 : AndroidUtilities.dp(12);
layoutParams.rightMargin = LocaleController.isRTL ? AndroidUtilities.dp(12) : 0;
layoutParams.topMargin = AndroidUtilities.dp(8);
layoutParams.gravity = LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT;
placeholderImabeView.setLayoutParams(layoutParams);
addView(placeholderImabeView, LayoutHelper.createFrame(40, 40, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 12, 8, LocaleController.isRTL ? 12 : 0, 0));
extTextView = new TextView(context);
extTextView.setTextColor(0xffffffff);
@ -96,17 +87,10 @@ public class SharedDocumentCell extends FrameLayout implements MediaController.F
extTextView.setSingleLine(true);
extTextView.setGravity(Gravity.CENTER);
extTextView.setEllipsize(TextUtils.TruncateAt.END);
addView(extTextView);
layoutParams = (LayoutParams) extTextView.getLayoutParams();
layoutParams.width = AndroidUtilities.dp(32);
layoutParams.height = LayoutHelper.WRAP_CONTENT;
layoutParams.topMargin = AndroidUtilities.dp(22);
layoutParams.leftMargin = LocaleController.isRTL ? 0 : AndroidUtilities.dp(16);
layoutParams.rightMargin = LocaleController.isRTL ? AndroidUtilities.dp(16) : 0;
layoutParams.gravity = LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT;
extTextView.setLayoutParams(layoutParams);
addView(extTextView, LayoutHelper.createFrame(32, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 16, 22, LocaleController.isRTL ? 16 : 0, 0));
thumbImageView = new BackupImageView(context);
addView(thumbImageView, LayoutHelper.createFrame(40, 40, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 12, 8, LocaleController.isRTL ? 12 : 0, 0));
thumbImageView.getImageReceiver().setDelegate(new ImageReceiver.ImageReceiverDelegate() {
@Override
public void didSetImage(ImageReceiver imageReceiver, boolean set, boolean thumb) {
@ -114,15 +98,6 @@ public class SharedDocumentCell extends FrameLayout implements MediaController.F
placeholderImabeView.setVisibility(set ? INVISIBLE : VISIBLE);
}
});
addView(thumbImageView);
layoutParams = (LayoutParams) thumbImageView.getLayoutParams();
layoutParams.width = AndroidUtilities.dp(40);
layoutParams.height = AndroidUtilities.dp(40);
layoutParams.leftMargin = LocaleController.isRTL ? 0 : AndroidUtilities.dp(12);
layoutParams.rightMargin = LocaleController.isRTL ? AndroidUtilities.dp(12) : 0;
layoutParams.topMargin = AndroidUtilities.dp(8);
layoutParams.gravity = LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT;
thumbImageView.setLayoutParams(layoutParams);
nameTextView = new TextView(context);
nameTextView.setTextColor(0xff222222);
@ -133,27 +108,11 @@ public class SharedDocumentCell extends FrameLayout implements MediaController.F
nameTextView.setSingleLine(true);
nameTextView.setEllipsize(TextUtils.TruncateAt.END);
nameTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
addView(nameTextView);
layoutParams = (LayoutParams) nameTextView.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.WRAP_CONTENT;
layoutParams.topMargin = AndroidUtilities.dp(5);
layoutParams.leftMargin = LocaleController.isRTL ? AndroidUtilities.dp(8) : AndroidUtilities.dp(72);
layoutParams.rightMargin = LocaleController.isRTL ? AndroidUtilities.dp(72) : AndroidUtilities.dp(8);
layoutParams.gravity = LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT;
nameTextView.setLayoutParams(layoutParams);
addView(nameTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 8 : 72, 5, LocaleController.isRTL ? 72 : 8, 0));
statusImageView = new ImageView(context);
statusImageView.setVisibility(INVISIBLE);
addView(statusImageView);
layoutParams = (LayoutParams) statusImageView.getLayoutParams();
layoutParams.width = LayoutHelper.WRAP_CONTENT;
layoutParams.height = LayoutHelper.WRAP_CONTENT;
layoutParams.topMargin = AndroidUtilities.dp(35);
layoutParams.leftMargin = LocaleController.isRTL ? AndroidUtilities.dp(8) : AndroidUtilities.dp(72);
layoutParams.rightMargin = LocaleController.isRTL ? AndroidUtilities.dp(72) : AndroidUtilities.dp(8);
layoutParams.gravity = LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT;
statusImageView.setLayoutParams(layoutParams);
addView(statusImageView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 8 : 72, 35, LocaleController.isRTL ? 72 : 8, 0));
dateTextView = new TextView(context);
dateTextView.setTextColor(0xff999999);
@ -163,38 +122,14 @@ public class SharedDocumentCell extends FrameLayout implements MediaController.F
dateTextView.setSingleLine(true);
dateTextView.setEllipsize(TextUtils.TruncateAt.END);
dateTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
addView(dateTextView);
layoutParams = (LayoutParams) dateTextView.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.WRAP_CONTENT;
layoutParams.topMargin = AndroidUtilities.dp(30);
layoutParams.leftMargin = LocaleController.isRTL ? AndroidUtilities.dp(8) : AndroidUtilities.dp(72);
layoutParams.rightMargin = LocaleController.isRTL ? AndroidUtilities.dp(72) : AndroidUtilities.dp(8);
layoutParams.gravity = LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT;
dateTextView.setLayoutParams(layoutParams);
addView(dateTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 8 : 72, 30, LocaleController.isRTL ? 72 : 8, 0));
progressView = new LineProgressView(context);
addView(progressView);
layoutParams = (LayoutParams) progressView.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = AndroidUtilities.dp(2);
layoutParams.topMargin = AndroidUtilities.dp(54);
layoutParams.leftMargin = LocaleController.isRTL ? 0 : AndroidUtilities.dp(72);
layoutParams.rightMargin = LocaleController.isRTL ? AndroidUtilities.dp(72) : 0;
layoutParams.gravity = LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT;
progressView.setLayoutParams(layoutParams);
addView(progressView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 2, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 72, 54, LocaleController.isRTL ? 72 : 0, 0));
checkBox = new CheckBox(context, R.drawable.round_check2);
checkBox.setVisibility(INVISIBLE);
addView(checkBox);
layoutParams = (LayoutParams) checkBox.getLayoutParams();
layoutParams.width = AndroidUtilities.dp(22);
layoutParams.height = AndroidUtilities.dp(22);
layoutParams.topMargin = AndroidUtilities.dp(30);
layoutParams.leftMargin = LocaleController.isRTL ? 0 : AndroidUtilities.dp(34);
layoutParams.rightMargin = LocaleController.isRTL ? AndroidUtilities.dp(34) : 0;
layoutParams.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
checkBox.setLayoutParams(layoutParams);
addView(checkBox, LayoutHelper.createFrame(22, 22, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 34, 30, LocaleController.isRTL ? 34 : 0, 0));
}
private int getThumbForNameOrMime(String name, String mime) {
@ -270,7 +205,7 @@ public class SharedDocumentCell extends FrameLayout implements MediaController.F
loading = false;
if (document != null && document.messageOwner.media != null) {
int idx = -1;
int idx;
String name = FileLoader.getDocumentFileName(document.messageOwner.media.document);
placeholderImabeView.setVisibility(VISIBLE);
extTextView.setVisibility(VISIBLE);
@ -285,7 +220,7 @@ public class SharedDocumentCell extends FrameLayout implements MediaController.F
thumbImageView.setImage(document.messageOwner.media.document.thumb.location, "40_40", (Drawable) null);
}
long date = (long) document.messageOwner.date * 1000;
dateTextView.setText(String.format("%s, %s", Utilities.formatFileSize(document.messageOwner.media.document.size), LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, LocaleController.formatterYear.format(new Date(date)), LocaleController.formatterDay.format(new Date(date)))));
dateTextView.setText(String.format("%s, %s", AndroidUtilities.formatFileSize(document.messageOwner.media.document.size), LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, LocaleController.formatterYear.format(new Date(date)), LocaleController.formatterDay.format(new Date(date)))));
} else {
nameTextView.setText("");
extTextView.setText("");
@ -304,7 +239,7 @@ public class SharedDocumentCell extends FrameLayout implements MediaController.F
public void updateFileExistIcon() {
if (message != null && message.messageOwner.media != null) {
String fileName = null;
File cacheFile = null;
File cacheFile;
if (message.messageOwner.attachPath == null || message.messageOwner.attachPath.length() == 0 || !(new File(message.messageOwner.attachPath).exists())) {
cacheFile = FileLoader.getPathToMessage(message.messageOwner);
if (!cacheFile.exists()) {

View File

@ -30,14 +30,7 @@ public class SharedMediaSectionCell extends FrameLayout {
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
textView.setTextColor(0xff222222);
textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
addView(textView);
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams)textView.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
layoutParams.leftMargin = AndroidUtilities.dp(13);
layoutParams.rightMargin = AndroidUtilities.dp(13);
layoutParams.gravity = LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT;
textView.setLayoutParams(layoutParams);
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 13, 0, 13, 0));
}
@Override

View File

@ -69,11 +69,7 @@ public class SharedPhotoVideoCell extends FrameLayoutFixed {
ImageView imageView1 = new ImageView(context);
imageView1.setImageResource(R.drawable.ic_video);
videoInfoContainer.addView(imageView1);
LinearLayout.LayoutParams layoutParams1 = (LinearLayout.LayoutParams) imageView1.getLayoutParams();
layoutParams1.width = LayoutHelper.WRAP_CONTENT;
layoutParams1.height = LayoutHelper.WRAP_CONTENT;
imageView1.setLayoutParams(layoutParams1);
videoInfoContainer.addView(imageView1, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT));
videoTextView = new TextView(context);
videoTextView.setTextColor(0xffffffff);
@ -186,14 +182,14 @@ public class SharedPhotoVideoCell extends FrameLayoutFixed {
photoVideoView.videoTextView.setText(String.format("%d:%02d", minutes, seconds));
if (messageObject.messageOwner.media.video.thumb != null) {
TLRPC.FileLocation location = messageObject.messageOwner.media.video.thumb.location;
photoVideoView.imageView.setImage(null, null, null, ApplicationLoader.applicationContext.getResources().getDrawable(R.drawable.photo_placeholder_in), null, location, "b", 0);
photoVideoView.imageView.setImage(null, null, null, ApplicationLoader.applicationContext.getResources().getDrawable(R.drawable.photo_placeholder_in), null, location, "b", null, 0);
} else {
photoVideoView.imageView.setImageResource(R.drawable.photo_placeholder_in);
}
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto && messageObject.messageOwner.media.photo != null && !messageObject.photoThumbs.isEmpty()) {
photoVideoView.videoInfoContainer.setVisibility(INVISIBLE);
TLRPC.PhotoSize photoSize = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 80);
photoVideoView.imageView.setImage(null, null, null, ApplicationLoader.applicationContext.getResources().getDrawable(R.drawable.photo_placeholder_in), null, photoSize.location, "b", 0);
photoVideoView.imageView.setImage(null, null, null, ApplicationLoader.applicationContext.getResources().getDrawable(R.drawable.photo_placeholder_in), null, photoSize.location, "b", null, 0);
} else {
photoVideoView.videoInfoContainer.setVisibility(INVISIBLE);
photoVideoView.imageView.setImageResource(R.drawable.photo_placeholder_in);

View File

@ -9,7 +9,6 @@
package org.telegram.ui.Cells;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.Gravity;
import org.telegram.android.AndroidUtilities;
@ -17,6 +16,7 @@ import org.telegram.messenger.R;
import org.telegram.messenger.TLRPC;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.FrameLayoutFixed;
import org.telegram.ui.Components.LayoutHelper;
public class StickerCell extends FrameLayoutFixed {
@ -27,13 +27,7 @@ public class StickerCell extends FrameLayoutFixed {
imageView = new BackupImageView(context);
imageView.setAspectFit(true);
addView(imageView);
LayoutParams layoutParams = (LayoutParams) imageView.getLayoutParams();
layoutParams.width = AndroidUtilities.dp(66);
layoutParams.height = AndroidUtilities.dp(66);
layoutParams.gravity = Gravity.CENTER_HORIZONTAL;
layoutParams.topMargin = AndroidUtilities.dp(5);
imageView.setLayoutParams(layoutParams);
addView(imageView, LayoutHelper.createFrame(66, 66, Gravity.CENTER_HORIZONTAL, 0, 5, 0, 0));
}
@Override
@ -52,8 +46,7 @@ public class StickerCell extends FrameLayoutFixed {
public void setSticker(TLRPC.Document document, int side) {
if (document != null) {
document.thumb.location.ext = "webp";
imageView.setImage(document.thumb.location, null, (Drawable) null);
imageView.setImage(document.thumb.location, null, "webp", null);
}
if (side == -1) {
setBackgroundResource(R.drawable.stickers_back_left);

View File

@ -9,10 +9,14 @@
package org.telegram.ui.Cells;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.TypedValue;
import android.view.Gravity;
import android.widget.FrameLayout;
import android.widget.TextView;
import org.telegram.android.AndroidUtilities;
import org.telegram.android.Emoji;
import org.telegram.android.query.StickersQuery;
import org.telegram.messenger.TLRPC;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.LayoutHelper;
@ -21,6 +25,7 @@ public class StickerEmojiCell extends FrameLayout {
private BackupImageView imageView;
private TLRPC.Document sticker;
private TextView emojiTextView;
public StickerEmojiCell(Context context) {
super(context);
@ -28,6 +33,10 @@ public class StickerEmojiCell extends FrameLayout {
imageView = new BackupImageView(context);
imageView.setAspectFit(true);
addView(imageView, LayoutHelper.createFrame(66, 66, Gravity.CENTER));
emojiTextView = new TextView(context);
emojiTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
addView(emojiTextView, LayoutHelper.createFrame(28, 28, Gravity.BOTTOM | Gravity.RIGHT));
}
@Override
@ -43,11 +52,30 @@ public class StickerEmojiCell extends FrameLayout {
return sticker;
}
public void setSticker(TLRPC.Document document) {
public void setSticker(TLRPC.Document document, boolean showEmoji) {
if (document != null) {
sticker = document;
document.thumb.location.ext = "webp";
imageView.setImage(document.thumb.location, null, (Drawable) null);
imageView.setImage(document.thumb.location, null, "webp", null);
if (showEmoji) {
boolean set = false;
for (TLRPC.DocumentAttribute attribute : document.attributes) {
if (attribute instanceof TLRPC.TL_documentAttributeSticker) {
if (attribute.alt != null && attribute.alt.length() > 0) {
emojiTextView.setText(Emoji.replaceEmoji(attribute.alt, emojiTextView.getPaint().getFontMetricsInt(), AndroidUtilities.dp(16)));
set = true;
}
break;
}
}
if (!set) {
emojiTextView.setText(Emoji.replaceEmoji(StickersQuery.getEmojiForSticker(sticker.id), emojiTextView.getPaint().getFontMetricsInt(), AndroidUtilities.dp(16)));
}
emojiTextView.setVisibility(VISIBLE);
} else {
emojiTextView.setVisibility(INVISIBLE);
}
}
}
}

View File

@ -0,0 +1,144 @@
/*
* This is the source code of Telegram for Android v. 2.x.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.Cells;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import org.telegram.android.AndroidUtilities;
import org.telegram.android.AnimationCompat.ViewProxy;
import org.telegram.android.LocaleController;
import org.telegram.android.query.StickersQuery;
import org.telegram.messenger.R;
import org.telegram.messenger.TLRPC;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.LayoutHelper;
import java.util.ArrayList;
public class StickerSetCell extends FrameLayout {
private TextView textView;
private TextView valueTextView;
private BackupImageView imageView;
private boolean needDivider;
private ImageView optionsButton;
private TLRPC.TL_stickerSet stickersSet;
private static Paint paint;
public StickerSetCell(Context context) {
super(context);
if (paint == null) {
paint = new Paint();
paint.setColor(0xffd9d9d9);
}
textView = new TextView(context);
textView.setTextColor(0xff212121);
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
textView.setLines(1);
textView.setMaxLines(1);
textView.setSingleLine(true);
textView.setEllipsize(TextUtils.TruncateAt.END);
textView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT, LocaleController.isRTL ? 40 : 71, 10, LocaleController.isRTL ? 40 : 71, 0));
valueTextView = new TextView(context);
valueTextView.setTextColor(0xff8a8a8a);
valueTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
valueTextView.setLines(1);
valueTextView.setMaxLines(1);
valueTextView.setSingleLine(true);
valueTextView.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
addView(valueTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT, LocaleController.isRTL ? 40 : 71, 35, LocaleController.isRTL ? 40 : 71, 0));
imageView = new BackupImageView(context);
imageView.setAspectFit(true);
addView(imageView, LayoutHelper.createFrame(48, 48, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 12, 8, LocaleController.isRTL ? 12 : 0, 0));
optionsButton = new ImageView(context);
optionsButton.setBackgroundResource(R.drawable.bar_selector_grey);
optionsButton.setImageResource(R.drawable.doc_actions_b);
optionsButton.setScaleType(ImageView.ScaleType.CENTER);
addView(optionsButton, LayoutHelper.createFrame(40, 40, (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.TOP));
/*ActionBarMenuItem menuItem = new ActionBarMenuItem(context, null, R.drawable.bar_selector_grey);
menuItem.setIcon(R.drawable.doc_actions_b);
addView(menuItem, LayoutHelper.createFrame(40, 40, (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.TOP, LocaleController.isRTL ? 40 : 0, 0, LocaleController.isRTL ? 0 : 40, 0));
menuItem.addSubItem(1, "test", 0);
menuItem.addSubItem(2, "test", 0);
menuItem.addSubItem(3, "test", 0);
menuItem.addSubItem(4, "test", 0);
menuItem.addSubItem(5, "test", 0);
menuItem.addSubItem(6, "test", 0);
menuItem.addSubItem(7, "test", 0);*/
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(64) + (needDivider ? 1 : 0), MeasureSpec.EXACTLY));
}
public void setStickersSet(TLRPC.TL_stickerSet set, boolean divider) {
needDivider = divider;
stickersSet = set;
if (stickersSet.id == -1) {
textView.setText(LocaleController.getString("GeniusStickerPackName", R.string.GeniusStickerPackName));
if (StickersQuery.getHideMainStickersPack()) {
ViewProxy.setAlpha(textView, 0.5f);
ViewProxy.setAlpha(valueTextView, 0.5f);
ViewProxy.setAlpha(imageView, 0.5f);
} else {
ViewProxy.setAlpha(textView, 1.0f);
ViewProxy.setAlpha(valueTextView, 1.0f);
ViewProxy.setAlpha(imageView, 1.0f);
}
} else {
textView.setText(stickersSet.title);
ViewProxy.setAlpha(textView, 1.0f);
ViewProxy.setAlpha(valueTextView, 1.0f);
ViewProxy.setAlpha(imageView, 1.0f);
}
ArrayList<TLRPC.Document> documents = StickersQuery.getStickersForSet(stickersSet.id);
if (documents != null) {
valueTextView.setText(LocaleController.formatPluralString("Stickers", documents.size()));
TLRPC.Document document = documents.get(0);
if (document.thumb != null && document.thumb.location != null) {
imageView.setImage(document.thumb.location, null, "webp", null);
}
} else {
valueTextView.setText(LocaleController.formatPluralString("Stickers", 0));
}
}
public void setOnOptionsClick(OnClickListener listener) {
optionsButton.setOnClickListener(listener);
}
public TLRPC.TL_stickerSet getStickersSet() {
return stickersSet;
}
@Override
protected void onDraw(Canvas canvas) {
if (needDivider) {
canvas.drawLine(0, getHeight() - 1, getWidth() - getPaddingRight(), getHeight() - 1, paint);
}
}
}

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