Update to 3.8.1

This commit is contained in:
DrKLO 2016-04-22 16:49:00 +03:00
parent a7513b3ba1
commit 06473773a6
732 changed files with 12475 additions and 6463 deletions

View File

@ -5,7 +5,7 @@ repositories {
}
dependencies {
compile 'com.android.support:support-v4:23.2.1'
compile 'com.android.support:support-v4:23.3.0'
compile "com.google.android.gms:play-services-gcm:8.4.0"
compile "com.google.android.gms:play-services-maps:8.4.0"
compile 'net.hockeyapp.android:HockeySDK:3.6.+'
@ -14,7 +14,7 @@ dependencies {
android {
compileSdkVersion 23
buildToolsVersion '23.0.2'
buildToolsVersion '23.0.3'
useLibrary 'org.apache.http.legacy'
defaultConfig.applicationId = "org.telegram.messenger"
@ -63,7 +63,7 @@ android {
}
}
defaultConfig.versionCode = 767
defaultConfig.versionCode = 787
sourceSets.main {
jniLibs.srcDir 'libs'
@ -114,6 +114,8 @@ android {
defaultConfig {
minSdkVersion 9
targetSdkVersion 23
versionName "3.7.0"
versionName "3.8.1"
}
}
apply plugin: 'com.google.gms.google-services'

View File

@ -0,0 +1,75 @@
{
"project_info": {
"project_id": "tmessages2",
"project_number": "760348033671",
"name": "Telegram"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:760348033671:android:f6afd7b67eae3860",
"client_id": "android:org.telegram.messenger",
"client_type": 1,
"android_client_info": {
"package_name": "org.telegram.messenger",
"certificate_hash": []
}
},
"oauth_client": [],
"api_key": [],
"services": {
"analytics_service": {
"status": 1
},
"cloud_messaging_service": {
"status": 2,
"apns_config": []
},
"appinvite_service": {
"status": 1,
"other_platform_oauth_client": []
},
"google_signin_service": {
"status": 1
},
"ads_service": {
"status": 1
}
}
},
{
"client_info": {
"mobilesdk_app_id": "1:760348033671:android:dc022572c167a16c",
"client_id": "android:org.telegram.messenger.beta",
"client_type": 1,
"android_client_info": {
"package_name": "org.telegram.messenger.beta",
"certificate_hash": []
}
},
"oauth_client": [],
"api_key": [],
"services": {
"analytics_service": {
"status": 1
},
"cloud_messaging_service": {
"status": 2,
"apns_config": []
},
"appinvite_service": {
"status": 1,
"other_platform_oauth_client": []
},
"google_signin_service": {
"status": 1
},
"ads_service": {
"status": 1
}
}
}
],
"client_info": [],
"ARTIFACT_VERSION": "1"
}

View File

@ -235,12 +235,12 @@ include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := tmessages.20
LOCAL_MODULE := tmessages.21
LOCAL_CFLAGS := -w -std=c11 -Os -DNULL=0 -DSOCKLEN_T=socklen_t -DLOCALE_NOT_USED -D_LARGEFILE_SOURCE=1 -D_FILE_OFFSET_BITS=64
LOCAL_CFLAGS += -Drestrict='' -D__EMX__ -DOPUS_BUILD -DFIXED_POINT -DUSE_ALLOCA -DHAVE_LRINT -DHAVE_LRINTF -fno-math-errno
LOCAL_CFLAGS += -DANDROID_NDK -DDISABLE_IMPORTGL -fno-strict-aliasing -fprefetch-loop-arrays -DAVOID_TABLES -DANDROID_TILE_BASED_DECODE -DANDROID_ARMV6_IDCT -ffast-math -D__STDC_CONSTANT_MACROS
LOCAL_CPPFLAGS := -DBSD=1 -ffast-math -Os -funroll-loops -std=c++11
LOCAL_LDLIBS := -ljnigraphics -llog -lz
LOCAL_LDLIBS := -ljnigraphics -llog -lz -latomic
LOCAL_STATIC_LIBRARIES := webp sqlite tgnet breakpad avformat avcodec avutil
LOCAL_SRC_FILES := \

View File

@ -157,6 +157,10 @@ void setNetworkAvailable(JNIEnv *env, jclass c, jboolean value) {
ConnectionsManager::getInstance().setNetworkAvailable(value);
}
void setPushConnectionEnabled(JNIEnv *env, jclass c, jboolean value) {
ConnectionsManager::getInstance().setPushConnectionEnabled(value);
}
class Delegate : public ConnectiosManagerDelegate {
void onUpdate() {
@ -194,7 +198,7 @@ class Delegate : public ConnectiosManagerDelegate {
}
};
void init(JNIEnv *env, jclass c, jint version, jint layer, jint apiId, jstring deviceModel, jstring systemVersion, jstring appVersion, jstring langCode, jstring configPath, jstring logPath, jint userId) {
void init(JNIEnv *env, jclass c, jint version, jint layer, jint apiId, jstring deviceModel, jstring systemVersion, jstring appVersion, jstring langCode, jstring configPath, jstring logPath, jint userId, jboolean enablePushConnection) {
const char *deviceModelStr = env->GetStringUTFChars(deviceModel, 0);
const char *systemVersionStr = env->GetStringUTFChars(systemVersion, 0);
const char *appVersionStr = env->GetStringUTFChars(appVersion, 0);
@ -202,7 +206,7 @@ void init(JNIEnv *env, jclass c, jint version, jint layer, jint apiId, jstring d
const char *configPathStr = env->GetStringUTFChars(configPath, 0);
const char *logPathStr = env->GetStringUTFChars(logPath, 0);
ConnectionsManager::getInstance().init(version, layer, apiId, std::string(deviceModelStr), std::string(systemVersionStr), std::string(appVersionStr), std::string(langCodeStr), std::string(configPathStr), std::string(logPathStr), userId, true);
ConnectionsManager::getInstance().init(version, layer, apiId, std::string(deviceModelStr), std::string(systemVersionStr), std::string(appVersionStr), std::string(langCodeStr), std::string(configPathStr), std::string(logPathStr), userId, true, enablePushConnection);
if (deviceModelStr != 0) {
env->ReleaseStringUTFChars(deviceModel, deviceModelStr);
@ -242,13 +246,14 @@ static JNINativeMethod ConnectionsManagerMethods[] = {
{"native_applyDatacenterAddress", "(ILjava/lang/String;I)V", (void *) applyDatacenterAddress},
{"native_getConnectionState", "()I", (void *) getConnectionState},
{"native_setUserId", "(I)V", (void *) setUserId},
{"native_init", "(IIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V", (void *) init},
{"native_init", "(IIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IZ)V", (void *) init},
{"native_switchBackend", "()V", (void *) switchBackend},
{"native_pauseNetwork", "()V", (void *) pauseNetwork},
{"native_resumeNetwork", "(Z)V", (void *) resumeNetwork},
{"native_updateDcSettings", "()V", (void *) updateDcSettings},
{"native_setUseIpv6", "(Z)V", (void *) setUseIpv6},
{"native_setNetworkAvailable", "(Z)V", (void *) setNetworkAvailable},
{"native_setPushConnectionEnabled", "(Z)V", (void *) setPushConnectionEnabled},
{"native_setJava", "(Z)V", (void *) setJava}
};

View File

@ -397,13 +397,13 @@ JNIEXPORT void Java_org_telegram_messenger_Utilities_calcCDT(JNIEnv *env, jclass
JNIEXPORT int Java_org_telegram_messenger_Utilities_pinBitmap(JNIEnv *env, jclass class, jobject bitmap) {
if (bitmap == NULL) {
return;
return 0;
}
unsigned char *pixels;
return AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0 ? 1 : 0;
}
JNIEXPORT int Java_org_telegram_messenger_Utilities_unpinBitmap(JNIEnv *env, jclass class, jobject bitmap) {
JNIEXPORT void Java_org_telegram_messenger_Utilities_unpinBitmap(JNIEnv *env, jclass class, jobject bitmap) {
if (bitmap == NULL) {
return;
}

View File

@ -394,7 +394,7 @@ void Connection::onDisconnected(int reason) {
ConnectionsManager::getInstance().onConnectionClosed(this);
uint32_t datacenterId = currentDatacenter->getDatacenterId();
if (connectionState == TcpConnectionStageIdle && connectionType == ConnectionTypeGeneric && (datacenterId == ConnectionsManager::getInstance().currentDatacenterId || datacenterId == ConnectionsManager::getInstance().movingToDatacenterId)) {
if (connectionState == TcpConnectionStageIdle && connectionType == ConnectionTypeGeneric && (currentDatacenter->isHandshaking() || datacenterId == ConnectionsManager::getInstance().currentDatacenterId || datacenterId == ConnectionsManager::getInstance().movingToDatacenterId)) {
connectionState = TcpConnectionStageReconnecting;
failedConnectionCount++;
if (failedConnectionCount == 1) {

View File

@ -170,22 +170,24 @@ void ConnectionsManager::select() {
}
Datacenter *datacenter = getDatacenterWithId(currentDatacenterId);
if ((sendingPushPing && abs(now - lastPushPingTime) >= 30000) || abs(now - lastPushPingTime) >= 60000 * 3 + 10000) {
lastPushPingTime = 0;
sendingPushPing = false;
if (datacenter != nullptr) {
Connection *connection = datacenter->getPushConnection(false);
if (connection != nullptr) {
connection->suspendConnection();
if (pushConnectionEnabled) {
if ((sendingPushPing && abs(now - lastPushPingTime) >= 30000) || abs(now - lastPushPingTime) >= 60000 * 3 + 10000) {
lastPushPingTime = 0;
sendingPushPing = false;
if (datacenter != nullptr) {
Connection *connection = datacenter->getPushConnection(false);
if (connection != nullptr) {
connection->suspendConnection();
}
}
DEBUG_D("push ping timeout");
}
DEBUG_D("push ping timeout");
}
if (abs(now - lastPushPingTime) >= 60000 * 3) {
DEBUG_D("time for push ping");
lastPushPingTime = now;
if (datacenter != nullptr) {
sendPing(datacenter, true);
if (abs(now - lastPushPingTime) >= 60000 * 3) {
DEBUG_D("time for push ping");
lastPushPingTime = now;
if (datacenter != nullptr) {
sendPing(datacenter, true);
}
}
}
@ -220,7 +222,7 @@ void ConnectionsManager::select() {
return;
} else {
lastPauseTime = now;
DEBUG_D("don't sleep 30 seconds because of salt, upload or download request");
DEBUG_D("don't sleep because of salt, upload or download request");
}
}
if (networkPaused) {
@ -285,7 +287,7 @@ void *ConnectionsManager::ThreadProc(void *data) {
javaVm->AttachCurrentThread(&jniEnv, NULL);
#endif
ConnectionsManager *networkManager = (ConnectionsManager *) (data);
if (networkManager->currentUserId != 0) {
if (networkManager->currentUserId != 0 && networkManager->pushConnectionEnabled) {
Datacenter *datacenter = networkManager->getDatacenterWithId(networkManager->currentDatacenterId);
if (datacenter != nullptr) {
datacenter->createPushConnection()->setSessionId(networkManager->pushSessionId);
@ -595,7 +597,6 @@ void ConnectionsManager::onConnectionConnected(Connection *connection) {
} else {
if (networkPaused && lastPauseTime != 0) {
lastPauseTime = getCurrentTimeMillis();
nextSleepTimeout = 30000;
}
processRequestQueue(connection->getConnectionType(), datacenter->getDatacenterId());
}
@ -1210,7 +1211,6 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
if (connection->connectionType == ConnectionTypePush) {
if (networkPaused) {
lastPauseTime = getCurrentTimeMillis();
nextSleepTimeout = 30000;
DEBUG_D("received internal push: wakeup network in background");
} else if (lastPauseTime != 0) {
lastPauseTime = getCurrentTimeMillis();
@ -1234,7 +1234,7 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
}
void ConnectionsManager::sendPing(Datacenter *datacenter, bool usePushConnection) {
if (usePushConnection && currentUserId == 0) {
if (usePushConnection && (currentUserId == 0 || !usePushConnection)) {
return;
}
Connection *connection = nullptr;
@ -1401,7 +1401,7 @@ void ConnectionsManager::sendRequest(TLObject *object, onCompleteFunc onComplete
request->ptr1 = ptr1;
request->ptr2 = ptr2;
request->rpcRequest = wrapInLayer(object, getDatacenterWithId(datacenterId), request);
DEBUG_D("send request wrapped %p - %s", request->rpcRequest.get(), typeid(*request->rpcRequest.get()).name());
DEBUG_D("send request wrapped %p - %s", request->rpcRequest.get(), typeid(*(request->rpcRequest.get())).name());
requestsQueue.push_back(std::unique_ptr<Request>(request));
if (immediate) {
processRequestQueue(0, 0);
@ -1452,7 +1452,7 @@ void ConnectionsManager::setUserId(int32_t userId) {
if (currentUserId != userId && userId != 0) {
updateDcSettings(0);
}
if (currentUserId != 0) {
if (currentUserId != 0 && pushConnectionEnabled) {
Datacenter *datacenter = getDatacenterWithId(currentDatacenterId);
if (datacenter != nullptr) {
datacenter->createPushConnection()->setSessionId(pushSessionId);
@ -2121,7 +2121,7 @@ void ConnectionsManager::processRequestQueue(uint32_t connectionTypes, uint32_t
request->outgoingQuery = message->outgoingBody;
message->outgoingBody = nullptr;
} else {
DEBUG_D("wrap body(%p, %s) to TL_invokeAfterMsg", message->body.get(), typeid(*message->body.get()).name());
DEBUG_D("wrap body(%p, %s) to TL_invokeAfterMsg", message->body.get(), typeid(*(message->body.get())).name());
request->query = std::move(message->body);
}
message->body = std::unique_ptr<TLObject>(request);
@ -2390,7 +2390,23 @@ void ConnectionsManager::setDelegate(ConnectiosManagerDelegate *connectiosManage
delegate = connectiosManagerDelegate;
}
void ConnectionsManager::init(uint32_t version, int32_t layer, int32_t apiId, std::string deviceModel, std::string systemVersion, std::string appVersion, std::string langCode, std::string configPath, std::string logPath, int32_t userId, bool isPaused) {
void ConnectionsManager::setPushConnectionEnabled(bool value) {
pushConnectionEnabled = value;
Datacenter *datacenter = getDatacenterWithId(currentDatacenterId);
if (datacenter != nullptr) {
if (!pushConnectionEnabled) {
Connection *connection = datacenter->getPushConnection(false);
if (connection != nullptr) {
connection->suspendConnection();
}
} else {
datacenter->createPushConnection()->setSessionId(pushSessionId);
sendPing(datacenter, true);
}
}
}
void ConnectionsManager::init(uint32_t version, int32_t layer, int32_t apiId, std::string deviceModel, std::string systemVersion, std::string appVersion, std::string langCode, std::string configPath, std::string logPath, int32_t userId, bool isPaused, bool enablePushConnection) {
currentVersion = version;
currentLayer = layer;
currentApiId = apiId;
@ -2401,6 +2417,7 @@ void ConnectionsManager::init(uint32_t version, int32_t layer, int32_t apiId, st
currentLangCode = langCode;
currentUserId = userId;
currentLogPath = logPath;
pushConnectionEnabled = enablePushConnection;
if (isPaused) {
lastPauseTime = getCurrentTimeMillis();
}
@ -2423,7 +2440,6 @@ void ConnectionsManager::resumeNetwork(bool partial) {
if (partial) {
if (networkPaused) {
lastPauseTime = getCurrentTimeMillis();
nextSleepTimeout = 30000;
networkPaused = false;
DEBUG_D("wakeup network in background");
} else if (lastPauseTime != 0) {

View File

@ -60,8 +60,9 @@ public:
void pauseNetwork();
void setNetworkAvailable(bool value);
void setUseIpv6(bool value);
void init(uint32_t version, int32_t layer, int32_t apiId, std::string deviceModel, std::string systemVersion, std::string appVersion, std::string langCode, std::string configPath, std::string logPath, int32_t userId, bool isPaused);
void init(uint32_t version, int32_t layer, int32_t apiId, std::string deviceModel, std::string systemVersion, std::string appVersion, std::string langCode, std::string configPath, std::string logPath, int32_t userId, bool isPaused, bool enablePushConnection);
void updateDcSettings(uint32_t datacenterId);
void setPushConnectionEnabled(bool value);
#ifdef ANDROID
void sendRequest(TLObject *object, onCompleteFunc onComplete, onQuickAckFunc onQuickAck, uint32_t flags, uint32_t datacenterId, ConnectionType connetionType, bool immediate, int32_t requestToken, jobject ptr1, jobject ptr2);
@ -133,7 +134,7 @@ private:
int32_t lastDcUpdateTime = 0;
int64_t lastPingTime = getCurrentTimeMillis();
bool networkPaused = false;
int32_t nextSleepTimeout = 30000;
int32_t nextSleepTimeout = CONNECTION_BACKGROUND_KEEP_TIME;
int64_t lastPauseTime = 0;
ConnectionState connectionState = ConnectionStateConnecting;
std::unique_ptr<ByteArray> movingAuthorization;
@ -172,6 +173,7 @@ private:
std::string currentLogPath;
int32_t currentUserId = 0;
bool registeredForInternalPush = false;
bool pushConnectionEnabled = true;
ConnectiosManagerDelegate *delegate;

View File

@ -17,10 +17,11 @@
#define USE_DEBUG_SESSION false
#define READ_BUFFER_SIZE 1024 * 128
#define DEBUG_VERSION
//#define DEBUG_VERSION
#define DEFAULT_DATACENTER_ID INT_MAX
#define DC_UPDATE_TIME 60 * 60
#define DOWNLOAD_CONNECTIONS_COUNT 2
#define CONNECTION_BACKGROUND_KEEP_TIME 10000
class TLObject;
class TL_error;

View File

@ -213,6 +213,8 @@
<receiver android:name=".WearReplyReceiver" android:enabled="true"/>
<receiver android:name=".ShareBroadcastReceiver" android:enabled="true"/>
<uses-library android:name="com.sec.android.app.multiwindow" android:required="false" />
<meta-data android:name="com.sec.android.support.multiwindow" android:value="true" />
<meta-data android:name="com.sec.android.multiwindow.DEFAULT_SIZE_W" android:value="632dp" />

View File

@ -77,7 +77,6 @@ public class SQLiteDatabase {
close();
}
private StackTraceElement[] temp;
public void beginTransaction() throws SQLiteException {
if (inTransaction) {
throw new SQLiteException("database already in transaction");

View File

@ -11,7 +11,6 @@ package org.telegram.messenger;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
@ -20,21 +19,19 @@ import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Parcelable;
import android.provider.Browser;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
@ -62,6 +59,7 @@ import org.telegram.messenger.AnimationCompat.AnimatorListenerAdapterProxy;
import org.telegram.messenger.AnimationCompat.AnimatorSetProxy;
import org.telegram.messenger.AnimationCompat.ObjectAnimatorProxy;
import org.telegram.messenger.AnimationCompat.ViewProxy;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.Components.ForegroundDetector;
import org.telegram.ui.Components.NumberPicker;
import org.telegram.ui.Components.TypefaceSpan;
@ -129,14 +127,111 @@ public class AndroidUtilities {
}
}
static {
density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density;
leftBaseline = isTablet() ? 80 : 72;
checkDisplaySize();
}
public static int[] calcDrawableColor(Drawable drawable) {
int bitmapColor = 0xff000000;
int result[] = new int[2];
try {
if (drawable instanceof BitmapDrawable) {
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
if (bitmap != null) {
Bitmap b = Bitmaps.createScaledBitmap(bitmap, 1, 1, true);
if (b != null) {
bitmapColor = b.getPixel(0, 0);
b.recycle();
}
}
} else if (drawable instanceof ColorDrawable) {
if (Build.VERSION.SDK_INT >= 11) {
bitmapColor = ((ColorDrawable) drawable).getColor();
} else {
bitmapColor = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).getInt("selectedColor", 0xff000000);
}
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
double[] hsv = rgbToHsv((bitmapColor >> 16) & 0xff, (bitmapColor >> 8) & 0xff, bitmapColor & 0xff);
hsv[1] = Math.min(1.0, hsv[1] + 0.05 + 0.1 * (1.0 - hsv[1]));
hsv[2] = Math.max(0, hsv[2] * 0.65);
int rgb[] = hsvToRgb(hsv[0], hsv[1], hsv[2]);
result[0] = Color.argb(0x66, rgb[0], rgb[1], rgb[2]);
result[1] = Color.argb(0x88, rgb[0], rgb[1], rgb[2]);
return result;
}
private static double[] rgbToHsv(int r, int g, int b) {
double rf = r / 255.0;
double gf = g / 255.0;
double bf = b / 255.0;
double max = (rf > gf && rf > bf) ? rf : (gf > bf) ? gf : bf;
double min = (rf < gf && rf < bf) ? rf : (gf < bf) ? gf : bf;
double h, s;
double d = max - min;
s = max == 0 ? 0 : d / max;
if (max == min) {
h = 0;
} else {
if (rf > gf && rf > bf) {
h = (gf - bf) / d + (gf < bf ? 6 : 0);
} else if (gf > bf) {
h = (bf - rf) / d + 2;
} else {
h = (rf - gf) / d + 4;
}
h /= 6;
}
return new double[]{h, s, max};
}
private static int[] hsvToRgb(double h, double s, double v) {
double r = 0, g = 0, b = 0;
double i = (int) Math.floor(h * 6);
double f = h * 6 - i;
double p = v * (1 - s);
double q = v * (1 - f * s);
double t = v * (1 - (1 - f) * s);
switch ((int) i % 6) {
case 0:
r = v;
g = t;
b = p;
break;
case 1:
r = q;
g = v;
b = p;
break;
case 2:
r = p;
g = v;
b = t;
break;
case 3:
r = p;
g = q;
b = v;
break;
case 4:
r = t;
g = p;
b = v;
break;
case 5:
r = v;
g = p;
b = q;
break;
}
return new int[]{(int) (r * 255), (int) (g * 255), (int) (b * 255)};
}
public static void requestAdjustResize(Activity activity, int classGuid) {
if (activity == null || isTablet()) {
return;
@ -154,8 +249,36 @@ public class AndroidUtilities {
}
}
public static boolean isGoogleMapsInstalled(final BaseFragment fragment) {
try {
ApplicationLoader.applicationContext.getPackageManager().getApplicationInfo("com.google.android.apps.maps", 0);
return true;
} catch (PackageManager.NameNotFoundException e) {
if (fragment.getParentActivity() == null) {
return false;
}
AlertDialog.Builder builder = new AlertDialog.Builder(fragment.getParentActivity());
builder.setMessage("Install Google Maps?");
builder.setCancelable(true);
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
try {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.google.android.apps.maps"));
fragment.getParentActivity().startActivityForResult(intent, 500);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
fragment.showDialog(builder.create());
return false;
}
}
public static void lockOrientation(Activity activity) {
if (activity == null || prevOrientation != -10 || Build.VERSION.SDK_INT < 9) {
if (activity == null || prevOrientation != -10) {
return;
}
try {
@ -164,22 +287,16 @@ public class AndroidUtilities {
if (manager != null && manager.getDefaultDisplay() != null) {
int rotation = manager.getDefaultDisplay().getRotation();
int orientation = activity.getResources().getConfiguration().orientation;
int SCREEN_ORIENTATION_REVERSE_LANDSCAPE = 8;
int SCREEN_ORIENTATION_REVERSE_PORTRAIT = 9;
if (Build.VERSION.SDK_INT < 9) {
SCREEN_ORIENTATION_REVERSE_LANDSCAPE = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
SCREEN_ORIENTATION_REVERSE_PORTRAIT = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
}
if (rotation == Surface.ROTATION_270) {
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else {
activity.setRequestedOrientation(SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
}
} else if (rotation == Surface.ROTATION_90) {
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
activity.setRequestedOrientation(SCREEN_ORIENTATION_REVERSE_PORTRAIT);
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
} else {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
@ -191,9 +308,9 @@ public class AndroidUtilities {
}
} else {
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
activity.setRequestedOrientation(SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
} else {
activity.setRequestedOrientation(SCREEN_ORIENTATION_REVERSE_PORTRAIT);
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
}
}
}
@ -203,7 +320,7 @@ public class AndroidUtilities {
}
public static void unlockOrientation(Activity activity) {
if (activity == null || Build.VERSION.SDK_INT < 9) {
if (activity == null) {
return;
}
try {
@ -430,46 +547,6 @@ public class AndroidUtilities {
}
}
public static void openUrl(Context context, String url) {
if (context == null || url == null) {
return;
}
openUrl(context, Uri.parse(url));
}
public static void openUrl(Context context, Uri uri) {
if (context == null || uri == null) {
return;
}
try {
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
if (MediaController.getInstance().canCustomTabs()) {
intent.putExtra("android.support.customtabs.extra.SESSION", (Parcelable) null);
intent.putExtra("android.support.customtabs.extra.TOOLBAR_COLOR", 0xff54759e);
intent.putExtra("android.support.customtabs.extra.TITLE_VISIBILITY", 1);
Intent actionIntent = new Intent(Intent.ACTION_SEND);
actionIntent.setType("text/plain");
actionIntent.putExtra(Intent.EXTRA_TEXT, uri.toString());
actionIntent.putExtra(Intent.EXTRA_SUBJECT, "");
PendingIntent pendingIntent = PendingIntent.getActivity(ApplicationLoader.applicationContext, 0, actionIntent, PendingIntent.FLAG_ONE_SHOT);
Bundle bundle = new Bundle();
bundle.putInt("android.support.customtabs.customaction.ID", 0);
bundle.putParcelable("android.support.customtabs.customaction.ICON", BitmapFactory.decodeResource(context.getResources(), R.drawable.abc_ic_menu_share_mtrl_alpha));
bundle.putString("android.support.customtabs.customaction.DESCRIPTION", LocaleController.getString("ShareFile", R.string.ShareFile));
bundle.putParcelable("android.support.customtabs.customaction.PENDING_INTENT", pendingIntent);
intent.putExtra("android.support.customtabs.extra.ACTION_BUTTON_BUNDLE", bundle);
intent.putExtra("android.support.customtabs.extra.TINT_ACTION_BUTTON", false);
}
intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
context.startActivity(intent);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
public static int getPhotoSize() {
if (photoSize == null) {
if (Build.VERSION.SDK_INT >= 16) {
@ -685,11 +762,11 @@ public class AndroidUtilities {
public static final int FLAG_TAG_COLOR = 4;
public static final int FLAG_TAG_ALL = FLAG_TAG_BR | FLAG_TAG_BOLD | FLAG_TAG_COLOR;
public static Spannable replaceTags(String str) {
public static SpannableStringBuilder replaceTags(String str) {
return replaceTags(str, FLAG_TAG_ALL);
}
public static Spannable replaceTags(String str, int flag) {
public static SpannableStringBuilder replaceTags(String str, int flag) {
try {
int start;
int end;

View File

@ -20,6 +20,9 @@ import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
@ -37,8 +40,6 @@ import org.telegram.ui.Components.ForegroundDetector;
import java.io.File;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Locale;
public class ApplicationLoader extends Application {
@ -47,6 +48,9 @@ public class ApplicationLoader extends Application {
private static boolean isCustomTheme;
private static final Object sync = new Object();
private static int serviceMessageColor;
private static int serviceSelectedMessageColor;
public static volatile Context applicationContext;
public static volatile Handler applicationHandler;
private static volatile boolean applicationInited = false;
@ -64,9 +68,27 @@ public class ApplicationLoader extends Application {
public static void reloadWallpaper() {
cachedWallpaper = null;
serviceMessageColor = 0;
ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE).edit().remove("serviceMessageColor").commit();
loadWallpaper();
}
private static void calcBackgroundColor() {
int result[] = AndroidUtilities.calcDrawableColor(cachedWallpaper);
serviceMessageColor = result[0];
serviceSelectedMessageColor = result[1];
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
preferences.edit().putInt("serviceMessageColor", serviceMessageColor).putInt("serviceSelectedMessageColor", serviceSelectedMessageColor).commit();
}
public static int getServiceMessageColor() {
return serviceMessageColor;
}
public static int getServiceSelectedMessageColor() {
return serviceSelectedMessageColor;
}
public static void loadWallpaper() {
if (cachedWallpaper != null) {
return;
@ -80,6 +102,8 @@ public class ApplicationLoader extends Application {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
int selectedBackground = preferences.getInt("selectedBackground", 1000001);
selectedColor = preferences.getInt("selectedColor", 0);
serviceMessageColor = preferences.getInt("serviceMessageColor", 0);
serviceSelectedMessageColor = preferences.getInt("serviceSelectedMessageColor", 0);
if (selectedColor == 0) {
if (selectedBackground == 1000001) {
cachedWallpaper = applicationContext.getResources().getDrawable(R.drawable.background_hd);
@ -104,6 +128,9 @@ public class ApplicationLoader extends Application {
}
cachedWallpaper = new ColorDrawable(selectedColor);
}
if (serviceMessageColor == 0) {
calcBackgroundColor();
}
}
}
});
@ -215,7 +242,7 @@ public class ApplicationLoader extends Application {
String configPath = getFilesDirFixed().toString();
try {
langCode = LocaleController.getLocaleString(LocaleController.getInstance().getSystemDefaultLocale());
langCode = LocaleController.getLocaleStringIso639();
deviceModel = Build.MANUFACTURER + Build.MODEL;
PackageInfo pInfo = ApplicationLoader.applicationContext.getPackageManager().getPackageInfo(ApplicationLoader.applicationContext.getPackageName(), 0);
appVersion = pInfo.versionName + " (" + pInfo.versionCode + ")";
@ -239,8 +266,11 @@ public class ApplicationLoader extends Application {
systemVersion = "SDK Unknown";
}
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE);
boolean enablePushConnection = preferences.getBoolean("pushConnection", true);
MessagesController.getInstance();
ConnectionsManager.getInstance().init(BuildVars.BUILD_VERSION, TLRPC.LAYER, BuildVars.APP_ID, deviceModel, systemVersion, appVersion, langCode, configPath, FileLog.getNetworkLogPath(), UserConfig.getClientUserId());
ConnectionsManager.getInstance().init(BuildVars.BUILD_VERSION, TLRPC.LAYER, BuildVars.APP_ID, deviceModel, systemVersion, appVersion, langCode, configPath, FileLog.getNetworkLogPath(), UserConfig.getClientUserId(), enablePushConnection);
if (UserConfig.getCurrentUser() != null) {
MessagesController.getInstance().putUser(UserConfig.getCurrentUser(), true);
ConnectionsManager.getInstance().applyCountryPortNumber(UserConfig.getCurrentUser().phone);
@ -323,13 +353,18 @@ public class ApplicationLoader extends Application {
@Override
public void run() {
if (checkPlayServices()) {
if (UserConfig.pushString == null || UserConfig.pushString.length() == 0) {
if (UserConfig.pushString != null && UserConfig.pushString.length() != 0) {
FileLog.d("tmessages", "GCM regId = " + UserConfig.pushString);
} else {
FileLog.d("tmessages", "GCM Registration not found.");
}
//if (UserConfig.pushString == null || UserConfig.pushString.length() == 0) {
Intent intent = new Intent(applicationContext, GcmRegistrationIntentService.class);
startService(intent);
} else {
FileLog.d("tmessages", "GCM regId = " + UserConfig.pushString);
}
//} else {
// FileLog.d("tmessages", "GCM regId = " + UserConfig.pushString);
//}
} else {
FileLog.d("tmessages", "No valid Google Play Services APK found.");
}

View File

@ -16,6 +16,7 @@ public class AutoMessageHeardReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ApplicationLoader.postInitApplication();
long dialog_id = intent.getLongExtra("dialog_id", 0);
int max_id = intent.getIntExtra("max_id", 0);
if (dialog_id == 0 || max_id == 0) {

View File

@ -18,6 +18,7 @@ public class AutoMessageReplyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ApplicationLoader.postInitApplication();
Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
if (remoteInput == null) {
return;
@ -31,7 +32,7 @@ public class AutoMessageReplyReceiver extends BroadcastReceiver {
if (dialog_id == 0 || max_id == 0) {
return;
}
SendMessagesHelper.getInstance().sendMessage(text.toString(), dialog_id, null, null, true, false, null, null);
SendMessagesHelper.getInstance().sendMessage(text.toString(), dialog_id, null, null, true, false, null, null, null);
MessagesController.getInstance().markDialogAsRead(dialog_id, max_id, max_id, 0, true, false);
}
}

View File

@ -10,8 +10,8 @@ package org.telegram.messenger;
public class BuildVars {
public static boolean DEBUG_VERSION = false;
public static int BUILD_VERSION = 767;
public static String BUILD_VERSION_STRING = "3.7";
public static int BUILD_VERSION = 787;
public static String BUILD_VERSION_STRING = "3.8";
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

@ -27,6 +27,8 @@ public class ClearCacheService extends IntentService {
@Override
protected void onHandleIntent(Intent intent) {
ApplicationLoader.postInitApplication();
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
final int keepMedia = preferences.getInt("keep_media", 2);
if (keepMedia == 2) {

View File

@ -173,7 +173,7 @@ public class ContactsController {
if (!updatingInviteText && (inviteText == null || time + 86400 < (int)(System.currentTimeMillis() / 1000))) {
updatingInviteText = true;
TLRPC.TL_help_getInviteText req = new TLRPC.TL_help_getInviteText();
req.lang_code = LocaleController.getLocaleString(LocaleController.getInstance().getSystemDefaultLocale());
req.lang_code = LocaleController.getLocaleStringIso639();
if (req.lang_code.length() == 0) {
req.lang_code = "en";
}
@ -1652,7 +1652,8 @@ public class ContactsController {
}
}*/
for (final TLRPC.User u : res.users) {
for (int a = 0; a < res.users.size(); a++) {
final TLRPC.User u = res.users.get(a);
Utilities.phoneBookQueue.postRunnable(new Runnable() {
@Override
public void run() {

View File

@ -115,7 +115,7 @@ public class FileLoadOperation {
}
ext = FileLoader.getDocumentFileName(documentLocation);
int idx;
if (ext == null || (idx = ext.lastIndexOf(".")) == -1) {
if (ext == null || (idx = ext.lastIndexOf('.')) == -1) {
ext = "";
} else {
ext = ext.substring(idx);

View File

@ -593,7 +593,9 @@ public class FileLoader {
}
}
} else if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
if (message.media.webpage.photo != null) {
if (message.media.webpage.document != null) {
return getPathToAttach(message.media.webpage.document);
} else if (message.media.webpage.photo != null) {
ArrayList<TLRPC.PhotoSize> sizes = message.media.webpage.photo.sizes;
if (sizes.size() > 0) {
TLRPC.PhotoSize sizeFull = getClosestPhotoSizeWithSize(sizes, AndroidUtilities.getPhotoSize());
@ -601,8 +603,6 @@ public class FileLoader {
return getPathToAttach(sizeFull);
}
}
} else if (message.media.webpage.document != null) {
return getPathToAttach(message.media.webpage.document);
}
}
}
@ -667,7 +667,8 @@ public class FileLoader {
}
int lastSide = 0;
TLRPC.PhotoSize closestObject = null;
for (TLRPC.PhotoSize obj : sizes) {
for (int a = 0; a < sizes.size(); a++) {
TLRPC.PhotoSize obj = sizes.get(a);
if (obj == null) {
continue;
}
@ -691,7 +692,7 @@ public class FileLoader {
public static String getFileExtension(File file) {
String name = file.getName();
try {
return name.substring(name.lastIndexOf(".") + 1);
return name.substring(name.lastIndexOf('.') + 1);
} catch (Exception e) {
return "";
}
@ -714,7 +715,7 @@ public class FileLoader {
public static String getDocumentExtension(TLRPC.Document document) {
String fileName = getDocumentFileName(document);
int idx = fileName.lastIndexOf(".");
int idx = fileName.lastIndexOf('.');
String ext = null;
if (idx != -1) {
ext = fileName.substring(idx + 1);
@ -740,7 +741,7 @@ public class FileLoader {
if (docExt == null) {
docExt = getDocumentFileName(document);
int idx;
if (docExt == null || (idx = docExt.lastIndexOf(".")) == -1) {
if (docExt == null || (idx = docExt.lastIndexOf('.')) == -1) {
docExt = "";
} else {
docExt = docExt.substring(idx);

View File

@ -138,8 +138,8 @@ public class FileLog {
try {
getInstance().streamWriter.write(getInstance().dateFormat.format(System.currentTimeMillis()) + " E/" + tag + "" + e + "\n");
StackTraceElement[] stack = e.getStackTrace();
for (StackTraceElement el : stack) {
getInstance().streamWriter.write(getInstance().dateFormat.format(System.currentTimeMillis()) + " E/" + tag + "" + el + "\n");
for (int a = 0; a < stack.length; a++) {
getInstance().streamWriter.write(getInstance().dateFormat.format(System.currentTimeMillis()) + " E/" + tag + "" + stack[a] + "\n");
}
getInstance().streamWriter.flush();
} catch (Exception e) {
@ -194,6 +194,9 @@ public class FileLog {
public static void cleanupLogs() {
File sdCard = ApplicationLoader.applicationContext.getExternalFilesDir(null);
if (sdCard == null) {
return;
}
File dir = new File (sdCard.getAbsolutePath() + "/logs");
File[] files = dir.listFiles();
if (files != null) {

View File

@ -46,6 +46,7 @@ public class GcmPushListenerService extends GcmListenerService {
FileLog.e("tmessages", e);
}
ConnectionsManager.onInternalPushReceived();
ConnectionsManager.getInstance().resumeNetworkMaybe();
}
});

View File

@ -24,9 +24,15 @@ public class GcmRegistrationIntentService extends IntentService {
protected void onHandleIntent(Intent intent) {
try {
InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken(BuildVars.GCM_SENDER_ID, GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
final String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId), GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
FileLog.d("tmessages", "GCM Registration Token: " + token);
sendRegistrationToServer(token);
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
ApplicationLoader.postInitApplication();
sendRegistrationToServer(token);
}
});
} catch (Exception e) {
FileLog.e("tmessages", e);
final int failCount = intent.getIntExtra("failCount", 0);

View File

@ -1809,7 +1809,7 @@ public class ImageLoader {
key = document.dc_id + "_" + document.id;
String docExt = FileLoader.getDocumentFileName(document);
int idx;
if (docExt == null || (idx = docExt.lastIndexOf(".")) == -1) {
if (docExt == null || (idx = docExt.lastIndexOf('.')) == -1) {
docExt = "";
} else {
docExt = docExt.substring(idx);
@ -1946,21 +1946,12 @@ public class ImageLoader {
}
}
public void loadHttpFile(String url, String extension) {
public void loadHttpFile(String url, String defaultExt) {
if (url == null || url.length() == 0 || httpFileLoadTasksByKeys.containsKey(url)) {
return;
}
String ext = extension;
if (ext == null) {
int idx = url.lastIndexOf(".");
if (idx != -1) {
ext = url.substring(idx + 1);
}
if (ext == null || ext.length() == 0 || ext.length() > 4) {
ext = "jpg";
}
}
File file = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), Utilities.MD5(url) + "_temp." + getHttpUrlExtension(url, extension));
String ext = getHttpUrlExtension(url, defaultExt);
File file = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), Utilities.MD5(url) + "_temp." + ext);
file.delete();
HttpFileTask task = new HttpFileTask(url, file, ext);
@ -2276,7 +2267,7 @@ public class ImageLoader {
public static String getHttpUrlExtension(String url, String defaultExt) {
String ext = null;
int idx = url.lastIndexOf(".");
int idx = url.lastIndexOf('.');
if (idx != -1) {
ext = url.substring(idx + 1);
}

View File

@ -50,6 +50,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
private Integer thumbTag;
private MessageObject parentMessageObject;
private boolean canceledLoading;
private static PorterDuffColorFilter selectedColorFilter = new PorterDuffColorFilter(0xffdddddd, PorterDuff.Mode.MULTIPLY);
private SetImageBackup setImageBackup;
@ -79,10 +80,11 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
private boolean forcePreview;
private int roundRadius;
private BitmapShader bitmapShader;
private Paint roundPaint;
private RectF roundRect;
private RectF bitmapRect;
private Matrix shaderMatrix;
private BitmapShader bitmapShaderThumb;
private static Paint roundPaint;
private RectF roundRect = new RectF();
private RectF bitmapRect = new RectF();
private Matrix shaderMatrix = new Matrix();
private float overrideAlpha = 1.0f;
private boolean isPressed;
private int orientation;
@ -95,11 +97,14 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
private ColorFilter colorFilter;
public ImageReceiver() {
this(null);
}
public ImageReceiver(View view) {
parentView = view;
if (roundPaint == null) {
roundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
}
public void cancelLoadImage() {
@ -156,6 +161,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
currentSize = 0;
currentImage = null;
bitmapShader = null;
bitmapShaderThumb = null;
ImageLoader.getInstance().cancelLoadingForImageReceiver(this, 0);
if (parentView != null) {
if (invalidateAll) {
@ -228,6 +234,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
currentThumbLocation = thumbLocation;
staticThumb = thumb;
bitmapShader = null;
bitmapShaderThumb = null;
currentAlpha = 1.0f;
if (delegate != null) {
@ -300,6 +307,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
currentSize = 0;
currentCacheOnly = false;
bitmapShader = null;
bitmapShaderThumb = null;
if (setImageBackup != null) {
setImageBackup.fileLocation = null;
setImageBackup.httpUrl = null;
@ -356,33 +364,40 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
return false;
}
private void drawDrawable(Canvas canvas, Drawable drawable, int alpha) {
private void drawDrawable(Canvas canvas, Drawable drawable, int alpha, BitmapShader shader) {
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
Paint paint = bitmapDrawable.getPaint();
Paint paint;
if (shader != null) {
paint = roundPaint;
} else {
paint = bitmapDrawable.getPaint();
}
boolean hasFilter = paint != null && paint.getColorFilter() != null;
if (hasFilter && !isPressed) {
bitmapDrawable.setColorFilter(null);
if (shader != null) {
roundPaint.setColorFilter(null);
} else {
bitmapDrawable.setColorFilter(null);
}
} else if (!hasFilter && isPressed) {
bitmapDrawable.setColorFilter(new PorterDuffColorFilter(0xffdddddd, PorterDuff.Mode.MULTIPLY));
if (shader != null) {
roundPaint.setColorFilter(selectedColorFilter);
} else {
bitmapDrawable.setColorFilter(selectedColorFilter);
}
}
if (colorFilter != null) {
bitmapDrawable.setColorFilter(colorFilter);
}
if (bitmapShader != null) {
drawRegion.set(imageX, imageY, imageX + imageW, imageY + imageH);
if (isVisible) {
roundRect.set(drawRegion);
shaderMatrix.reset();
shaderMatrix.setRectToRect(bitmapRect, roundRect, Matrix.ScaleToFit.FILL);
bitmapShader.setLocalMatrix(shaderMatrix);
roundPaint.setAlpha(alpha);
canvas.drawRoundRect(roundRect, roundRadius, roundRadius, roundPaint);
if (shader != null) {
roundPaint.setColorFilter(colorFilter);
} else {
bitmapDrawable.setColorFilter(colorFilter);
}
} else {
int bitmapW;
int bitmapH;
}
int bitmapW;
int bitmapH;
if (bitmapDrawable instanceof AnimatedFileDrawable) {
if (orientation % 360 == 90 || orientation % 360 == 270) {
bitmapW = bitmapDrawable.getIntrinsicHeight();
bitmapH = bitmapDrawable.getIntrinsicWidth();
@ -390,9 +405,47 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
bitmapW = bitmapDrawable.getIntrinsicWidth();
bitmapH = bitmapDrawable.getIntrinsicHeight();
}
float scaleW = bitmapW / (float) imageW;
float scaleH = bitmapH / (float) imageH;
} else {
if (orientation % 360 == 90 || orientation % 360 == 270) {
bitmapW = bitmapDrawable.getBitmap().getHeight();
bitmapH = bitmapDrawable.getBitmap().getWidth();
} else {
bitmapW = bitmapDrawable.getBitmap().getWidth();
bitmapH = bitmapDrawable.getBitmap().getHeight();
}
}
float scaleW = bitmapW / (float) imageW;
float scaleH = bitmapH / (float) imageH;
if (shader != null) {
roundPaint.setShader(shader);
float scale = Math.min(scaleW, scaleH);
roundRect.set(imageX, imageY, imageX + imageW, imageY + imageH);
shaderMatrix.reset();
if (Math.abs(scaleW - scaleH) > 0.00001f) {
if (bitmapW / scaleH > imageW) {
drawRegion.set(imageX - ((int) (bitmapW / scaleH) - imageW) / 2, imageY, imageX + ((int) (bitmapW / scaleH) + imageW) / 2, imageY + imageH);
} else {
drawRegion.set(imageX, imageY - ((int) (bitmapH / scaleW) - imageH) / 2, imageX + imageW, imageY + ((int) (bitmapH / scaleW) + imageH) / 2);
}
} else {
drawRegion.set(imageX, imageY, imageX + imageW, imageY + imageH);
}
if (isVisible) {
if (Math.abs(scaleW - scaleH) > 0.00001f) {
int w = (int) Math.floor(imageW * scale);
int h = (int) Math.floor(imageH * scale);
bitmapRect.set((bitmapW - w) / 2, (bitmapH - h) / 2, (bitmapW + w) / 2, (bitmapH + h) / 2);
shaderMatrix.setRectToRect(bitmapRect, roundRect, Matrix.ScaleToFit.START);
} else {
bitmapRect.set(0, 0, bitmapW, bitmapH);
shaderMatrix.setRectToRect(bitmapRect, roundRect, Matrix.ScaleToFit.FILL);
}
shader.setLocalMatrix(shaderMatrix);
roundPaint.setAlpha(alpha);
canvas.drawRoundRect(roundRect, roundRadius, roundRadius, roundPaint);
}
} else {
if (isAspectFit) {
float scale = Math.max(scaleW, scaleH);
canvas.save();
@ -428,12 +481,16 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
}
if (bitmapW / scaleH > imageW) {
bitmapW /= scaleH;
drawRegion.set(imageX - (bitmapW - imageW) / 2, imageY, imageX + (bitmapW + imageW) / 2, imageY + imageH);
if (bitmapDrawable instanceof AnimatedFileDrawable) {
drawRegion.set(imageX, imageY, imageX + imageW, imageY + imageH);
} else {
bitmapH /= scaleW;
drawRegion.set(imageX, imageY - (bitmapH - imageH) / 2, imageX + imageW, imageY + (bitmapH + imageH) / 2);
if (bitmapW / scaleH > imageW) {
bitmapW /= scaleH;
drawRegion.set(imageX - (bitmapW - imageW) / 2, imageY, imageX + (bitmapW + imageW) / 2, imageY + imageH);
} else {
bitmapH /= scaleW;
drawRegion.set(imageX, imageY - (bitmapH - imageH) / 2, imageX + imageW, imageY + (bitmapH + imageH) / 2);
}
}
if (orientation % 360 == 90 || orientation % 360 == 270) {
int width = (drawRegion.right - drawRegion.left) / 2;
@ -519,7 +576,11 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
if (currentAlpha != 1) {
if (!skip) {
long currentTime = System.currentTimeMillis();
currentAlpha += (currentTime - lastUpdateAlphaTime) / 150.0f;
long dt = currentTime - lastUpdateAlphaTime;
if (dt > 18) {
dt = 18;
}
currentAlpha += dt / 150.0f;
if (currentAlpha > 1) {
currentAlpha = 1;
}
@ -539,17 +600,20 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
try {
Drawable drawable = null;
boolean animationNotReady = currentImage instanceof AnimatedFileDrawable && !((AnimatedFileDrawable) currentImage).hasBitmap();
boolean isThumb = false;
if (!forcePreview && currentImage != null && !animationNotReady) {
drawable = currentImage;
} else if (staticThumb instanceof BitmapDrawable) {
drawable = staticThumb;
isThumb = true;
} else if (currentThumb != null) {
drawable = currentThumb;
isThumb = true;
}
if (drawable != null) {
if (crossfadeAlpha != 0) {
if (crossfadeWithThumb && animationNotReady) {
drawDrawable(canvas, drawable, (int) (overrideAlpha * 255));
drawDrawable(canvas, drawable, (int) (overrideAlpha * 255), bitmapShaderThumb);
} else {
if (crossfadeWithThumb && currentAlpha != 1.0f) {
Drawable thumbDrawable = null;
@ -565,19 +629,19 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
}
if (thumbDrawable != null) {
drawDrawable(canvas, thumbDrawable, (int) (overrideAlpha * 255));
drawDrawable(canvas, thumbDrawable, (int) (overrideAlpha * 255), bitmapShaderThumb);
}
}
drawDrawable(canvas, drawable, (int) (overrideAlpha * currentAlpha * 255));
drawDrawable(canvas, drawable, (int) (overrideAlpha * currentAlpha * 255), isThumb ? bitmapShaderThumb : bitmapShader);
}
} else {
drawDrawable(canvas, drawable, (int) (overrideAlpha * 255));
drawDrawable(canvas, drawable, (int) (overrideAlpha * 255), isThumb ? bitmapShaderThumb : bitmapShader);
}
checkAlphaAnimation(animationNotReady && crossfadeWithThumb);
return true;
} else if (staticThumb != null) {
drawDrawable(canvas, staticThumb, 255);
drawDrawable(canvas, staticThumb, 255, null);
checkAlphaAnimation(animationNotReady);
return true;
} else {
@ -753,19 +817,6 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
public void setRoundRadius(int value) {
roundRadius = value;
if (roundRadius != 0) {
if (roundPaint == null) {
roundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
roundRect = new RectF();
shaderMatrix = new Matrix();
bitmapRect = new RectF();
}
} else {
roundPaint = null;
roundRect = null;
shaderMatrix = null;
bitmapRect = null;
}
}
public int getRoundRadius() {
@ -853,11 +904,15 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
ImageLoader.getInstance().incrementUseCount(currentKey);
}
currentImage = bitmap;
if (roundRadius != 0) {
Bitmap object = bitmap.getBitmap();
bitmapShader = new BitmapShader(object, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
roundPaint.setShader(bitmapShader);
bitmapRect.set(0, 0, object.getWidth(), object.getHeight());
if (roundRadius != 0 && bitmap instanceof BitmapDrawable) {
if (bitmap instanceof AnimatedFileDrawable) {
((AnimatedFileDrawable) bitmap).setRoundRadius(roundRadius);
} else {
Bitmap object = bitmap.getBitmap();
bitmapShader = new BitmapShader(object, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
}
} else {
bitmapShader = null;
}
if (!memCache && !forcePreview) {
@ -892,6 +947,17 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
currentThumb = bitmap;
if (roundRadius != 0 && currentImage == null && bitmap instanceof BitmapDrawable) {
if (bitmap instanceof AnimatedFileDrawable) {
((AnimatedFileDrawable) bitmap).setRoundRadius(roundRadius);
} else {
Bitmap object = bitmap.getBitmap();
bitmapShaderThumb = new BitmapShader(object, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
}
} else {
bitmapShaderThumb = null;
}
if (!memCache && crossfadeAlpha != 2) {
currentAlpha = 0.0f;
lastUpdateAlphaTime = System.currentTimeMillis();
@ -961,6 +1027,12 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
ImageLoader.getInstance().incrementUseCount(currentThumbKey);
}
currentThumb = (BitmapDrawable) args[0];
if (roundRadius != 0 && currentImage == null && currentThumb instanceof BitmapDrawable && !(currentThumb instanceof AnimatedFileDrawable)) {
Bitmap object = ((BitmapDrawable) currentThumb).getBitmap();
bitmapShaderThumb = new BitmapShader(object, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
} else {
bitmapShaderThumb = null;
}
if (staticThumb instanceof BitmapDrawable) {
staticThumb = null;
}

View File

@ -309,7 +309,31 @@ public class LocaleController {
return systemDefaultLocale;
}
public static String getLocaleString(Locale locale) {
private String getLocaleString(Locale locale) {
if (locale == null) {
return "en";
}
String languageCode = locale.getLanguage();
String countryCode = locale.getCountry();
String variantCode = locale.getVariant();
if (languageCode.length() == 0 && countryCode.length() == 0) {
return "en";
}
StringBuilder result = new StringBuilder(11);
result.append(languageCode);
if (countryCode.length() > 0 || variantCode.length() > 0) {
result.append('_');
}
result.append(countryCode);
if (variantCode.length() > 0) {
result.append('_');
}
result.append(variantCode);
return result.toString();
}
public static String getLocaleStringIso639() {
Locale locale = getInstance().getSystemDefaultLocale();
if (locale == null) {
return "en";
}
@ -583,7 +607,11 @@ public class LocaleController {
private String getStringInternal(String key, int res) {
String value = localeValues.get(key);
if (value == null) {
value = ApplicationLoader.applicationContext.getString(res);
try {
value = ApplicationLoader.applicationContext.getString(res);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
if (value == null) {
value = "LOC_ERR:" + key;

View File

@ -12,6 +12,7 @@ import android.Manifest;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.DownloadManager;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
@ -236,7 +237,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
private float[] gravityFast = new float[3];
private float[] linearAcceleration = new float[3];
private boolean hasAudioFocus;
private int hasAudioFocus;
private boolean callInProgress;
private ArrayList<MessageObject> videoConvertQueue = new ArrayList<>();
@ -279,6 +280,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
public static AlbumEntry allPhotosAlbumEntry;
private HashMap<String, ArrayList<WeakReference<FileDownloadProgressListener>>> loadingFileObservers = new HashMap<>();
private HashMap<String, ArrayList<MessageObject>> loadingFileMessagesObservers = new HashMap<>();
private HashMap<Integer, String> observersByTag = new HashMap<>();
private boolean listenerInProgress = false;
private HashMap<String, FileDownloadProgressListener> addLaterArray = new HashMap<>();
@ -694,7 +696,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
if (MediaController.getInstance().isPlayingAudio(MediaController.getInstance().getPlayingMessageObject()) && !MediaController.getInstance().isAudioPaused()) {
MediaController.getInstance().pauseAudio(MediaController.getInstance().getPlayingMessageObject());
}
hasAudioFocus = false;
hasAudioFocus = 0;
} else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
//MediaController.getInstance().playAudio(MediaController.getInstance().getPlayingMessageObject());
}
@ -1161,6 +1163,10 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
public void addLoadingFileObserver(String fileName, FileDownloadProgressListener observer) {
addLoadingFileObserver(fileName, null, observer);
}
public void addLoadingFileObserver(String fileName, MessageObject messageObject, FileDownloadProgressListener observer) {
if (listenerInProgress) {
addLaterArray.put(fileName, observer);
return;
@ -1173,6 +1179,14 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
loadingFileObservers.put(fileName, arrayList);
}
arrayList.add(new WeakReference<>(observer));
if (messageObject != null) {
ArrayList<MessageObject> messageObjects = loadingFileMessagesObservers.get(fileName);
if (messageObjects == null) {
messageObjects = new ArrayList<>();
loadingFileMessagesObservers.put(fileName, messageObjects);
}
messageObjects.add(messageObject);
}
observersByTag.put(observer.getObserverTag(), fileName);
}
@ -1203,7 +1217,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
private void processLaterArrays() {
for (HashMap.Entry<String, FileDownloadProgressListener> listener : addLaterArray.entrySet()) {
addLoadingFileObserver(listener.getKey(), listener.getValue());
addLoadingFileObserver(listener.getKey(), listener.getValue()); //TODO
}
addLaterArray.clear();
for (FileDownloadProgressListener listener : deleteLaterArray) {
@ -1218,9 +1232,11 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
if (id == NotificationCenter.FileDidFailedLoad) {
listenerInProgress = true;
String fileName = (String) args[0];
loadingFileMessagesObservers.get(fileName);
ArrayList<WeakReference<FileDownloadProgressListener>> arrayList = loadingFileObservers.get(fileName);
if (arrayList != null) {
for (WeakReference<FileDownloadProgressListener> reference : arrayList) {
for (int a = 0; a < arrayList.size(); a++) {
WeakReference<FileDownloadProgressListener> reference = arrayList.get(a);
if (reference.get() != null) {
reference.get().onFailedDownload(fileName);
observersByTag.remove(reference.get().getObserverTag());
@ -1235,15 +1251,24 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
listenerInProgress = true;
String fileName = (String) args[0];
if (downloadingCurrentMessage && playingMessageObject != null) {
String file = FileLoader.getAttachFileName(playingMessageObject.messageOwner.media.document);
String file = FileLoader.getAttachFileName(playingMessageObject.getDocument());
if (file.equals(fileName)) {
playMusicAgain = true;
playAudio(playingMessageObject);
}
}
ArrayList<MessageObject> messageObjects = loadingFileMessagesObservers.get(fileName);
if (messageObjects != null) {
for (int a = 0; a < messageObjects.size(); a++) {
MessageObject messageObject = messageObjects.get(a);
messageObject.mediaExists = true;
}
loadingFileMessagesObservers.remove(fileName);
}
ArrayList<WeakReference<FileDownloadProgressListener>> arrayList = loadingFileObservers.get(fileName);
if (arrayList != null) {
for (WeakReference<FileDownloadProgressListener> reference : arrayList) {
for (int a = 0; a < arrayList.size(); a++) {
WeakReference<FileDownloadProgressListener> reference = arrayList.get(a);
if (reference.get() != null) {
reference.get().onSuccessDownload(fileName);
observersByTag.remove(reference.get().getObserverTag());
@ -1588,14 +1613,14 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
startRecording(raiseChat.getDialogId(), null, false);
}
ignoreOnPause = true;
if (proximityWakeLock != null && !proximityWakeLock.isHeld()) {
if (proximityHasDifferentValues && proximityWakeLock != null && !proximityWakeLock.isHeld()) {
proximityWakeLock.acquire();
}
}
} else if (playingMessageObject != null && playingMessageObject.isVoice()) {
if (!useFrontSpeaker) {
FileLog.e("tmessages", "start listen");
if (proximityWakeLock != null && !proximityWakeLock.isHeld()) {
if (proximityHasDifferentValues && proximityWakeLock != null && !proximityWakeLock.isHeld()) {
proximityWakeLock.acquire();
}
useFrontSpeaker = true;
@ -1610,7 +1635,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
if (playingMessageObject != null && playingMessageObject.isVoice()) {
if (!useFrontSpeaker) {
FileLog.e("tmessages", "start listen by proximity only");
if (proximityWakeLock != null && !proximityWakeLock.isHeld()) {
if (proximityHasDifferentValues && proximityWakeLock != null && !proximityWakeLock.isHeld()) {
proximityWakeLock.acquire();
}
useFrontSpeaker = true;
@ -1624,7 +1649,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
stopRecording(2);
raiseToEarRecord = false;
ignoreOnPause = false;
if (proximityWakeLock != null && proximityWakeLock.isHeld()) {
if (proximityHasDifferentValues && proximityWakeLock != null && proximityWakeLock.isHeld()) {
proximityWakeLock.release();
}
} else if (useFrontSpeaker) {
@ -1632,7 +1657,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
useFrontSpeaker = false;
startAudioAgain(true);
ignoreOnPause = false;
if (proximityWakeLock != null && proximityWakeLock.isHeld()) {
if (proximityHasDifferentValues && proximityWakeLock != null && proximityWakeLock.isHeld()) {
proximityWakeLock.release();
}
}
@ -1758,7 +1783,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
sensorManager.unregisterListener(MediaController.this, proximitySensor);
}
});
if (proximityWakeLock != null && proximityWakeLock.isHeld()) {
if (proximityHasDifferentValues && proximityWakeLock != null && proximityWakeLock.isHeld()) {
proximityWakeLock.release();
}
}
@ -1807,7 +1832,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
isPaused = false;
if (playingMessageObject != null) {
if (downloadingCurrentMessage) {
FileLoader.getInstance().cancelLoadFile(playingMessageObject.messageOwner.media.document);
FileLoader.getInstance().cancelLoadFile(playingMessageObject.getDocument());
}
MessageObject lastFile = playingMessageObject;
playingMessageObject.audioProgress = 0.0f;
@ -1816,6 +1841,8 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
playingMessageObject = null;
downloadingCurrentMessage = false;
if (notify) {
NotificationsController.getInstance().audioManager.abandonAudioFocus(this);
hasAudioFocus = 0;
if (voiceMessagesPlaylist != null) {
if (byVoiceEnd && voiceMessagesPlaylist.get(0) == lastFile) {
voiceMessagesPlaylist.remove(0);
@ -1944,7 +1971,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
if (currentPlaylistNum == -1) {
playlist.clear();
shuffledPlaylist.clear();
return false;
playlist.add(current);
}
if (current.isMusic()) {
if (shuffleMusic) {
@ -2062,7 +2089,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
final File cacheFile = file != null ? file : FileLoader.getPathToMessage(nextAudio.messageOwner);
boolean exist = cacheFile != null && cacheFile.exists();
if (cacheFile != null && cacheFile != file && !cacheFile.exists() && nextAudio.isMusic()) {
FileLoader.getInstance().loadFile(nextAudio.messageOwner.media.document, false, false);
FileLoader.getInstance().loadFile(nextAudio.getDocument(), false, false);
}
}
@ -2078,6 +2105,27 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
}
private void checkAudioFocus(MessageObject messageObject) {
int neededAudioFocus;
if (messageObject.isVoice()) {
if (useFrontSpeaker) {
neededAudioFocus = 3;
} else {
neededAudioFocus = 2;
}
} else {
neededAudioFocus = 1;
}
if (hasAudioFocus != neededAudioFocus) {
hasAudioFocus = neededAudioFocus;
if (neededAudioFocus == 3) {
NotificationsController.getInstance().audioManager.requestAudioFocus(this, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN);
} else {
NotificationsController.getInstance().audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, neededAudioFocus == 2 ? AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK : AudioManager.AUDIOFOCUS_GAIN);
}
}
}
public boolean playAudio(final MessageObject messageObject) {
if (messageObject == null) {
return false;
@ -2109,14 +2157,14 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
final File cacheFile = file != null ? file : FileLoader.getPathToMessage(messageObject.messageOwner);
if (cacheFile != null && cacheFile != file && !cacheFile.exists() && messageObject.isMusic()) {
FileLoader.getInstance().loadFile(messageObject.messageOwner.media.document, false, false);
FileLoader.getInstance().loadFile(messageObject.getDocument(), false, false);
downloadingCurrentMessage = true;
isPaused = false;
lastProgress = 0;
lastPlayPcm = 0;
audioInfo = null;
playingMessageObject = messageObject;
if (playingMessageObject.messageOwner.media.document != null) {
if (playingMessageObject.getDocument() != null) {
Intent intent = new Intent(ApplicationLoader.applicationContext, MusicPlayerService.class);
ApplicationLoader.applicationContext.startService(intent);
} else {
@ -2221,10 +2269,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
return false;
}
}
if (!hasAudioFocus) {
hasAudioFocus = true;
NotificationsController.getInstance().audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
}
checkAudioFocus(messageObject);
isPaused = false;
lastProgress = 0;
@ -2403,10 +2448,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
audioTrackPlayer.play();
checkPlayerQueue();
}
if (!hasAudioFocus) {
hasAudioFocus = true;
NotificationsController.getInstance().audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
}
checkAudioFocus(messageObject);
isPaused = false;
NotificationCenter.getInstance().postNotificationName(NotificationCenter.audioPlayStateChanged, playingMessageObject.getId());
} catch (Exception e) {
@ -2548,8 +2590,8 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
return;
}
if (waveform != null) {
for (int a = 0; a < messageObject.messageOwner.media.document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = messageObject.messageOwner.media.document.attributes.get(a);
for (int a = 0; a < messageObject.getDocument().attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = messageObject.getDocument().attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeAudio) {
attribute.waveform = waveform;
attribute.flags |= 4;
@ -2593,7 +2635,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
audioToSend.attributes.add(attributeAudio);
if (duration > 700) {
if (send == 1) {
SendMessagesHelper.getInstance().sendMessage(audioToSend, null, recordingAudioFileToSend.getAbsolutePath(), recordDialogId, recordReplyingMessageObject, recordAsAdmin, null);
SendMessagesHelper.getInstance().sendMessage(audioToSend, null, recordingAudioFileToSend.getAbsolutePath(), recordDialogId, recordReplyingMessageObject, recordAsAdmin, null, null);
}
NotificationCenter.getInstance().postNotificationName(NotificationCenter.audioDidSent, send == 2 ? audioToSend : null, send == 2 ? recordingAudioFileToSend.getAbsolutePath() : null);
} else {
@ -2655,7 +2697,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
});
}
public static void saveFile(String fullPath, Context context, final int type, final String name) {
public static void saveFile(String fullPath, Context context, final int type, final String name, final String mime) {
if (fullPath == null) {
return;
}
@ -2752,8 +2794,15 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
}
if (result && (type == 0 || type == 1 || type == 3)) {
AndroidUtilities.addMediaToGallery(Uri.fromFile(destFile));
if (result) {
if (type == 2) {
if (Build.VERSION.SDK_INT >= 12) {
DownloadManager downloadManager = (DownloadManager) ApplicationLoader.applicationContext.getSystemService(Context.DOWNLOAD_SERVICE);
downloadManager.addCompletedDownload(destFile.getName(), destFile.getName(), false, mime, destFile.getAbsolutePath(), destFile.length(), true);
}
} else {
AndroidUtilities.addMediaToGallery(Uri.fromFile(destFile));
}
}
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -2985,7 +3034,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
public static void loadGalleryPhotosAlbums(final int guid) {
new Thread(new Runnable() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
final ArrayList<AlbumEntry> albumsSorted = new ArrayList<>();
@ -3130,7 +3179,9 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
});
}
}).start();
});
thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
}
public void scheduleVideoConvert(MessageObject messageObject) {

View File

@ -23,12 +23,14 @@ import android.text.util.Linkify;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.TypefaceSpan;
import org.telegram.ui.Components.URLSpanBotCommand;
import org.telegram.ui.Components.URLSpanNoUnderline;
import org.telegram.ui.Components.URLSpanNoUnderlineBold;
import org.telegram.ui.Components.URLSpanReplacement;
import java.io.File;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Calendar;
@ -47,7 +49,7 @@ public class MessageObject {
public CharSequence linkDescription;
public CharSequence caption;
public MessageObject replyMessageObject;
public int type;
public int type = 1000;
public int contentType;
public String dateKey;
public String monthKey;
@ -57,8 +59,14 @@ public class MessageObject {
public ArrayList<TLRPC.PhotoSize> photoThumbs;
public VideoEditedInfo videoEditedInfo;
public boolean viewsReloaded;
public int wantedBotKeyboardWidth;
public boolean attachPathExists;
public boolean mediaExists;
public boolean forceUpdate;
private static TextPaint textPaint;
private static TextPaint botButtonPaint;
public int lastLineWidth;
public int textWidth;
public int textHeight;
@ -86,8 +94,8 @@ public class MessageObject {
public MessageObject(TLRPC.Message message, AbstractMap<Integer, TLRPC.User> users, AbstractMap<Integer, TLRPC.Chat> chats, boolean generateLayout) {
if (textPaint == null) {
textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
textPaint.setColor(0xff000000);
textPaint.linkColor = 0xff316f9f;
textPaint.setColor(Theme.MSG_TEXT_COLOR);
textPaint.linkColor = Theme.MSG_LINK_TEXT_COLOR;
}
textPaint.setTextSize(AndroidUtilities.dp(MessagesController.getInstance().fontSize));
@ -348,68 +356,8 @@ public class MessageObject {
messageText = "";
}
if (message instanceof TLRPC.TL_message || message instanceof TLRPC.TL_messageForwarded_old2) {
if (isMediaEmpty()) {
contentType = 0;
type = 0;
if (messageText == null || messageText.length() == 0) {
messageText = "Empty message";
}
} else if (message.media instanceof TLRPC.TL_messageMediaPhoto) {
contentType = 0;
type = 1;
} else if (message.media instanceof TLRPC.TL_messageMediaGeo || message.media instanceof TLRPC.TL_messageMediaVenue) {
contentType = 0;
type = 4;
} else if (isVideo()) {
contentType = 0;
type = 3;
} else if (isVoice()) {
contentType = 2;
type = 2;
} else if (message.media instanceof TLRPC.TL_messageMediaContact) {
contentType = 3;
type = 12;
} else if (message.media instanceof TLRPC.TL_messageMediaUnsupported) {
contentType = 0;
type = 0;
} else if (message.media instanceof TLRPC.TL_messageMediaDocument) {
contentType = 0;
if (message.media.document.mime_type != null) {
if (isGifDocument(message.media.document)) {
type = 8;
} else if (message.media.document.mime_type.equals("image/webp") && isSticker()) {
type = 13;
} else if (isMusic()) {
type = 14;
contentType = 8;
} else {
type = 9;
}
} else {
type = 9;
}
}
} else if (message instanceof TLRPC.TL_messageService) {
if (message.action instanceof TLRPC.TL_messageActionLoginUnknownLocation) {
contentType = 0;
type = 0;
} else if (message.action instanceof TLRPC.TL_messageActionChatEditPhoto || message.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) {
contentType = 4;
type = 11;
} else if (message.action instanceof TLRPC.TL_messageEncryptedAction) {
if (message.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages || message.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL) {
contentType = 4;
type = 10;
} else {
contentType = -1;
type = -1;
}
} else {
contentType = 4;
type = 10;
}
}
setType();
measureInlineBotButtons();
Calendar rightNow = new GregorianCalendar();
rightNow.setTimeInMillis((long) (messageOwner.date) * 1000);
@ -417,11 +365,7 @@ public class MessageObject {
int dateYear = rightNow.get(Calendar.YEAR);
int dateMonth = rightNow.get(Calendar.MONTH);
dateKey = String.format("%d_%02d_%02d", dateYear, dateMonth, dateDay);
if (contentType == 2 || contentType == 0 || contentType == 8) {
monthKey = String.format("%d_%02d", dateYear, dateMonth);
} else if (contentType == 9) {
//dateKey = "0_0_0";
}
monthKey = String.format("%d_%02d", dateYear, dateMonth);
if (messageOwner.message != null && messageOwner.id < 0 && messageOwner.message.length() > 6 && isVideo()) {
videoEditedInfo = new VideoEditedInfo();
@ -435,13 +379,14 @@ public class MessageObject {
}
layoutCreated = generateLayout;
generateThumbs(false);
checkMediaExistance();
}
public static TextPaint getTextPaint() {
if (textPaint == null) {
textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
textPaint.setColor(0xff000000);
textPaint.linkColor = 0xff316f9f;
textPaint.setColor(Theme.MSG_TEXT_COLOR);
textPaint.linkColor = Theme.MSG_LINK_TEXT_COLOR;
textPaint.setTextSize(AndroidUtilities.dp(MessagesController.getInstance().fontSize));
}
return textPaint;
@ -482,6 +427,7 @@ public class MessageObject {
if (mess.length() > 20) {
mess = mess.subSequence(0, 20) + "...";
}
mess = Emoji.replaceEmoji(mess, textPaint.getFontMetricsInt(), AndroidUtilities.dp(20), false);
messageText = replaceWithLink(LocaleController.formatString("ActionPinnedText", R.string.ActionPinnedText, mess), "un1", fromUser != null ? fromUser : chat);
} else {
messageText = replaceWithLink(LocaleController.getString("ActionPinnedNoText", R.string.ActionPinnedNoText), "un1", fromUser != null ? fromUser : chat);
@ -489,6 +435,86 @@ public class MessageObject {
}
}
private void measureInlineBotButtons() {
wantedBotKeyboardWidth = 0;
if (!(messageOwner.reply_markup instanceof TLRPC.TL_replyInlineMarkup)) {
return;
}
if (botButtonPaint == null) {
botButtonPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
botButtonPaint.setTextSize(AndroidUtilities.dp(15));
botButtonPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
}
for (int a = 0; a < messageOwner.reply_markup.rows.size(); a++) {
TLRPC.TL_keyboardButtonRow row = messageOwner.reply_markup.rows.get(a);
int maxButtonSize = 0;
int size = row.buttons.size();
for (int b = 0; b < size; b++) {
CharSequence text = Emoji.replaceEmoji(row.buttons.get(b).text, botButtonPaint.getFontMetricsInt(), AndroidUtilities.dp(15), false);
StaticLayout staticLayout = new StaticLayout(text, botButtonPaint, AndroidUtilities.dp(2000), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
if (staticLayout.getLineCount() > 0) {
maxButtonSize = Math.max(maxButtonSize, (int) Math.ceil(staticLayout.getLineWidth(0) - staticLayout.getLineLeft(0)) + AndroidUtilities.dp(4));
}
}
wantedBotKeyboardWidth = Math.max(wantedBotKeyboardWidth, (maxButtonSize + AndroidUtilities.dp(12)) * size + AndroidUtilities.dp(5) * (size - 1));
}
}
public void setType() {
if (messageOwner instanceof TLRPC.TL_message || messageOwner instanceof TLRPC.TL_messageForwarded_old2) {
if (isMediaEmpty()) {
type = 0;
if (messageText == null || messageText.length() == 0) {
messageText = "Empty message";
}
} else if (messageOwner.media instanceof TLRPC.TL_messageMediaPhoto) {
type = 1;
} else if (messageOwner.media instanceof TLRPC.TL_messageMediaGeo || messageOwner.media instanceof TLRPC.TL_messageMediaVenue) {
type = 4;
} else if (isVideo()) {
type = 3;
} else if (isVoice()) {
type = 2;
} else if (isMusic()) {
type = 14;
} else if (messageOwner.media instanceof TLRPC.TL_messageMediaContact) {
type = 12;
} else if (messageOwner.media instanceof TLRPC.TL_messageMediaUnsupported) {
type = 0;
} else if (messageOwner.media instanceof TLRPC.TL_messageMediaDocument) {
if (messageOwner.media.document.mime_type != null) {
if (isGifDocument(messageOwner.media.document)) {
type = 8;
} else if (messageOwner.media.document.mime_type.equals("image/webp") && isSticker()) {
type = 13;
} else {
type = 9;
}
} else {
type = 9;
}
}
} else if (messageOwner instanceof TLRPC.TL_messageService) {
if (messageOwner.action instanceof TLRPC.TL_messageActionLoginUnknownLocation) {
type = 0;
} else if (messageOwner.action instanceof TLRPC.TL_messageActionChatEditPhoto || messageOwner.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) {
contentType = 1;
type = 11;
} else if (messageOwner.action instanceof TLRPC.TL_messageEncryptedAction) {
if (messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionScreenshotMessages || messageOwner.action.encryptedAction instanceof TLRPC.TL_decryptedMessageActionSetMessageTTL) {
contentType = 1;
type = 10;
} else {
contentType = -1;
type = -1;
}
} else {
contentType = 1;
type = 10;
}
}
}
public void checkLayout() {
if (!layoutCreated) {
layoutCreated = true;
@ -564,6 +590,8 @@ public class MessageObject {
} else if (photoThumbs != null && !photoThumbs.isEmpty() && messageOwner.media.document.thumb != null) {
TLRPC.PhotoSize photoObject = photoThumbs.get(0);
photoObject.location = messageOwner.media.document.thumb.location;
photoObject.w = messageOwner.media.document.thumb.w;
photoObject.h = messageOwner.media.document.thumb.h;
}
}
} else if (messageOwner.media instanceof TLRPC.TL_messageMediaWebPage) {
@ -585,6 +613,16 @@ public class MessageObject {
}
}
}
} else if (messageOwner.media.webpage.document != null) {
if (!(messageOwner.media.webpage.document.thumb instanceof TLRPC.TL_photoSizeEmpty)) {
if (!update) {
photoThumbs = new ArrayList<>();
photoThumbs.add(messageOwner.media.webpage.document.thumb);
} else if (photoThumbs != null && !photoThumbs.isEmpty() && messageOwner.media.webpage.document.thumb != null) {
TLRPC.PhotoSize photoObject = photoThumbs.get(0);
photoObject.location = messageOwner.media.webpage.document.thumb.location;
}
}
}
}
}
@ -641,7 +679,7 @@ public class MessageObject {
public String getExtension() {
String fileName = getFileName();
int idx = fileName.lastIndexOf(".");
int idx = fileName.lastIndexOf('.');
String ext = null;
if (idx != -1) {
ext = fileName.substring(idx + 1);
@ -1251,6 +1289,18 @@ public class MessageObject {
return false;
}
public static boolean isMusicDocument(TLRPC.Document document) {
if (document != null) {
for (int a = 0; a < document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeAudio) {
return !attribute.voice;
}
}
}
return false;
}
public static boolean isVideoDocument(TLRPC.Document document) {
if (document != null) {
boolean isAnimated = false;
@ -1268,29 +1318,36 @@ public class MessageObject {
return false;
}
public TLRPC.Document getDocument() {
if (messageOwner.media instanceof TLRPC.TL_messageMediaWebPage) {
return messageOwner.media.webpage.document;
}
return messageOwner.media != null ? messageOwner.media.document : null;
}
public static boolean isStickerMessage(TLRPC.Message message) {
return message.media != null && message.media.document != null && isStickerDocument(message.media.document);
}
public static boolean isMusicMessage(TLRPC.Message message) {
if (message.media != null && message.media.document != null) {
for (int a = 0; a < message.media.document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = message.media.document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeAudio) {
return !attribute.voice;
}
}
if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
return isMusicDocument(message.media.webpage.document);
}
return false;
return message.media != null && message.media.document != null && isMusicDocument(message.media.document);
}
public static boolean isVoiceMessage(TLRPC.Message message) {
if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
return isVoiceDocument(message.media.webpage.document);
}
return message.media != null && message.media.document != null && isVoiceDocument(message.media.document);
}
public static boolean isVideoMessage(TLRPC.Message message) {
if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
return isVideoDocument(message.media.webpage.document);
}
return message.media != null && message.media.document != null && isVideoDocument(message.media.document);
/* && message.media.document.mime_type.equals("video/mp4")*/
}
public static TLRPC.InputStickerSet getInputStickerSet(TLRPC.Message message) {
@ -1320,17 +1377,25 @@ public class MessageObject {
public int getApproximateHeight() {
if (type == 0) {
return textHeight;
} else if (contentType == 2) {
return AndroidUtilities.dp(68);
} else if (contentType == 3) {
int height = textHeight + (messageOwner.media instanceof TLRPC.TL_messageMediaWebPage && messageOwner.media.webpage instanceof TLRPC.TL_webPage ? AndroidUtilities.dp(100) : 0);
if (isReply()) {
height += AndroidUtilities.dp(42);
}
return height;
} else if (type == 2) {
return AndroidUtilities.dp(72);
} else if (type == 12) {
return AndroidUtilities.dp(71);
} else if (type == 9) {
return AndroidUtilities.dp(100);
} else if (type == 4) {
return AndroidUtilities.dp(114);
} else if (type == 14) {
return AndroidUtilities.dp(78);
return AndroidUtilities.dp(82);
} else if (type == 10) {
return AndroidUtilities.dp(30);
} else if (type == 11) {
return AndroidUtilities.dp(50);
} else if (type == 13) {
float maxHeight = AndroidUtilities.displaySize.y * 0.4f;
float maxWidth;
@ -1403,6 +1468,9 @@ public class MessageObject {
}
public boolean isSticker() {
if (type != 1000) {
return type == 13;
}
return isStickerMessage(messageOwner);
}
@ -1431,15 +1499,21 @@ public class MessageObject {
}
public String getMusicTitle() {
for (int a = 0; a < messageOwner.media.document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = messageOwner.media.document.attributes.get(a);
TLRPC.Document document;
if (type == 0) {
document = messageOwner.media.webpage.document;
} else {
document = messageOwner.media.document;
}
for (int a = 0; a < document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeAudio) {
if (attribute.voice) {
return LocaleController.formatDateAudio(messageOwner.date);
}
String title = attribute.title;
if (title == null || title.length() == 0) {
title = FileLoader.getDocumentFileName(messageOwner.media.document);
title = FileLoader.getDocumentFileName(document);
if (title == null || title.length() == 0) {
title = LocaleController.getString("AudioUnknownTitle", R.string.AudioUnknownTitle);
}
@ -1451,8 +1525,14 @@ public class MessageObject {
}
public String getMusicAuthor() {
for (int a = 0; a < messageOwner.media.document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = messageOwner.media.document.attributes.get(a);
TLRPC.Document document;
if (type == 0) {
document = messageOwner.media.webpage.document;
} else {
document = messageOwner.media.document;
}
for (int a = 0; a < document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeAudio) {
if (attribute.voice) {
if (isOutOwner() || messageOwner.fwd_from != null && messageOwner.fwd_from.from_id == UserConfig.getClientUserId()) {
@ -1514,14 +1594,21 @@ public class MessageObject {
}
public static boolean canEditMessage(TLRPC.Message message, TLRPC.Chat chat) {
if (message == null || message.to_id == null || message.to_id.channel_id == 0 || message.action != null && !(message.action instanceof TLRPC.TL_messageActionEmpty) || isForwardedMessage(message) || message.via_bot_id != 0 || message.id < 0 || Math.abs(message.date - ConnectionsManager.getInstance().getCurrentTime()) > MessagesController.getInstance().maxEditTime) {
if (message == null || message.to_id == null || message.action != null && !(message.action instanceof TLRPC.TL_messageActionEmpty) || isForwardedMessage(message) || message.via_bot_id != 0 || message.id < 0 || Math.abs(message.date - ConnectionsManager.getInstance().getCurrentTime()) > MessagesController.getInstance().maxEditTime) {
return false;
}
if (message.to_id.channel_id == 0) {
return message.out && (message.media instanceof TLRPC.TL_messageMediaPhoto ||
message.media instanceof TLRPC.TL_messageMediaDocument && (isVideoMessage(message) || isGifDocument(message.media.document)) ||
message.media instanceof TLRPC.TL_messageMediaEmpty ||
message.media instanceof TLRPC.TL_messageMediaWebPage ||
message.media == null);
}
if (chat == null && message.to_id.channel_id != 0) {
chat = MessagesController.getInstance().getChat(message.to_id.channel_id);
}
if (chat == null) {
return false;
if (chat == null) {
return false;
}
}
if (chat.megagroup && message.out || !chat.megagroup && (chat.creator || chat.editor && isOut(message)) && isImportant(message)) {
if (message.media instanceof TLRPC.TL_messageMediaPhoto ||
@ -1583,4 +1670,35 @@ public class MessageObject {
}
return null;
}
public void checkMediaExistance() {
File cacheFile = null;
if (type == 1) {
TLRPC.PhotoSize currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(photoThumbs, AndroidUtilities.getPhotoSize());
if (currentPhotoObject != null) {
mediaExists = FileLoader.getPathToMessage(messageOwner).exists();
}
} else if (type == 8 || type == 3 || type == 9 || type == 2 || type == 14) {
if (messageOwner.attachPath != null && messageOwner.attachPath.length() > 0) {
File f = new File(messageOwner.attachPath);
attachPathExists = f.exists();
}
if (!attachPathExists) {
mediaExists = FileLoader.getPathToMessage(messageOwner).exists();
}
} else {
TLRPC.Document document = getDocument();
if (document != null) {
mediaExists = FileLoader.getPathToAttach(document).exists();
} else if (type == 0) {
TLRPC.PhotoSize currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(photoThumbs, AndroidUtilities.getPhotoSize());
if (currentPhotoObject == null) {
return;
}
if (currentPhotoObject != null) {
mediaExists = FileLoader.getPathToAttach(currentPhotoObject, true).exists();
}
}
}
}
}

View File

@ -629,20 +629,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
if (user.min) {
if (oldUser != null) {
if (!fromCache) {
if (user.first_name != null) {
oldUser.first_name = user.first_name;
oldUser.flags |= 2;
} else {
oldUser.first_name = null;
oldUser.flags = oldUser.flags &~ 2;
}
if (user.last_name != null) {
oldUser.last_name = user.last_name;
oldUser.flags |= 4;
} else {
oldUser.last_name = null;
oldUser.flags = oldUser.flags &~ 4;
}
if (user.username != null) {
oldUser.username = user.username;
oldUser.flags |= 8;
@ -675,20 +661,6 @@ public class MessagesController implements NotificationCenter.NotificationCenter
users.put(user.id, user);
} else if (oldUser.min) {
user.min = false;
if (oldUser.first_name != null) {
user.first_name = oldUser.first_name;
user.flags |= 2;
} else {
user.first_name = null;
user.flags = user.flags &~ 2;
}
if (oldUser.last_name != null) {
user.last_name = oldUser.last_name;
user.flags |= 4;
} else {
user.last_name = null;
user.flags = user.flags &~ 4;
}
if (oldUser.username != null) {
user.username = oldUser.username;
user.flags |= 8;
@ -2029,13 +2001,20 @@ public class MessagesController implements NotificationCenter.NotificationCenter
if (user == null) {
return;
}
if (pu.action instanceof TLRPC.TL_sendMessageUploadAudioAction || pu.action instanceof TLRPC.TL_sendMessageRecordAudioAction) {
if (pu.action instanceof TLRPC.TL_sendMessageRecordAudioAction) {
if (lower_id < 0) {
newPrintingStrings.put(key, LocaleController.formatString("IsRecordingAudio", R.string.IsRecordingAudio, getUserNameForTyping(user)));
} else {
newPrintingStrings.put(key, LocaleController.getString("RecordingAudio", R.string.RecordingAudio));
}
newPrintingStringsTypes.put(key, 1);
} else if (pu.action instanceof TLRPC.TL_sendMessageUploadAudioAction) {
if (lower_id < 0) {
newPrintingStrings.put(key, LocaleController.formatString("IsSendingAudio", R.string.IsSendingAudio, getUserNameForTyping(user)));
} else {
newPrintingStrings.put(key, LocaleController.getString("SendingAudio", R.string.SendingAudio));
}
newPrintingStringsTypes.put(key, 2);
} else if (pu.action instanceof TLRPC.TL_sendMessageUploadVideoAction || pu.action instanceof TLRPC.TL_sendMessageRecordVideoAction) {
if (lower_id < 0) {
newPrintingStrings.put(key, LocaleController.formatString("IsSendingVideo", R.string.IsSendingVideo, getUserNameForTyping(user)));
@ -2213,6 +2192,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 important, final int loadIndex, final int first_unread, final int unread_count, final int last_date, final boolean queryFromServer) {
FileLog.e("tmessages", "load messages in chat " + dialog_id + " count " + count + " max_id " + max_id + " cache " + fromCache + " mindate = " + midDate + " guid " + classGuid + " load_type " + load_type + " last_message_id " + last_message_id + " imp " + important + " index " + loadIndex + " firstUnread " + first_unread + " underad count " + unread_count + " last_date " + last_date + " queryFromServer " + queryFromServer);
int lower_part = (int) dialog_id;
if (fromCache || lower_part == 0) {
MessagesStorage.getInstance().getMessages(dialog_id, count, max_id, midDate, classGuid, load_type, important, loadIndex);
@ -2323,6 +2303,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
public void processLoadedMessages(final TLRPC.messages_Messages messagesRes, final long dialog_id, final int count, final int max_id, final boolean isCache, final int classGuid,
final int first_unread, final int last_message_id, final int unread_count, final int last_date, final int load_type, final int important, final boolean isEnd, final int loadIndex, final boolean queryFromServer) {
FileLog.e("tmessages", "processLoadedMessages size " + messagesRes.messages.size() + " in chat " + dialog_id + " count " + count + " max_id " + max_id + " cache " + isCache + " guid " + classGuid + " load_type " + load_type + " last_message_id " + last_message_id + " imp " + important + " index " + loadIndex + " firstUnread " + first_unread + " underad count " + unread_count + " last_date " + last_date + " queryFromServer " + queryFromServer);
Utilities.stageQueue.postRunnable(new Runnable() {
@Override
public void run() {
@ -2998,7 +2979,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
MessagesStorage.getInstance().setDialogFlags(dialog_id, ((long) until << 32) | 1);
NotificationsController.getInstance().removeNotificationsForDialog(dialog_id);
} else {
if (currentValue != 0) {
if (currentValue != 0 && currentValue != 1) {
updated = true;
if (dialog != null) {
dialog.notify_settings.mute_until = 0;
@ -4172,7 +4153,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
TLRPC.TL_help_getAppChangelog req = new TLRPC.TL_help_getAppChangelog();
req.app_version = BuildVars.BUILD_VERSION_STRING;
try {
req.lang_code = LocaleController.getLocaleString(LocaleController.getInstance().getSystemDefaultLocale());
req.lang_code = LocaleController.getLocaleStringIso639();
req.device_model = Build.MANUFACTURER + Build.MODEL;
req.system_version = "SDK " + Build.VERSION.SDK_INT;
} catch (Exception e) {
@ -4221,7 +4202,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
req.token = regid;
req.app_sandbox = false;
try {
req.lang_code = LocaleController.getLocaleString(LocaleController.getInstance().getSystemDefaultLocale());
req.lang_code = LocaleController.getLocaleStringIso639();
if (req.lang_code.length() == 0) {
req.lang_code = "en";
}
@ -4250,25 +4231,23 @@ public class MessagesController implements NotificationCenter.NotificationCenter
req.system_version = "SDK Unknown";
}
if (req.app_version != null) {
ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
@Override
public void run(TLObject response, TLRPC.TL_error error) {
if (response instanceof TLRPC.TL_boolTrue) {
FileLog.e("tmessages", "registered for push");
UserConfig.registeredForPush = true;
UserConfig.pushString = regid;
UserConfig.saveConfig(false);
}
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
registeringForPush = false;
}
});
ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
@Override
public void run(TLObject response, TLRPC.TL_error error) {
if (response instanceof TLRPC.TL_boolTrue) {
FileLog.e("tmessages", "registered for push");
UserConfig.registeredForPush = true;
UserConfig.pushString = regid;
UserConfig.saveConfig(false);
}
});
}
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
registeringForPush = false;
}
});
}
});
}
public void loadCurrentState() {
@ -4848,6 +4827,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
public void run() {
MessagesStorage.getInstance().putUsersAndChats(res.users, res.chats, true, false);
if (!msgUpdates.isEmpty()) {
final HashMap<Integer, long[]> corrected = new HashMap<>();
for (TLRPC.TL_updateMessageID update : msgUpdates) {
@ -4953,10 +4933,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
});
}
MessagesStorage.getInstance().startTransaction(false);
MessagesStorage.getInstance().putMessages(res.new_messages, false, false, false, MediaController.getInstance().getAutodownloadMask());
MessagesStorage.getInstance().putUsersAndChats(res.users, res.chats, false, false);
MessagesStorage.getInstance().commitTransaction(false);
MessagesStorage.getInstance().putMessages(res.new_messages, true, false, false, MediaController.getInstance().getAutodownloadMask());
}
});
@ -4991,8 +4968,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
}
MessagesStorage.getInstance().saveDiffParams(MessagesStorage.lastSeqValue, MessagesStorage.lastPtsValue, MessagesStorage.lastDateValue, MessagesStorage.lastQtsValue);
FileLog.e("tmessages", "received difference with date = " + MessagesStorage.lastDateValue + " pts = " + MessagesStorage.lastPtsValue + " seq = " + MessagesStorage.lastSeqValue);
FileLog.e("tmessages", "messages = " + res.new_messages.size() + " users = " + res.users.size() + " chats = " + res.chats.size() + " other updates = " + res.other_updates.size());
FileLog.e("tmessages", "received difference with date = " + MessagesStorage.lastDateValue + " pts = " + MessagesStorage.lastPtsValue + " seq = " + MessagesStorage.lastSeqValue + " messages = " + res.new_messages.size() + " users = " + res.users.size() + " chats = " + res.chats.size() + " other updates = " + res.other_updates.size());
}
});
}
@ -5147,7 +5123,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter
private int getUpdateType(TLRPC.Update update) {
if (update instanceof TLRPC.TL_updateNewMessage || update instanceof TLRPC.TL_updateReadMessagesContents || update instanceof TLRPC.TL_updateReadHistoryInbox ||
update instanceof TLRPC.TL_updateReadHistoryOutbox || update instanceof TLRPC.TL_updateDeleteMessages || update instanceof TLRPC.TL_updateWebPage) {
update instanceof TLRPC.TL_updateReadHistoryOutbox || update instanceof TLRPC.TL_updateDeleteMessages || update instanceof TLRPC.TL_updateWebPage ||
update instanceof TLRPC.TL_updateEditMessage) {
return 0;
} else if (update instanceof TLRPC.TL_updateNewEncryptedMessage) {
return 1;
@ -5174,8 +5151,11 @@ public class MessagesController implements NotificationCenter.NotificationCenter
TLRPC.User user3 = null;
TLRPC.Chat channel = null;
if (user == null) {
if (user == null || user.min) { //TODO
user = MessagesStorage.getInstance().getUserSync(user_id);
if (user != null && user.min) {
user = null;
}
putUser(user, true);
}
@ -5646,7 +5626,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter
ConcurrentHashMap<Integer, TLRPC.Chat> chatsDict;
if (usersArr != null) {
usersDict = new ConcurrentHashMap<>();
for (TLRPC.User user : usersArr) {
for (int a = 0; a < usersArr.size(); a++) {
TLRPC.User user = usersArr.get(a);
usersDict.put(user.id, user);
}
} else {
@ -5655,7 +5636,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
if (chatsArr != null) {
chatsDict = new ConcurrentHashMap<>();
for (TLRPC.Chat chat : chatsArr) {
for (int a = 0; a < chatsArr.size(); a++) {
TLRPC.Chat chat = chatsArr.get(a);
chatsDict.put(chat.id, chat);
}
} else {
@ -5683,14 +5665,20 @@ public class MessagesController implements NotificationCenter.NotificationCenter
message = ((TLRPC.TL_updateNewMessage) update).message;
} else {
message = ((TLRPC.TL_updateNewChannelMessage) update).message;
if (!message.out && message.from_id == UserConfig.getClientUserId()) { //TODO remove later
message.out = true;
}
}
TLRPC.Chat chat = null;
if (checkForUsers) {
int chat_id = 0;
int user_id = 0;
if (message.to_id.channel_id != 0) {
chat_id = message.to_id.channel_id;
} else if (message.to_id.chat_id != 0) {
chat_id = message.to_id.chat_id;
} else if (message.to_id.user_id != 0) {
user_id = message.to_id.user_id;
}
if (chat_id != 0) {
chat = chatsDict.get(chat_id);
@ -5708,14 +5696,30 @@ public class MessagesController implements NotificationCenter.NotificationCenter
message.flags |= TLRPC.MESSAGE_FLAG_MEGAGROUP;
}
}
if (message.from_id > 0) {
TLRPC.User user = getUser(message.from_id);
if (usersDict.get(message.from_id) == null && user == null) {
return false;
for (int a = 0; a < 3; a++) {
if (a != 0) {
user_id = a == 1 ? message.from_id : (message.fwd_from != null ? message.fwd_from.from_id : 0);
}
if (user != null && user.status != null && user.status.expires <= 0) {
onlinePrivacy.put(message.from_id, ConnectionsManager.getInstance().getCurrentTime());
interfaceUpdateMask |= UPDATE_MASK_STATUS;
if (user_id > 0) {
TLRPC.User user = usersDict.get(user_id);
if (user == null || user.min) {
user = getUser(user_id);
}
if (user == null || user.min) {
user = MessagesStorage.getInstance().getUserSync(user_id);
if (user != null && user.min) {
user = null;
}
putUser(user, true);
}
if (user == null) {
return false;
}
if (a == 1 && user.status != null && user.status.expires <= 0) {
onlinePrivacy.put(user_id, ConnectionsManager.getInstance().getCurrentTime());
interfaceUpdateMask |= UPDATE_MASK_STATUS;
}
}
}
}
@ -6103,12 +6107,13 @@ public class MessagesController implements NotificationCenter.NotificationCenter
} else if (update instanceof TLRPC.TL_updateChannel) {
updatesOnMainThread.add(update);
} else if (update instanceof TLRPC.TL_updateChannelMessageViews) {
TLRPC.TL_updateChannelMessageViews updateChannelMessageViews = (TLRPC.TL_updateChannelMessageViews) update;
SparseIntArray array = channelViews.get(update.channel_id);
if (array == null) {
array = new SparseIntArray();
channelViews.put(update.channel_id, array);
}
array.put(update.id, update.views);
array.put(updateChannelMessageViews.id, update.views);
} else if (update instanceof TLRPC.TL_updateChatParticipantAdmin) {
MessagesStorage.getInstance().updateChatInfo(update.chat_id, update.user_id, 2, update.is_admin ? 1 : 0, update.version);
} else if (update instanceof TLRPC.TL_updateChatAdmins) {
@ -6121,8 +6126,13 @@ public class MessagesController implements NotificationCenter.NotificationCenter
updatesOnMainThread.add(update);
} else if (update instanceof TLRPC.TL_updateSavedGifs) {
updatesOnMainThread.add(update);
} else if (update instanceof TLRPC.TL_updateEditChannelMessage) {
TLRPC.Message message = ((TLRPC.TL_updateEditChannelMessage) update).message;
} else if (update instanceof TLRPC.TL_updateEditChannelMessage || update instanceof TLRPC.TL_updateEditMessage) {
TLRPC.Message message;
if (update instanceof TLRPC.TL_updateEditChannelMessage) {
message = ((TLRPC.TL_updateEditChannelMessage) update).message;
} else {
message = ((TLRPC.TL_updateEditMessage) update).message;
}
if (message.to_id.channel_id != 0 && !message.out) {
message.unread = true;
if (message.post || (message.flags & TLRPC.MESSAGE_FLAG_MEGAGROUP) != 0) {
@ -6130,14 +6140,16 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
}
long dialog_id = -update.channel_id;
Integer value = dialogs_read_inbox_max.get(dialog_id);
if (value == null) {
value = MessagesStorage.getInstance().getChannelReadInboxMax(update.channel_id);
}
if (value >= message.id) {
message.unread = false;
message.media_unread = false;
if (update instanceof TLRPC.TL_updateEditChannelMessage) {
long dialog_id = -update.channel_id;
Integer value = dialogs_read_inbox_max.get(dialog_id);
if (value == null) {
value = MessagesStorage.getInstance().getChannelReadInboxMax(update.channel_id);
}
if (value >= message.id) {
message.unread = false;
message.media_unread = false;
} //TODO unread for updateEditMessage?
}
ImageLoader.saveMessageThumbs(message);
@ -6161,7 +6173,8 @@ public class MessagesController implements NotificationCenter.NotificationCenter
}
arr.add(obj);
} else if (update instanceof TLRPC.TL_updateChannelPinnedMessage) {
MessagesStorage.getInstance().updateChannelPinnedMessage(update.channel_id, update.id);
TLRPC.TL_updateChannelPinnedMessage updateChannelPinnedMessage = (TLRPC.TL_updateChannelPinnedMessage) update;
MessagesStorage.getInstance().updateChannelPinnedMessage(update.channel_id, updateChannelPinnedMessage.id);
}
}
if (!messages.isEmpty()) {
@ -6839,10 +6852,15 @@ public class MessagesController implements NotificationCenter.NotificationCenter
return;
}
String reason = null;
boolean closeLast = false;
if (chat != null) {
reason = getRestrictionReason(chat.restriction_reason);
} else if (user != null) {
reason = getRestrictionReason(user.restriction_reason);
if (user.bot) {
type = 1;
closeLast = true;
}
}
if (reason != null) {
showCantOpenAlert(fragment, reason);
@ -6856,7 +6874,7 @@ public class MessagesController implements NotificationCenter.NotificationCenter
if (type == 0) {
fragment.presentFragment(new ProfileActivity(args));
} else {
fragment.presentFragment(new ChatActivity(args)/*, fragment instanceof ChatActivity*/);
fragment.presentFragment(new ChatActivity(args), closeLast);
}
}
}

View File

@ -423,7 +423,7 @@ public class MessagesStorage {
while (cursor.next()) {
int chat_id = cursor.intValue(0);
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(1));
if (data != null && cursor.byteBufferValue(1, data) != 0) {
if (cursor.byteBufferValue(1, data) != 0) {
TLRPC.ChatParticipants participants = TLRPC.ChatParticipants.TLdeserialize(data, data.readInt32(false), false);
if (participants != null) {
TLRPC.TL_chatFull chatFull = new TLRPC.TL_chatFull();
@ -663,7 +663,7 @@ public class MessagesStorage {
cursor = database.queryFinalized("SELECT read_state, data, send_state, mid, date, uid FROM messages WHERE uid IN (" + ids.toString() + ") AND out = 0 AND read_state IN(0,2) ORDER BY date DESC LIMIT 50");
while (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(1));
if (data != null && cursor.byteBufferValue(1, data) != 0) {
if (cursor.byteBufferValue(1, data) != 0) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
MessageObject.setUnreadFlags(message, cursor.intValue(0));
message.id = cursor.intValue(3);
@ -793,7 +793,7 @@ public class MessagesStorage {
searchImage.date = cursor.intValue(7);
if (!cursor.isNull(8)) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(8));
if (data != null && cursor.byteBufferValue(8, data) != 0) {
if (cursor.byteBufferValue(8, data) != 0) {
searchImage.document = TLRPC.Document.TLdeserialize(data, data.readInt32(false), false);
}
data.reuse();
@ -937,7 +937,7 @@ public class MessagesStorage {
final ArrayList<TLRPC.WallPaper> wallPapers = new ArrayList<>();
while (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
if (cursor.byteBufferValue(0, data) != 0) {
TLRPC.WallPaper wallPaper = TLRPC.WallPaper.TLdeserialize(data, data.readInt32(false), false);
wallPapers.add(wallPaper);
}
@ -1040,7 +1040,7 @@ public class MessagesStorage {
try {
while (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
if (cursor.byteBufferValue(0, data) != 0) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
if (message != null && message.from_id == uid && message.id != 1) {
mids.add(message.id);
@ -1104,7 +1104,7 @@ public class MessagesStorage {
try {
while (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
if (cursor.byteBufferValue(0, data) != 0) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
if (message != null && message.media != null) {
if (message.media instanceof TLRPC.TL_messageMediaPhoto) {
@ -1163,7 +1163,7 @@ public class MessagesStorage {
try {
while (cursor2.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor2.byteArrayLength(0));
if (data != null && cursor2.byteBufferValue(0, data) != 0) {
if (cursor2.byteBufferValue(0, data) != 0) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
if (message != null) {
arrayList.add(message);
@ -1240,7 +1240,7 @@ public class MessagesStorage {
while (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
if (cursor.byteBufferValue(0, data) != 0) {
TLRPC.Photo photo = TLRPC.Photo.TLdeserialize(data, data.readInt32(false), false);
res.photos.add(photo);
}
@ -1514,7 +1514,7 @@ public class MessagesStorage {
ArrayList<TLRPC.User> loadedUsers = new ArrayList<>();
if (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
if (cursor.byteBufferValue(0, data) != 0) {
info = TLRPC.ChatFull.TLdeserialize(data, data.readInt32(false), false);
info.pinned_msg_id = cursor.intValue(1);
}
@ -1696,7 +1696,7 @@ public class MessagesStorage {
ArrayList<TLRPC.User> loadedUsers = new ArrayList<>();
if (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
if (cursor.byteBufferValue(0, data) != 0) {
info = TLRPC.ChatFull.TLdeserialize(data, data.readInt32(false), false);
info.pinned_msg_id = cursor.intValue(1);
}
@ -1783,7 +1783,7 @@ public class MessagesStorage {
ArrayList<TLRPC.User> loadedUsers = new ArrayList<>();
if (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
if (cursor.byteBufferValue(0, data) != 0) {
info = TLRPC.ChatFull.TLdeserialize(data, data.readInt32(false), false);
}
data.reuse();
@ -1814,13 +1814,14 @@ public class MessagesStorage {
storageQueue.postRunnable(new Runnable() {
@Override
public void run() {
MessageObject pinnedMessageObject = null;
TLRPC.ChatFull info = null;
ArrayList<TLRPC.User> loadedUsers = new ArrayList<>();
try {
SQLiteCursor cursor = database.queryFinalized("SELECT info, pinned FROM chat_settings_v2 WHERE uid = " + chat_id);
TLRPC.ChatFull info = null;
ArrayList<TLRPC.User> loadedUsers = new ArrayList<>();
if (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
if (cursor.byteBufferValue(0, data) != 0) {
info = TLRPC.ChatFull.TLdeserialize(data, data.readInt32(false), false);
info.pinned_msg_id = cursor.intValue(1);
}
@ -1847,7 +1848,7 @@ public class MessagesStorage {
try {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
NativeByteBuffer data2 = new NativeByteBuffer(cursor.byteArrayLength(2));
if (data != null && cursor.byteBufferValue(0, data) != 0 && data2 != null && cursor.byteBufferValue(2, data2) != 0) {
if (cursor.byteBufferValue(0, data) != 0 && cursor.byteBufferValue(2, data2) != 0) {
TLRPC.User user = TLRPC.User.TLdeserialize(data, data.readInt32(false), false);
TLRPC.ChannelParticipant participant = TLRPC.ChannelParticipant.TLdeserialize(data2, data2.readInt32(false), false);
if (user != null && participant != null) {
@ -1886,15 +1887,13 @@ public class MessagesStorage {
if (semaphore != null) {
semaphore.release();
}
MessageObject pinnedMessageObject = null;
if (info instanceof TLRPC.TL_channelFull && info.pinned_msg_id != 0) {
pinnedMessageObject = MessagesQuery.loadPinnedMessage(chat_id, info.pinned_msg_id, false);
}
MessagesController.getInstance().processChatInfo(chat_id, info, loadedUsers, true, force, byChannelUsers, pinnedMessageObject);
} catch (Exception e) {
FileLog.e("tmessages", e);
} finally {
MessagesController.getInstance().processChatInfo(chat_id, info, loadedUsers, true, force, byChannelUsers, pinnedMessageObject);
if (semaphore != null) {
semaphore.release();
}
@ -2162,7 +2161,7 @@ public class MessagesStorage {
SQLiteCursor cursor = database.queryFinalized("SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.uid, s.seq_in, s.seq_out, m.ttl FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid LEFT JOIN messages_seq as s ON m.mid = s.mid WHERE m.mid < 0 AND m.send_state = 1 ORDER BY m.mid DESC LIMIT " + count);
while (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(1));
if (data != null && cursor.byteBufferValue(1, data) != 0) {
if (cursor.byteBufferValue(1, data) != 0) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
if (!messageHashMap.containsKey(message.id)) {
MessageObject.setUnreadFlags(message, cursor.intValue(0));
@ -2306,6 +2305,7 @@ public class MessagesStorage {
messageMaxId |= ((long) channelId) << 32;
}
boolean isEnd = false;
int num = dialog_id == 777000 ? 4 : 1;
try {
ArrayList<Integer> usersToLoad = new ArrayList<>();
ArrayList<Integer> chatsToLoad = new ArrayList<>();
@ -2346,12 +2346,26 @@ public class MessagesStorage {
}
cursor.dispose();
}
} else if (max_id_query == 0) {
int existingUnreadCount = 0;
cursor = database.queryFinalized(String.format(Locale.US, "SELECT COUNT(*) FROM messages WHERE uid = %d AND mid > 0 " + imp + "AND out = 0 AND read_state IN(0,2)", dialog_id));
if (cursor.next()) {
existingUnreadCount = cursor.intValue(0);
}
cursor.dispose();
if (existingUnreadCount == count_unread) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT min(mid) FROM messages WHERE uid = %d AND out = 0 AND read_state IN(0,2) AND mid > 0" + imp, dialog_id));
if (cursor.next()) {
messageMaxId = max_id_query = min_unread_id = cursor.intValue(0);
}
cursor.dispose();
}
}
}
if (count_query > count_unread || count_unread < 4) {
if (count_query > count_unread || count_unread < num) {
count_query = Math.max(count_query, count_unread + 10);
if (count_unread < 4) {
if (count_unread < num) {
count_unread = 0;
min_unread_id = 0;
messageMaxId = 0;
@ -2393,12 +2407,14 @@ public class MessagesStorage {
}
cursor.dispose();
boolean containMessage = true;
cursor = database.queryFinalized(String.format(Locale.US, "SELECT start FROM " + holesTable + " WHERE uid = %d AND start < %d AND end > %d", dialog_id, max_id_query, max_id_query));
if (cursor.next()) {
containMessage = false;
boolean containMessage = max_id_query != 0;
if (containMessage) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT start FROM " + holesTable + " WHERE uid = %d AND start < %d AND end > %d", dialog_id, max_id_query, max_id_query));
if (cursor.next()) {
containMessage = false;
}
cursor.dispose();
}
cursor.dispose();
if (containMessage) {
long holeMessageMaxId = 0;
@ -2430,11 +2446,11 @@ public class MessagesStorage {
holeMessageMaxId |= ((long) channelId) << 32;
}
}
cursor = database.queryFinalized(String.format(Locale.US, "SELECT * FROM (SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid <= %d AND m.mid >= %d " + imp + "ORDER BY m.date DESC, m.mid DESC LIMIT %d) UNION " +
"SELECT * FROM (SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid > %d AND m.mid <= %d " + imp + "ORDER BY m.date ASC, m.mid ASC LIMIT %d)", dialog_id, messageMaxId, holeMessageMinId, count_query / 2, dialog_id, messageMaxId, holeMessageMaxId, count_query / 2));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT * FROM (SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media, m.ttl FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid <= %d AND m.mid >= %d " + imp + "ORDER BY m.date DESC, m.mid DESC LIMIT %d) UNION " +
"SELECT * FROM (SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media, m.ttl FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid > %d AND m.mid <= %d " + imp + "ORDER BY m.date ASC, m.mid ASC LIMIT %d)", dialog_id, messageMaxId, holeMessageMinId, count_query / 2, dialog_id, messageMaxId, holeMessageMaxId, count_query / 2));
} else {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT * FROM (SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid <= %d " + imp + "ORDER BY m.date DESC, m.mid DESC LIMIT %d) UNION " +
"SELECT * FROM (SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid > %d " + imp + "ORDER BY m.date ASC, m.mid ASC LIMIT %d)", dialog_id, messageMaxId, count_query / 2, dialog_id, messageMaxId, count_query / 2));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT * FROM (SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media, m.ttl FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid <= %d " + imp + "ORDER BY m.date DESC, m.mid DESC LIMIT %d) UNION " +
"SELECT * FROM (SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media, m.ttl FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid > %d " + imp + "ORDER BY m.date ASC, m.mid ASC LIMIT %d)", dialog_id, messageMaxId, count_query / 2, dialog_id, messageMaxId, count_query / 2));
}
} else {
cursor = null;
@ -2450,9 +2466,9 @@ public class MessagesStorage {
}
cursor.dispose();
if (holeMessageId != 0) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.date >= %d AND m.mid > %d AND m.mid <= %d " + imp + "ORDER BY m.date ASC, m.mid ASC LIMIT %d", dialog_id, minDate, messageMaxId, holeMessageId, count_query));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media, m.ttl FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.date >= %d AND m.mid > %d AND m.mid <= %d " + imp + "ORDER BY m.date ASC, m.mid ASC LIMIT %d", dialog_id, minDate, messageMaxId, holeMessageId, count_query));
} else {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.date >= %d AND m.mid > %d " + imp + "ORDER BY m.date ASC, m.mid ASC LIMIT %d", dialog_id, minDate, messageMaxId, count_query));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media, m.ttl FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.date >= %d AND m.mid > %d " + imp + "ORDER BY m.date ASC, m.mid ASC LIMIT %d", dialog_id, minDate, messageMaxId, count_query));
}
} else if (minDate != 0) {
if (messageMaxId != 0) {
@ -2466,12 +2482,12 @@ public class MessagesStorage {
}
cursor.dispose();
if (holeMessageId != 0) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.date <= %d AND m.mid < %d AND (m.mid >= %d OR m.mid < 0) " + imp + "ORDER BY m.date DESC, m.mid DESC LIMIT %d", dialog_id, minDate, messageMaxId, holeMessageId, count_query));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media, m.ttl FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.date <= %d AND m.mid < %d AND (m.mid >= %d OR m.mid < 0) " + imp + "ORDER BY m.date DESC, m.mid DESC LIMIT %d", dialog_id, minDate, messageMaxId, holeMessageId, count_query));
} else {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.date <= %d AND m.mid < %d " + imp + "ORDER BY m.date DESC, m.mid DESC LIMIT %d", dialog_id, minDate, messageMaxId, count_query));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media, m.ttl FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.date <= %d AND m.mid < %d " + imp + "ORDER BY m.date DESC, m.mid DESC LIMIT %d", dialog_id, minDate, messageMaxId, count_query));
}
} else {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.date <= %d " + imp + "ORDER BY m.date DESC, m.mid DESC LIMIT %d,%d", dialog_id, minDate, offset_query, count_query));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media, m.ttl FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.date <= %d " + imp + "ORDER BY m.date DESC, m.mid DESC LIMIT %d,%d", dialog_id, minDate, offset_query, count_query));
}
} else {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT max(mid) FROM messages WHERE uid = %d AND mid > 0", dialog_id));
@ -2490,20 +2506,20 @@ public class MessagesStorage {
}
cursor.dispose();
if (holeMessageId != 0) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND (m.mid >= %d OR m.mid < 0) " + imp + "ORDER BY m.date DESC, m.mid DESC LIMIT %d,%d", dialog_id, holeMessageId, offset_query, count_query));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media, m.ttl FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND (m.mid >= %d OR m.mid < 0) " + imp + "ORDER BY m.date DESC, m.mid DESC LIMIT %d,%d", dialog_id, holeMessageId, offset_query, count_query));
} else {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d " + imp + "ORDER BY m.date DESC, m.mid DESC LIMIT %d,%d", dialog_id, offset_query, count_query));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media, m.ttl FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d " + imp + "ORDER BY m.date DESC, m.mid DESC LIMIT %d,%d", dialog_id, offset_query, count_query));
}
}
} else {
isEnd = true;
if (load_type == 1) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid < %d ORDER BY m.mid DESC LIMIT %d", dialog_id, max_id, count_query));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media, m.ttl FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid < %d ORDER BY m.mid DESC LIMIT %d", dialog_id, max_id, count_query));
} else if (minDate != 0) {
if (max_id != 0) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid > %d ORDER BY m.mid ASC LIMIT %d", dialog_id, max_id, count_query));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media, m.ttl FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.mid > %d ORDER BY m.mid ASC LIMIT %d", dialog_id, max_id, count_query));
} else {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.date <= %d ORDER BY m.mid ASC LIMIT %d,%d", dialog_id, minDate, offset_query, count_query));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media, m.ttl FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d AND m.date <= %d ORDER BY m.mid ASC LIMIT %d,%d", dialog_id, minDate, offset_query, count_query));
}
} else {
if (load_type == 2) {
@ -2528,9 +2544,9 @@ public class MessagesStorage {
}
}
if (count_query > count_unread || count_unread < 4) {
if (count_query > count_unread || count_unread < num) {
count_query = Math.max(count_query, count_unread + 10);
if (count_unread < 4) {
if (count_unread < num) {
count_unread = 0;
min_unread_id = 0;
last_message_id = 0;
@ -2539,13 +2555,13 @@ public class MessagesStorage {
offset_query = count_unread - count_query;
count_query += 10;
}
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d ORDER BY m.mid ASC LIMIT %d,%d", dialog_id, offset_query, count_query));
cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.read_state, m.data, m.send_state, m.mid, m.date, r.random_id, m.replydata, m.media, m.ttl FROM messages as m LEFT JOIN randoms as r ON r.mid = m.mid WHERE m.uid = %d ORDER BY m.mid ASC LIMIT %d,%d", dialog_id, offset_query, count_query));
}
}
if (cursor != null) {
while (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(1));
if (data != null && cursor.byteBufferValue(1, data) != 0) {
if (cursor.byteBufferValue(1, data) != 0) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
MessageObject.setUnreadFlags(message, cursor.intValue(0));
message.id = cursor.intValue(3);
@ -2554,6 +2570,7 @@ public class MessagesStorage {
if ((message.flags & TLRPC.MESSAGE_FLAG_HAS_VIEWS) != 0) {
message.views = cursor.intValue(7);
}
message.ttl = cursor.intValue(8);
res.messages.add(message);
addUsersAndChatsFromMessage(message, usersToLoad, chatsToLoad);
@ -2561,7 +2578,7 @@ public class MessagesStorage {
if (message.reply_to_msg_id != 0 || message.reply_to_random_id != 0) {
if (!cursor.isNull(6)) {
NativeByteBuffer data2 = new NativeByteBuffer(cursor.byteArrayLength(6));
if (data2 != null && cursor.byteBufferValue(6, data2) != 0) {
if (cursor.byteBufferValue(6, data2) != 0) {
message.replyMessage = TLRPC.Message.TLdeserialize(data2, data2.readInt32(false), false);
if (message.replyMessage != null) {
addUsersAndChatsFromMessage(message.replyMessage, usersToLoad, chatsToLoad);
@ -2685,7 +2702,7 @@ public class MessagesStorage {
}
while (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
if (cursor.byteBufferValue(0, data) != 0) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
message.id = cursor.intValue(1);
message.date = cursor.intValue(2);
@ -2800,7 +2817,7 @@ public class MessagesStorage {
SQLiteCursor cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM sent_files_v2 WHERE uid = '%s' AND type = %d", id, type));
if (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
if (cursor.byteBufferValue(0, data) != 0) {
TLObject file = TLRPC.MessageMedia.TLdeserialize(data, data.readInt32(false), false);
if (file instanceof TLRPC.TL_messageMediaDocument) {
result.add(((TLRPC.TL_messageMediaDocument) file).document);
@ -3170,23 +3187,9 @@ public class MessagesStorage {
if (cursor.next()) {
try {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
if (cursor.byteBufferValue(0, data) != 0) {
TLRPC.User oldUser = TLRPC.User.TLdeserialize(data, data.readInt32(false), false);
if (oldUser != null) {
if (user.first_name != null) {
oldUser.first_name = user.first_name;
oldUser.flags |= 2;
} else {
oldUser.first_name = null;
oldUser.flags = oldUser.flags &~ 2;
}
if (user.last_name != null) {
oldUser.last_name = user.last_name;
oldUser.flags |= 4;
} else {
oldUser.last_name = null;
oldUser.flags = oldUser.flags &~ 4;
}
if (user.username != null) {
oldUser.username = user.username;
oldUser.flags |= 8;
@ -3246,7 +3249,7 @@ public class MessagesStorage {
if (cursor.next()) {
try {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
if (cursor.byteBufferValue(0, data) != 0) {
TLRPC.Chat oldChat = TLRPC.Chat.TLdeserialize(data, data.readInt32(false), false);
if (oldChat != null) {
oldChat.title = chat.title;
@ -3296,7 +3299,7 @@ public class MessagesStorage {
while (cursor.next()) {
try {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
if (cursor.byteBufferValue(0, data) != 0) {
TLRPC.User user = TLRPC.User.TLdeserialize(data, data.readInt32(false), false);
if (user != null) {
if (user.status != null) {
@ -3321,7 +3324,7 @@ public class MessagesStorage {
while (cursor.next()) {
try {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
if (cursor.byteBufferValue(0, data) != 0) {
TLRPC.Chat chat = TLRPC.Chat.TLdeserialize(data, data.readInt32(false), false);
if (chat != null) {
result.add(chat);
@ -3343,7 +3346,7 @@ public class MessagesStorage {
while (cursor.next()) {
try {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
if (cursor.byteBufferValue(0, data) != 0) {
TLRPC.EncryptedChat chat = TLRPC.EncryptedChat.TLdeserialize(data, data.readInt32(false), false);
if (chat != null) {
chat.user_id = cursor.intValue(1);
@ -3460,7 +3463,7 @@ public class MessagesStorage {
downloadObject.type = cursor.intValue(1);
downloadObject.id = cursor.longValue(0);
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(2));
if (data != null && cursor.byteBufferValue(2, data) != 0) {
if (cursor.byteBufferValue(2, data) != 0) {
TLRPC.MessageMedia messageMedia = TLRPC.MessageMedia.TLdeserialize(data, data.readInt32(false), false);
if (messageMedia.document != null) {
downloadObject.object = messageMedia.document;
@ -3522,7 +3525,7 @@ public class MessagesStorage {
while (cursor.next()) {
int mid = cursor.intValue(0);
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(1));
if (data != null && cursor.byteBufferValue(1, data) != 0) {
if (cursor.byteBufferValue(1, data) != 0) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
if (message.media instanceof TLRPC.TL_messageMediaWebPage) {
message.id = mid;
@ -3679,6 +3682,10 @@ public class MessagesStorage {
});
}
private boolean isValidKeyboardToSave(TLRPC.Message message) {
return message.reply_markup != null && !(message.reply_markup instanceof TLRPC.TL_replyInlineMarkup) && (!message.reply_markup.selective || message.mentioned);
}
private void putMessagesInternal(final ArrayList<TLRPC.Message> messages, final boolean withTransaction, final boolean doNotUpdateDialogDate, final int downloadMask) {
try {
if (withTransaction) {
@ -3759,7 +3766,7 @@ public class MessagesStorage {
messagesMediaIdsMap.put(messageId, message.dialog_id);
mediaTypes.put(messageId, SharedMediaQuery.getMediaType(message));
}
if (message.reply_markup != null && (!message.reply_markup.selective || message.mentioned)) {
if (isValidKeyboardToSave(message)) {
TLRPC.Message oldMessage = botKeyboards.get(message.dialog_id);
if (oldMessage == null || oldMessage.id < message.id) {
botKeyboards.put(message.dialog_id, message);
@ -4556,7 +4563,7 @@ public class MessagesStorage {
continue;
}
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(1));
if (data != null && cursor.byteBufferValue(1, data) != 0) {
if (cursor.byteBufferValue(1, data) != 0) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
if (message != null && message.media != null) {
if (message.media instanceof TLRPC.TL_messageMediaPhoto) {
@ -4671,7 +4678,7 @@ public class MessagesStorage {
dialogs.dialogs.add(dialog);
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(4));
if (data != null && cursor.byteBufferValue(4, data) != 0) {
if (cursor.byteBufferValue(4, data) != 0) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
MessageObject.setUnreadFlags(message, cursor.intValue(5));
message.id = cursor.intValue(6);
@ -5096,7 +5103,7 @@ public class MessagesStorage {
state3.bindInteger(5, message.id);
state3.bindInteger(6, 0);
state3.bindLong(7, messageId);
state3.bindInteger(8, load_type < 0 ? message.ttl : 0);
state3.bindInteger(8, message.ttl);
state3.bindInteger(9, messages.pts);
state3.bindInteger(10, message.date);
state3.step();
@ -5157,7 +5164,7 @@ public class MessagesStorage {
}
data.reuse();
if (load_type == 0 && message.reply_markup != null && (!message.reply_markup.selective || message.mentioned)) {
if (load_type == 0 && isValidKeyboardToSave(message)) {
if (botKeyboard == null || botKeyboard.id < message.id) {
botKeyboard = message;
}
@ -5338,7 +5345,7 @@ public class MessagesStorage {
dialogs.dialogs.add(dialog);
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(4));
if (data != null && cursor.byteBufferValue(4, data) != 0) {
if (cursor.byteBufferValue(4, data) != 0) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
if (message != null) {
MessageObject.setUnreadFlags(message, cursor.intValue(5));
@ -5413,7 +5420,7 @@ public class MessagesStorage {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid, date, uid FROM messages WHERE mid IN(%s)", TextUtils.join(",", replyMessages)));
while (cursor.next()) {
NativeByteBuffer data = new NativeByteBuffer(cursor.byteArrayLength(0));
if (data != null && cursor.byteBufferValue(0, data) != 0) {
if (cursor.byteBufferValue(0, data) != 0) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
message.id = cursor.intValue(1);
message.date = cursor.intValue(2);
@ -5594,7 +5601,7 @@ public class MessagesStorage {
}
isMegagroup = MessageObject.isMegagroup(message);
if (message.reply_markup != null && (!message.reply_markup.selective || message.mentioned)) {
if (isValidKeyboardToSave(message)) {
BotQuery.putBotKeyboard(dialog.id, message);
}

View File

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

View File

@ -70,6 +70,7 @@ public class NotificationCenter {
public static final int needReloadRecentDialogsSearch = totalEvents++;
public static final int locationPermissionGranted = totalEvents++;
public static final int peerSettingsDidLoaded = totalEvents++;
public static final int wasUnableToFindCurrentLocation = totalEvents++;
public static final int httpFileDidLoaded = totalEvents++;
public static final int httpFileDidFailedLoad = totalEvents++;
@ -115,6 +116,8 @@ public class NotificationCenter {
private int broadcasting = 0;
private boolean animationInProgress;
private int[] allowedNotifications;
public interface NotificationCenterDelegate {
void didReceivedNotification(int id, Object... args);
}
@ -145,6 +148,10 @@ public class NotificationCenter {
return localInstance;
}
public void setAllowedNotificationsDutingAnimation(int notifications[]) {
allowedNotifications = notifications;
}
public void setAnimationInProgress(boolean value) {
animationInProgress = value;
if (!animationInProgress && !delayedPosts.isEmpty()) {
@ -157,8 +164,13 @@ public class NotificationCenter {
public void postNotificationName(int id, Object... args) {
boolean allowDuringAnimation = false;
if (id == chatInfoDidLoaded || id == dialogsNeedReload || id == closeChats || id == messagesDidLoaded || id == mediaCountDidLoaded || id == mediaDidLoaded || id == botInfoDidLoaded || id == botKeyboardDidLoaded) {
allowDuringAnimation = true;
if (allowedNotifications != null) {
for (int a = 0; a < allowedNotifications.length; a++) {
if (allowedNotifications[a] == id) {
allowDuringAnimation = true;
break;
}
}
}
postNotificationNameInternal(id, allowDuringAnimation, args);
}

View File

@ -380,6 +380,7 @@ public class NotificationsController {
int oldCount = popupArray.size();
HashMap<Long, Boolean> settingsCache = new HashMap<>();
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Context.MODE_PRIVATE);
boolean allowPinned = preferences.getBoolean("PinnedMessages", true);
int popup = 0;
for (int a = 0; a < messageObjects.size(); a++) {
@ -398,6 +399,9 @@ public class NotificationsController {
continue;
}
if (messageObject.messageOwner.mentioned) {
if (!allowPinned && messageObject.messageOwner.action instanceof TLRPC.TL_messageActionPinMessage) {
continue;
}
dialog_id = messageObject.messageOwner.from_id;
}
if (isPersonalMessage(messageObject)) {
@ -683,7 +687,7 @@ public class NotificationsController {
int chat_id = messageObject.messageOwner.to_id.chat_id != 0 ? messageObject.messageOwner.to_id.chat_id : messageObject.messageOwner.to_id.channel_id;
int from_id = messageObject.messageOwner.to_id.user_id;
if (from_id == 0) {
if (messageObject.isFromUser()) {
if (messageObject.isFromUser() || messageObject.getId() < 0) {
from_id = messageObject.messageOwner.from_id;
} else {
from_id = -chat_id;
@ -725,7 +729,7 @@ public class NotificationsController {
}
String msg = null;
if ((int)dialog_id == 0 || AndroidUtilities.needShowPasscode(false) || UserConfig.isWaitingForPasscodeEnter) {
if ((int) dialog_id == 0 || AndroidUtilities.needShowPasscode(false) || UserConfig.isWaitingForPasscodeEnter) {
msg = LocaleController.getString("YouHaveNewMessage", R.string.YouHaveNewMessage);
} else {
if (chat_id == 0 && from_id != 0) {
@ -787,12 +791,6 @@ public class NotificationsController {
}
if (singleUserId != 0) {
if (messageObject.messageOwner.to_id.channel_id != 0 && !messageObject.isMegagroup()) {
TLRPC.User user = MessagesController.getInstance().getUser(singleUserId);
if (user != null) {
name = UserObject.getUserName(user);
} else {
name = "";
}
msg = LocaleController.formatString("ChannelAddedByNotification", R.string.ChannelAddedByNotification, name, chat.title);
} else {
if (singleUserId == UserConfig.getClientUserId()) {
@ -1513,7 +1511,7 @@ public class NotificationsController {
if (silent != 1 && !notifyDisabled) {
if (ApplicationLoader.mainInterfacePaused || inAppPreview) {
if (lastMessage.length() > 100) {
lastMessage = lastMessage.substring(0, 100).replace("\n", " ").trim() + "...";
lastMessage = lastMessage.substring(0, 100).replace('\n', ' ').trim() + "...";
}
mBuilder.setTicker(lastMessage);
}

View File

@ -849,6 +849,36 @@ public class SecretChatHelper {
});
}
private void applyPeerLayer(final TLRPC.EncryptedChat chat, int newPeerLayer) {
int currentPeerLayer = AndroidUtilities.getPeerLayerVersion(chat.layer);
if (newPeerLayer <= currentPeerLayer) {
return;
}
if (chat.key_hash.length == 16 && currentPeerLayer >= 46) {
try {
byte[] sha256 = Utilities.computeSHA256(chat.auth_key, 0, chat.auth_key.length);
byte[] key_hash = new byte[36];
System.arraycopy(chat.key_hash, 0, key_hash, 0, 16);
System.arraycopy(sha256, 0, key_hash, 16, 20);
chat.key_hash = key_hash;
MessagesStorage.getInstance().updateEncryptedChat(chat);
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
}
chat.layer = AndroidUtilities.setPeerLayerVersion(chat.layer, newPeerLayer);
MessagesStorage.getInstance().updateEncryptedChatLayer(chat);
if (currentPeerLayer < CURRENT_SECRET_CHAT_LAYER) {
sendNotifyLayerMessage(chat, null);
}
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.encryptedChatUpdated, chat);
}
});
}
public TLRPC.Message processDecryptedObject(final TLRPC.EncryptedChat chat, final TLRPC.EncryptedFile file, int date, long random_id, TLObject object, boolean new_key_used) {
if (object != null) {
int from_id = chat.admin_id;
@ -1156,30 +1186,7 @@ public class SecretChatHelper {
MessagesStorage.getInstance().createTaskForSecretChat(chat.id, time, time, 1, serviceMessage.action.random_ids);
}
} else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionNotifyLayer) {
int currentPeerLayer = AndroidUtilities.getPeerLayerVersion(chat.layer);
if (chat.key_hash.length == 16 && currentPeerLayer >= 46) {
try {
byte[] sha256 = Utilities.computeSHA256(chat.auth_key, 0, chat.auth_key.length);
byte[] key_hash = new byte[36];
System.arraycopy(chat.key_hash, 0, key_hash, 0, 16);
System.arraycopy(sha256, 0, key_hash, 16, 20);
chat.key_hash = key_hash;
MessagesStorage.getInstance().updateEncryptedChat(chat);
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
}
chat.layer = AndroidUtilities.setPeerLayerVersion(chat.layer, serviceMessage.action.layer);
MessagesStorage.getInstance().updateEncryptedChatLayer(chat);
if (currentPeerLayer < CURRENT_SECRET_CHAT_LAYER) {
sendNotifyLayerMessage(chat, null);
}
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
NotificationCenter.getInstance().postNotificationName(NotificationCenter.encryptedChatUpdated, chat);
}
});
applyPeerLayer(chat, serviceMessage.action.layer);
} else if (serviceMessage.action instanceof TLRPC.TL_decryptedMessageActionRequestKey) {
if (chat.exchange_id != 0) {
if (chat.exchange_id > serviceMessage.action.exchange_id) {
@ -1374,6 +1381,7 @@ public class SecretChatHelper {
for (int a = 0; a < holes.size(); a++) {
TL_decryptedMessageHolder holder = holes.get(a);
if (holder.layer.out_seq_no == chat.seq_in || chat.seq_in == holder.layer.out_seq_no - 2) {
applyPeerLayer(chat, holder.layer.layer);
chat.seq_in = holder.layer.out_seq_no;
holes.remove(a);
a--;
@ -1493,6 +1501,7 @@ public class SecretChatHelper {
arr.add(holder);
return null;
}
applyPeerLayer(chat, layer.layer);
chat.seq_in = layer.out_seq_no;
MessagesStorage.getInstance().updateEncryptedChatSeq(chat);
object = layer.message;

View File

@ -11,14 +11,19 @@ package org.telegram.messenger;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.media.MediaMetadataRetriever;
import android.media.MediaPlayer;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.webkit.MimeTypeMap;
import android.widget.Toast;
@ -31,6 +36,7 @@ import org.telegram.tgnet.RequestDelegate;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ChatActivity;
import java.io.File;
import java.io.RandomAccessFile;
@ -45,6 +51,148 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
private HashMap<String, ArrayList<DelayedMessage>> delayedMessages = new HashMap<>();
private HashMap<Integer, MessageObject> unsentMessages = new HashMap<>();
private HashMap<Integer, TLRPC.Message> sendingMessages = new HashMap<>();
private HashMap<String, MessageObject> waitingForLocation = new HashMap<>();
private HashMap<String, MessageObject> waitingForCallback = new HashMap<>();
private LocationProvider locationProvider = new LocationProvider(new LocationProvider.LocationProviderDelegate() {
@Override
public void onLocationAcquired(Location location) {
sendLocation(location);
waitingForLocation.clear();
}
@Override
public void onUnableLocationAcquire() {
HashMap<String, MessageObject> waitingForLocationCopy = new HashMap<>(waitingForLocation);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.wasUnableToFindCurrentLocation, waitingForLocationCopy);
waitingForLocation.clear();
}
});
public static class LocationProvider {
public interface LocationProviderDelegate {
void onLocationAcquired(Location location);
void onUnableLocationAcquire();
}
private LocationProviderDelegate delegate;
private LocationManager locationManager;
private GpsLocationListener gpsLocationListener = new GpsLocationListener();
private GpsLocationListener networkLocationListener = new GpsLocationListener();
private Runnable locationQueryCancelRunnable;
private Location lastKnownLocation;
private class GpsLocationListener implements LocationListener {
@Override
public void onLocationChanged(Location location) {
if (location == null || locationQueryCancelRunnable == null) {
return;
}
FileLog.e("tmessages", "found location " + location);
lastKnownLocation = location;
if (location.getAccuracy() < 100) {
if (delegate != null) {
delegate.onLocationAcquired(location);
}
if (locationQueryCancelRunnable != null) {
AndroidUtilities.cancelRunOnUIThread(locationQueryCancelRunnable);
}
cleanup();
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
}
public LocationProvider() {
}
public LocationProvider(LocationProviderDelegate locationProviderDelegate) {
delegate = locationProviderDelegate;
}
public void setDelegate(LocationProviderDelegate locationProviderDelegate) {
delegate = locationProviderDelegate;
}
private void cleanup() {
locationManager.removeUpdates(gpsLocationListener);
locationManager.removeUpdates(networkLocationListener);
lastKnownLocation = null;
locationQueryCancelRunnable = null;
}
public void start() {
if (locationManager == null) {
locationManager = (LocationManager) ApplicationLoader.applicationContext.getSystemService(Context.LOCATION_SERVICE);
}
try {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1, 0, gpsLocationListener);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
try {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1, 0, networkLocationListener);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
try {
lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (lastKnownLocation == null) {
lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
if (locationQueryCancelRunnable != null) {
AndroidUtilities.cancelRunOnUIThread(locationQueryCancelRunnable);
}
locationQueryCancelRunnable = new Runnable() {
@Override
public void run() {
if (locationQueryCancelRunnable != this) {
return;
}
if (delegate != null) {
if (lastKnownLocation != null) {
delegate.onLocationAcquired(lastKnownLocation);
} else {
delegate.onUnableLocationAcquire();
}
}
cleanup();
}
};
AndroidUtilities.runOnUIThread(locationQueryCancelRunnable, 5000);
}
public void stop() {
if (locationManager == null) {
return;
}
if (locationQueryCancelRunnable != null) {
AndroidUtilities.cancelRunOnUIThread(locationQueryCancelRunnable);
}
cleanup();
}
}
protected class DelayedMessage {
public TLObject sendRequest;
@ -90,7 +238,10 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
delayedMessages.clear();
unsentMessages.clear();
sendingMessages.clear();
waitingForLocation.clear();
waitingForCallback.clear();
currentChatInfo = null;
locationProvider.stop();
}
public void setCurrentChatInfo(TLRPC.ChatFull info) {
@ -259,7 +410,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
for (int a = 0; a < arr.size(); a++) {
final DelayedMessage message = arr.get(a);
if (message.type == 0) {
String md5 = Utilities.MD5(message.httpLocation) + ".jpg";
String md5 = Utilities.MD5(message.httpLocation) + "." + ImageLoader.getHttpUrlExtension(message.httpLocation, "file");
final File cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), md5);
Utilities.globalQueue.postRunnable(new Runnable() {
@Override
@ -455,18 +606,18 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
if (messageObject.messageOwner.media != null && !(messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaEmpty) && !(messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaWebPage)) {
if (messageObject.messageOwner.media.photo instanceof TLRPC.TL_photo) {
sendMessage((TLRPC.TL_photo) messageObject.messageOwner.media.photo, null, did, messageObject.replyMessageObject, asAdmin, null);
sendMessage((TLRPC.TL_photo) messageObject.messageOwner.media.photo, null, did, messageObject.replyMessageObject, asAdmin, null, null);
} 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, asAdmin, null);
sendMessage((TLRPC.TL_document) messageObject.messageOwner.media.document, null, messageObject.messageOwner.attachPath, did, messageObject.replyMessageObject, asAdmin, null, null);
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaVenue || messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGeo) {
sendMessage(messageObject.messageOwner.media, did, messageObject.replyMessageObject, asAdmin);
sendMessage(messageObject.messageOwner.media, did, messageObject.replyMessageObject, asAdmin, null, null);
} else if (messageObject.messageOwner.media.phone_number != null) {
TLRPC.User user = new TLRPC.TL_userContact_old2();
user.phone = messageObject.messageOwner.media.phone_number;
user.first_name = messageObject.messageOwner.media.first_name;
user.last_name = messageObject.messageOwner.media.last_name;
user.id = messageObject.messageOwner.media.user_id;
sendMessage(user, did, messageObject.replyMessageObject, asAdmin);
sendMessage(user, did, messageObject.replyMessageObject, asAdmin, null, null);
} else {
ArrayList<MessageObject> arrayList = new ArrayList<>();
arrayList.add(messageObject);
@ -477,7 +628,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaWebPage) {
webPage = messageObject.messageOwner.media.webpage;
}
sendMessage(messageObject.messageOwner.message, did, messageObject.replyMessageObject, webPage, true, asAdmin, messageObject.messageOwner.entities, null);
sendMessage(messageObject.messageOwner.message, did, messageObject.replyMessageObject, webPage, true, asAdmin, messageObject.messageOwner.entities, null, null);
} else {
ArrayList<MessageObject> arrayList = new ArrayList<>();
arrayList.add(messageObject);
@ -528,34 +679,8 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
}
}
for (int a = 0; a < document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeSticker) {
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) < 46) {
document.attributes.remove(a);
document.attributes.add(new TLRPC.TL_documentAttributeSticker_old());
} else {
if (attribute.stickerset != null) {
String name = StickersQuery.getStickerSetName(attribute.stickerset.id);
if (name != null && name.length() > 0) {
attribute.stickerset = new TLRPC.TL_inputStickerSetShortName();
attribute.stickerset.short_name = name;
} else {
attribute.stickerset = new TLRPC.TL_inputStickerSetEmpty();
}
} else {
attribute.stickerset = new TLRPC.TL_inputStickerSetEmpty();
}
}
break;
}
}
}
SendMessagesHelper.getInstance().sendMessage((TLRPC.TL_document) document, null, null, peer, replyingMessageObject, asAdmin, null);
}
public void sendMessage(TLRPC.User user, long peer, MessageObject reply_to_msg, boolean asAdmin) {
sendMessage(null, null, null, null, user, null, peer, null, reply_to_msg, null, true, asAdmin, null, null, null);
SendMessagesHelper.getInstance().sendMessage((TLRPC.TL_document) document, null, null, peer, replyingMessageObject, asAdmin, null, null);
}
public void sendMessage(ArrayList<MessageObject> messages, final long peer, boolean asAdmin) {
@ -680,6 +805,10 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
putToSendingMessages(newMsg);
boolean differentDialog = false;
if (BuildVars.DEBUG_VERSION) {
FileLog.e("tmessages", "forward message user_id = " + inputPeer.user_id + " chat_id = " + inputPeer.chat_id + " channel_id = " + inputPeer.channel_id + " access_hash = " + inputPeer.access_hash);
}
if (arr.size() == 100 || a == messages.size() - 1 || a != messages.size() - 1 && messages.get(a + 1).getDialogId() != msgObj.getDialogId()) {
MessagesStorage.getInstance().putMessages(new ArrayList<>(arr), false, true, false, 0);
MessagesController.getInstance().updateInterfaceWithMessages(peer, objArr);
@ -688,9 +817,16 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
TLRPC.TL_messages_forwardMessages req = new TLRPC.TL_messages_forwardMessages();
req.to_peer = inputPeer;
if (msgObj.messageOwner.to_id instanceof TLRPC.TL_peerChannel) {
req.from_peer = MessagesController.getInputPeer(-msgObj.messageOwner.to_id.channel_id);
if (req.to_peer instanceof TLRPC.TL_inputPeerChannel) {
req.silent = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE).getBoolean("silent_" + peer, false);
}
if (msgObj.messageOwner.to_id instanceof TLRPC.TL_peerChannel) {
TLRPC.Chat chat = MessagesController.getInstance().getChat(msgObj.messageOwner.to_id.channel_id);
req.from_peer = new TLRPC.TL_inputPeerChannel();
req.from_peer.channel_id = msgObj.messageOwner.to_id.channel_id;
if (chat != null) {
req.from_peer.access_hash = chat.access_hash;
}
} else {
req.from_peer = new TLRPC.TL_inputPeerEmpty();
}
@ -713,7 +849,8 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
for (int a = 0; a < updates.updates.size(); a++) {
TLRPC.Update update = updates.updates.get(a);
if (update instanceof TLRPC.TL_updateMessageID) {
newMessagesByIds.put(update.id, update.random_id);
TLRPC.TL_updateMessageID updateMessageID = (TLRPC.TL_updateMessageID) update;
newMessagesByIds.put(updateMessageID.id, updateMessageID.random_id);
updates.updates.remove(a);
a--;
}
@ -815,12 +952,12 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setCancelable(false);
TLRPC.TL_channels_editMessage req = new TLRPC.TL_channels_editMessage();
req.channel = MessagesController.getInputChannel(messageObject.messageOwner.to_id.channel_id);
TLRPC.TL_messages_editMessage req = new TLRPC.TL_messages_editMessage();
req.peer = MessagesController.getInputPeer((int) messageObject.getDialogId());
req.message = message;
req.flags |= 2048;
req.id = messageObject.getId();
req.no_webpage = !searchLinks;
FileLog.d("tmessages", "try to edit message " + req.id + " in channel " + req.channel.channel_id + " hash " + req.channel.access_hash + " message " + req.message);
final int reqId = ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
@Override
public void run(TLObject response, TLRPC.TL_error error) {
@ -872,31 +1009,104 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
}
private void sendLocation(Location location) {
TLRPC.TL_messageMediaGeo mediaGeo = new TLRPC.TL_messageMediaGeo();
mediaGeo.geo = new TLRPC.TL_geoPoint();
mediaGeo.geo.lat = location.getLatitude();
mediaGeo.geo._long = location.getLongitude();
for (HashMap.Entry<String, MessageObject> entry : waitingForLocation.entrySet()) {
MessageObject messageObject = entry.getValue();
SendMessagesHelper.getInstance().sendMessage(mediaGeo, messageObject.getDialogId(), messageObject, false, null, null);
}
}
public void sendCurrentLocation(final MessageObject messageObject, final TLRPC.KeyboardButton button) {
final String key = messageObject.getId() + "_" + Utilities.bytesToHex(button.data);
waitingForLocation.put(key, messageObject);
locationProvider.start();
}
public boolean isSendingCurrentLocation(MessageObject messageObject, TLRPC.KeyboardButton button) {
return !(messageObject == null || button == null) && waitingForLocation.containsKey(messageObject.getId() + "_" + Utilities.bytesToHex(button.data));
}
public void sendCallback(final MessageObject messageObject, final TLRPC.KeyboardButton button, final ChatActivity parentFragment) {
if (messageObject == null || button == null || parentFragment == null) {
return;
}
final String key = messageObject.getId() + "_" + Utilities.bytesToHex(button.data);
waitingForCallback.put(key, messageObject);
TLRPC.TL_messages_getBotCallbackAnswer req = new TLRPC.TL_messages_getBotCallbackAnswer();
req.peer = MessagesController.getInputPeer((int) messageObject.getDialogId());
req.msg_id = messageObject.getId();
req.data = button.data;
ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
@Override
public void run(final TLObject response, TLRPC.TL_error error) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
if (response != null) {
TLRPC.TL_messages_botCallbackAnswer res = (TLRPC.TL_messages_botCallbackAnswer) response;
if (res.message != null) {
if (res.alert) {
if (parentFragment.getParentActivity() == null) {
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(parentFragment.getParentActivity());
builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null);
builder.setMessage(res.message);
parentFragment.showDialog(builder.create());
} else {
int uid = messageObject.messageOwner.from_id;
if (messageObject.messageOwner.via_bot_id != 0) {
uid = messageObject.messageOwner.via_bot_id;
}
TLRPC.User user = MessagesController.getInstance().getUser(uid);
if (user == null) {
return;
}
parentFragment.showAlert(user, res.message);
}
}
}
waitingForCallback.remove(key);
}
});
}
}, ConnectionsManager.RequestFlagFailOnServerErrors);
}
public boolean isSendingCallback(MessageObject messageObject, TLRPC.KeyboardButton button) {
return !(messageObject == null || button == null) && waitingForCallback.containsKey(messageObject.getId() + "_" + Utilities.bytesToHex(button.data));
}
public void sendMessage(MessageObject retryMessageObject, boolean asAdmin) {
sendMessage(null, null, null, null, null, null, retryMessageObject.getDialogId(), retryMessageObject.messageOwner.attachPath, null, null, true, asAdmin, retryMessageObject, null, retryMessageObject.messageOwner.params);
sendMessage(null, null, null, null, null, null, retryMessageObject.getDialogId(), retryMessageObject.messageOwner.attachPath, null, null, true, asAdmin, retryMessageObject, null, retryMessageObject.messageOwner.reply_markup, retryMessageObject.messageOwner.params);
}
public void sendMessage(TLRPC.TL_document document, VideoEditedInfo videoEditedInfo, String path, long peer, MessageObject reply_to_msg, boolean asAdmin, HashMap<String, String> params) {
sendMessage(null, null, null, videoEditedInfo, null, document, peer, path, reply_to_msg, null, true, asAdmin, null, null, params);
public void sendMessage(TLRPC.User user, long peer, MessageObject reply_to_msg, boolean asAdmin, TLRPC.ReplyMarkup replyMarkup, HashMap<String, String> params) {
sendMessage(null, null, null, null, user, null, peer, null, reply_to_msg, null, true, asAdmin, null, null, replyMarkup, params);
}
public void sendMessage(String message, long peer, MessageObject reply_to_msg, TLRPC.WebPage webPage, boolean searchLinks, boolean asAdmin, ArrayList<TLRPC.MessageEntity> entities, HashMap<String, String> params) {
sendMessage(message, null, null, null, null, null, peer, null, reply_to_msg, webPage, searchLinks, asAdmin, null, entities, params);
public void sendMessage(TLRPC.TL_document document, VideoEditedInfo videoEditedInfo, String path, long peer, MessageObject reply_to_msg, boolean asAdmin, TLRPC.ReplyMarkup replyMarkup, HashMap<String, String> params) {
sendMessage(null, null, null, videoEditedInfo, null, document, peer, path, reply_to_msg, null, true, asAdmin, null, null, replyMarkup, params);
}
public void sendMessage(TLRPC.MessageMedia location, long peer, MessageObject reply_to_msg, boolean asAdmin) {
sendMessage(null, location, null, null, null, null, peer, null, reply_to_msg, null, true, asAdmin, null, null, null);
public void sendMessage(String message, long peer, MessageObject reply_to_msg, TLRPC.WebPage webPage, boolean searchLinks, boolean asAdmin, ArrayList<TLRPC.MessageEntity> entities, TLRPC.ReplyMarkup replyMarkup, HashMap<String, String> params) {
sendMessage(message, null, null, null, null, null, peer, null, reply_to_msg, webPage, searchLinks, asAdmin, null, entities, replyMarkup, params);
}
public void sendMessage(TLRPC.TL_photo photo, String path, long peer, MessageObject reply_to_msg, boolean asAdmin, HashMap<String, String> params) {
sendMessage(null, null, photo, null, null, null, peer, path, reply_to_msg, null, true, asAdmin, null, null, params);
public void sendMessage(TLRPC.MessageMedia location, long peer, MessageObject reply_to_msg, boolean asAdmin, TLRPC.ReplyMarkup replyMarkup, HashMap<String, String> params) {
sendMessage(null, location, null, null, null, null, peer, null, reply_to_msg, null, true, asAdmin, null, null, replyMarkup, params);
}
/*public void sendMessage(TLRPC.TL_video video, VideoEditedInfo videoEditedInfo, String path, long peer, MessageObject reply_to_msg, boolean asAdmin, HashMap<String, String> params) {
sendMessage(null, null, null, video, videoEditedInfo, null, null, null, peer, path, reply_to_msg, null, true, asAdmin, null, null, params);
}*/
public void sendMessage(TLRPC.TL_photo photo, String path, long peer, MessageObject reply_to_msg, boolean asAdmin, TLRPC.ReplyMarkup replyMarkup, HashMap<String, String> params) {
sendMessage(null, null, photo, null, null, null, peer, path, reply_to_msg, null, true, asAdmin, null, null, replyMarkup, params);
}
private void sendMessage(String message, TLRPC.MessageMedia location, TLRPC.TL_photo photo, VideoEditedInfo videoEditedInfo, TLRPC.User user, TLRPC.TL_document document, long peer, String path, MessageObject reply_to_msg, TLRPC.WebPage webPage, boolean searchLinks, boolean asAdmin, MessageObject retryMessageObject, ArrayList<TLRPC.MessageEntity> entities, HashMap<String, String> params) {
private void sendMessage(String message, TLRPC.MessageMedia location, TLRPC.TL_photo photo, VideoEditedInfo videoEditedInfo, TLRPC.User user, TLRPC.TL_document document, long peer, String path, MessageObject reply_to_msg, TLRPC.WebPage webPage, boolean searchLinks, boolean asAdmin, MessageObject retryMessageObject, ArrayList<TLRPC.MessageEntity> entities, TLRPC.ReplyMarkup replyMarkup, HashMap<String, String> params) {
if (peer == 0) {
return;
}
@ -935,27 +1145,18 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
try {
if (retryMessageObject != null) {
newMsg = retryMessageObject.messageOwner;
if (retryMessageObject.isForwarded()) {
type = 4;
} else {
if (retryMessageObject.type == 0) {
message = newMsg.message;
if (params != null && params.containsKey("query_id")) {
type = 9;
} else {
type = 0;
}
type = 0;
} else if (retryMessageObject.type == 4) {
location = newMsg.media;
type = 1;
} else if (retryMessageObject.type == 1) {
photo = (TLRPC.TL_photo) newMsg.media.photo;
if (params != null && params.containsKey("query_id")) {
type = 9;
} else {
type = 2;
}
type = 2;
} else if (retryMessageObject.type == 3) {
type = 3;
document = (TLRPC.TL_document) newMsg.media.document;
@ -966,17 +1167,16 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
user.last_name = newMsg.media.last_name;
user.id = newMsg.media.user_id;
type = 6;
} else if (retryMessageObject.type == 8 || retryMessageObject.type == 9 || retryMessageObject.type == 13) {
} else if (retryMessageObject.type == 8 || retryMessageObject.type == 9 || retryMessageObject.type == 13 || retryMessageObject.type == 14) {
document = (TLRPC.TL_document) newMsg.media.document;
if (params != null && params.containsKey("query_id")) {
type = 9;
} else {
type = 7;
}
type = 7;
} else if (retryMessageObject.type == 2) {
document = (TLRPC.TL_document) newMsg.media.document;
type = 8;
}
if (params != null && params.containsKey("query_id")) {
type = 9;
}
}
} else {
if (message != null) {
@ -1017,7 +1217,11 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
newMsg.media = location;
newMsg.message = "";
type = 1;
if (params != null && params.containsKey("query_id")) {
type = 9;
} else {
type = 1;
}
} else if (photo != null) {
if (encryptedChat != null && AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
newMsg = new TLRPC.TL_message_secret();
@ -1057,7 +1261,11 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
user.last_name = newMsg.media.last_name = "";
}
newMsg.message = "";
type = 6;
if (params != null && params.containsKey("query_id")) {
type = 9;
} else {
type = 6;
}
} else if (document != null) {
if (encryptedChat != null && AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 17) {
newMsg = new TLRPC.TL_message_secret();
@ -1067,12 +1275,12 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
newMsg.media = new TLRPC.TL_messageMediaDocument();
newMsg.media.caption = document.caption != null ? document.caption : "";
newMsg.media.document = document;
if (MessageObject.isVideoDocument(document)) {
if (params != null && params.containsKey("query_id")) {
type = 9;
} else if (MessageObject.isVideoDocument(document)) {
type = 3;
} else if (MessageObject.isVoiceDocument(document)) {
type = 8;
} else if (params != null && params.containsKey("query_id")) {
type = 9;
} else {
type = 7;
}
@ -1086,6 +1294,30 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
} else {
newMsg.attachPath = path;
}
if (encryptedChat != null && MessageObject.isStickerDocument(document)) {
for (int a = 0; a < document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeSticker) {
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) < 46) {
document.attributes.remove(a);
document.attributes.add(new TLRPC.TL_documentAttributeSticker_old());
} else {
if (attribute.stickerset != null) {
String name = StickersQuery.getStickerSetName(attribute.stickerset.id);
if (name != null && name.length() > 0) {
attribute.stickerset = new TLRPC.TL_inputStickerSetShortName();
attribute.stickerset.short_name = name;
} else {
attribute.stickerset = new TLRPC.TL_inputStickerSetEmpty();
}
} else {
attribute.stickerset = new TLRPC.TL_inputStickerSetEmpty();
}
}
break;
}
}
}
}
if (newMsg.attachPath == null) {
newMsg.attachPath = "";
@ -1146,6 +1378,10 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
}
newMsg.reply_to_msg_id = reply_to_msg.getId();
}
if (replyMarkup != null && encryptedChat == null) {
newMsg.flags |= TLRPC.MESSAGE_FLAG_HAS_MARKUP;
newMsg.reply_markup = replyMarkup;
}
if (lower_id != 0) {
if (high_id == 1) {
if (currentChatInfo == null) {
@ -1225,6 +1461,12 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
MessagesController.getInstance().updateInterfaceWithMessages(peer, objArr);
NotificationCenter.getInstance().postNotificationName(NotificationCenter.dialogsNeedReload);
if (BuildVars.DEBUG_VERSION) {
if (sendToPeer != null) {
FileLog.e("tmessages", "send message user_id = " + sendToPeer.user_id + " chat_id = " + sendToPeer.chat_id + " channel_id = " + sendToPeer.channel_id + " access_hash = " + sendToPeer.access_hash);
}
}
if (type == 0 || type == 9 && message != null && encryptedChat != null) {
if (encryptedChat == null) {
if (sendToPeers != null) {
@ -1524,6 +1766,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
} else if (type == 2 || type == 9 && photo != null) {
TLRPC.PhotoSize small = photo.sizes.get(0);
TLRPC.PhotoSize big = photo.sizes.get(photo.sizes.size() - 1);
ImageLoader.fillPhotoSizeWithBytes(small);
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 46) {
reqSend.media = new TLRPC.TL_decryptedMessageMediaPhoto();
reqSend.media.caption = photo.caption != null ? photo.caption : "";
@ -1540,7 +1783,6 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
((TLRPC.TL_decryptedMessageMediaPhoto_layer8) reqSend.media).thumb = new byte[0];
}
}
ImageLoader.fillPhotoSizeWithBytes(small);
reqSend.media.thumb_h = small.h;
reqSend.media.thumb_w = small.w;
reqSend.media.w = big.w;
@ -1747,7 +1989,12 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
TLRPC.TL_messages_forwardMessages reqSend = new TLRPC.TL_messages_forwardMessages();
reqSend.to_peer = sendToPeer;
if (retryMessageObject.messageOwner.ttl != 0) {
reqSend.from_peer = MessagesController.getInputPeer(retryMessageObject.messageOwner.ttl);
TLRPC.Chat chat = MessagesController.getInstance().getChat(-retryMessageObject.messageOwner.ttl);
reqSend.from_peer = new TLRPC.TL_inputPeerChannel();
reqSend.from_peer.channel_id = -retryMessageObject.messageOwner.ttl;
if (chat != null) {
reqSend.from_peer.access_hash = chat.access_hash;
}
} else {
reqSend.from_peer = new TLRPC.TL_inputPeerEmpty();
}
@ -1797,13 +2044,23 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
if (message.type == 0) {
if (message.httpLocation != null) {
putToDelayedMessages(message.httpLocation, message);
ImageLoader.getInstance().loadHttpFile(message.httpLocation, "jpg");
ImageLoader.getInstance().loadHttpFile(message.httpLocation, "file");
} else {
String location = FileLoader.getPathToAttach(message.location, true).toString();
putToDelayedMessages(location, message);
if (message.sendRequest != null) {
String location = FileLoader.getPathToAttach(message.location).toString();
putToDelayedMessages(location, message);
FileLoader.getInstance().uploadFile(location, false, true);
} else {
String location = FileLoader.getPathToAttach(message.location).toString();
if (message.sendEncryptedRequest != null && message.location.dc_id != 0) {
File file = new File(location);
if (!file.exists()) {
putToDelayedMessages(FileLoader.getAttachFileName(message.location), message);
FileLoader.getInstance().loadFile(message.location, "jpg", 0, false);
return;
}
}
putToDelayedMessages(location, message);
FileLoader.getInstance().uploadFile(location, true, true);
}
}
@ -2139,8 +2396,10 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
size2.location = size.location;
size2.size = size.size;
}
} else if (MessageObject.isStickerMessage(sentMessage) && size2 != null && size2.location != null) {
} else if (size2 != null && MessageObject.isStickerMessage(sentMessage) && size2.location != null) {
size.location = size2.location;
} else if (size2 != null && size2.location instanceof TLRPC.TL_fileLocationUnavailable) {
newMsg.media.document.thumb = sentMessage.media.document.thumb;
}
newMsg.media.document.dc_id = sentMessage.media.document.dc_id;
@ -2291,7 +2550,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
String name = f.getName();
String ext = "";
int idx = path.lastIndexOf(".");
int idx = path.lastIndexOf('.');
if (idx != -1) {
ext = path.substring(idx + 1);
}
@ -2390,25 +2649,9 @@ 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;
if (isEncrypted) {
int high_id = (int) (dialog_id >> 32);
TLRPC.EncryptedChat encryptedChat = MessagesController.getInstance().getEncryptedChat(high_id);
if (encryptedChat == null) {
return false;
}
if (AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) >= 46) {
attributeSticker = new TLRPC.TL_documentAttributeSticker();
attributeSticker.alt = "";
attributeSticker.stickerset = new TLRPC.TL_inputStickerSetEmpty();
} else {
attributeSticker = new TLRPC.TL_documentAttributeSticker_old();
}
} else {
attributeSticker = new TLRPC.TL_documentAttributeSticker();
attributeSticker.alt = "";
attributeSticker.stickerset = new TLRPC.TL_inputStickerSetEmpty();
}
TLRPC.TL_documentAttributeSticker 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();
attributeImageSize.w = bmOptions.outWidth;
@ -2432,7 +2675,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
SendMessagesHelper.getInstance().sendMessage(documentFinal, null, pathFinal, dialog_id, reply_to_msg, asAdmin, params);
SendMessagesHelper.getInstance().sendMessage(documentFinal, null, pathFinal, dialog_id, reply_to_msg, asAdmin, null, params);
}
});
return true;
@ -2505,7 +2748,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
SendMessagesHelper.getInstance().sendMessage(documentFinal, null, messageObject.messageOwner.attachPath, dialog_id, reply_to_msg, asAdmin, params);
SendMessagesHelper.getInstance().sendMessage(documentFinal, null, messageObject.messageOwner.attachPath, dialog_id, reply_to_msg, asAdmin, null, params);
}
});
}
@ -2582,74 +2825,177 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
String finalPath = null;
TLRPC.TL_document document = null;
TLRPC.TL_photo photo = null;
if (result instanceof TLRPC.TL_botInlineMediaResultDocument) {
if (result instanceof TLRPC.TL_botInlineMediaResult) {
if (result.document != null) {
if (result.document instanceof TLRPC.TL_document) {
document = (TLRPC.TL_document) result.document;
}
}
} else if (result instanceof TLRPC.TL_botInlineMediaResultPhoto) {
if (result.photo != null) {
} else if (result.photo != null) {
if (result.photo instanceof TLRPC.TL_photo) {
photo = (TLRPC.TL_photo) result.photo;
}
}
} else {
if (result.content_url != null) {
finalPath = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), Utilities.MD5(result.content_url) + "." + ImageLoader.getHttpUrlExtension(result.content_url, "jpg")).getAbsolutePath();
if (result.type.equals("gif")){
document = new TLRPC.TL_document();
document.id = 0;
document.date = ConnectionsManager.getInstance().getCurrentTime();
TLRPC.TL_documentAttributeFilename fileName = new TLRPC.TL_documentAttributeFilename();
fileName.file_name = "animation.gif";
document.attributes.add(fileName);
document.size = 0;
document.dc_id = 0;
if (finalPath.endsWith("mp4")) {
document.mime_type = "video/mp4";
document.attributes.add(new TLRPC.TL_documentAttributeAnimated());
} else {
document.mime_type = "image/gif";
}
try {
Bitmap bitmap;
if (finalPath.endsWith("mp4")) {
bitmap = ThumbnailUtils.createVideoThumbnail(finalPath, MediaStore.Video.Thumbnails.MINI_KIND);
} else {
bitmap = ImageLoader.loadBitmap(finalPath, null, 90, 90, true);
File f = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), Utilities.MD5(result.content_url) + "." + ImageLoader.getHttpUrlExtension(result.content_url, "file"));
if (f.exists()) {
finalPath = f.getAbsolutePath();
} else {
finalPath = result.content_url;
}
switch (result.type) {
case "audio":
case "voice":
case "file":
case "video":
case "sticker":
case "gif": {
document = new TLRPC.TL_document();
document.id = 0;
document.size = 0;
document.dc_id = 0;
document.mime_type = result.content_type;
document.date = ConnectionsManager.getInstance().getCurrentTime();
TLRPC.TL_documentAttributeFilename fileName = new TLRPC.TL_documentAttributeFilename();
document.attributes.add(fileName);
switch (result.type) {
case "gif": {
fileName.file_name = "animation.gif";
if (finalPath.endsWith("mp4")) {
document.mime_type = "video/mp4";
document.attributes.add(new TLRPC.TL_documentAttributeAnimated());
} else {
document.mime_type = "image/gif";
}
try {
Bitmap bitmap;
if (finalPath.endsWith("mp4")) {
bitmap = ThumbnailUtils.createVideoThumbnail(finalPath, MediaStore.Video.Thumbnails.MINI_KIND);
} else {
bitmap = ImageLoader.loadBitmap(finalPath, null, 90, 90, true);
}
if (bitmap != null) {
document.thumb = ImageLoader.scaleAndSaveImage(bitmap, 90, 90, 55, false);
bitmap.recycle();
}
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
break;
}
case "voice": {
TLRPC.TL_documentAttributeAudio audio = new TLRPC.TL_documentAttributeAudio();
audio.duration = result.duration;
audio.voice = true;
fileName.file_name = "audio.ogg";
document.attributes.add(audio);
document.thumb = new TLRPC.TL_photoSizeEmpty();
document.thumb.type = "s";
break;
}
case "audio": {
TLRPC.TL_documentAttributeAudio audio = new TLRPC.TL_documentAttributeAudio();
audio.duration = result.duration;
audio.title = result.title;
audio.flags |= 1;
if (result.description != null) {
audio.performer = result.description;
audio.flags |= 2;
}
fileName.file_name = "audio.mp3";
document.attributes.add(audio);
document.thumb = new TLRPC.TL_photoSizeEmpty();
document.thumb.type = "s";
break;
}
case "file": {
int idx = result.content_type.indexOf('/');
if (idx != -1) {
fileName.file_name = "file." + result.content_type.substring(idx + 1);
} else {
fileName.file_name = "file";
}
break;
}
case "video": {
fileName.file_name = "video.mp4";
TLRPC.TL_documentAttributeVideo attributeVideo = new TLRPC.TL_documentAttributeVideo();
attributeVideo.w = result.w;
attributeVideo.h = result.h;
attributeVideo.duration = result.duration;
document.attributes.add(attributeVideo);
try {
String thumbPath = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), Utilities.MD5(result.thumb_url) + "." + ImageLoader.getHttpUrlExtension(result.thumb_url, "jpg")).getAbsolutePath();
Bitmap bitmap = ImageLoader.loadBitmap(thumbPath, null, 90, 90, true);
if (bitmap != null) {
document.thumb = ImageLoader.scaleAndSaveImage(bitmap, 90, 90, 55, false);
bitmap.recycle();
}
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
break;
}
case "sticker": {
TLRPC.TL_documentAttributeSticker 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();
attributeImageSize.w = result.w;
attributeImageSize.h = result.h;
document.attributes.add(attributeImageSize);
fileName.file_name = "sticker.webp";
try {
String thumbPath = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), Utilities.MD5(result.thumb_url) + "." + ImageLoader.getHttpUrlExtension(result.thumb_url, "webp")).getAbsolutePath();
Bitmap bitmap = ImageLoader.loadBitmap(thumbPath, null, 90, 90, true); //TODO support on old androids
if (bitmap != null) {
document.thumb = ImageLoader.scaleAndSaveImage(bitmap, 90, 90, 55, false);
bitmap.recycle();
}
} catch (Throwable e) {
FileLog.e("tmessages", e);
}
break;
}
}
if (bitmap != null) {
document.thumb = ImageLoader.scaleAndSaveImage(bitmap, 90, 90, 55, false);
bitmap.recycle();
if (fileName.file_name == null) {
fileName.file_name = "file";
}
} catch (Exception e) {
FileLog.e("tmessages", e);
if (document.mime_type == null) {
document.mime_type = "application/octet-stream";
}
if (document.thumb == null) {
document.thumb = new TLRPC.TL_photoSize();
document.thumb.w = result.w;
document.thumb.h = result.h;
document.thumb.size = 0;
document.thumb.location = new TLRPC.TL_fileLocationUnavailable();
document.thumb.type = "x";
}
break;
}
if (document.thumb == null) {
document.thumb = new TLRPC.TL_photoSize();
document.thumb.w = result.w;
document.thumb.h = result.h;
document.thumb.size = 0;
document.thumb.location = new TLRPC.TL_fileLocationUnavailable();
document.thumb.type = "x";
}
} else if (result.type.equals("photo")) {
File cacheFile = new File(finalPath);
if (cacheFile.exists()) {
photo = SendMessagesHelper.getInstance().generatePhotoSizes(cacheFile.toString(), null);
}
if (photo == null) {
photo = new TLRPC.TL_photo();
photo.date = ConnectionsManager.getInstance().getCurrentTime();
TLRPC.TL_photoSize photoSize = new TLRPC.TL_photoSize();
photoSize.w = result.w;
photoSize.h = result.h;
photoSize.size = 1;
photoSize.location = new TLRPC.TL_fileLocationUnavailable();
photoSize.type = "x";
photo.sizes.add(photoSize);
case "photo": {
if (f.exists()) {
photo = SendMessagesHelper.getInstance().generatePhotoSizes(finalPath, null);
}
if (photo == null) {
photo = new TLRPC.TL_photo();
photo.date = ConnectionsManager.getInstance().getCurrentTime();
TLRPC.TL_photoSize photoSize = new TLRPC.TL_photoSize();
photoSize.w = result.w;
photoSize.h = result.h;
photoSize.size = 1;
photoSize.location = new TLRPC.TL_fileLocationUnavailable();
photoSize.type = "x";
photo.sizes.add(photoSize);
}
break;
}
}
}
@ -2665,17 +3011,35 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
public void run() {
if (finalDocument != null) {
finalDocument.caption = result.send_message.caption;
SendMessagesHelper.getInstance().sendMessage(finalDocument, null, finalPathFinal, dialog_id, reply_to_msg, asAdmin, params);
SendMessagesHelper.getInstance().sendMessage(finalDocument, null, finalPathFinal, dialog_id, reply_to_msg, asAdmin, result.send_message.reply_markup, params);
} else if (finalPhoto != null) {
finalPhoto.caption = result.send_message.caption;
SendMessagesHelper.getInstance().sendMessage(finalPhoto, result.content_url, dialog_id, reply_to_msg, asAdmin, params);
SendMessagesHelper.getInstance().sendMessage(finalPhoto, result.content_url, dialog_id, reply_to_msg, asAdmin, result.send_message.reply_markup, params);
}
}
});
}
}).run();
} else if (result.send_message instanceof TLRPC.TL_botInlineMessageText) {
SendMessagesHelper.getInstance().sendMessage(result.send_message.message, dialog_id, reply_to_msg, null, !result.send_message.no_webpage, asAdmin, result.send_message.entities, params);
SendMessagesHelper.getInstance().sendMessage(result.send_message.message, dialog_id, reply_to_msg, null, !result.send_message.no_webpage, asAdmin, result.send_message.entities, result.send_message.reply_markup, params);
} else if (result.send_message instanceof TLRPC.TL_botInlineMessageMediaVenue) {
TLRPC.TL_messageMediaVenue venue = new TLRPC.TL_messageMediaVenue();
venue.geo = result.send_message.geo;
venue.address = result.send_message.address;
venue.title = result.send_message.title;
venue.provider = result.send_message.provider;
venue.venue_id = result.send_message.venue_id;
SendMessagesHelper.getInstance().sendMessage(venue, dialog_id, reply_to_msg, asAdmin, result.send_message.reply_markup, params);
} else if (result.send_message instanceof TLRPC.TL_botInlineMessageMediaGeo) {
TLRPC.TL_messageMediaGeo location = new TLRPC.TL_messageMediaGeo();
location.geo = result.send_message.geo;
SendMessagesHelper.getInstance().sendMessage(location, dialog_id, reply_to_msg, asAdmin, result.send_message.reply_markup, params);
} else if (result.send_message instanceof TLRPC.TL_botInlineMessageMediaContact) {
TLRPC.User user = new TLRPC.TL_user();
user.phone = result.send_message.phone_number;
user.first_name = result.send_message.first_name;
user.last_name = result.send_message.last_name;
SendMessagesHelper.getInstance().sendMessage(user, dialog_id, reply_to_msg, asAdmin, result.send_message.reply_markup, params);
}
}
@ -2775,7 +3139,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
SendMessagesHelper.getInstance().sendMessage(documentFinal, null, pathFinal, dialog_id, reply_to_msg, asAdmin, params);
SendMessagesHelper.getInstance().sendMessage(documentFinal, null, pathFinal, dialog_id, reply_to_msg, asAdmin, null, params);
}
});
} else {
@ -2825,7 +3189,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
SendMessagesHelper.getInstance().sendMessage(photoFinal, needDownloadHttpFinal ? searchImage.imageUrl : null, dialog_id, reply_to_msg, asAdmin, params);
SendMessagesHelper.getInstance().sendMessage(photoFinal, needDownloadHttpFinal ? searchImage.imageUrl : null, dialog_id, reply_to_msg, asAdmin, null, params);
}
});
}
@ -2864,7 +3228,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
int count = (int) Math.ceil(textFinal.length() / 4096.0f);
for (int a = 0; a < count; a++) {
String mess = textFinal.substring(a * 4096, Math.min((a + 1) * 4096, textFinal.length()));
SendMessagesHelper.getInstance().sendMessage(mess, dialog_id, null, null, true, asAdmin, null, null);
SendMessagesHelper.getInstance().sendMessage(mess, dialog_id, null, null, true, asAdmin, null, null, null);
}
}
}
@ -2973,7 +3337,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
SendMessagesHelper.getInstance().sendMessage(photoFinal, null, dialog_id, reply_to_msg, asAdmin, params);
SendMessagesHelper.getInstance().sendMessage(photoFinal, null, dialog_id, reply_to_msg, asAdmin, null, params);
}
});
}
@ -3103,7 +3467,7 @@ public class SendMessagesHelper implements NotificationCenter.NotificationCenter
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
SendMessagesHelper.getInstance().sendMessage(videoFinal, videoEditedInfo, finalPath, dialog_id, reply_to_msg, asAdmin, params);
SendMessagesHelper.getInstance().sendMessage(videoFinal, videoEditedInfo, finalPath, dialog_id, reply_to_msg, asAdmin, null, params);
}
});
} else {

View File

@ -0,0 +1,29 @@
/*
* This is the source code of Telegram for Android v. 3.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-2016.
*/
package org.telegram.messenger;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class ShareBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String url = intent.getDataString();
if (url != null) {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, url);
Intent chooserIntent = Intent.createChooser(shareIntent, LocaleController.getString("ShareLink", R.string.ShareLink));
chooserIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(chooserIntent);
}
}
}

View File

@ -47,7 +47,7 @@ public class Utilities {
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 int unpinBitmap(Bitmap bitmap);
public native static void unpinBitmap(Bitmap bitmap);
public native static void blurBitmap(Object bitmap, int radius, int unpin, int width, int height, int stride);
public native static void calcCDT(ByteBuffer hsvBuffer, int width, int height, ByteBuffer buffer);
public native static boolean loadWebpImage(Bitmap bitmap, ByteBuffer buffer, int len, BitmapFactory.Options options, boolean unpin);
@ -255,8 +255,8 @@ public class Utilities {
java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
byte[] array = md.digest(md5.getBytes());
StringBuilder sb = new StringBuilder();
for (byte anArray : array) {
sb.append(Integer.toHexString((anArray & 0xFF) | 0x100).substring(1, 3));
for (int a = 0; a < array.length; a++) {
sb.append(Integer.toHexString((array[a] & 0xFF) | 0x100).substring(1, 3));
}
return sb.toString();
} catch (java.security.NoSuchAlgorithmException e) {

View File

@ -18,6 +18,7 @@ public class WearReplyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ApplicationLoader.postInitApplication();
Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
if (remoteInput == null) {
return;
@ -31,7 +32,7 @@ public class WearReplyReceiver extends BroadcastReceiver {
if (dialog_id == 0 || max_id == 0) {
return;
}
SendMessagesHelper.getInstance().sendMessage(text.toString(), dialog_id, null, null, true, false, null, null);
SendMessagesHelper.getInstance().sendMessage(text.toString(), dialog_id, null, null, true, false, null, null, null);
MessagesController.getInstance().markDialogAsRead(dialog_id, max_id, max_id, 0, true, false);
}
}

View File

@ -0,0 +1,188 @@
/*
* This is the source code of Telegram for Android v. 3.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-2016.
*/
package org.telegram.messenger.browser;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaController;
import org.telegram.messenger.R;
import org.telegram.messenger.ShareBroadcastReceiver;
import org.telegram.messenger.support.customtabs.CustomTabsCallback;
import org.telegram.messenger.support.customtabs.CustomTabsClient;
import org.telegram.messenger.support.customtabs.CustomTabsIntent;
import org.telegram.messenger.support.customtabs.CustomTabsServiceConnection;
import org.telegram.messenger.support.customtabs.CustomTabsSession;
import org.telegram.messenger.support.customtabsclient.shared.CustomTabsHelper;
import org.telegram.messenger.support.customtabsclient.shared.ServiceConnection;
import org.telegram.messenger.support.customtabsclient.shared.ServiceConnectionCallback;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.LaunchActivity;
import java.lang.ref.WeakReference;
public class Browser {
private static WeakReference<CustomTabsSession> customTabsCurrentSession;
private static CustomTabsSession customTabsSession;
private static CustomTabsClient customTabsClient;
private static CustomTabsServiceConnection customTabsServiceConnection;
private static String customTabsPackageToBind;
private static WeakReference<Activity> currentCustomTabsActivity;
private static CustomTabsSession getCurrentSession() {
return customTabsCurrentSession == null ? null : customTabsCurrentSession.get();
}
private static void setCurrentSession(CustomTabsSession session) {
customTabsCurrentSession = new WeakReference<>(session);
}
private static CustomTabsSession getSession() {
if (customTabsClient == null) {
customTabsSession = null;
} else if (customTabsSession == null) {
customTabsSession = customTabsClient.newSession(new NavigationCallback());
setCurrentSession(customTabsSession);
}
return customTabsSession;
}
public static void bindCustomTabsService(Activity activity) {
if (Build.VERSION.SDK_INT < 15) {
return;
}
Activity currentActivity = currentCustomTabsActivity == null ? null : currentCustomTabsActivity.get();
if (currentActivity != null && currentActivity != activity) {
unbindCustomTabsService(currentActivity);
}
if (customTabsClient != null) {
return;
}
currentCustomTabsActivity = new WeakReference<>(activity);
try {
if (TextUtils.isEmpty(customTabsPackageToBind)) {
customTabsPackageToBind = CustomTabsHelper.getPackageNameToUse(activity);
if (customTabsPackageToBind == null) {
return;
}
}
customTabsServiceConnection = new ServiceConnection(new ServiceConnectionCallback() {
@Override
public void onServiceConnected(CustomTabsClient client) {
customTabsClient = client;
if (customTabsClient != null) {
customTabsClient.warmup(0);
}
}
@Override
public void onServiceDisconnected() {
customTabsClient = null;
}
});
if (!CustomTabsClient.bindCustomTabsService(activity, customTabsPackageToBind, customTabsServiceConnection)) {
customTabsServiceConnection = null;
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
public static void unbindCustomTabsService(Activity activity) {
if (Build.VERSION.SDK_INT < 15 || customTabsServiceConnection == null) {
return;
}
Activity currentActivity = currentCustomTabsActivity == null ? null : currentCustomTabsActivity.get();
if (currentActivity == activity) {
currentCustomTabsActivity.clear();
}
try {
activity.unbindService(customTabsServiceConnection);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
customTabsClient = null;
customTabsSession = null;
}
private static class NavigationCallback extends CustomTabsCallback {
@Override
public void onNavigationEvent(int navigationEvent, Bundle extras) {
FileLog.e("tmessages", "code = " + navigationEvent + " extras " + extras);
}
}
public static void openUrl(Context context, String url) {
openUrl(context, Uri.parse(url), true);
}
public static void openUrl(Context context, Uri uri) {
openUrl(context, uri, true);
}
public static void openUrl(Context context, String url, boolean allowCustom) {
if (context == null || url == null) {
return;
}
openUrl(context, Uri.parse(url), allowCustom);
}
public static void openUrl(Context context, Uri uri, boolean allowCustom) {
if (context == null || uri == null) {
return;
}
try {
boolean internalUri = isInternalUri(uri);
if (Build.VERSION.SDK_INT >= 15 && allowCustom && MediaController.getInstance().canCustomTabs() && !internalUri) {
Intent share = new Intent(ApplicationLoader.applicationContext, ShareBroadcastReceiver.class);
share.setAction(Intent.ACTION_SEND);
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(getSession());
builder.setToolbarColor(Theme.ACTION_BAR_COLOR);
builder.setShowTitle(true);
builder.setActionButton(BitmapFactory.decodeResource(context.getResources(), R.drawable.abc_ic_menu_share_mtrl_alpha), LocaleController.getString("ShareFile", R.string.ShareFile), PendingIntent.getBroadcast(ApplicationLoader.applicationContext, 0, share, 0), false);
CustomTabsIntent intent = builder.build();
intent.launchUrl((Activity) context, uri);
} else {
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
if (internalUri) {
ComponentName componentName = new ComponentName(context.getPackageName(), LaunchActivity.class.getName());
intent.setComponent(componentName);
}
intent.putExtra(android.provider.Browser.EXTRA_APPLICATION_ID, context.getPackageName());
context.startActivity(intent);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
public static boolean isInternalUrl(String url) {
return isInternalUri(Uri.parse(url));
}
public static boolean isInternalUri(Uri uri) {
String host = uri.getHost();
host = host != null ? host.toLowerCase() : "";
return "tg".equals(uri.getScheme()) || "telegram.me".equals(host) || "telegram.dog".equals(host);
}
}

View File

@ -144,12 +144,14 @@ public class SharedMediaQuery {
if (message == null) {
return -1;
}
if (message.media instanceof TLRPC.TL_messageMediaPhoto || MessageObject.isVideoMessage(message)) {
if (message.media instanceof TLRPC.TL_messageMediaPhoto) {
return MEDIA_PHOTOVIDEO;
} else if (MessageObject.isVoiceMessage(message)) {
return MEDIA_AUDIO;
} else if (message.media instanceof TLRPC.TL_messageMediaDocument) {
if (MessageObject.isStickerMessage(message)) {
if (MessageObject.isVoiceMessage(message)) {
return MEDIA_AUDIO;
} else if (MessageObject.isVideoMessage(message)) {
return MEDIA_PHOTOVIDEO;
} else if (MessageObject.isStickerMessage(message)) {
return -1;
} else if (MessageObject.isMusicMessage(message)) {
return MEDIA_MUSIC;

View File

@ -8,11 +8,7 @@
package org.telegram.messenger.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;
@ -29,8 +25,6 @@ import org.telegram.tgnet.RequestDelegate;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.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;
@ -85,6 +79,14 @@ public class StickersQuery {
return document;
}
public static TLRPC.TL_messages_stickerSet getStickerSetByName(String name) {
return stickerSetsByName.get(name);
}
public static TLRPC.TL_messages_stickerSet getStickerSetById(Long id) {
return stickerSetsById.get(id);
}
public static HashMap<String, ArrayList<TLRPC.Document>> getAllStickers() {
return allStickers;
}
@ -441,100 +443,6 @@ 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 int reqId = ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
@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.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);
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().sendRequest(req, new RequestDelegate() {
@Override
public void run(TLObject response, final TLRPC.TL_error error) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
if (fragment.getParentActivity() != null) {
if (error == null) {
Toast.makeText(fragment.getParentActivity(), LocaleController.getString("AddStickersInstalled", R.string.AddStickersInstalled), Toast.LENGTH_SHORT).show();
} else {
if (error.text.equals("STICKERSETS_TOO_MUCH")) {
Toast.makeText(fragment.getParentActivity(), LocaleController.getString("TooMuchStickersets", R.string.TooMuchStickersets), 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, 0);
}
});
}
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().cancelRequest(reqId, true);
try {
dialog.dismiss();
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
});
fragment.setVisibleDialog(progressDialog);
progressDialog.show();
}
public static void removeStickersSet(final Context context, TLRPC.StickerSet stickerSet, int hide) {
TLRPC.TL_inputStickerSetID stickerSetID = new TLRPC.TL_inputStickerSetID();
stickerSetID.access_hash = stickerSet.access_hash;

View File

@ -0,0 +1,40 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.messenger.support.customtabs;
import android.os.Bundle;
/**
* A callback class for custom tabs client to get messages regarding events in their custom tabs.
*/
public class CustomTabsCallback {
public static final int NAVIGATION_STARTED = 1;
public static final int NAVIGATION_FINISHED = 2;
public static final int NAVIGATION_FAILED = 3;
public static final int NAVIGATION_ABORTED = 4;
public static final int TAB_SHOWN = 5;
public static final int TAB_HIDDEN = 6;
public CustomTabsCallback() {
}
public void onNavigationEvent(int navigationEvent, Bundle extras) {
}
public void extraCallback(String callbackName, Bundle args) {
}
}

View File

@ -0,0 +1,87 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.messenger.support.customtabs;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.RemoteException;
import android.text.TextUtils;
public class CustomTabsClient {
private final ICustomTabsService mService;
private final ComponentName mServiceComponentName;
CustomTabsClient(ICustomTabsService service, ComponentName componentName) {
this.mService = service;
this.mServiceComponentName = componentName;
}
public static boolean bindCustomTabsService(Context context, String packageName, CustomTabsServiceConnection connection) {
Intent intent = new Intent("android.support.customtabs.action.CustomTabsService");
if (!TextUtils.isEmpty(packageName)) {
intent.setPackage(packageName);
}
return context.bindService(intent, connection, 33);
}
public boolean warmup(long flags) {
try {
return this.mService.warmup(flags);
} catch (RemoteException var4) {
return false;
}
}
public CustomTabsSession newSession(final CustomTabsCallback callback) {
ICustomTabsCallback.Stub wrapper = new ICustomTabsCallback.Stub() {
public void onNavigationEvent(int navigationEvent, Bundle extras) {
if (callback != null) {
callback.onNavigationEvent(navigationEvent, extras);
}
}
public void extraCallback(String callbackName, Bundle args) throws RemoteException {
if (callback != null) {
callback.extraCallback(callbackName, args);
}
}
};
try {
if (!this.mService.newSession(wrapper)) {
return null;
}
} catch (RemoteException var4) {
return null;
}
return new CustomTabsSession(this.mService, wrapper, this.mServiceComponentName);
}
public Bundle extraCommand(String commandName, Bundle args) {
try {
return this.mService.extraCommand(commandName, args);
} catch (RemoteException var4) {
return null;
}
}
}

View File

@ -0,0 +1,206 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.messenger.support.customtabs;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.AnimRes;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.ActivityOptionsCompat;
import android.support.v4.app.BundleCompat;
import java.util.ArrayList;
/**
* Class holding the {@link Intent} and start bundle for a Custom Tabs Activity.
*
* <p>
* <strong>Note:</strong> The constants below are public for the browser implementation's benefit.
* You are strongly encouraged to use {@link CustomTabsIntent.Builder}.</p>
*/
public final class CustomTabsIntent {
public static final String EXTRA_SESSION = "android.support.customtabs.extra.SESSION";
public static final String EXTRA_TOOLBAR_COLOR = "android.support.customtabs.extra.TOOLBAR_COLOR";
public static final String EXTRA_ENABLE_URLBAR_HIDING = "android.support.customtabs.extra.ENABLE_URLBAR_HIDING";
public static final String EXTRA_CLOSE_BUTTON_ICON = "android.support.customtabs.extra.CLOSE_BUTTON_ICON";
public static final String EXTRA_TITLE_VISIBILITY_STATE = "android.support.customtabs.extra.TITLE_VISIBILITY";
public static final int NO_TITLE = 0;
public static final int SHOW_PAGE_TITLE = 1;
public static final String EXTRA_ACTION_BUTTON_BUNDLE = "android.support.customtabs.extra.ACTION_BUTTON_BUNDLE";
public static final String EXTRA_TOOLBAR_ITEMS = "android.support.customtabs.extra.TOOLBAR_ITEMS";
public static final String EXTRA_SECONDARY_TOOLBAR_COLOR = "android.support.customtabs.extra.SECONDARY_TOOLBAR_COLOR";
public static final String KEY_ICON = "android.support.customtabs.customaction.ICON";
public static final String KEY_DESCRIPTION = "android.support.customtabs.customaction.DESCRIPTION";
public static final String KEY_PENDING_INTENT = "android.support.customtabs.customaction.PENDING_INTENT";
public static final String EXTRA_TINT_ACTION_BUTTON = "android.support.customtabs.extra.TINT_ACTION_BUTTON";
public static final String EXTRA_MENU_ITEMS = "android.support.customtabs.extra.MENU_ITEMS";
public static final String KEY_MENU_ITEM_TITLE = "android.support.customtabs.customaction.MENU_ITEM_TITLE";
public static final String EXTRA_EXIT_ANIMATION_BUNDLE = "android.support.customtabs.extra.EXIT_ANIMATION_BUNDLE";
public static final String EXTRA_DEFAULT_SHARE_MENU_ITEM = "android.support.customtabs.extra.SHARE_MENU_ITEM";
public static final String KEY_ID = "android.support.customtabs.customaction.ID";
public static final int TOOLBAR_ACTION_BUTTON_ID = 0;
private static final int MAX_TOOLBAR_ITEMS = 5;
@NonNull
public final Intent intent;
@Nullable
public final Bundle startAnimationBundle;
public void launchUrl(Activity context, Uri url) {
this.intent.setData(url);
ActivityCompat.startActivity(context, this.intent, this.startAnimationBundle);
}
private CustomTabsIntent(Intent intent, Bundle startAnimationBundle) {
this.intent = intent;
this.startAnimationBundle = startAnimationBundle;
}
public static int getMaxToolbarItems() {
return 5;
}
public static final class Builder {
private final Intent mIntent;
private ArrayList<Bundle> mMenuItems;
private Bundle mStartAnimationBundle;
private ArrayList<Bundle> mActionButtons;
public Builder() {
this(null);
}
public Builder(@Nullable CustomTabsSession session) {
this.mIntent = new Intent("android.intent.action.VIEW");
this.mMenuItems = null;
this.mStartAnimationBundle = null;
this.mActionButtons = null;
if (session != null) {
this.mIntent.setPackage(session.getComponentName().getPackageName());
}
Bundle bundle = new Bundle();
BundleCompat.putBinder(bundle, "android.support.customtabs.extra.SESSION", session == null ? null : session.getBinder());
this.mIntent.putExtras(bundle);
}
public CustomTabsIntent.Builder setToolbarColor(@ColorInt int color) {
this.mIntent.putExtra("android.support.customtabs.extra.TOOLBAR_COLOR", color);
return this;
}
public CustomTabsIntent.Builder enableUrlBarHiding() {
this.mIntent.putExtra("android.support.customtabs.extra.ENABLE_URLBAR_HIDING", true);
return this;
}
public CustomTabsIntent.Builder setCloseButtonIcon(@NonNull Bitmap icon) {
this.mIntent.putExtra("android.support.customtabs.extra.CLOSE_BUTTON_ICON", icon);
return this;
}
public CustomTabsIntent.Builder setShowTitle(boolean showTitle) {
this.mIntent.putExtra("android.support.customtabs.extra.TITLE_VISIBILITY", showTitle ? 1 : 0);
return this;
}
public CustomTabsIntent.Builder addMenuItem(@NonNull String label, @NonNull PendingIntent pendingIntent) {
if (this.mMenuItems == null) {
this.mMenuItems = new ArrayList();
}
Bundle bundle = new Bundle();
bundle.putString("android.support.customtabs.customaction.MENU_ITEM_TITLE", label);
bundle.putParcelable("android.support.customtabs.customaction.PENDING_INTENT", pendingIntent);
this.mMenuItems.add(bundle);
return this;
}
public CustomTabsIntent.Builder addDefaultShareMenuItem() {
this.mIntent.putExtra("android.support.customtabs.extra.SHARE_MENU_ITEM", true);
return this;
}
public CustomTabsIntent.Builder setActionButton(@NonNull Bitmap icon, @NonNull String description, @NonNull PendingIntent pendingIntent, boolean shouldTint) {
Bundle bundle = new Bundle();
bundle.putInt("android.support.customtabs.customaction.ID", 0);
bundle.putParcelable("android.support.customtabs.customaction.ICON", icon);
bundle.putString("android.support.customtabs.customaction.DESCRIPTION", description);
bundle.putParcelable("android.support.customtabs.customaction.PENDING_INTENT", pendingIntent);
this.mIntent.putExtra("android.support.customtabs.extra.ACTION_BUTTON_BUNDLE", bundle);
this.mIntent.putExtra("android.support.customtabs.extra.TINT_ACTION_BUTTON", shouldTint);
return this;
}
public CustomTabsIntent.Builder setActionButton(@NonNull Bitmap icon, @NonNull String description, @NonNull PendingIntent pendingIntent) {
return this.setActionButton(icon, description, pendingIntent, false);
}
public CustomTabsIntent.Builder addToolbarItem(int id, @NonNull Bitmap icon, @NonNull String description, PendingIntent pendingIntent) throws IllegalStateException {
if (this.mActionButtons == null) {
this.mActionButtons = new ArrayList();
}
if (this.mActionButtons.size() >= 5) {
throw new IllegalStateException("Exceeded maximum toolbar item count of 5");
} else {
Bundle bundle = new Bundle();
bundle.putInt("android.support.customtabs.customaction.ID", id);
bundle.putParcelable("android.support.customtabs.customaction.ICON", icon);
bundle.putString("android.support.customtabs.customaction.DESCRIPTION", description);
bundle.putParcelable("android.support.customtabs.customaction.PENDING_INTENT", pendingIntent);
this.mActionButtons.add(bundle);
return this;
}
}
public CustomTabsIntent.Builder setSecondaryToolbarColor(@ColorInt int color) {
this.mIntent.putExtra("android.support.customtabs.extra.SECONDARY_TOOLBAR_COLOR", color);
return this;
}
public CustomTabsIntent.Builder setStartAnimations(@NonNull Context context, @AnimRes int enterResId, @AnimRes int exitResId) {
this.mStartAnimationBundle = ActivityOptionsCompat.makeCustomAnimation(context, enterResId, exitResId).toBundle();
return this;
}
public CustomTabsIntent.Builder setExitAnimations(@NonNull Context context, @AnimRes int enterResId, @AnimRes int exitResId) {
Bundle bundle = ActivityOptionsCompat.makeCustomAnimation(context, enterResId, exitResId).toBundle();
this.mIntent.putExtra("android.support.customtabs.extra.EXIT_ANIMATION_BUNDLE", bundle);
return this;
}
public CustomTabsIntent build() {
if (this.mMenuItems != null) {
this.mIntent.putParcelableArrayListExtra("android.support.customtabs.extra.MENU_ITEMS", this.mMenuItems);
}
if (this.mActionButtons != null) {
this.mIntent.putParcelableArrayListExtra("android.support.customtabs.extra.TOOLBAR_ITEMS", this.mActionButtons);
}
return new CustomTabsIntent(this.mIntent, this.mStartAnimationBundle);
}
}
}

View File

@ -0,0 +1,105 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.messenger.support.customtabs;
import android.app.Service;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
import android.os.RemoteException;
import android.support.v4.util.ArrayMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
public abstract class CustomTabsService extends Service {
public static final String ACTION_CUSTOM_TABS_CONNECTION = "android.support.customtabs.action.CustomTabsService";
public static final String KEY_URL = "android.support.customtabs.otherurls.URL";
private final Map<IBinder, DeathRecipient> mDeathRecipientMap = new ArrayMap();
private ICustomTabsService.Stub mBinder = new ICustomTabsService.Stub() {
public boolean warmup(long flags) {
return CustomTabsService.this.warmup(flags);
}
public boolean newSession(ICustomTabsCallback callback) {
final CustomTabsSessionToken sessionToken = new CustomTabsSessionToken(callback);
try {
DeathRecipient e = new DeathRecipient() {
public void binderDied() {
CustomTabsService.this.cleanUpSession(sessionToken);
}
};
synchronized (CustomTabsService.this.mDeathRecipientMap) {
callback.asBinder().linkToDeath(e, 0);
CustomTabsService.this.mDeathRecipientMap.put(callback.asBinder(), e);
}
return CustomTabsService.this.newSession(sessionToken);
} catch (RemoteException var7) {
return false;
}
}
public boolean mayLaunchUrl(ICustomTabsCallback callback, Uri url, Bundle extras, List<Bundle> otherLikelyBundles) {
return CustomTabsService.this.mayLaunchUrl(new CustomTabsSessionToken(callback), url, extras, otherLikelyBundles);
}
public Bundle extraCommand(String commandName, Bundle args) {
return CustomTabsService.this.extraCommand(commandName, args);
}
public boolean updateVisuals(ICustomTabsCallback callback, Bundle bundle) {
return CustomTabsService.this.updateVisuals(new CustomTabsSessionToken(callback), bundle);
}
};
public CustomTabsService() {
}
public IBinder onBind(Intent intent) {
return this.mBinder;
}
protected boolean cleanUpSession(CustomTabsSessionToken sessionToken) {
try {
Map e = this.mDeathRecipientMap;
synchronized (this.mDeathRecipientMap) {
IBinder binder = sessionToken.getCallbackBinder();
DeathRecipient deathRecipient = this.mDeathRecipientMap.get(binder);
binder.unlinkToDeath(deathRecipient, 0);
this.mDeathRecipientMap.remove(binder);
return true;
}
} catch (NoSuchElementException var7) {
return false;
}
}
protected abstract boolean warmup(long var1);
protected abstract boolean newSession(CustomTabsSessionToken var1);
protected abstract boolean mayLaunchUrl(CustomTabsSessionToken var1, Uri var2, Bundle var3, List<Bundle> var4);
protected abstract Bundle extraCommand(String var1, Bundle var2);
protected abstract boolean updateVisuals(CustomTabsSessionToken var1, Bundle var2);
}

View File

@ -0,0 +1,33 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.messenger.support.customtabs;
import android.content.ComponentName;
import android.content.ServiceConnection;
import android.os.IBinder;
public abstract class CustomTabsServiceConnection implements ServiceConnection {
public CustomTabsServiceConnection() {
}
public final void onServiceConnected(final ComponentName name, IBinder service) {
this.onCustomTabsServiceConnected(name, new CustomTabsClient(ICustomTabsService.Stub.asInterface(service), name) {
});
}
public abstract void onCustomTabsServiceConnected(ComponentName var1, CustomTabsClient var2);
}

View File

@ -0,0 +1,79 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.messenger.support.customtabs;
import android.content.ComponentName;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.NonNull;
import java.util.List;
/**
* A class to be used for Custom Tabs related communication. Clients that want to launch Custom Tabs
* can use this class exclusively to handle all related communication.
*/
public final class CustomTabsSession {
private static final String TAG = "CustomTabsSession";
private final ICustomTabsService mService;
private final ICustomTabsCallback mCallback;
private final ComponentName mComponentName;
CustomTabsSession(ICustomTabsService service, ICustomTabsCallback callback, ComponentName componentName) {
this.mService = service;
this.mCallback = callback;
this.mComponentName = componentName;
}
public boolean mayLaunchUrl(Uri url, Bundle extras, List<Bundle> otherLikelyBundles) {
try {
return this.mService.mayLaunchUrl(this.mCallback, url, extras, otherLikelyBundles);
} catch (RemoteException var5) {
return false;
}
}
public boolean setActionButton(@NonNull Bitmap icon, @NonNull String description) {
return this.setToolbarItem(0, icon, description);
}
public boolean setToolbarItem(int id, @NonNull Bitmap icon, @NonNull String description) {
Bundle bundle = new Bundle();
bundle.putInt("android.support.customtabs.customaction.ID", id);
bundle.putParcelable("android.support.customtabs.customaction.ICON", icon);
bundle.putString("android.support.customtabs.customaction.DESCRIPTION", description);
Bundle metaBundle = new Bundle();
metaBundle.putBundle("android.support.customtabs.extra.ACTION_BUTTON_BUNDLE", bundle);
try {
return this.mService.updateVisuals(this.mCallback, metaBundle);
} catch (RemoteException var7) {
return false;
}
}
IBinder getBinder() {
return this.mCallback.asBinder();
}
ComponentName getComponentName() {
return this.mComponentName;
}
}

View File

@ -0,0 +1,75 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.messenger.support.customtabs;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v4.app.BundleCompat;
import android.util.Log;
/**
* Wrapper class that can be used as a unique identifier for a session. Also contains an accessor
* for the {@link CustomTabsCallback} for the session if there was any.
*/
public class CustomTabsSessionToken {
private static final String TAG = "CustomTabsSessionToken";
private final ICustomTabsCallback mCallbackBinder;
private final CustomTabsCallback mCallback;
public static CustomTabsSessionToken getSessionTokenFromIntent(Intent intent) {
Bundle b = intent.getExtras();
IBinder binder = BundleCompat.getBinder(b, "android.support.customtabs.extra.SESSION");
return binder == null ? null : new CustomTabsSessionToken(ICustomTabsCallback.Stub.asInterface(binder));
}
CustomTabsSessionToken(ICustomTabsCallback callbackBinder) {
this.mCallbackBinder = callbackBinder;
this.mCallback = new CustomTabsCallback() {
public void onNavigationEvent(int navigationEvent, Bundle extras) {
try {
CustomTabsSessionToken.this.mCallbackBinder.onNavigationEvent(navigationEvent, extras);
} catch (RemoteException var4) {
Log.e("CustomTabsSessionToken", "RemoteException during ICustomTabsCallback transaction");
}
}
};
}
IBinder getCallbackBinder() {
return this.mCallbackBinder.asBinder();
}
public int hashCode() {
return this.getCallbackBinder().hashCode();
}
public boolean equals(Object o) {
if (!(o instanceof CustomTabsSessionToken)) {
return false;
} else {
CustomTabsSessionToken token = (CustomTabsSessionToken) o;
return token.getCallbackBinder().equals(this.mCallbackBinder.asBinder());
}
}
public CustomTabsCallback getCallback() {
return this.mCallback;
}
}

View File

@ -0,0 +1,142 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.messenger.support.customtabs;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Parcel;
import android.os.RemoteException;
public interface ICustomTabsCallback extends IInterface {
void onNavigationEvent(int var1, Bundle var2) throws RemoteException;
void extraCallback(String var1, Bundle var2) throws RemoteException;
abstract class Stub extends Binder implements ICustomTabsCallback {
private static final String DESCRIPTOR = "android.support.customtabs.ICustomTabsCallback";
static final int TRANSACTION_onNavigationEvent = 2;
static final int TRANSACTION_extraCallback = 3;
public Stub() {
this.attachInterface(this, "android.support.customtabs.ICustomTabsCallback");
}
public static ICustomTabsCallback asInterface(IBinder obj) {
if (obj == null) {
return null;
} else {
IInterface iin = obj.queryLocalInterface("android.support.customtabs.ICustomTabsCallback");
return (iin != null && iin instanceof ICustomTabsCallback ? (ICustomTabsCallback) iin : new ICustomTabsCallback.Stub.Proxy(obj));
}
}
public IBinder asBinder() {
return this;
}
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
Bundle _arg1;
switch (code) {
case 2:
data.enforceInterface("android.support.customtabs.ICustomTabsCallback");
int _arg01 = data.readInt();
if (0 != data.readInt()) {
_arg1 = Bundle.CREATOR.createFromParcel(data);
} else {
_arg1 = null;
}
this.onNavigationEvent(_arg01, _arg1);
return true;
case 3:
data.enforceInterface("android.support.customtabs.ICustomTabsCallback");
String _arg0 = data.readString();
if (0 != data.readInt()) {
_arg1 = Bundle.CREATOR.createFromParcel(data);
} else {
_arg1 = null;
}
this.extraCallback(_arg0, _arg1);
return true;
case 1598968902:
reply.writeString("android.support.customtabs.ICustomTabsCallback");
return true;
default:
return super.onTransact(code, data, reply, flags);
}
}
private static class Proxy implements ICustomTabsCallback {
private IBinder mRemote;
Proxy(IBinder remote) {
this.mRemote = remote;
}
public IBinder asBinder() {
return this.mRemote;
}
public String getInterfaceDescriptor() {
return "android.support.customtabs.ICustomTabsCallback";
}
public void onNavigationEvent(int navigationEvent, Bundle extras) throws RemoteException {
Parcel _data = Parcel.obtain();
try {
_data.writeInterfaceToken("android.support.customtabs.ICustomTabsCallback");
_data.writeInt(navigationEvent);
if (extras != null) {
_data.writeInt(1);
extras.writeToParcel(_data, 0);
} else {
_data.writeInt(0);
}
this.mRemote.transact(2, _data, null, 1);
} finally {
_data.recycle();
}
}
public void extraCallback(String callbackName, Bundle args) throws RemoteException {
Parcel _data = Parcel.obtain();
try {
_data.writeInterfaceToken("android.support.customtabs.ICustomTabsCallback");
_data.writeString(callbackName);
if (args != null) {
_data.writeInt(1);
args.writeToParcel(_data, 0);
} else {
_data.writeInt(0);
}
this.mRemote.transact(3, _data, null, 1);
} finally {
_data.recycle();
}
}
}
}
}

View File

@ -0,0 +1,291 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.telegram.messenger.support.customtabs;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Parcel;
import android.os.RemoteException;
import java.util.ArrayList;
import java.util.List;
public interface ICustomTabsService extends IInterface {
boolean warmup(long var1) throws RemoteException;
boolean newSession(ICustomTabsCallback var1) throws RemoteException;
boolean mayLaunchUrl(ICustomTabsCallback var1, Uri var2, Bundle var3, List<Bundle> var4) throws RemoteException;
Bundle extraCommand(String var1, Bundle var2) throws RemoteException;
boolean updateVisuals(ICustomTabsCallback var1, Bundle var2) throws RemoteException;
abstract class Stub extends Binder implements ICustomTabsService {
private static final String DESCRIPTOR = "android.support.customtabs.ICustomTabsService";
static final int TRANSACTION_warmup = 2;
static final int TRANSACTION_newSession = 3;
static final int TRANSACTION_mayLaunchUrl = 4;
static final int TRANSACTION_extraCommand = 5;
static final int TRANSACTION_updateVisuals = 6;
public Stub() {
this.attachInterface(this, "android.support.customtabs.ICustomTabsService");
}
public static ICustomTabsService asInterface(IBinder obj) {
if (obj == null) {
return null;
} else {
IInterface iin = obj.queryLocalInterface("android.support.customtabs.ICustomTabsService");
return (iin != null && iin instanceof ICustomTabsService ? (ICustomTabsService) iin : new ICustomTabsService.Stub.Proxy(obj));
}
}
public IBinder asBinder() {
return this;
}
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
ICustomTabsCallback _arg0;
Bundle _arg1;
boolean _result;
Bundle _result2;
switch (code) {
case 2:
data.enforceInterface("android.support.customtabs.ICustomTabsService");
long _arg02 = data.readLong();
_result = this.warmup(_arg02);
reply.writeNoException();
reply.writeInt(_result ? 1 : 0);
return true;
case 3:
data.enforceInterface("android.support.customtabs.ICustomTabsService");
_arg0 = ICustomTabsCallback.Stub.asInterface(data.readStrongBinder());
boolean _arg12 = this.newSession(_arg0);
reply.writeNoException();
reply.writeInt(_arg12 ? 1 : 0);
return true;
case 4:
data.enforceInterface("android.support.customtabs.ICustomTabsService");
_arg0 = ICustomTabsCallback.Stub.asInterface(data.readStrongBinder());
Uri _arg11;
if (0 != data.readInt()) {
_arg11 = Uri.CREATOR.createFromParcel(data);
} else {
_arg11 = null;
}
if (0 != data.readInt()) {
_result2 = Bundle.CREATOR.createFromParcel(data);
} else {
_result2 = null;
}
ArrayList _arg3 = data.createTypedArrayList(Bundle.CREATOR);
boolean _result1 = this.mayLaunchUrl(_arg0, _arg11, _result2, _arg3);
reply.writeNoException();
reply.writeInt(_result1 ? 1 : 0);
return true;
case 5:
data.enforceInterface("android.support.customtabs.ICustomTabsService");
String _arg01 = data.readString();
if (0 != data.readInt()) {
_arg1 = Bundle.CREATOR.createFromParcel(data);
} else {
_arg1 = null;
}
_result2 = this.extraCommand(_arg01, _arg1);
reply.writeNoException();
if (_result2 != null) {
reply.writeInt(1);
_result2.writeToParcel(reply, 1);
} else {
reply.writeInt(0);
}
return true;
case 6:
data.enforceInterface("android.support.customtabs.ICustomTabsService");
_arg0 = ICustomTabsCallback.Stub.asInterface(data.readStrongBinder());
if (0 != data.readInt()) {
_arg1 = Bundle.CREATOR.createFromParcel(data);
} else {
_arg1 = null;
}
_result = this.updateVisuals(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(_result ? 1 : 0);
return true;
case 1598968902:
reply.writeString("android.support.customtabs.ICustomTabsService");
return true;
default:
return super.onTransact(code, data, reply, flags);
}
}
private static class Proxy implements ICustomTabsService {
private IBinder mRemote;
Proxy(IBinder remote) {
this.mRemote = remote;
}
public IBinder asBinder() {
return this.mRemote;
}
public String getInterfaceDescriptor() {
return "android.support.customtabs.ICustomTabsService";
}
public boolean warmup(long flags) throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
boolean _result;
try {
_data.writeInterfaceToken("android.support.customtabs.ICustomTabsService");
_data.writeLong(flags);
this.mRemote.transact(2, _data, _reply, 0);
_reply.readException();
_result = 0 != _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
public boolean newSession(ICustomTabsCallback callback) throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
boolean _result;
try {
_data.writeInterfaceToken("android.support.customtabs.ICustomTabsService");
_data.writeStrongBinder(callback != null ? callback.asBinder() : null);
this.mRemote.transact(3, _data, _reply, 0);
_reply.readException();
_result = 0 != _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
public boolean mayLaunchUrl(ICustomTabsCallback callback, Uri url, Bundle extras, List<Bundle> otherLikelyBundles) throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
boolean _result;
try {
_data.writeInterfaceToken("android.support.customtabs.ICustomTabsService");
_data.writeStrongBinder(callback != null ? callback.asBinder() : null);
if (url != null) {
_data.writeInt(1);
url.writeToParcel(_data, 0);
} else {
_data.writeInt(0);
}
if (extras != null) {
_data.writeInt(1);
extras.writeToParcel(_data, 0);
} else {
_data.writeInt(0);
}
_data.writeTypedList(otherLikelyBundles);
this.mRemote.transact(4, _data, _reply, 0);
_reply.readException();
_result = 0 != _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
public Bundle extraCommand(String commandName, Bundle args) throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
Bundle _result;
try {
_data.writeInterfaceToken("android.support.customtabs.ICustomTabsService");
_data.writeString(commandName);
if (args != null) {
_data.writeInt(1);
args.writeToParcel(_data, 0);
} else {
_data.writeInt(0);
}
this.mRemote.transact(5, _data, _reply, 0);
_reply.readException();
if (0 != _reply.readInt()) {
_result = Bundle.CREATOR.createFromParcel(_reply);
} else {
_result = null;
}
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
public boolean updateVisuals(ICustomTabsCallback callback, Bundle bundle) throws RemoteException {
Parcel _data = Parcel.obtain();
Parcel _reply = Parcel.obtain();
boolean _result;
try {
_data.writeInterfaceToken("android.support.customtabs.ICustomTabsService");
_data.writeStrongBinder(callback != null ? callback.asBinder() : null);
if (bundle != null) {
_data.writeInt(1);
bundle.writeToParcel(_data, 0);
} else {
_data.writeInt(0);
}
this.mRemote.transact(6, _data, _reply, 0);
_reply.readException();
_result = 0 != _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
}
}

View File

@ -0,0 +1,142 @@
// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.telegram.messenger.support.customtabsclient.shared;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
/**
* Helper class for Custom Tabs.
*/
public class CustomTabsHelper {
private static final String TAG = "CustomTabsHelper";
static final String STABLE_PACKAGE = "com.android.chrome";
static final String BETA_PACKAGE = "com.chrome.beta";
static final String DEV_PACKAGE = "com.chrome.dev";
static final String LOCAL_PACKAGE = "com.google.android.apps.chrome";
private static final String EXTRA_CUSTOM_TABS_KEEP_ALIVE =
"android.support.customtabs.extra.KEEP_ALIVE";
private static final String ACTION_CUSTOM_TABS_CONNECTION =
"android.support.customtabs.action.CustomTabsService";
private static String sPackageNameToUse;
private CustomTabsHelper() {}
public static void addKeepAliveExtra(Context context, Intent intent) {
Intent keepAliveIntent = new Intent().setClassName(
context.getPackageName(), KeepAliveService.class.getCanonicalName());
intent.putExtra(EXTRA_CUSTOM_TABS_KEEP_ALIVE, keepAliveIntent);
}
/**
* Goes through all apps that handle VIEW intents and have a warmup service. Picks
* the one chosen by the user if there is one, otherwise makes a best effort to return a
* valid package name.
*
* This is <strong>not</strong> threadsafe.
*
* @param context {@link Context} to use for accessing {@link PackageManager}.
* @return The package name recommended to use for connecting to custom tabs related components.
*/
public static String getPackageNameToUse(Context context) {
if (sPackageNameToUse != null) return sPackageNameToUse;
PackageManager pm = context.getPackageManager();
// Get default VIEW intent handler.
Intent activityIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.example.com"));
ResolveInfo defaultViewHandlerInfo = pm.resolveActivity(activityIntent, 0);
String defaultViewHandlerPackageName = null;
if (defaultViewHandlerInfo != null) {
defaultViewHandlerPackageName = defaultViewHandlerInfo.activityInfo.packageName;
}
// Get all apps that can handle VIEW intents.
List<ResolveInfo> resolvedActivityList = pm.queryIntentActivities(activityIntent, 0);
List<String> packagesSupportingCustomTabs = new ArrayList<>();
for (ResolveInfo info : resolvedActivityList) {
Intent serviceIntent = new Intent();
serviceIntent.setAction(ACTION_CUSTOM_TABS_CONNECTION);
serviceIntent.setPackage(info.activityInfo.packageName);
if (pm.resolveService(serviceIntent, 0) != null) {
packagesSupportingCustomTabs.add(info.activityInfo.packageName);
}
}
// Now packagesSupportingCustomTabs contains all apps that can handle both VIEW intents
// and service calls.
if (packagesSupportingCustomTabs.isEmpty()) {
sPackageNameToUse = null;
} else if (packagesSupportingCustomTabs.size() == 1) {
sPackageNameToUse = packagesSupportingCustomTabs.get(0);
} else if (!TextUtils.isEmpty(defaultViewHandlerPackageName)
&& !hasSpecializedHandlerIntents(context, activityIntent)
&& packagesSupportingCustomTabs.contains(defaultViewHandlerPackageName)) {
sPackageNameToUse = defaultViewHandlerPackageName;
} else if (packagesSupportingCustomTabs.contains(STABLE_PACKAGE)) {
sPackageNameToUse = STABLE_PACKAGE;
} else if (packagesSupportingCustomTabs.contains(BETA_PACKAGE)) {
sPackageNameToUse = BETA_PACKAGE;
} else if (packagesSupportingCustomTabs.contains(DEV_PACKAGE)) {
sPackageNameToUse = DEV_PACKAGE;
} else if (packagesSupportingCustomTabs.contains(LOCAL_PACKAGE)) {
sPackageNameToUse = LOCAL_PACKAGE;
}
return sPackageNameToUse;
}
/**
* Used to check whether there is a specialized handler for a given intent.
* @param intent The intent to check with.
* @return Whether there is a specialized handler for the given intent.
*/
private static boolean hasSpecializedHandlerIntents(Context context, Intent intent) {
try {
PackageManager pm = context.getPackageManager();
List<ResolveInfo> handlers = pm.queryIntentActivities(
intent,
PackageManager.GET_RESOLVED_FILTER);
if (handlers == null || handlers.size() == 0) {
return false;
}
for (ResolveInfo resolveInfo : handlers) {
IntentFilter filter = resolveInfo.filter;
if (filter == null) continue;
if (filter.countDataAuthorities() == 0 || filter.countDataPaths() == 0) continue;
if (resolveInfo.activityInfo == null) continue;
return true;
}
} catch (RuntimeException e) {
Log.e(TAG, "Runtime exception while getting specialized handlers");
}
return false;
}
/**
* @return All possible chrome package names that provide custom tabs feature.
*/
public static String[] getPackages() {
return new String[]{"", STABLE_PACKAGE, BETA_PACKAGE, DEV_PACKAGE, LOCAL_PACKAGE};
}
}

View File

@ -0,0 +1,29 @@
// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.telegram.messenger.support.customtabsclient.shared;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
public class KeepAliveService extends Service {
private static final Binder sBinder = new Binder();
@Override
public IBinder onBind(Intent intent) {
return sBinder;
}
}

View File

@ -0,0 +1,42 @@
// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.telegram.messenger.support.customtabsclient.shared;
import android.content.ComponentName;
import org.telegram.messenger.support.customtabs.CustomTabsClient;
import org.telegram.messenger.support.customtabs.CustomTabsServiceConnection;
import java.lang.ref.WeakReference;
public class ServiceConnection extends CustomTabsServiceConnection {
private WeakReference<ServiceConnectionCallback> mConnectionCallback;
public ServiceConnection(ServiceConnectionCallback connectionCallback) {
mConnectionCallback = new WeakReference<>(connectionCallback);
}
@Override
public void onCustomTabsServiceConnected(ComponentName name, CustomTabsClient client) {
ServiceConnectionCallback connectionCallback = mConnectionCallback.get();
if (connectionCallback != null) connectionCallback.onServiceConnected(client);
}
@Override
public void onServiceDisconnected(ComponentName name) {
ServiceConnectionCallback connectionCallback = mConnectionCallback.get();
if (connectionCallback != null) connectionCallback.onServiceDisconnected();
}
}

View File

@ -0,0 +1,33 @@
// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.telegram.messenger.support.customtabsclient.shared;
import org.telegram.messenger.support.customtabs.CustomTabsClient;
/**
* Callback for events when connecting and disconnecting from Custom Tabs Service.
*/
public interface ServiceConnectionCallback {
/**
* Called when the service is connected.
* @param client a CustomTabsClient
*/
void onServiceConnected(CustomTabsClient client);
/**
* Called when the service is disconnected.
*/
void onServiceDisconnected();
}

View File

@ -540,7 +540,7 @@ public class LinearLayoutManager extends RecyclerView.LayoutManager implements
onAnchorReady(recycler, state, mAnchorInfo, firstLayoutDirection);
detachAndScrapAttachedViews(recycler);
mLayoutState.mInfinite = mOrientationHelper.getMode() == View.MeasureSpec.UNSPECIFIED;
mLayoutState.mInfinite = resolveIsInfinite();
mLayoutState.mIsPreLayout = state.isPreLayout();
if (mAnchorInfo.mLayoutFromEnd) {
// fill towards start
@ -1128,7 +1128,8 @@ public class LinearLayoutManager extends RecyclerView.LayoutManager implements
private void updateLayoutState(int layoutDirection, int requiredSpace,
boolean canUseExistingSpace, RecyclerView.State state) {
mLayoutState.mInfinite = mOrientationHelper.getMode() == View.MeasureSpec.UNSPECIFIED;
// If parent provides a hint, don't measure unlimited.
mLayoutState.mInfinite = resolveIsInfinite();
mLayoutState.mExtra = getExtraLayoutSpace(state);
mLayoutState.mLayoutDirection = layoutDirection;
int scrollingOffset;
@ -1162,6 +1163,11 @@ public class LinearLayoutManager extends RecyclerView.LayoutManager implements
mLayoutState.mScrollingOffset = scrollingOffset;
}
boolean resolveIsInfinite() {
return mOrientationHelper.getMode() == View.MeasureSpec.UNSPECIFIED
&& mOrientationHelper.getEnd() == 0;
}
int scrollBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
if (getChildCount() == 0 || dy == 0) {
return 0;

View File

@ -59,6 +59,7 @@ import android.view.FocusFinder;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewParent;
@ -152,6 +153,9 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
private static final boolean DEBUG = false;
private static final int[] NESTED_SCROLLING_ATTRS
= {16843830 /* android.R.attr.nestedScrollingEnabled */};
/**
* On Kitkat and JB MR2, there is a bug which prevents DisplayList from being invalidated if
* a View is two levels deep(wrt to ViewHolder.itemView). DisplayList can be invalidated by
@ -161,8 +165,14 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
*/
private static final boolean FORCE_INVALIDATE_DISPLAY_LIST = Build.VERSION.SDK_INT == 18
|| Build.VERSION.SDK_INT == 19 || Build.VERSION.SDK_INT == 20;
/**
* On M+, an unspecified measure spec may include a hint which we can use. On older platforms,
* this value might be garbage. To save LayoutManagers from it, RecyclerView sets the size to
* 0 when mode is unspecified.
*/
static final boolean ALLOW_SIZE_IN_UNSPECIFIED_SPEC = Build.VERSION.SDK_INT >= 23;
private static final boolean DISPATCH_TEMP_DETACH = false;
static final boolean DISPATCH_TEMP_DETACH = false;
public static final int HORIZONTAL = 0;
public static final int VERTICAL = 1;
@ -392,7 +402,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
// preserved not to create a new one in each layout pass
private final int[] mMinMaxLayoutPositions = new int[2];
private final NestedScrollingChildHelper mScrollingChildHelper;
private NestedScrollingChildHelper mScrollingChildHelper;
private final int[] mScrollOffset = new int[2];
private final int[] mScrollConsumed = new int[2];
private final int[] mNestedOffsets = new int[2];
@ -485,8 +495,9 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
mAccessibilityManager = (AccessibilityManager) getContext()
.getSystemService(Context.ACCESSIBILITY_SERVICE);
setAccessibilityDelegateCompat(new RecyclerViewAccessibilityDelegate(this));
// Create the layoutManager if specified.
mScrollingChildHelper = new NestedScrollingChildHelper(this);
// Re-set whether nested scrolling is enabled so that it is set on all API levels
setNestedScrollingEnabled(true);
}
@ -568,7 +579,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
if (className.charAt(0) == '.') {
return context.getPackageName() + className;
}
if (className.contains(".")) {
if (className.indexOf('.') != -1) {
return className;
}
return RecyclerView.class.getPackage().getName() + '.' + className;
@ -1037,6 +1048,11 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (!(state instanceof SavedState)) {
super.onRestoreInstanceState(state);
return;
}
mPendingSavedState = (SavedState) state;
super.onRestoreInstanceState(mPendingSavedState.getSuperState());
if (mLayout != null && mPendingSavedState.mLayoutState != null) {
@ -1327,6 +1343,14 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
}
}
/**
* Convenience method to scroll to a certain position.
*
* RecyclerView does not implement scrolling logic, rather forwards the call to
* {@link android.support.v7.widget.RecyclerView.LayoutManager#scrollToPosition(int)}
* @param position Scroll to this adapter position
* @see android.support.v7.widget.RecyclerView.LayoutManager#scrollToPosition(int)
*/
public void scrollToPosition(int position) {
if (mLayoutFrozen) {
return;
@ -3188,17 +3212,10 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
if (count == 0) {
return minPositionPreLayout != 0 || maxPositionPreLayout != 0;
}
for (int i = 0; i < count; ++i) {
final ViewHolder holder = getChildViewHolderInt(mChildHelper.getChildAt(i));
if (holder.shouldIgnore()) {
continue;
}
final int pos = holder.getLayoutPosition();
if (pos < minPositionPreLayout || pos > maxPositionPreLayout) {
return true;
}
}
return false;
// get the new min max
findMinMaxChildLayoutPositions(mMinMaxLayoutPositions);
return mMinMaxLayoutPositions[0] != minPositionPreLayout ||
mMinMaxLayoutPositions[1] != maxPositionPreLayout;
}
@Override
@ -5990,28 +6007,43 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
* onMeasure method OR fake measure specs created by the RecyclerView.
* For example, when a layout is run, RecyclerView always sets these specs to be
* EXACTLY because a LayoutManager cannot resize RecyclerView during a layout pass.
* <p>
* Also, to be able to use the hint in unspecified measure specs, RecyclerView checks the
* API level and sets the size to 0 pre-M to avoid any issue that might be caused by
* corrupt values. Older platforms have no responsibility to provide a size if they set
* mode to unspecified.
*/
private int mWidthSpec, mHeightSpec;
private int mWidthMode, mHeightMode;
private int mWidth, mHeight;
void setRecyclerView(RecyclerView recyclerView) {
if (recyclerView == null) {
mRecyclerView = null;
mChildHelper = null;
mWidthSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.EXACTLY);
mHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.EXACTLY);
mWidth = 0;
mHeight = 0;
} else {
mRecyclerView = recyclerView;
mChildHelper = recyclerView.mChildHelper;
mWidthSpec = MeasureSpec
.makeMeasureSpec(recyclerView.getWidth(), MeasureSpec.EXACTLY);
mHeightSpec = MeasureSpec
.makeMeasureSpec(recyclerView.getHeight(), MeasureSpec.EXACTLY);
mWidth = recyclerView.getWidth();
mHeight = recyclerView.getHeight();
}
mWidthMode = MeasureSpec.EXACTLY;
mHeightMode = MeasureSpec.EXACTLY;
}
void setMeasureSpecs(int wSpec, int hSpec) {
mWidthSpec = wSpec;
mHeightSpec = hSpec;
mWidth = MeasureSpec.getSize(wSpec);
mWidthMode = MeasureSpec.getMode(wSpec);
if (mWidthMode == MeasureSpec.UNSPECIFIED && !ALLOW_SIZE_IN_UNSPECIFIED_SPEC) {
mWidth = 0;
}
mHeight = MeasureSpec.getSize(hSpec);
mHeightMode = MeasureSpec.getMode(hSpec);
if (mHeightMode == MeasureSpec.UNSPECIFIED && !ALLOW_SIZE_IN_UNSPECIFIED_SPEC) {
mHeight = 0;
}
}
/**
@ -7054,7 +7086,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
* @see View#onMeasure(int, int)
*/
public int getWidthMode() {
return MeasureSpec.getMode(mWidthSpec);
return mWidthMode;
}
/**
@ -7072,7 +7104,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
* @see View#onMeasure(int, int)
*/
public int getHeightMode() {
return MeasureSpec.getMode(mHeightSpec);
return mHeightMode;
}
/**
@ -7081,7 +7113,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
* @return Width in pixels
*/
public int getWidth() {
return MeasureSpec.getSize(mWidthSpec);
return mWidth;
}
/**
@ -7090,7 +7122,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
* @return Height in pixels
*/
public int getHeight() {
return MeasureSpec.getSize(mHeightSpec);
return mHeight;
}
/**
@ -7567,6 +7599,7 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
}
}
//noinspection WrongConstant
return MeasureSpec.makeMeasureSpec(resultSize, resultMode);
}
@ -9310,49 +9343,49 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
@Override
public void setNestedScrollingEnabled(boolean enabled) {
mScrollingChildHelper.setNestedScrollingEnabled(enabled);
getScrollingChildHelper().setNestedScrollingEnabled(enabled);
}
@Override
public boolean isNestedScrollingEnabled() {
return mScrollingChildHelper.isNestedScrollingEnabled();
return getScrollingChildHelper().isNestedScrollingEnabled();
}
@Override
public boolean startNestedScroll(int axes) {
return mScrollingChildHelper.startNestedScroll(axes);
return getScrollingChildHelper().startNestedScroll(axes);
}
@Override
public void stopNestedScroll() {
mScrollingChildHelper.stopNestedScroll();
getScrollingChildHelper().stopNestedScroll();
}
@Override
public boolean hasNestedScrollingParent() {
return mScrollingChildHelper.hasNestedScrollingParent();
return getScrollingChildHelper().hasNestedScrollingParent();
}
@Override
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed,
int dyUnconsumed, int[] offsetInWindow) {
return mScrollingChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed,
return getScrollingChildHelper().dispatchNestedScroll(dxConsumed, dyConsumed,
dxUnconsumed, dyUnconsumed, offsetInWindow);
}
@Override
public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
return mScrollingChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
return getScrollingChildHelper().dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
}
@Override
public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
return mScrollingChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
return getScrollingChildHelper().dispatchNestedFling(velocityX, velocityY, consumed);
}
@Override
public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
return mScrollingChildHelper.dispatchNestedPreFling(velocityX, velocityY);
return getScrollingChildHelper().dispatchNestedPreFling(velocityX, velocityY);
}
/**
@ -11056,4 +11089,11 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
*/
int onGetChildDrawingOrder(int childCount, int i);
}
private NestedScrollingChildHelper getScrollingChildHelper() {
if (mScrollingChildHelper == null) {
mScrollingChildHelper = new NestedScrollingChildHelper(this);
}
return mScrollingChildHelper;
}
}

View File

@ -27,6 +27,7 @@ import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.accessibility.AccessibilityEventCompat;
@ -110,7 +111,9 @@ public class StaggeredGridLayoutManager extends RecyclerView.LayoutManager {
* Primary orientation is the layout's orientation, secondary orientation is the orientation
* for spans. Having both makes code much cleaner for calculations.
*/
@NonNull
OrientationHelper mPrimaryOrientation;
@NonNull
OrientationHelper mSecondaryOrientation;
private int mOrientation;
@ -120,7 +123,8 @@ public class StaggeredGridLayoutManager extends RecyclerView.LayoutManager {
*/
private int mSizePerSpan;
private LayoutState mLayoutState;
@NonNull
private final LayoutState mLayoutState;
private boolean mReverseLayout = false;
@ -221,6 +225,8 @@ public class StaggeredGridLayoutManager extends RecyclerView.LayoutManager {
setSpanCount(properties.spanCount);
setReverseLayout(properties.reverseLayout);
setAutoMeasureEnabled(mGapStrategy != GAP_HANDLING_NONE);
mLayoutState = new LayoutState();
createOrientationHelpers();
}
/**
@ -234,6 +240,14 @@ public class StaggeredGridLayoutManager extends RecyclerView.LayoutManager {
mOrientation = orientation;
setSpanCount(spanCount);
setAutoMeasureEnabled(mGapStrategy != GAP_HANDLING_NONE);
mLayoutState = new LayoutState();
createOrientationHelpers();
}
private void createOrientationHelpers() {
mPrimaryOrientation = OrientationHelper.createOrientationHelper(this, mOrientation);
mSecondaryOrientation = OrientationHelper
.createOrientationHelper(this, 1 - mOrientation);
}
/**
@ -426,12 +440,9 @@ public class StaggeredGridLayoutManager extends RecyclerView.LayoutManager {
return;
}
mOrientation = orientation;
if (mPrimaryOrientation != null && mSecondaryOrientation != null) {
// swap
OrientationHelper tmp = mPrimaryOrientation;
mPrimaryOrientation = mSecondaryOrientation;
mSecondaryOrientation = tmp;
}
OrientationHelper tmp = mPrimaryOrientation;
mPrimaryOrientation = mSecondaryOrientation;
mSecondaryOrientation = tmp;
requestLayout();
}
@ -526,15 +537,6 @@ public class StaggeredGridLayoutManager extends RecyclerView.LayoutManager {
requestLayout();
}
private void ensureOrientationHelper() {
if (mPrimaryOrientation == null) {
mPrimaryOrientation = OrientationHelper.createOrientationHelper(this, mOrientation);
mSecondaryOrientation = OrientationHelper
.createOrientationHelper(this, 1 - mOrientation);
mLayoutState = new LayoutState();
}
}
/**
* Calculates the views' layout order. (e.g. from end to start or start to end)
* RTL layout support is applied automatically. So if layout is RTL and
@ -593,7 +595,6 @@ public class StaggeredGridLayoutManager extends RecyclerView.LayoutManager {
private void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state,
boolean shouldCheckForGaps) {
ensureOrientationHelper();
final AnchorInfo anchorInfo = mAnchorInfo;
anchorInfo.reset();
@ -1036,7 +1037,6 @@ public class StaggeredGridLayoutManager extends RecyclerView.LayoutManager {
if (getChildCount() == 0) {
return 0;
}
ensureOrientationHelper();
return ScrollbarHelper.computeScrollOffset(state, mPrimaryOrientation,
findFirstVisibleItemClosestToStart(!mSmoothScrollbarEnabled, true)
, findFirstVisibleItemClosestToEnd(!mSmoothScrollbarEnabled, true),
@ -1057,7 +1057,6 @@ public class StaggeredGridLayoutManager extends RecyclerView.LayoutManager {
if (getChildCount() == 0) {
return 0;
}
ensureOrientationHelper();
return ScrollbarHelper.computeScrollExtent(state, mPrimaryOrientation,
findFirstVisibleItemClosestToStart(!mSmoothScrollbarEnabled, true)
, findFirstVisibleItemClosestToEnd(!mSmoothScrollbarEnabled, true),
@ -1078,7 +1077,6 @@ public class StaggeredGridLayoutManager extends RecyclerView.LayoutManager {
if (getChildCount() == 0) {
return 0;
}
ensureOrientationHelper();
return ScrollbarHelper.computeScrollRange(state, mPrimaryOrientation,
findFirstVisibleItemClosestToStart(!mSmoothScrollbarEnabled, true)
, findFirstVisibleItemClosestToEnd(!mSmoothScrollbarEnabled, true),
@ -1175,7 +1173,6 @@ public class StaggeredGridLayoutManager extends RecyclerView.LayoutManager {
}
if (getChildCount() > 0) {
ensureOrientationHelper();
state.mAnchorPosition = mLastLayoutFromEnd ? getLastChildPosition()
: getFirstChildPosition();
state.mVisibleAnchorPosition = findFirstVisibleItemPositionInt();
@ -1288,7 +1285,6 @@ public class StaggeredGridLayoutManager extends RecyclerView.LayoutManager {
* children order.
*/
View findFirstVisibleItemClosestToStart(boolean fullyVisible, boolean acceptPartiallyVisible) {
ensureOrientationHelper();
final int boundsStart = mPrimaryOrientation.getStartAfterPadding();
final int boundsEnd = mPrimaryOrientation.getEndAfterPadding();
final int limit = getChildCount();
@ -1319,7 +1315,6 @@ public class StaggeredGridLayoutManager extends RecyclerView.LayoutManager {
* children order.
*/
View findFirstVisibleItemClosestToEnd(boolean fullyVisible, boolean acceptPartiallyVisible) {
ensureOrientationHelper();
final int boundsStart = mPrimaryOrientation.getStartAfterPadding();
final int boundsEnd = mPrimaryOrientation.getEndAfterPadding();
View partiallyVisible = null;
@ -1407,7 +1402,8 @@ public class StaggeredGridLayoutManager extends RecyclerView.LayoutManager {
}
mLayoutState.mStopInFocusable = false;
mLayoutState.mRecycle = true;
mLayoutState.mInfinite = mPrimaryOrientation.getMode() == View.MeasureSpec.UNSPECIFIED;
mLayoutState.mInfinite = mPrimaryOrientation.getMode() == View.MeasureSpec.UNSPECIFIED &&
mPrimaryOrientation.getEnd() == 0;
}
private void setLayoutStateDirection(int direction) {
@ -2046,7 +2042,6 @@ public class StaggeredGridLayoutManager extends RecyclerView.LayoutManager {
}
int scrollBy(int dt, RecyclerView.Recycler recycler, RecyclerView.State state) {
ensureOrientationHelper();
final int referenceChildPosition;
final int layoutDir;
if (dt > 0) { // layout towards end
@ -2124,6 +2119,7 @@ public class StaggeredGridLayoutManager extends RecyclerView.LayoutManager {
return 0;
}
@SuppressWarnings("deprecation")
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
if (mOrientation == HORIZONTAL) {
@ -2171,7 +2167,6 @@ public class StaggeredGridLayoutManager extends RecyclerView.LayoutManager {
return null;
}
ensureOrientationHelper();
resolveShouldLayoutReverse();
final int layoutDir = convertFocusDirectionToLayoutDirection(direction);
if (layoutDir == LayoutState.INVALID_LAYOUT) {

View File

@ -32,7 +32,11 @@ import static org.telegram.messenger.support.widget.ViewInfoStore.InfoRecord.FLA
import static org.telegram.messenger.support.widget.ViewInfoStore.InfoRecord.FLAG_APPEAR;
import static org.telegram.messenger.support.widget.ViewInfoStore.InfoRecord.FLAG_PRE;
import static org.telegram.messenger.support.widget.ViewInfoStore.InfoRecord.FLAG_POST;
/**
* This class abstracts all tracking for Views to run animations
*
* @hide
*/
class ViewInfoStore {
private static final boolean DEBUG = false;

View File

@ -1384,7 +1384,7 @@ public class ItemTouchHelper extends RecyclerView.ItemDecoration
/**
* Drag scroll speed keeps accelerating until this many milliseconds before being capped.
*/
private static final long DRAG_SCROLL_ACCELERATION_LIMIT_TIME_MS = 2000;
private static final long DRAG_SCROLL_ACCELERATION_LIMIT_TIME_MS = 500;
private int mCachedMaxScrollSpeed = -1;

View File

@ -201,8 +201,12 @@ public class ConnectionsManager {
native_setNetworkAvailable(isNetworkOnline());
}
public void init(int version, int layer, int apiId, String deviceModel, String systemVersion, String appVersion, String langCode, String configPath, String logPath, int userId) {
native_init(version, layer, apiId, deviceModel, systemVersion, appVersion, langCode, configPath, logPath, userId);
public void setPushConnectionEnabled(boolean value) {
native_setPushConnectionEnabled(value);
}
public void init(int version, int layer, int apiId, String deviceModel, String systemVersion, String appVersion, String langCode, String configPath, String logPath, int userId, boolean enablePushConnection) {
native_init(version, layer, apiId, deviceModel, systemVersion, appVersion, langCode, configPath, logPath, userId, enablePushConnection);
checkConnection();
BroadcastReceiver networkStateReceiver = new BroadcastReceiver() {
@Override
@ -342,8 +346,10 @@ public class ConnectionsManager {
@Override
public void run() {
try {
getInstance().wakeLock.acquire(20000);
FileLog.d("tmessages", "acquire wakelock");
if (!getInstance().wakeLock.isHeld()) {
getInstance().wakeLock.acquire(10000);
FileLog.d("tmessages", "acquire wakelock");
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
@ -368,8 +374,9 @@ public class ConnectionsManager {
public static native void native_applyDatacenterAddress(int datacenterId, String ipAddress, int port);
public static native int native_getConnectionState();
public static native void native_setUserId(int id);
public static native void native_init(int version, int layer, int apiId, String deviceModel, String systemVersion, String appVersion, String langCode, String configPath, String logPath, int userId);
public static native void native_init(int version, int layer, int apiId, String deviceModel, String systemVersion, String appVersion, String langCode, String configPath, String logPath, int userId, boolean enablePushConnection);
public static native void native_setJava(boolean useJavaByteBuffers);
public static native void native_setPushConnectionEnabled(boolean value);
public int generateClassGuid() {
return lastClassGuid++;

File diff suppressed because it is too large Load Diff

View File

@ -12,21 +12,17 @@ import android.content.Context;
import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.AnimationCompat.AnimatorListenerAdapterProxy;
import org.telegram.messenger.AnimationCompat.AnimatorSetProxy;
import org.telegram.messenger.AnimationCompat.ObjectAnimatorProxy;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.R;
import org.telegram.ui.Components.LayoutHelper;
import java.util.ArrayList;
@ -44,21 +40,23 @@ public class ActionBar extends FrameLayout {
}
private ImageView backButtonImageView;
private TextView titleTextView;
private TextView subTitleTextView;
private SimpleTextView titleTextView;
private SimpleTextView subtitleTextView;
private View actionModeTop;
private ActionBarMenu menu;
private ActionBarMenu actionMode;
private boolean occupyStatusBar = Build.VERSION.SDK_INT >= 21;
private boolean actionModeVisible;
private boolean addToContainer = true;
private boolean interceptTouches = true;
private int extraHeight;
private boolean allowOverlayTitle;
private CharSequence lastTitle;
private boolean castShadows = true;
protected boolean isSearchFieldVisible;
protected int itemsBackgroundResourceId;
protected int itemsBackgroundColor;
private boolean isBackOverlayVisible;
protected BaseFragment parentFragment;
public ActionBarMenuOnItemClick actionBarMenuOnItemClick;
@ -73,7 +71,7 @@ public class ActionBar extends FrameLayout {
}
backButtonImageView = new ImageView(getContext());
backButtonImageView.setScaleType(ImageView.ScaleType.CENTER);
backButtonImageView.setBackgroundResource(itemsBackgroundResourceId);
backButtonImageView.setBackgroundDrawable(Theme.createBarSelectorDrawable(itemsBackgroundColor));
backButtonImageView.setPadding(AndroidUtilities.dp(1), 0, 0, 0);
addView(backButtonImageView, LayoutHelper.createFrame(54, 54, Gravity.LEFT | Gravity.TOP));
@ -110,18 +108,14 @@ public class ActionBar extends FrameLayout {
backButtonImageView.setImageResource(resource);
}
private void createSubtitleTextView() {
if (subTitleTextView != null) {
private void createsubtitleTextView() {
if (subtitleTextView != null) {
return;
}
subTitleTextView = new TextView(getContext());
subTitleTextView.setGravity(Gravity.LEFT);
subTitleTextView.setTextColor(0xffd7e8f7);
subTitleTextView.setSingleLine(true);
subTitleTextView.setLines(1);
subTitleTextView.setMaxLines(1);
subTitleTextView.setEllipsize(TextUtils.TruncateAt.END);
addView(subTitleTextView, 0, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP));
subtitleTextView = new SimpleTextView(getContext());
subtitleTextView.setGravity(Gravity.LEFT);
subtitleTextView.setTextColor(Theme.ACTION_BAR_SUBTITLE_COLOR);
addView(subtitleTextView, 0, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP));
}
public void setAddToContainer(boolean value) {
@ -133,12 +127,12 @@ public class ActionBar extends FrameLayout {
}
public void setSubtitle(CharSequence value) {
if (value != null && subTitleTextView == null) {
createSubtitleTextView();
if (value != null && subtitleTextView == null) {
createsubtitleTextView();
}
if (subTitleTextView != null) {
subTitleTextView.setVisibility(value != null && !isSearchFieldVisible ? VISIBLE : INVISIBLE);
subTitleTextView.setText(value);
if (subtitleTextView != null) {
subtitleTextView.setVisibility(value != null && !isSearchFieldVisible ? VISIBLE : INVISIBLE);
subtitleTextView.setText(value);
}
}
@ -146,12 +140,8 @@ public class ActionBar extends FrameLayout {
if (titleTextView != null) {
return;
}
titleTextView = new TextView(getContext());
titleTextView = new SimpleTextView(getContext());
titleTextView.setGravity(Gravity.LEFT);
titleTextView.setLines(1);
titleTextView.setMaxLines(1);
titleTextView.setSingleLine(true);
titleTextView.setEllipsize(TextUtils.TruncateAt.END);
titleTextView.setTextColor(0xffffffff);
titleTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
addView(titleTextView, 0, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP));
@ -168,18 +158,14 @@ public class ActionBar extends FrameLayout {
}
}
public TextView getSubTitleTextView() {
return subTitleTextView;
public SimpleTextView getSubtitleTextView() {
return subtitleTextView;
}
public TextView getTitleTextView() {
public SimpleTextView getTitleTextView() {
return titleTextView;
}
public Drawable getSubTitleIcon() {
return subTitleTextView.getCompoundDrawables()[0];
}
public String getTitle() {
if (titleTextView == null) {
return null;
@ -258,8 +244,8 @@ public class ActionBar extends FrameLayout {
if (titleTextView != null) {
titleTextView.setVisibility(INVISIBLE);
}
if (subTitleTextView != null) {
subTitleTextView.setVisibility(INVISIBLE);
if (subtitleTextView != null) {
subtitleTextView.setVisibility(INVISIBLE);
}
if (menu != null) {
menu.setVisibility(INVISIBLE);
@ -275,8 +261,8 @@ public class ActionBar extends FrameLayout {
if (titleTextView != null) {
titleTextView.setVisibility(INVISIBLE);
}
if (subTitleTextView != null) {
subTitleTextView.setVisibility(INVISIBLE);
if (subtitleTextView != null) {
subtitleTextView.setVisibility(INVISIBLE);
}
if (menu != null) {
menu.setVisibility(INVISIBLE);
@ -287,7 +273,7 @@ public class ActionBar extends FrameLayout {
if (drawable instanceof BackDrawable) {
((BackDrawable) drawable).setRotation(1, true);
}
backButtonImageView.setBackgroundResource(R.drawable.bar_selector_mode);
backButtonImageView.setBackgroundDrawable(Theme.createBarSelectorDrawable(itemsBackgroundColor));
}
}
@ -324,8 +310,8 @@ public class ActionBar extends FrameLayout {
if (titleTextView != null) {
titleTextView.setVisibility(VISIBLE);
}
if (subTitleTextView != null) {
subTitleTextView.setVisibility(VISIBLE);
if (subtitleTextView != null) {
subtitleTextView.setVisibility(VISIBLE);
}
if (menu != null) {
menu.setVisibility(VISIBLE);
@ -335,7 +321,7 @@ public class ActionBar extends FrameLayout {
if (drawable instanceof BackDrawable) {
((BackDrawable) drawable).setRotation(0, true);
}
backButtonImageView.setBackgroundResource(itemsBackgroundResourceId);
backButtonImageView.setBackgroundDrawable(Theme.createBarSelectorDrawable(itemsBackgroundColor));
}
}
@ -361,8 +347,8 @@ public class ActionBar extends FrameLayout {
if (titleTextView != null) {
titleTextView.setVisibility(visible ? INVISIBLE : VISIBLE);
}
if (subTitleTextView != null) {
subTitleTextView.setVisibility(visible ? INVISIBLE : VISIBLE);
if (subtitleTextView != null) {
subtitleTextView.setVisibility(visible ? INVISIBLE : VISIBLE);
}
Drawable drawable = backButtonImageView.getDrawable();
if (drawable != null && drawable instanceof MenuDrawable) {
@ -370,6 +356,14 @@ public class ActionBar extends FrameLayout {
}
}
public void setInterceptTouches(boolean value) {
interceptTouches = value;
}
public void setExtraHeight(int value) {
extraHeight = value;
}
public void closeSearchField() {
if (!isSearchFieldVisible || menu == null) {
return;
@ -391,7 +385,7 @@ public class ActionBar extends FrameLayout {
int actionBarHeight = getCurrentActionBarHeight();
int actionBarHeightSpec = MeasureSpec.makeMeasureSpec(actionBarHeight, MeasureSpec.EXACTLY);
setMeasuredDimension(width, actionBarHeight + (occupyStatusBar ? AndroidUtilities.statusBarHeight : 0));
setMeasuredDimension(width, actionBarHeight + (occupyStatusBar ? AndroidUtilities.statusBarHeight : 0) + extraHeight);
int textLeft;
if (backButtonImageView != null && backButtonImageView.getVisibility() != GONE) {
@ -411,24 +405,24 @@ public class ActionBar extends FrameLayout {
menu.measure(menuWidth, actionBarHeightSpec);
}
if (titleTextView != null && titleTextView.getVisibility() != GONE || subTitleTextView != null && subTitleTextView.getVisibility() != GONE) {
if (titleTextView != null && titleTextView.getVisibility() != GONE || subtitleTextView != null && subtitleTextView.getVisibility() != GONE) {
int availableWidth = width - (menu != null ? menu.getMeasuredWidth() : 0) - AndroidUtilities.dp(16) - textLeft;
if (titleTextView != null && titleTextView.getVisibility() != GONE) {
titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, !AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 18 : 20);
titleTextView.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(actionBarHeight, MeasureSpec.AT_MOST));
titleTextView.setTextSize(!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 18 : 20);
titleTextView.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(24), MeasureSpec.AT_MOST));
}
if (subTitleTextView != null && subTitleTextView.getVisibility() != GONE) {
subTitleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, !AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 14 : 16);
subTitleTextView.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(actionBarHeight, MeasureSpec.AT_MOST));
if (subtitleTextView != null && subtitleTextView.getVisibility() != GONE) {
subtitleTextView.setTextSize(!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 14 : 16);
subtitleTextView.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.AT_MOST));
}
}
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
if (child.getVisibility() == GONE || child == titleTextView || child == subTitleTextView || child == menu || child == backButtonImageView) {
if (child.getVisibility() == GONE || child == titleTextView || child == subtitleTextView || child == menu || child == backButtonImageView) {
continue;
}
measureChildWithMargins(child, widthMeasureSpec, 0, MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.EXACTLY), 0);
@ -452,25 +446,24 @@ public class ActionBar extends FrameLayout {
menu.layout(menuLeft, additionalTop, menuLeft + menu.getMeasuredWidth(), additionalTop + menu.getMeasuredHeight());
}
int offset = AndroidUtilities.dp(!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 1 : 2);
if (titleTextView != null && titleTextView.getVisibility() != GONE) {
int textTop;
if (subTitleTextView != null && subTitleTextView.getVisibility() != GONE) {
textTop = (getCurrentActionBarHeight() / 2 - titleTextView.getMeasuredHeight()) / 2 + offset;
if (subtitleTextView != null && subtitleTextView.getVisibility() != GONE) {
textTop = (getCurrentActionBarHeight() / 2 - titleTextView.getTextHeight()) / 2 + AndroidUtilities.dp(!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 2 : 3);
} else {
textTop = (getCurrentActionBarHeight() - titleTextView.getMeasuredHeight()) / 2 - AndroidUtilities.dp(1);
textTop = (getCurrentActionBarHeight() - titleTextView.getTextHeight()) / 2;
}
titleTextView.layout(textLeft, additionalTop + textTop, textLeft + titleTextView.getMeasuredWidth(), additionalTop + textTop + titleTextView.getMeasuredHeight());
titleTextView.layout(textLeft, additionalTop + textTop, textLeft + titleTextView.getMeasuredWidth(), additionalTop + textTop + titleTextView.getTextHeight());
}
if (subTitleTextView != null && subTitleTextView.getVisibility() != GONE) {
int textTop = getCurrentActionBarHeight() / 2 + (getCurrentActionBarHeight() / 2 - subTitleTextView.getMeasuredHeight()) / 2 - offset;
subTitleTextView.layout(textLeft, additionalTop + textTop, textLeft + subTitleTextView.getMeasuredWidth(), additionalTop + textTop + subTitleTextView.getMeasuredHeight());
if (subtitleTextView != null && subtitleTextView.getVisibility() != GONE) {
int textTop = getCurrentActionBarHeight() / 2 + (getCurrentActionBarHeight() / 2 - subtitleTextView.getTextHeight()) / 2 - AndroidUtilities.dp(!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 1 : 1);
subtitleTextView.layout(textLeft, additionalTop + textTop, textLeft + subtitleTextView.getMeasuredWidth(), additionalTop + textTop + subtitleTextView.getTextHeight());
}
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
if (child.getVisibility() == GONE || child == titleTextView || child == subTitleTextView || child == menu || child == backButtonImageView) {
if (child.getVisibility() == GONE || child == titleTextView || child == subtitleTextView || child == menu || child == backButtonImageView) {
continue;
}
@ -563,10 +556,10 @@ public class ActionBar extends FrameLayout {
return occupyStatusBar;
}
public void setItemsBackground(int resourceId) {
itemsBackgroundResourceId = resourceId;
public void setItemsBackgroundColor(int color) {
itemsBackgroundColor = color;
if (backButtonImageView != null) {
backButtonImageView.setBackgroundResource(itemsBackgroundResourceId);
backButtonImageView.setBackgroundDrawable(Theme.createBarSelectorDrawable(itemsBackgroundColor));
}
}
@ -580,8 +573,7 @@ public class ActionBar extends FrameLayout {
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
return true;
return super.onTouchEvent(event) || interceptTouches;
}
public static int getCurrentActionBarHeight() {

View File

@ -28,6 +28,7 @@ import android.widget.FrameLayout;
import android.widget.LinearLayout;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.messenger.AnimationCompat.AnimatorListenerAdapterProxy;
import org.telegram.messenger.AnimationCompat.AnimatorSetProxy;
@ -248,7 +249,7 @@ public class ActionBarLayout extends FrameLayout {
}
final int restoreCount = canvas.save();
if (!transitionAnimationInProgress && clipLeft != 0 && clipRight != 0) {
if (!transitionAnimationInProgress) {
canvas.clipRect(clipLeft, 0, clipRight, getHeight());
}
final boolean result = super.drawChild(canvas, child, drawingTime);
@ -427,7 +428,7 @@ public class ActionBarLayout extends FrameLayout {
distToMove = containerView.getMeasuredWidth() - x;
animatorSet.playTogether(
ObjectAnimatorProxy.ofFloat(containerView, "translationX", containerView.getMeasuredWidth()),
ObjectAnimatorProxy.ofFloat(this, "innerTranslationX", (float)containerView.getMeasuredWidth())
ObjectAnimatorProxy.ofFloat(this, "innerTranslationX", (float) containerView.getMeasuredWidth())
);
} else {
distToMove = x;
@ -706,6 +707,7 @@ public class ActionBarLayout extends FrameLayout {
ViewProxy.setTranslationX(containerView, 0);
}
};
FileLog.e("tmessages", "onOpenAnimationsStart");
fragment.onTransitionAnimationStart(true, false);
AnimatorSetProxy animation = fragment.onCustomTransitionAnimation(true, new Runnable() {
@Override
@ -828,6 +830,7 @@ public class ActionBarLayout extends FrameLayout {
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
fragmentView.setLayoutParams(layoutParams);
FileLog.e("tmessages", "onCloseAnimationStart");
previousFragment.onTransitionAnimationStart(true, true);
currentFragment.onTransitionAnimationStart(false, false);
previousFragment.onResume();
@ -918,6 +921,7 @@ public class ActionBarLayout extends FrameLayout {
onAnimationEndCheck(false);
}
});
FileLog.e("tmessages", "onCloseAnimationsStart");
currentAnimation.start();
} else {
removeFragmentFromStackInternal(currentFragment);
@ -1043,11 +1047,13 @@ public class ActionBarLayout extends FrameLayout {
if (post) {
new Handler().post(new Runnable() {
public void run() {
FileLog.e("tmessages", "onCloseAnimationEnd");
onCloseAnimationEndRunnable.run();
onCloseAnimationEndRunnable = null;
}
});
} else {
FileLog.e("tmessages", "onCloseAnimationEnd");
onCloseAnimationEndRunnable.run();
onCloseAnimationEndRunnable = null;
}
@ -1061,11 +1067,13 @@ public class ActionBarLayout extends FrameLayout {
if (post) {
new Handler().post(new Runnable() {
public void run() {
FileLog.e("tmessages", "onOpenAnimationEnd");
onOpenAnimationEndRunnable.run();
onOpenAnimationEndRunnable = null;
}
});
} else {
FileLog.e("tmessages", "onOpenAnimationEnd");
onOpenAnimationEndRunnable.run();
onOpenAnimationEndRunnable = null;
}

View File

@ -38,7 +38,7 @@ public class ActionBarMenu extends LinearLayout {
addView(view);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) view.getLayoutParams();
layoutParams.height = LayoutHelper.MATCH_PARENT;
view.setBackgroundResource(parentActionBar.itemsBackgroundResourceId);
view.setBackgroundDrawable(Theme.createBarSelectorDrawable(parentActionBar.itemsBackgroundColor));
view.setLayoutParams(layoutParams);
view.setOnClickListener(new OnClickListener() {
@Override
@ -50,23 +50,23 @@ public class ActionBarMenu extends LinearLayout {
}
public ActionBarMenuItem addItem(int id, Drawable drawable) {
return addItem(id, 0, parentActionBar.itemsBackgroundResourceId, drawable, AndroidUtilities.dp(48));
return addItem(id, 0, parentActionBar.itemsBackgroundColor, drawable, AndroidUtilities.dp(48));
}
public ActionBarMenuItem addItem(int id, int icon) {
return addItem(id, icon, parentActionBar.itemsBackgroundResourceId);
return addItem(id, icon, parentActionBar.itemsBackgroundColor);
}
public ActionBarMenuItem addItem(int id, int icon, int backgroundResource) {
return addItem(id, icon, backgroundResource, null, AndroidUtilities.dp(48));
public ActionBarMenuItem addItem(int id, int icon, int backgroundColor) {
return addItem(id, icon, backgroundColor, null, AndroidUtilities.dp(48));
}
public ActionBarMenuItem addItemWithWidth(int id, int icon, int width) {
return addItem(id, icon, parentActionBar.itemsBackgroundResourceId, null, width);
return addItem(id, icon, parentActionBar.itemsBackgroundColor, null, width);
}
public ActionBarMenuItem addItem(int id, int icon, int backgroundResource, Drawable drawable, int width) {
ActionBarMenuItem menuItem = new ActionBarMenuItem(getContext(), this, backgroundResource);
public ActionBarMenuItem addItem(int id, int icon, int backgroundColor, Drawable drawable, int width) {
ActionBarMenuItem menuItem = new ActionBarMenuItem(getContext(), this, backgroundColor);
menuItem.setTag(id);
if (drawable != null) {
menuItem.iconView.setImageDrawable(drawable);

View File

@ -85,9 +85,11 @@ public class ActionBarMenuItem extends FrameLayoutFixed {
protected boolean overrideMenuClick;
private boolean processedPopupClick;
public ActionBarMenuItem(Context context, ActionBarMenu menu, int background) {
public ActionBarMenuItem(Context context, ActionBarMenu menu, int backgroundColor) {
super(context);
setBackgroundResource(background);
if (backgroundColor != 0) {
setBackgroundDrawable(Theme.createBarSelectorDrawable(backgroundColor));
}
parentMenu = menu;
iconView = new ImageView(context);

View File

@ -19,7 +19,6 @@ import android.view.ViewGroup;
import org.telegram.messenger.AnimationCompat.AnimatorSetProxy;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.tgnet.ConnectionsManager;
public class BaseFragment {
@ -116,14 +115,19 @@ public class BaseFragment {
}
}
if (parentLayout != null && actionBar == null) {
actionBar = new ActionBar(parentLayout.getContext());
actionBar = createActionBar(parentLayout.getContext());
actionBar.parentFragment = this;
actionBar.setBackgroundColor(0xff54759e);
actionBar.setItemsBackground(R.drawable.bar_selector);
}
}
}
protected ActionBar createActionBar(Context context) {
ActionBar actionBar = new ActionBar(context);
actionBar.setBackgroundColor(Theme.ACTION_BAR_COLOR);
actionBar.setItemsBackgroundColor(Theme.ACTION_BAR_SELECTOR_COLOR);
return actionBar;
}
public void finishFragment() {
finishFragment(true);
}

View File

@ -56,11 +56,13 @@ public class BottomSheet extends Dialog {
private LinearLayout containerView;
private FrameLayout container;
private Object lastInsets;
private WindowInsets lastInsets;
private boolean dismissed;
private int tag;
private boolean disableBackground;
private DialogInterface.OnClickListener onClickListener;
private CharSequence[] items;
@ -70,20 +72,21 @@ public class BottomSheet extends Dialog {
private boolean fullWidth;
private boolean isGrid;
private ColorDrawable backgroundDrawable = new ColorDrawable(0xff000000);
private static Drawable shadowDrawable;
private boolean focusable;
private Paint ciclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private static int backgroundPaddingTop;
private static int backgroundPaddingLeft;
private Drawable shadowDrawable;
protected static int backgroundPaddingTop;
protected static int backgroundPaddingLeft;
private boolean useRevealAnimation;
private float revealRadius;
private int revealX;
private int revealY;
private boolean applyTopPaddings = true;
private boolean applyTopPadding = true;
private boolean applyBottomPadding = true;
private DecelerateInterpolator decelerateInterpolator = new DecelerateInterpolator();
private AccelerateInterpolator accelerateInterpolator = new AccelerateInterpolator();
@ -212,7 +215,17 @@ public class BottomSheet extends Dialog {
}
public BottomSheet(Context context, boolean needFocus) {
super(context);
super(context, R.style.TransparentDialog);
if (Build.VERSION.SDK_INT >= 21 && !"N".equals(Build.VERSION.CODENAME)) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
}
Rect padding = new Rect();
shadowDrawable = context.getResources().getDrawable(R.drawable.sheet_shadow);
shadowDrawable.getPadding(padding);
backgroundPaddingLeft = padding.left;
backgroundPaddingTop = padding.top;
container = new FrameLayout(getContext()) {
@ -227,12 +240,17 @@ public class BottomSheet extends Dialog {
if (containerView != null) {
int left = useRevealAnimation && Build.VERSION.SDK_INT <= 19 ? 0 : backgroundPaddingLeft;
if (!fullWidth) {
int widthSpec;
if (AndroidUtilities.isTablet()) {
int side = (int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.8f);
containerView.measure(MeasureSpec.makeMeasureSpec(side + left * 2, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST));
widthSpec = MeasureSpec.makeMeasureSpec((int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.8f) + left * 2, MeasureSpec.EXACTLY);
} else {
int maxWidth = Math.min(AndroidUtilities.dp(480), width);
containerView.measure(isPortrait ? MeasureSpec.makeMeasureSpec(width + left * 2, MeasureSpec.EXACTLY) : MeasureSpec.makeMeasureSpec((int) Math.max(width * 0.8f, maxWidth) + left * 2, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST));
widthSpec = MeasureSpec.makeMeasureSpec(isPortrait ? width + left * 2 : (int) Math.max(width * 0.8f, Math.min(AndroidUtilities.dp(480), width)) + left * 2, MeasureSpec.EXACTLY);
}
if (lastInsets != null && Build.VERSION.SDK_INT >= 21 && focusable) {
containerView.getLayoutParams();
containerView.measure(widthSpec, MeasureSpec.makeMeasureSpec(height - lastInsets.getSystemWindowInsetBottom(), MeasureSpec.AT_MOST));
} else {
containerView.measure(widthSpec, MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST));
}
} else {
containerView.measure(MeasureSpec.makeMeasureSpec(width + left * 2, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST));
@ -245,9 +263,7 @@ public class BottomSheet extends Dialog {
continue;
}
if (lastInsets != null && Build.VERSION.SDK_INT >= 21) {
WindowInsets wi = (WindowInsets) lastInsets;
wi = wi.replaceSystemWindowInsets(wi.getSystemWindowInsetLeft(), wi.getSystemWindowInsetTop(), 0, wi.getSystemWindowInsetBottom());
child.dispatchApplyWindowInsets(wi);
child.dispatchApplyWindowInsets(lastInsets);
}
measureChildWithMargins(child, MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), 0, MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY), 0);
}
@ -258,6 +274,13 @@ public class BottomSheet extends Dialog {
if (containerView != null) {
int l = ((right - left) - containerView.getMeasuredWidth()) / 2;
int t = (bottom - top) - containerView.getMeasuredHeight();
if (lastInsets != null && Build.VERSION.SDK_INT >= 21) {
l += lastInsets.getSystemWindowInsetLeft() / 2;
l -= lastInsets.getSystemWindowInsetRight() / 2;
if (focusable) {
t -= lastInsets.getSystemWindowInsetBottom();
}
}
containerView.layout(l, t, l + containerView.getMeasuredWidth(), t + getMeasuredHeight());
}
@ -321,14 +344,14 @@ public class BottomSheet extends Dialog {
});
container.setBackgroundDrawable(backgroundDrawable);
focusable = needFocus;
if (Build.VERSION.SDK_INT >= 21 && !focusable) {
if (Build.VERSION.SDK_INT >= 21 && !"N".equals(Build.VERSION.CODENAME)) {
container.setFitsSystemWindows(true);
container.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
@SuppressLint("NewApi")
@Override
public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
lastInsets = insets;
container.requestLayout();
v.requestLayout();
return insets.consumeSystemWindowInsets();
}
});
@ -341,18 +364,7 @@ public class BottomSheet extends Dialog {
super.onCreate(savedInstanceState);
Window window = getWindow();
window.setBackgroundDrawableResource(R.drawable.transparent);
window.requestFeature(Window.FEATURE_NO_TITLE);
window.setWindowAnimations(R.style.DialogNoAnimation);
if (shadowDrawable == null) {
Rect padding = new Rect();
shadowDrawable = getContext().getResources().getDrawable(R.drawable.sheet_shadow);
shadowDrawable.getPadding(padding);
backgroundPaddingLeft = padding.left;
backgroundPaddingTop = padding.top;
}
setContentView(container, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
ciclePaint.setColor(0xffffffff);
@ -363,8 +375,6 @@ public class BottomSheet extends Dialog {
protected void onDraw(Canvas canvas) {
if (useRevealAnimation && Build.VERSION.SDK_INT <= 19) {
canvas.drawCircle(revealX, revealY, revealRadius, ciclePaint);
//shadowDrawable.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight());
//shadowDrawable.draw(canvas);
}
}
@ -373,6 +383,11 @@ public class BottomSheet extends Dialog {
return super.drawChild(canvas, child, drawingTime);
}
};
if (Build.VERSION.SDK_INT >= 21) {
containerView.setFitsSystemWindows(true);
}
containerView.setVisibility(View.INVISIBLE);
backgroundDrawable.setAlpha(0);
containerView.setWillNotDraw(false);
containerView.setOrientation(LinearLayout.VERTICAL);
container.addView(containerView, 0, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM));
@ -456,20 +471,18 @@ public class BottomSheet extends Dialog {
}
}
WindowManager.LayoutParams params = getWindow().getAttributes();
WindowManager.LayoutParams params = window.getAttributes();
params.width = ViewGroup.LayoutParams.MATCH_PARENT;
params.gravity = Gravity.TOP | Gravity.LEFT;
params.dimAmount = 0;
params.flags &= ~WindowManager.LayoutParams.FLAG_DIM_BEHIND;
if (!focusable) {
params.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
params.dimAmount = 0;
params.flags &= ~WindowManager.LayoutParams.FLAG_DIM_BEHIND;
} else {
params.dimAmount = 0.2f;
}
if (Build.VERSION.SDK_INT < 21) {
params.height = ViewGroup.LayoutParams.MATCH_PARENT;
}
getWindow().setAttributes(params);
window.setAttributes(params);
}
@Override
@ -479,14 +492,14 @@ public class BottomSheet extends Dialog {
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
}
dismissed = false;
if (Build.VERSION.SDK_INT >= 21 || !useRevealAnimation) {
if ((Build.VERSION.SDK_INT >= 21 || !useRevealAnimation) && !disableBackground) {
containerView.setBackgroundDrawable(shadowDrawable);
} else {
containerView.setBackgroundDrawable(null);
}
int left = useRevealAnimation && Build.VERSION.SDK_INT <= 19 ? 0 : backgroundPaddingLeft;
int top = useRevealAnimation && Build.VERSION.SDK_INT <= 19 ? 0 : backgroundPaddingTop;
containerView.setPadding(left, (applyTopPaddings ? AndroidUtilities.dp(8) : 0) + top, left, (applyTopPaddings ? AndroidUtilities.dp(isGrid ? 16 : 8) : 0));
int left = useRevealAnimation && Build.VERSION.SDK_INT <= 19 || disableBackground ? 0 : backgroundPaddingLeft;
int top = useRevealAnimation && Build.VERSION.SDK_INT <= 19 || disableBackground ? 0 : backgroundPaddingTop;
containerView.setPadding(left, (applyTopPadding ? AndroidUtilities.dp(8) : 0) + top, left, (applyBottomPadding ? AndroidUtilities.dp(isGrid ? 16 : 8) : 0));
if (Build.VERSION.SDK_INT >= 21) {
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
@ -499,6 +512,26 @@ public class BottomSheet extends Dialog {
}
}
public void setCustomView(View view) {
customView = view;
}
public void setTitle(CharSequence value) {
title = value;
}
public void setApplyTopPadding(boolean value) {
applyTopPadding = value;
}
public void setApplyBottomPadding(boolean value) {
applyBottomPadding = value;
}
public void setDisableBackground(boolean value) {
disableBackground = value;
}
protected void setRevealRadius(float radius) {
revealRadius = radius;
delegate.onRevealAnimationProgress(!dismissed, radius, revealX, revealY);
@ -513,12 +546,6 @@ public class BottomSheet extends Dialog {
@SuppressLint("NewApi")
private void startRevealAnimation(final boolean open) {
if (open) {
backgroundDrawable.setAlpha(0);
containerView.setVisibility(View.VISIBLE);
} else {
backgroundDrawable.setAlpha(51);
}
ViewProxy.setTranslationY(containerView, 0);
AnimatorSet animatorSet = new AnimatorSet();
@ -621,6 +648,8 @@ public class BottomSheet extends Dialog {
if (containerView.getMeasuredHeight() == 0) {
containerView.measure(View.MeasureSpec.makeMeasureSpec(AndroidUtilities.displaySize.x, View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(AndroidUtilities.displaySize.y, View.MeasureSpec.AT_MOST));
}
backgroundDrawable.setAlpha(0);
containerView.setVisibility(View.VISIBLE);
if (useRevealAnimation) {
startRevealAnimation(true);
} else {
@ -629,7 +658,7 @@ public class BottomSheet extends Dialog {
AnimatorSetProxy animatorSetProxy = new AnimatorSetProxy();
animatorSetProxy.playTogether(
ObjectAnimatorProxy.ofFloat(containerView, "translationY", 0),
ObjectAnimatorProxy.ofInt(backgroundDrawable, "alpha", focusable ? 0 : 51));
ObjectAnimatorProxy.ofInt(backgroundDrawable, "alpha", 51));
animatorSetProxy.setDuration(200);
animatorSetProxy.setStartDelay(20);
animatorSetProxy.setInterpolator(new DecelerateInterpolator());
@ -712,6 +741,7 @@ public class BottomSheet extends Dialog {
}
dismissed = true;
if (useRevealAnimation) {
backgroundDrawable.setAlpha(51);
startRevealAnimation(false);
} else {
AnimatorSetProxy animatorSetProxy = new AnimatorSetProxy();
@ -806,8 +836,13 @@ public class BottomSheet extends Dialog {
return this;
}
public Builder setApplyTopPaddings(boolean value) {
bottomSheet.applyTopPaddings = value;
public Builder setApplyTopPadding(boolean value) {
bottomSheet.applyTopPadding = value;
return this;
}
public Builder setApplyBottomPadding(boolean value) {
bottomSheet.applyBottomPadding = value;
return this;
}

View File

@ -70,23 +70,23 @@ public class DrawerLayoutContainer extends FrameLayout {
if (Build.VERSION.SDK_INT >= 21) {
setFitsSystemWindows(true);
setOnApplyWindowInsetsListener(new InsetsListener());
setOnApplyWindowInsetsListener(new OnApplyWindowInsetsListener() {
@SuppressLint("NewApi")
@Override
public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
final DrawerLayoutContainer drawerLayout = (DrawerLayoutContainer) v;
lastInsets = insets;
drawerLayout.setWillNotDraw(insets.getSystemWindowInsetTop() <= 0 && getBackground() == null);
drawerLayout.requestLayout();
return insets.consumeSystemWindowInsets();
}
});
setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
shadowLeft = getResources().getDrawable(R.drawable.menu_shadow);
}
@SuppressLint("NewApi")
private class InsetsListener implements View.OnApplyWindowInsetsListener {
@Override
public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
final DrawerLayoutContainer drawerLayout = (DrawerLayoutContainer) v;
drawerLayout.setChildInsets(insets, insets.getSystemWindowInsetTop() > 0);
return insets.consumeSystemWindowInsets();
}
}
@SuppressLint("NewApi")
private void dispatchChildInsets(View child, Object insets, int drawerGravity) {
WindowInsets wi = (WindowInsets) insets;
@ -119,12 +119,6 @@ public class DrawerLayoutContainer extends FrameLayout {
return 0;
}
private void setChildInsets(Object insets, boolean draw) {
lastInsets = insets;
setWillNotDraw(!draw && getBackground() == null);
requestLayout();
}
public void setDrawerLayout(ViewGroup layout) {
drawerLayout = layout;
addView(drawerLayout);
@ -371,6 +365,7 @@ public class DrawerLayoutContainer extends FrameLayout {
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
inLayout = true;
FileLog.w("tmessages", "onLayout");
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
@ -397,6 +392,10 @@ public class DrawerLayoutContainer extends FrameLayout {
@Override
public void requestLayout() {
if (!inLayout) {
/*StackTraceElement[] elements = Thread.currentThread().getStackTrace();
for (int a = 0; a < elements.length; a++) {
FileLog.d("tmessages", "on " + elements[a]);
}*/
super.requestLayout();
}
}

View File

@ -0,0 +1,281 @@
/*
* This is the source code of Telegram for Android v. 3.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-2016.
*/
package org.telegram.ui.ActionBar;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.text.SpannableStringBuilder;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.View;
import org.telegram.messenger.AndroidUtilities;
public class SimpleTextView extends View implements Drawable.Callback {
private Layout layout;
private TextPaint textPaint;
private int gravity = Gravity.LEFT | Gravity.TOP;
private CharSequence text;
private SpannableStringBuilder spannableStringBuilder;
private Drawable leftDrawable;
private Drawable rightDrawable;
private int drawablePadding = AndroidUtilities.dp(4);
private int leftDrawableTopPadding;
private int rightDrawableTopPadding;
private int offsetX;
private int textWidth;
private int textHeight;
private boolean wasLayout;
public enum Alignment {
ALIGN_NORMAL,
ALIGN_OPPOSITE,
ALIGN_CENTER,
ALIGN_LEFT,
ALIGN_RIGHT
}
public SimpleTextView(Context context) {
super(context);
textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
}
public void setTextColor(int color) {
textPaint.setColor(color);
invalidate();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
wasLayout = false;
}
public void setTextSize(int size) {
int newSize = AndroidUtilities.dp(size);
if (newSize == textPaint.getTextSize()) {
return;
}
textPaint.setTextSize(newSize);
recreateLayoutMaybe();
}
public void setGravity(int value) {
gravity = value;
}
public void setTypeface(Typeface typeface) {
textPaint.setTypeface(typeface);
}
public int getSideDrawablesSize() {
int size = 0;
if (leftDrawable != null) {
size += leftDrawable.getIntrinsicWidth() + drawablePadding;
}
if (rightDrawable != null) {
size += rightDrawable.getIntrinsicWidth() + drawablePadding;
}
return size;
}
public Paint getPaint() {
return textPaint;
}
private void createLayout(int width) {
if (text != null) {
try {
if (leftDrawable != null) {
width -= leftDrawable.getIntrinsicWidth();
width -= drawablePadding;
}
if (rightDrawable != null) {
width -= rightDrawable.getIntrinsicWidth();
width -= drawablePadding;
}
width -= getPaddingLeft() + getPaddingRight();
CharSequence string = TextUtils.ellipsize(text, textPaint, width, TextUtils.TruncateAt.END);
if (layout != null && TextUtils.equals(layout.getText(), string)) {
return;
}
layout = new StaticLayout(string, 0, string.length(), textPaint, width + AndroidUtilities.dp(8), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
if (layout.getLineCount() > 0) {
textWidth = (int) Math.ceil(layout.getLineWidth(0));
textHeight = layout.getLineBottom(0);
if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.LEFT) {
offsetX = -(int) layout.getLineLeft(0);
} else if (layout.getLineLeft(0) == 0) {
offsetX = width - textWidth;
} else {
offsetX = 0;
}
}
} catch (Exception e) {
//ignore
}
} else {
layout = null;
textWidth = 0;
textHeight = 0;
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
createLayout(width - getPaddingLeft() - getPaddingRight());
int finalHeight;
if (MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY) {
finalHeight = height;
} else {
finalHeight = textHeight;
}
setMeasuredDimension(width, finalHeight);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
if (changed) {
wasLayout = true;
}
}
public int getTextWidth() {
return textWidth;
}
public int getTextHeight() {
return textHeight;
}
public void setLeftDrawableTopPadding(int value) {
leftDrawableTopPadding = value;
}
public void setRightDrawableTopPadding(int value) {
rightDrawableTopPadding = value;
}
public void setLeftDrawable(int resId) {
setLeftDrawable(resId == 0 ? null : getContext().getResources().getDrawable(resId));
}
public void setRightDrawable(int resId) {
setRightDrawable(resId == 0 ? null : getContext().getResources().getDrawable(resId));
}
public void setLeftDrawable(Drawable drawable) {
if (leftDrawable == drawable) {
return;
}
if (leftDrawable != null) {
leftDrawable.setCallback(null);
}
leftDrawable = drawable;
if (drawable != null) {
drawable.setCallback(this);
}
recreateLayoutMaybe();
}
public void setRightDrawable(Drawable drawable) {
if (rightDrawable == drawable) {
return;
}
if (rightDrawable != null) {
rightDrawable.setCallback(null);
}
rightDrawable = drawable;
if (drawable != null) {
drawable.setCallback(this);
}
recreateLayoutMaybe();
}
public void setText(CharSequence value) {
if (text == null && value == null || text != null && value != null && text.equals(value)) {
return;
}
text = value;
recreateLayoutMaybe();
}
public void setDrawablePadding(int value) {
if (drawablePadding == value) {
return;
}
drawablePadding = value;
recreateLayoutMaybe();
}
private void recreateLayoutMaybe() {
if (wasLayout) {
createLayout(getMeasuredWidth());
invalidate();
} else {
requestLayout();
}
}
public CharSequence getText() {
if (text == null) {
return "";
}
return text;
}
@Override
protected void onDraw(Canvas canvas) {
int textOffsetX = 0;
if (leftDrawable != null) {
int y = (textHeight - leftDrawable.getIntrinsicHeight()) / 2 + leftDrawableTopPadding;
leftDrawable.setBounds(0, y, leftDrawable.getIntrinsicWidth(), y + leftDrawable.getIntrinsicHeight());
leftDrawable.draw(canvas);
if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.LEFT) {
textOffsetX += drawablePadding + leftDrawable.getIntrinsicWidth();
}
}
if (rightDrawable != null) {
int x = textOffsetX + textWidth + drawablePadding;
if (leftDrawable != null) {
x += drawablePadding + leftDrawable.getIntrinsicWidth();
}
int y = (textHeight - rightDrawable.getIntrinsicHeight()) / 2 + rightDrawableTopPadding;
rightDrawable.setBounds(x, y, x + rightDrawable.getIntrinsicWidth(), y + rightDrawable.getIntrinsicHeight());
rightDrawable.draw(canvas);
}
if (layout != null) {
if (offsetX + textOffsetX != 0) {
canvas.save();
canvas.translate(offsetX + textOffsetX, 0);
}
layout.draw(canvas);
if (offsetX + textOffsetX != 0) {
canvas.restore();
}
}
}
@Override
public void invalidateDrawable(Drawable who) {
invalidate();
}
}

View File

@ -0,0 +1,419 @@
/*
* This is the source code of Telegram for Android v. 3.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-2016.
*/
package org.telegram.ui.ActionBar;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.RippleDrawable;
import android.graphics.drawable.StateListDrawable;
import android.os.Build;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.R;
public class Theme {
public static final int ACTION_BAR_COLOR = 0xff527da3;
public static final int ACTION_BAR_PHOTO_VIEWER_COLOR = 0x7f000000;
public static final int ACTION_BAR_MEDIA_PICKER_COLOR = 0xff333333;
public static final int ACTION_BAR_CHANNEL_INTRO_COLOR = 0xffffffff;
public static final int ACTION_BAR_PLAYER_COLOR = 0xffffffff;
public static final int ACTION_BAR_TITLE_COLOR = 0xffffffff;
public static final int ACTION_BAR_SUBTITLE_COLOR = 0xffd5e8f7;
public static final int ACTION_BAR_PROFILE_COLOR = 0xff598fba;
public static final int ACTION_BAR_PROFILE_SUBTITLE_COLOR = 0xffd7eafa;
public static final int ACTION_BAR_MAIN_AVATAR_COLOR = 0xff5085b1;
public static final int ACTION_BAR_ACTION_MODE_TEXT_COLOR = 0xff737373;
public static final int ACTION_BAR_SELECTOR_COLOR = 0xff406d94;
public static final int INPUT_FIELD_SELECTOR_COLOR = 0xffd6d6d6;
public static final int ACTION_BAR_PICKER_SELECTOR_COLOR = 0xff3d3d3d;
public static final int ACTION_BAR_WHITE_SELECTOR_COLOR = 0x40ffffff;
public static final int ACTION_BAR_AUDIO_SELECTOR_COLOR = 0x2f000000;
public static final int ACTION_BAR_CHANNEL_INTRO_SELECTOR_COLOR = 0x2f000000;
public static final int ACTION_BAR_MODE_SELECTOR_COLOR = 0xfff0f0f0;
public static final int ACTION_BAR_BLUE_SELECTOR_COLOR = 0xff4981ad;
public static final int ACTION_BAR_CYAN_SELECTOR_COLOR = 0xff39849d;
public static final int ACTION_BAR_GREEN_SELECTOR_COLOR = 0xff48953d;
public static final int ACTION_BAR_ORANGE_SELECTOR_COLOR = 0xffe67429;
public static final int ACTION_BAR_PINK_SELECTOR_COLOR = 0xffd44e7b;
public static final int ACTION_BAR_RED_SELECTOR_COLOR = 0xffbc4b41;
public static final int ACTION_BAR_VIOLET_SELECTOR_COLOR = 0xff735fbe;
public static final int ACTION_BAR_YELLOW_SELECTOR_COLOR = 0xffef9f09;
public static final int CHAT_UNREAD_TEXT_COLOR = 0xff5695cc;
public static final int CHAT_ADD_CONTACT_TEXT_COLOR = 0xff4a82b5;
public static final int CHAT_REPORT_SPAM_TEXT_COLOR = 0xffcf5957;
public static final int CHAT_BOTTOM_OVERLAY_TEXT_COLOR = 0xff7f7f7f;
public static final int CHAT_BOTTOM_CHAT_OVERLAY_TEXT_COLOR = 0xff3a8ccf;
public static final int CHAT_GIF_HINT_TEXT_COLOR = 0xffffffff;
public static final int CHAT_EMPTY_VIEW_TEXT_COLOR = 0xffffffff;
public static final int INAPP_PLAYER_PERFORMER_TEXT_COLOR = 0xff2f3438;
public static final int INAPP_PLAYER_TITLE_TEXT_COLOR = 0xff2f3438;
public static final int INAPP_PLAYER_BACKGROUND_COLOR = 0xffffffff;
public static final int REPLY_PANEL_NAME_TEXT_COLOR = 0xff3a8ccf;
public static final int REPLY_PANEL_MESSAGE_TEXT_COLOR = 0xff222222;
public static final int ALERT_PANEL_NAME_TEXT_COLOR = 0xff3a8ccf;
public static final int ALERT_PANEL_MESSAGE_TEXT_COLOR = 0xff999999;
public static final int AUTODOWNLOAD_SHEET_SAVE_TEXT_COLOR = 0xff3a8ccf;
public static final int SHARE_SHEET_COPY_TEXT_COLOR = 0xff3a8ccf;
public static final int SHARE_SHEET_SEND_TEXT_COLOR = 0xff3ec1f9;
public static final int SHARE_SHEET_SEND_DISABLED_TEXT_COLOR = 0xffb3b3b3;
public static final int SHARE_SHEET_EDIT_TEXT_COLOR = 0xff212121;
public static final int SHARE_SHEET_EDIT_PLACEHOLDER_TEXT_COLOR = 0xff979797;
public static final int SHARE_SHEET_BADGE_TEXT_COLOR = 0xffffffff;
public static final int STICKERS_SHEET_TITLE_TEXT_COLOR = 0xff212121;
public static final int STICKERS_SHEET_SEND_TEXT_COLOR = 0xff3a8ccf;
public static final int STICKERS_SHEET_ADD_TEXT_COLOR = 0xff3a8ccf;
public static final int STICKERS_SHEET_CLOSE_TEXT_COLOR = 0xff3a8ccf;
public static final int STICKERS_SHEET_REMOVE_TEXT_COLOR = 0xffcd5a5a;
public static final int PINNED_PANEL_NAME_TEXT_COLOR = 0xff3a8ccf;
public static final int PINNED_PANEL_MESSAGE_TEXT_COLOR = 0xff999999;
public static final int SECRET_CHAT_INFO_TEXT_COLOR = 0xffffffff;
public static final int MSG_WEB_PREVIEW_DURATION_TEXT_COLOR = 0xffffffff;
public static final int MSG_SECRET_TIME_TEXT_COLOR = 0xffe4e2e0;
public static final int MSG_STICKER_NAME_TEXT_COLOR = 0xffffffff;
public static final int MSG_BOT_BUTTON_TEXT_COLOR = 0xffffffff;
public static final int MSG_BOT_PROGRESS_COLOR = 0xffffffff;
public static final int MSG_IN_FORDWARDED_NAME_TEXT_COLOR = 0xff3886c7;
public static final int MSG_OUT_FORDWARDED_NAME_TEXT_COLOR = 0xff55ab4f;
public static final int MSG_IN_VIA_BOT_NAME_TEXT_COLOR = 0xff3a8ccf;
public static final int MSG_OUT_VIA_BOT_NAME_TEXT_COLOR = 0xff55ab4f;
public static final int MSG_STICKER_VIA_BOT_NAME_TEXT_COLOR = 0xffffffff;
public static final int MSG_IN_REPLY_LINE_COLOR = 0xff70b4e8;
public static final int MSG_OUT_REPLY_LINE_COLOR = 0xff88c97b;
public static final int MSG_STICKER_REPLY_LINE_COLOR = 0xffffffff;
public static final int MSG_IN_REPLY_NAME_TEXT_COLOR = 0xff3a8ccf;
public static final int MSG_OUT_REPLY_NAME_TEXT_COLOR = 0xff55ab4f;
public static final int MSG_STICKER_REPLY_NAME_TEXT_COLOR = 0xffffffff;
public static final int MSG_IN_REPLY_MESSAGE_TEXT_COLOR = 0xff000000;
public static final int MSG_OUT_REPLY_MESSAGE_TEXT_COLOR = 0xff000000;
public static final int MSG_IN_REPLY_MEDIA_MESSAGE_TEXT_COLOR = 0xffa1aab3;
public static final int MSG_OUT_REPLY_MEDIA_MESSAGE_TEXT_COLOR = 0xff65b05b;
public static final int MSG_IN_REPLY_MEDIA_MESSAGE_SELETED_TEXT_COLOR = 0xff89b4c1;
public static final int MSG_OUT_REPLY_MEDIA_MESSAGE_SELETED_TEXT_COLOR = 0xff65b05b;
public static final int MSG_STICKER_REPLY_MESSAGE_TEXT_COLOR = 0xffffffff;
public static final int MSG_IN_WEB_PREVIEW_LINE_COLOR = 0xff70b4e8;
public static final int MSG_OUT_WEB_PREVIEW_LINE_COLOR = 0xff88c97b;
public static final int MSG_IN_SITE_NAME_TEXT_COLOR = 0xff3a8ccf;
public static final int MSG_OUT_SITE_NAME_TEXT_COLOR = 0xff55ab4f;
public static final int MSG_IN_CONTACT_NAME_TEXT_COLOR = 0xff4e9ad4;
public static final int MSG_OUT_CONTACT_NAME_TEXT_COLOR = 0xff55ab4f;
public static final int MSG_IN_CONTACT_PHONE_TEXT_COLOR = 0xff2f3438;
public static final int MSG_OUT_CONTACT_PHONE_TEXT_COLOR = 0xff354234;
public static final int MSG_MEDIA_PROGRESS_COLOR = 0xffffffff;
public static final int MSG_IN_AUDIO_PROGRESS_COLOR = 0xffffffff;
public static final int MSG_OUT_AUDIO_PROGRESS_COLOR = 0xffefffde;
public static final int MSG_IN_AUDIO_SELECTED_PROGRESS_COLOR = 0xffe2f8ff;
public static final int MSG_OUT_AUDIO_SELECTED_PROGRESS_COLOR = 0xffd4f5bc;
public static final int MSG_MEDIA_TIME_TEXT_COLOR = 0xffffffff;
public static final int MSG_IN_TIME_TEXT_COLOR = 0xffa1aab3;
public static final int MSG_OUT_TIME_TEXT_COLOR = 0xff70b15c;
public static final int MSG_IN_TIME_SELECTED_TEXT_COLOR = 0xff89b4c1;
public static final int MSG_OUT_TIME_SELECTED_TEXT_COLOR = 0xff70b15c;
public static final int MSG_IN_AUDIO_PERFORMER_TEXT_COLOR = 0xff2f3438;
public static final int MSG_OUT_AUDIO_PERFORMER_TEXT_COLOR = 0xff354234;
public static final int MSG_IN_AUDIO_TITLE_TEXT_COLOR = 0xff4e9ad4;
public static final int MSG_OUT_AUDIO_TITLE_TEXT_COLOR = 0xff55ab4f;
public static final int MSG_IN_AUDIO_DURATION_TEXT_COLOR = 0xffa1aab3;
public static final int MSG_OUT_AUDIO_DURATION_TEXT_COLOR = 0xff65b05b;
public static final int MSG_IN_AUDIO_DURATION_SELECTED_TEXT_COLOR = 0xff89b4c1;
public static final int MSG_OUT_AUDIO_DURATION_SELECTED_TEXT_COLOR = 0xff65b05b;
public static final int MSG_IN_AUDIO_SEEKBAR_COLOR = 0xffe4eaf0;
public static final int MSG_OUT_AUDIO_SEEKBAR_COLOR = 0xffbbe3ac;
public static final int MSG_IN_AUDIO_SEEKBAR_SELECTED_COLOR = 0xffbcdee8;
public static final int MSG_OUT_AUDIO_SEEKBAR_SELECTED_COLOR = 0xffa9dd96;
public static final int MSG_IN_AUDIO_SEEKBAR_FILL_COLOR = 0xff72b5e8;
public static final int MSG_OUT_AUDIO_SEEKBAR_FILL_COLOR = 0xff78c272;
public static final int MSG_IN_VOICE_SEEKBAR_COLOR = 0xffdee5eb;
public static final int MSG_OUT_VOICE_SEEKBAR_COLOR = 0xffbbe3ac;
public static final int MSG_IN_VOICE_SEEKBAR_SELECTED_COLOR = 0xffbcdee8;
public static final int MSG_OUT_VOICE_SEEKBAR_SELECTED_COLOR = 0xffa9dd96;
public static final int MSG_IN_VOICE_SEEKBAR_FILL_COLOR = 0xff72b5e8;
public static final int MSG_OUT_VOICE_SEEKBAR_FILL_COLOR = 0xff78c272;
public static final int MSG_IN_FILE_PROGRESS_COLOR = 0xffebf0f5;
public static final int MSG_OUT_FILE_PROGRESS_COLOR = 0xffdaf5c3;
public static final int MSG_IN_FILE_PROGRESS_SELECTED_COLOR = 0xffcbeaf6;
public static final int MSG_OUT_FILE_PROGRESS_SELECTED_COLOR = 0xffc5eca7;
public static final int MSG_IN_FILE_NAME_TEXT_COLOR = 0xff4e9ad4;
public static final int MSG_OUT_FILE_NAME_TEXT_COLOR = 0xff55ab4f;
public static final int MSG_IN_FILE_INFO_TEXT_COLOR = 0xffa1aab3;
public static final int MSG_OUT_FILE_INFO_TEXT_COLOR = 0xff65b05b;
public static final int MSG_IN_FILE_INFO_SELECTED_TEXT_COLOR = 0xff89b4c1;
public static final int MSG_OUT_FILE_INFO_SELECTED_TEXT_COLOR = 0xff65b05b;
public static final int MSG_IN_FILE_BACKGROUND_COLOR = 0xffebf0f5;
public static final int MSG_OUT_FILE_BACKGROUND_COLOR = 0xffdaf5c3;
public static final int MSG_IN_FILE_BACKGROUND_SELECTED_COLOR = 0xffcbeaf6;
public static final int MSG_OUT_FILE_BACKGROUND_SELECTED_COLOR = 0xffc5eca7;
public static final int MSG_IN_VENUE_NAME_TEXT_COLOR = 0xff4e9ad4;
public static final int MSG_OUT_VENUE_NAME_TEXT_COLOR = 0xff55ab4f;
public static final int MSG_IN_VENUE_INFO_TEXT_COLOR = 0xffa1aab3;
public static final int MSG_OUT_VENUE_INFO_TEXT_COLOR = 0xff65b05b;
public static final int MSG_IN_VENUE_INFO_SELECTED_TEXT_COLOR = 0xff89b4c1;
public static final int MSG_OUT_VENUE_INFO_SELECTED_TEXT_COLOR = 0xff65b05b;
public static final int MSG_MEDIA_INFO_TEXT_COLOR = 0xffffffff;
public static final int MSG_TEXT_COLOR = 0xff000000;
public static final int MSG_LINK_TEXT_COLOR = 0xff2678b6;
public static final int MSG_LINK_SELECT_BACKGROUND_COLOR = 0x3362a9e3;
public static Drawable backgroundDrawableIn;
public static Drawable backgroundDrawableInSelected;
public static Drawable backgroundDrawableOut;
public static Drawable backgroundDrawableOutSelected;
public static Drawable backgroundMediaDrawableIn;
public static Drawable backgroundMediaDrawableInSelected;
public static Drawable backgroundMediaDrawableOut;
public static Drawable backgroundMediaDrawableOutSelected;
public static Drawable checkDrawable;
public static Drawable halfCheckDrawable;
public static Drawable clockDrawable;
public static Drawable broadcastDrawable;
public static Drawable checkMediaDrawable;
public static Drawable halfCheckMediaDrawable;
public static Drawable clockMediaDrawable;
public static Drawable broadcastMediaDrawable;
public static Drawable errorDrawable;
public static Drawable systemDrawable;
public static Drawable backgroundBluePressed;
public static Drawable timeBackgroundDrawable;
public static Drawable timeStickerBackgroundDrawable;
public static Drawable botLink;
public static Drawable botInline;
public static Drawable[] clockChannelDrawable = new Drawable[2];
public static Drawable[] cornerOuter = new Drawable[4];
public static Drawable[] cornerInner = new Drawable[4];
public static Drawable shareDrawable;
public static Drawable shareIconDrawable;
public static Drawable[] viewsCountDrawable = new Drawable[2];
public static Drawable viewsOutCountDrawable;
public static Drawable viewsMediaCountDrawable;
public static Drawable geoInDrawable;
public static Drawable geoOutDrawable;
public static Drawable inlineDocDrawable;
public static Drawable inlineAudioDrawable;
public static Drawable inlineLocationDrawable;
public static Drawable[] contactDrawable = new Drawable[2];
public static Drawable[][] fileStatesDrawable = new Drawable[10][2];
public static Drawable[][] photoStatesDrawables = new Drawable[13][2];
public static Drawable[] docMenuDrawable = new Drawable[4];
public static PorterDuffColorFilter colorFilter;
public static PorterDuffColorFilter colorPressedFilter;
private static int currentColor;
private static Paint maskPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
public static void loadRecources(Context context) {
if (backgroundDrawableIn == null) {
backgroundDrawableIn = context.getResources().getDrawable(R.drawable.msg_in);
backgroundDrawableInSelected = context.getResources().getDrawable(R.drawable.msg_in_selected);
backgroundDrawableOut = context.getResources().getDrawable(R.drawable.msg_out);
backgroundDrawableOutSelected = context.getResources().getDrawable(R.drawable.msg_out_selected);
backgroundMediaDrawableIn = context.getResources().getDrawable(R.drawable.msg_in_photo);
backgroundMediaDrawableInSelected = context.getResources().getDrawable(R.drawable.msg_in_photo_selected);
backgroundMediaDrawableOut = context.getResources().getDrawable(R.drawable.msg_out_photo);
backgroundMediaDrawableOutSelected = context.getResources().getDrawable(R.drawable.msg_out_photo_selected);
checkDrawable = context.getResources().getDrawable(R.drawable.msg_check);
halfCheckDrawable = context.getResources().getDrawable(R.drawable.msg_halfcheck);
clockDrawable = context.getResources().getDrawable(R.drawable.msg_clock);
checkMediaDrawable = context.getResources().getDrawable(R.drawable.msg_check_w);
halfCheckMediaDrawable = context.getResources().getDrawable(R.drawable.msg_halfcheck_w);
clockMediaDrawable = context.getResources().getDrawable(R.drawable.msg_clock_photo);
clockChannelDrawable[0] = context.getResources().getDrawable(R.drawable.msg_clock2);
clockChannelDrawable[1] = context.getResources().getDrawable(R.drawable.msg_clock2_s);
errorDrawable = context.getResources().getDrawable(R.drawable.msg_warning);
timeBackgroundDrawable = context.getResources().getDrawable(R.drawable.phototime2_b);
timeStickerBackgroundDrawable = context.getResources().getDrawable(R.drawable.phototime2);
broadcastDrawable = context.getResources().getDrawable(R.drawable.broadcast3);
broadcastMediaDrawable = context.getResources().getDrawable(R.drawable.broadcast4);
systemDrawable = context.getResources().getDrawable(R.drawable.system);
botLink = context.getResources().getDrawable(R.drawable.bot_link);
botInline = context.getResources().getDrawable(R.drawable.bot_lines);
viewsCountDrawable[0] = context.getResources().getDrawable(R.drawable.post_views);
viewsCountDrawable[1] = context.getResources().getDrawable(R.drawable.post_views_s);
viewsOutCountDrawable = context.getResources().getDrawable(R.drawable.post_viewsg);
viewsMediaCountDrawable = context.getResources().getDrawable(R.drawable.post_views_w);
fileStatesDrawable[0][0] = context.getResources().getDrawable(R.drawable.play_g);
fileStatesDrawable[0][1] = context.getResources().getDrawable(R.drawable.play_g_s);
fileStatesDrawable[1][0] = context.getResources().getDrawable(R.drawable.pause_g);
fileStatesDrawable[1][1] = context.getResources().getDrawable(R.drawable.pause_g_s);
fileStatesDrawable[2][0] = context.getResources().getDrawable(R.drawable.file_g_load);
fileStatesDrawable[2][1] = context.getResources().getDrawable(R.drawable.file_g_load_s);
fileStatesDrawable[3][0] = context.getResources().getDrawable(R.drawable.file_g);
fileStatesDrawable[3][1] = context.getResources().getDrawable(R.drawable.file_g_s);
fileStatesDrawable[4][0] = context.getResources().getDrawable(R.drawable.file_g_cancel);
fileStatesDrawable[4][1] = context.getResources().getDrawable(R.drawable.file_g_cancel_s);
fileStatesDrawable[5][0] = context.getResources().getDrawable(R.drawable.play_b);
fileStatesDrawable[5][1] = context.getResources().getDrawable(R.drawable.play_b_s);
fileStatesDrawable[6][0] = context.getResources().getDrawable(R.drawable.pause_b);
fileStatesDrawable[6][1] = context.getResources().getDrawable(R.drawable.pause_b_s);
fileStatesDrawable[7][0] = context.getResources().getDrawable(R.drawable.file_b_load);
fileStatesDrawable[7][1] = context.getResources().getDrawable(R.drawable.file_b_load_s);
fileStatesDrawable[8][0] = context.getResources().getDrawable(R.drawable.file_b);
fileStatesDrawable[8][1] = context.getResources().getDrawable(R.drawable.file_b_s);
fileStatesDrawable[9][0] = context.getResources().getDrawable(R.drawable.file_b_cancel);
fileStatesDrawable[9][1] = context.getResources().getDrawable(R.drawable.file_b_cancel_s);
photoStatesDrawables[0][0] = context.getResources().getDrawable(R.drawable.photoload);
photoStatesDrawables[0][1] = context.getResources().getDrawable(R.drawable.photoload_pressed);
photoStatesDrawables[1][0] = context.getResources().getDrawable(R.drawable.photocancel);
photoStatesDrawables[1][1] = context.getResources().getDrawable(R.drawable.photocancel_pressed);
photoStatesDrawables[2][0] = context.getResources().getDrawable(R.drawable.photogif);
photoStatesDrawables[2][1] = context.getResources().getDrawable(R.drawable.photogif_pressed);
photoStatesDrawables[3][0] = context.getResources().getDrawable(R.drawable.playvideo);
photoStatesDrawables[3][1] = context.getResources().getDrawable(R.drawable.playvideo_pressed);
//photoStatesDrawables[4] = context.getResources().getDrawable(R.drawable.photopause);
photoStatesDrawables[4][0] = photoStatesDrawables[4][1] = context.getResources().getDrawable(R.drawable.burn);
photoStatesDrawables[5][0] = photoStatesDrawables[5][1] = context.getResources().getDrawable(R.drawable.circle);
photoStatesDrawables[6][0] = photoStatesDrawables[6][1] = context.getResources().getDrawable(R.drawable.photocheck);
photoStatesDrawables[7][0] = context.getResources().getDrawable(R.drawable.photoload_g);
photoStatesDrawables[7][1] = context.getResources().getDrawable(R.drawable.photoload_g_s);
photoStatesDrawables[8][0] = context.getResources().getDrawable(R.drawable.photocancel_g);
photoStatesDrawables[8][1] = context.getResources().getDrawable(R.drawable.photocancel_g_s);
photoStatesDrawables[9][0] = context.getResources().getDrawable(R.drawable.doc_green);
photoStatesDrawables[9][1] = context.getResources().getDrawable(R.drawable.doc_green);
photoStatesDrawables[10][0] = context.getResources().getDrawable(R.drawable.photoload_b);
photoStatesDrawables[10][1] = context.getResources().getDrawable(R.drawable.photoload_b_s);
photoStatesDrawables[11][0] = context.getResources().getDrawable(R.drawable.photocancel_b);
photoStatesDrawables[11][1] = context.getResources().getDrawable(R.drawable.photocancel_b_s);
photoStatesDrawables[12][0] = context.getResources().getDrawable(R.drawable.doc_blue);
photoStatesDrawables[12][1] = context.getResources().getDrawable(R.drawable.doc_blue_s);
docMenuDrawable[0] = context.getResources().getDrawable(R.drawable.doc_actions_b);
docMenuDrawable[1] = context.getResources().getDrawable(R.drawable.doc_actions_g);
docMenuDrawable[2] = context.getResources().getDrawable(R.drawable.doc_actions_b_s);
docMenuDrawable[3] = context.getResources().getDrawable(R.drawable.video_actions);
contactDrawable[0] = context.getResources().getDrawable(R.drawable.contact_blue);
contactDrawable[1] = context.getResources().getDrawable(R.drawable.contact_green);
shareDrawable = context.getResources().getDrawable(R.drawable.share_round);
shareIconDrawable = context.getResources().getDrawable(R.drawable.share_arrow);
geoInDrawable = context.getResources().getDrawable(R.drawable.location_b);
geoOutDrawable = context.getResources().getDrawable(R.drawable.location_g);
context.getResources().getDrawable(R.drawable.attach_camera_states);
context.getResources().getDrawable(R.drawable.attach_gallery_states);
context.getResources().getDrawable(R.drawable.attach_video_states);
context.getResources().getDrawable(R.drawable.attach_audio_states);
context.getResources().getDrawable(R.drawable.attach_file_states);
context.getResources().getDrawable(R.drawable.attach_contact_states);
context.getResources().getDrawable(R.drawable.attach_location_states);
context.getResources().getDrawable(R.drawable.attach_hide_states);
cornerOuter[0] = context.getResources().getDrawable(R.drawable.corner_out_tl);
cornerOuter[1] = context.getResources().getDrawable(R.drawable.corner_out_tr);
cornerOuter[2] = context.getResources().getDrawable(R.drawable.corner_out_br);
cornerOuter[3] = context.getResources().getDrawable(R.drawable.corner_out_bl);
cornerInner[0] = context.getResources().getDrawable(R.drawable.corner_in_tr);
cornerInner[1] = context.getResources().getDrawable(R.drawable.corner_in_tl);
cornerInner[2] = context.getResources().getDrawable(R.drawable.corner_in_br);
cornerInner[3] = context.getResources().getDrawable(R.drawable.corner_in_bl);
inlineDocDrawable = context.getResources().getDrawable(R.drawable.bot_file);
inlineAudioDrawable = context.getResources().getDrawable(R.drawable.bot_music);
inlineLocationDrawable = context.getResources().getDrawable(R.drawable.bot_location);
}
int color = ApplicationLoader.getServiceMessageColor();
if (currentColor != color) {
colorFilter = new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY);
colorPressedFilter = new PorterDuffColorFilter(ApplicationLoader.getServiceSelectedMessageColor(), PorterDuff.Mode.MULTIPLY);
currentColor = color;
for (int a = 0; a < 4; a++) {
cornerOuter[a].setColorFilter(colorFilter);
cornerInner[a].setColorFilter(colorFilter);
}
timeStickerBackgroundDrawable.setColorFilter(colorFilter);
}
}
public static Drawable createBarSelectorDrawable(int color) {
return createBarSelectorDrawable(color, true);
}
public static Drawable createBarSelectorDrawable(int color, boolean masked) {
Drawable drawable;
if (Build.VERSION.SDK_INT >= 21) {
Drawable maskDrawable = null;
if (masked) {
maskPaint.setColor(0xffffffff);
maskDrawable = new Drawable() {
@Override
public void draw(Canvas canvas) {
android.graphics.Rect bounds = getBounds();
canvas.drawCircle(bounds.centerX(), bounds.centerY(), AndroidUtilities.dp(18), maskPaint);
}
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
}
@Override
public int getOpacity() {
return 0;
}
};
}
ColorStateList colorStateList = new ColorStateList(
new int[][]{new int[]{}},
new int[]{color}
);
return new RippleDrawable(colorStateList, null, maskDrawable);
} else {
StateListDrawable stateListDrawable = new StateListDrawable();
stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, new ColorDrawable(color));
stateListDrawable.addState(new int[]{android.R.attr.state_focused}, new ColorDrawable(color));
stateListDrawable.addState(new int[]{android.R.attr.state_selected}, new ColorDrawable(color));
if (Build.VERSION.SDK_INT >= 11) {
stateListDrawable.addState(new int[]{android.R.attr.state_activated}, new ColorDrawable(color));
}
stateListDrawable.addState(new int[]{}, new ColorDrawable(0x00000000));
return stateListDrawable;
}
}
}

View File

@ -202,7 +202,7 @@ public class ChatActivityAdapter {
Intent intent = new Intent(Intent.ACTION_VIEW);
if (message.type == 8 || message.type == 9) {
MimeTypeMap myMime = MimeTypeMap.getSingleton();
int idx = fileName.lastIndexOf(".");
int idx = fileName.lastIndexOf('.');
if (idx != -1) {
String ext = fileName.substring(idx + 1);
realMimeType = myMime.getMimeTypeFromExtension(ext.toLowerCase());

View File

@ -81,6 +81,13 @@ public class DialogsAdapter extends RecyclerView.Adapter {
return arrayList.get(i);
}
@Override
public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
if (holder.itemView instanceof DialogCell) {
((DialogCell) holder.itemView).checkCurrentDialogIndex();
}
}
@Override
public long getItemId(int i) {
return i;

View File

@ -331,7 +331,7 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
recentSearchObjects.add(0, recentSearchObject);
recentSearchObject.did = did;
recentSearchObject.object = object;
recentSearchObject.date = (int) System.currentTimeMillis() / 1000;
recentSearchObject.date = (int) (System.currentTimeMillis() / 1000);
notifyDataSetChanged();
MessagesStorage.getInstance().getStorageQueue().postRunnable(new Runnable() {
@Override
@ -340,7 +340,7 @@ public class DialogsSearchAdapter extends BaseSearchAdapterRecycler {
SQLitePreparedStatement state = MessagesStorage.getInstance().getDatabase().executeFast("REPLACE INTO search_recent VALUES(?, ?)");
state.requery();
state.bindLong(1, did);
state.bindInteger(2, (int) System.currentTimeMillis() / 1000);
state.bindInteger(2, (int) (System.currentTimeMillis() / 1000));
state.step();
state.dispose();
} catch (Exception e) {

View File

@ -8,17 +8,29 @@
package org.telegram.ui.Adapters;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.view.View;
import android.view.ViewGroup;
import org.telegram.SQLite.SQLiteCursor;
import org.telegram.SQLite.SQLitePreparedStatement;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.MessagesStorage;
import org.telegram.messenger.R;
import org.telegram.messenger.SendMessagesHelper;
import org.telegram.messenger.UserObject;
import org.telegram.messenger.support.widget.LinearLayoutManager;
import org.telegram.messenger.support.widget.RecyclerView;
@ -26,6 +38,8 @@ import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.RequestDelegate;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.Cells.BotSwitchCell;
import org.telegram.ui.Cells.ContextLinkCell;
import org.telegram.ui.Cells.MentionCell;
@ -42,7 +56,7 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
void onContextClick(TLRPC.BotInlineResult result);
}
private class Holder extends RecyclerView.ViewHolder {
public class Holder extends RecyclerView.ViewHolder {
public Holder(View itemView) {
super(itemView);
@ -50,6 +64,7 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
}
private Context mContext;
private long dialog_id;
private TLRPC.ChatFull info;
private ArrayList<TLRPC.User> botRecent;
private ArrayList<TLRPC.User> searchResultUsernames;
@ -58,6 +73,7 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
private ArrayList<String> searchResultCommandsHelp;
private ArrayList<TLRPC.User> searchResultCommandsUsers;
private ArrayList<TLRPC.BotInlineResult> searchResultBotContext;
private TLRPC.TL_inlineBotSwitchPM searchResultBotContextSwitch;
private HashMap<String, TLRPC.BotInlineResult> searchResultBotContextById;
private MentionsAdapterDelegate delegate;
private HashMap<Integer, TLRPC.BotInfo> botInfo;
@ -82,11 +98,62 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
private TLRPC.User foundContextBot;
private boolean contextMedia;
private Runnable contextQueryRunnable;
private Location lastKnownLocation;
public MentionsAdapter(Context context, boolean isDarkTheme, MentionsAdapterDelegate delegate) {
private BaseFragment parentFragment;
private SendMessagesHelper.LocationProvider locationProvider = new SendMessagesHelper.LocationProvider(new SendMessagesHelper.LocationProvider.LocationProviderDelegate() {
@Override
public void onLocationAcquired(Location location) {
if (foundContextBot != null && foundContextBot.bot_inline_geo) {
lastKnownLocation = location;
searchForContextBotResults(foundContextBot, searchingContextQuery, "");
}
}
@Override
public void onUnableLocationAcquire() {
onLocationUnavailable();
}
}) {
@Override
public void stop() {
super.stop();
lastKnownLocation = null;
}
};
public MentionsAdapter(Context context, boolean isDarkTheme, long did, MentionsAdapterDelegate delegate) {
mContext = context;
this.delegate = delegate;
this.isDarkTheme = isDarkTheme;
dialog_id = did;
}
public void onDestroy() {
if (locationProvider != null) {
locationProvider.stop();
}
if (contextQueryRunnable != null) {
AndroidUtilities.cancelRunOnUIThread(contextQueryRunnable);
contextQueryRunnable = null;
}
if (contextUsernameReqid != 0) {
ConnectionsManager.getInstance().cancelRequest(contextUsernameReqid, true);
contextUsernameReqid = 0;
}
if (contextQueryReqid != 0) {
ConnectionsManager.getInstance().cancelRequest(contextQueryReqid, true);
contextQueryReqid = 0;
}
foundContextBot = null;
searchingContextUsername = null;
searchingContextQuery = null;
noUserName = false;
}
public void setParentFragment(BaseFragment fragment) {
parentFragment = fragment;
}
public void setChatInfo(TLRPC.ChatFull chatParticipants) {
@ -115,7 +182,21 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
}
cursor.dispose();
if (uids != null) {
final ArrayList<Integer> uidsFinal = uids;
final ArrayList<TLRPC.User> users = MessagesStorage.getInstance().getUsers(uids);
Collections.sort(users, new Comparator<TLRPC.User>() {
@Override
public int compare(TLRPC.User lhs, TLRPC.User rhs) {
int idx1 = uidsFinal.indexOf(lhs.id);
int idx2 = uidsFinal.indexOf(rhs.id);
if (idx1 > idx2) {
return 1;
} else if (idx1 < idx2) {
return -1;
}
return 0;
}
});
AndroidUtilities.runOnUIThread(new Runnable() {
@Override
public void run() {
@ -240,10 +321,18 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
}
}
public TLRPC.TL_inlineBotSwitchPM getBotContextSwitch() {
return searchResultBotContextSwitch;
}
public int getContextBotId() {
return foundContextBot != null ? foundContextBot.id : 0;
}
public TLRPC.User getContextBotUser() {
return foundContextBot != null ? foundContextBot : null;
}
public String getContextBotName() {
return foundContextBot != null ? foundContextBot.username : "";
}
@ -251,6 +340,7 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
private void searchForContextBot(final String username, final String query) {
searchResultBotContext = null;
searchResultBotContextById = null;
searchResultBotContextSwitch = null;
notifyDataSetChanged();
if (foundContextBot != null) {
delegate.needChangePanelVisibility(false);
@ -271,6 +361,7 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
foundContextBot = null;
searchingContextUsername = null;
searchingContextQuery = null;
locationProvider.stop();
noUserName = false;
if (delegate != null) {
delegate.onContextSearch(false);
@ -325,6 +416,7 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
}
contextUsernameReqid = 0;
foundContextBot = null;
locationProvider.stop();
if (error == null) {
TLRPC.TL_contacts_resolvedPeer res = (TLRPC.TL_contacts_resolvedPeer) response;
if (!res.users.isEmpty()) {
@ -333,6 +425,35 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
MessagesController.getInstance().putUser(user, false);
MessagesStorage.getInstance().putUsersAndChats(res.users, null, true, true);
foundContextBot = user;
if (foundContextBot.bot_inline_geo) {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE);
boolean allowGeo = preferences.getBoolean("inlinegeo_" + foundContextBot.id, false);
if (!allowGeo && parentFragment != null && parentFragment.getParentActivity() != null) {
final TLRPC.User foundContextBotFinal = foundContextBot;
AlertDialog.Builder builder = new AlertDialog.Builder(parentFragment.getParentActivity());
builder.setTitle(LocaleController.getString("ShareYouLocationTitle", R.string.ShareYouLocationTitle));
builder.setMessage(LocaleController.getString("ShareYouLocationInline", R.string.ShareYouLocationInline));
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
if (foundContextBotFinal != null) {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("Notifications", Activity.MODE_PRIVATE);
preferences.edit().putBoolean("inlinegeo_" + foundContextBotFinal.id, true).commit();
checkLocationPermissionsOrStart();
}
}
});
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
onLocationUnavailable();
}
});
parentFragment.showDialog(builder.create());
} else {
checkLocationPermissionsOrStart();
}
}
}
}
}
@ -355,6 +476,28 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
AndroidUtilities.runOnUIThread(contextQueryRunnable, 400);
}
private void onLocationUnavailable() {
if (foundContextBot != null && foundContextBot.bot_inline_geo) {
lastKnownLocation = new Location("network");
lastKnownLocation.setLatitude(-1000);
lastKnownLocation.setLongitude(-1000);
searchForContextBotResults(foundContextBot, searchingContextQuery, "");
}
}
private void checkLocationPermissionsOrStart() {
if (parentFragment == null || parentFragment.getParentActivity() == null) {
return;
}
if (Build.VERSION.SDK_INT >= 23 && parentFragment.getParentActivity().checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
parentFragment.getParentActivity().requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, 2);
return;
}
if (foundContextBot != null && foundContextBot.bot_inline_geo) {
locationProvider.start();
}
}
public int getOrientation() {
return searchResultBotContext != null && !searchResultBotContext.isEmpty() && contextMedia ? LinearLayoutManager.HORIZONTAL : LinearLayoutManager.VERTICAL;
}
@ -384,10 +527,26 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
searchingContextQuery = null;
return;
}
if (user.bot_inline_geo && lastKnownLocation == null) {
return;
}
TLRPC.TL_messages_getInlineBotResults req = new TLRPC.TL_messages_getInlineBotResults();
req.bot = MessagesController.getInputUser(user);
req.query = query;
req.offset = offset;
if (user.bot_inline_geo && lastKnownLocation != null && lastKnownLocation.getLatitude() != -1000) {
req.flags |= 1;
req.geo_point = new TLRPC.TL_inputGeoPoint();
req.geo_point.lat = lastKnownLocation.getLatitude();
req.geo_point._long = lastKnownLocation.getLongitude();
}
int lower_id = (int) dialog_id;
int high_id = (int) (dialog_id >> 32);
if (lower_id != 0) {
req.peer = MessagesController.getInputPeer(lower_id);
} else {
req.peer = new TLRPC.TL_inputPeerEmpty();
}
contextQueryReqid = ConnectionsManager.getInstance().sendRequest(req, new RequestDelegate() {
@Override
public void run(final TLObject response, final TLRPC.TL_error error) {
@ -406,6 +565,7 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
nextQueryOffset = res.next_offset;
if (searchResultBotContextById == null) {
searchResultBotContextById = new HashMap<>();
searchResultBotContextSwitch = res.switch_pm;
}
for (int a = 0; a < res.results.size(); a++) {
TLRPC.BotInlineResult result = res.results.get(a);
@ -433,11 +593,13 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
searchResultCommandsHelp = null;
searchResultCommandsUsers = null;
if (added) {
notifyItemRangeInserted(searchResultBotContext.size() - res.results.size(), res.results.size());
boolean hasTop = getOrientation() == LinearLayoutManager.VERTICAL && searchResultBotContextSwitch != null;
notifyItemChanged(searchResultBotContext.size() - res.results.size() + (hasTop ? 1 : 0) - 1);
notifyItemRangeInserted(searchResultBotContext.size() - res.results.size() + (hasTop ? 1 : 0), res.results.size());
} else {
notifyDataSetChanged();
}
delegate.needChangePanelVisibility(!searchResultBotContext.isEmpty());
delegate.needChangePanelVisibility(!searchResultBotContext.isEmpty() || searchResultBotContextSwitch != null);
}
}
});
@ -666,7 +828,7 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
@Override
public int getItemCount() {
if (searchResultBotContext != null) {
return searchResultBotContext.size();
return searchResultBotContext.size() + (getOrientation() == LinearLayoutManager.VERTICAL && searchResultBotContextSwitch != null ? 1 : 0);
} else if (searchResultUsernames != null) {
return searchResultUsernames.size();
} else if (searchResultHashtags != null) {
@ -680,6 +842,9 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
@Override
public int getItemViewType(int position) {
if (searchResultBotContext != null) {
if (position == 0 && getOrientation() == LinearLayoutManager.VERTICAL && searchResultBotContextSwitch != null) {
return 2;
}
return 1;
} else {
return 0;
@ -688,6 +853,14 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
public Object getItem(int i) {
if (searchResultBotContext != null) {
boolean hasTop = getOrientation() == LinearLayoutManager.VERTICAL && searchResultBotContextSwitch != null;
if (hasTop) {
if (i == 0) {
return searchResultBotContextSwitch;
} else {
i--;
}
}
if (i < 0 || i >= searchResultBotContext.size()) {
return null;
}
@ -741,6 +914,8 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
delegate.onContextClick(cell.getResult());
}
});
} else if (viewType == 2) {
view = new BotSwitchCell(mContext);
} else {
view = new MentionCell(mContext);
((MentionCell) view).setIsDarkTheme(isDarkTheme);
@ -751,7 +926,17 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (searchResultBotContext != null) {
((ContextLinkCell) holder.itemView).setLink(searchResultBotContext.get(position), contextMedia, position != searchResultBotContext.size() - 1);
boolean hasTop = getOrientation() == LinearLayoutManager.VERTICAL && searchResultBotContextSwitch != null;
if (holder.getItemViewType() == 2) {
if (hasTop) {
((BotSwitchCell) holder.itemView).setText(searchResultBotContextSwitch.text);
}
} else {
if (hasTop) {
position--;
}
((ContextLinkCell) holder.itemView).setLink(searchResultBotContext.get(position), contextMedia, position != searchResultBotContext.size() - 1, hasTop && position == 0);
}
} else {
if (searchResultUsernames != null) {
((MentionCell) holder.itemView).setUser(searchResultUsernames.get(position));
@ -762,4 +947,16 @@ public class MentionsAdapter extends BaseSearchAdapterRecycler {
}
}
}
public void onRequestPermissionsResultFragment(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == 2) {
if (foundContextBot != null && foundContextBot.bot_inline_geo) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
locationProvider.start();
} else {
onLocationUnavailable();
}
}
}
}
}

View File

@ -1,106 +0,0 @@
/*
* This is the source code of Telegram for Android v. 3.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-2016.
*/
package org.telegram.ui.Adapters;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import org.telegram.messenger.MediaController;
import org.telegram.messenger.support.widget.RecyclerView;
import org.telegram.ui.Cells.PhotoAttachPhotoCell;
import java.util.HashMap;
public class PhotoAttachAdapter extends RecyclerView.Adapter {
private Context mContext;
private PhotoAttachAdapterDelegate delegate;
private HashMap<Integer, MediaController.PhotoEntry> selectedPhotos = new HashMap<>();
public interface PhotoAttachAdapterDelegate {
void selectedPhotosChanged();
}
private class Holder extends RecyclerView.ViewHolder {
public Holder(View itemView) {
super(itemView);
}
}
public PhotoAttachAdapter(Context context) {
mContext = context;
}
public void clearSelectedPhotos() {
if (!selectedPhotos.isEmpty()) {
for (HashMap.Entry<Integer, MediaController.PhotoEntry> entry : selectedPhotos.entrySet()) {
MediaController.PhotoEntry photoEntry = entry.getValue();
photoEntry.imagePath = null;
photoEntry.thumbPath = null;
photoEntry.caption = null;
}
selectedPhotos.clear();
delegate.selectedPhotosChanged();
notifyDataSetChanged();
}
}
public HashMap<Integer, MediaController.PhotoEntry> getSelectedPhotos() {
return selectedPhotos;
}
public void setDelegate(PhotoAttachAdapterDelegate photoAttachAdapterDelegate) {
delegate = photoAttachAdapterDelegate;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
PhotoAttachPhotoCell cell = (PhotoAttachPhotoCell) holder.itemView;
MediaController.PhotoEntry photoEntry = MediaController.allPhotosAlbumEntry.photos.get(position);
cell.setPhotoEntry(photoEntry, position == MediaController.allPhotosAlbumEntry.photos.size() - 1);
cell.setChecked(selectedPhotos.containsKey(photoEntry.imageId), false);
cell.getImageView().setTag(position);
cell.setTag(position);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
PhotoAttachPhotoCell cell = new PhotoAttachPhotoCell(mContext);
cell.setDelegate(new PhotoAttachPhotoCell.PhotoAttachPhotoCellDelegate() {
@Override
public void onCheckClick(PhotoAttachPhotoCell v) {
MediaController.PhotoEntry photoEntry = v.getPhotoEntry();
if (selectedPhotos.containsKey(photoEntry.imageId)) {
selectedPhotos.remove(photoEntry.imageId);
v.setChecked(false, true);
photoEntry.imagePath = null;
photoEntry.thumbPath = null;
v.setPhotoEntry(photoEntry, (Integer) v.getTag() == MediaController.allPhotosAlbumEntry.photos.size() - 1);
} else {
selectedPhotos.put(photoEntry.imageId, photoEntry);
v.setChecked(true, true);
}
delegate.selectedPhotosChanged();
}
});
return new Holder(cell);
}
@Override
public int getItemCount() {
return (MediaController.allPhotosAlbumEntry != null ? MediaController.allPhotosAlbumEntry.photos.size() : 0);
}
@Override
public int getItemViewType(int position) {
return 0;
}
}

View File

@ -30,6 +30,7 @@ import org.telegram.messenger.R;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.ActionBar;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.LineProgressView;
@ -179,9 +180,9 @@ public class AudioPlayerActivity extends BaseFragment implements NotificationCen
});
fragmentView = frameLayout;
actionBar.setBackgroundColor(0xffffffff);
actionBar.setBackgroundColor(Theme.ACTION_BAR_PLAYER_COLOR);
actionBar.setBackButtonImage(R.drawable.pl_back);
actionBar.setItemsBackground(R.drawable.bar_selector_audio);
actionBar.setItemsBackgroundColor(Theme.ACTION_BAR_AUDIO_SELECTOR_COLOR);
if (!AndroidUtilities.isTablet()) {
actionBar.showActionModeTop();
}
@ -436,7 +437,7 @@ public class AudioPlayerActivity extends BaseFragment implements NotificationCen
actionBar.setTitle(messageObject.getMusicTitle());
actionBar.getTitleTextView().setTextColor(0xff212121);
actionBar.setSubtitle(messageObject.getMusicAuthor());
actionBar.getSubTitleTextView().setTextColor(0xff8a8a8a);
actionBar.getSubtitleTextView().setTextColor(0xff8a8a8a);
}
AudioInfo audioInfo = MediaController.getInstance().getAudioInfo();
if (audioInfo != null && audioInfo.getCover() != null) {
@ -451,10 +452,14 @@ public class AudioPlayerActivity extends BaseFragment implements NotificationCen
if (durationTextView != null) {
int duration = 0;
for (TLRPC.DocumentAttribute attribute : messageObject.messageOwner.media.document.attributes) {
if (attribute instanceof TLRPC.TL_documentAttributeAudio) {
duration = attribute.duration;
break;
TLRPC.Document document = messageObject.getDocument();
if (document != null) {
for (int a = 0; a < document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeAudio) {
duration = attribute.duration;
break;
}
}
}
durationTextView.setText(duration != 0 ? String.format("%d:%02d", duration / 60, duration % 60) : "-:--");

View File

@ -472,7 +472,8 @@ public class CacheControlActivity extends BaseFragment {
return;
}
BottomSheet.Builder builder = new BottomSheet.Builder(getParentActivity());
builder.setApplyTopPaddings(false);
builder.setApplyTopPadding(false);
builder.setApplyBottomPadding(false);
LinearLayout linearLayout = new LinearLayout(getParentActivity());
linearLayout.setOrientation(LinearLayout.VERTICAL);
for (int a = 0; a < 6; a++) {

View File

@ -12,6 +12,7 @@ import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Build;
import android.text.Layout;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
@ -29,8 +30,10 @@ import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.browser.Browser;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.LinkPath;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.URLSpanNoUnderline;
public class AboutLinkCell extends FrameLayout {
@ -60,10 +63,10 @@ public class AboutLinkCell extends FrameLayout {
textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
textPaint.setTextSize(AndroidUtilities.dp(16));
textPaint.setColor(0xff000000);
textPaint.linkColor = 0xff316f9f;
textPaint.linkColor = Theme.MSG_LINK_TEXT_COLOR;
urlPaint = new Paint();
urlPaint.setColor(0x33316f9f);
urlPaint.setColor(Theme.MSG_LINK_SELECT_BACKGROUND_COLOR);
imageView = new ImageView(context);
imageView.setScaleType(ImageView.ScaleType.CENTER);
@ -107,6 +110,12 @@ public class AboutLinkCell extends FrameLayout {
float x = event.getX();
float y = event.getY();
if (Build.VERSION.SDK_INT >= 21 && getBackground() != null) {
if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) {
getBackground().setHotspot(x, y);
}
}
boolean result = false;
if (textLayout != null) {
if (event.getAction() == MotionEvent.ACTION_DOWN || pressedLink != null && event.getAction() == MotionEvent.ACTION_UP) {
@ -128,7 +137,7 @@ public class AboutLinkCell extends FrameLayout {
result = true;
try {
int start = buffer.getSpanStart(pressedLink);
urlPath.setCurrentLayout(textLayout, start);
urlPath.setCurrentLayout(textLayout, start, 0);
textLayout.getSelectionPath(start, buffer.getSpanEnd(pressedLink), urlPath);
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -154,7 +163,7 @@ public class AboutLinkCell extends FrameLayout {
}
} else {
if (pressedLink instanceof URLSpan) {
AndroidUtilities.openUrl(getContext(), ((URLSpan) pressedLink).getURL());
Browser.openUrl(getContext(), ((URLSpan) pressedLink).getURL());
} else {
pressedLink.onClick(this);
}

View File

@ -55,6 +55,10 @@ public class BaseCell extends View {
setDrawableBounds(drawable, x, y, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
}
protected void setDrawableBounds(Drawable drawable, float x, float y) {
setDrawableBounds(drawable, (int) x, (int) y, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
}
protected void setDrawableBounds(Drawable drawable, int x, int y, int w, int h) {
if (drawable != null) {
drawable.setBounds(x, y, x + w, y + h);

View File

@ -28,8 +28,9 @@ import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.messenger.browser.Browser;
import org.telegram.ui.Components.LinkPath;
import org.telegram.ui.Components.ResourceLoader;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.TypefaceSpan;
import org.telegram.ui.Components.URLSpanNoUnderline;
@ -60,10 +61,10 @@ public class BotHelpCell extends View {
textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
textPaint.setTextSize(AndroidUtilities.dp(16));
textPaint.setColor(0xff000000);
textPaint.linkColor = 0xff316f9f;
textPaint.linkColor = Theme.MSG_LINK_TEXT_COLOR;
urlPaint = new Paint();
urlPaint.setColor(0x33316f9f);
urlPaint.setColor(Theme.MSG_LINK_SELECT_BACKGROUND_COLOR);
}
public void setDelegate(BotHelpCellDelegate botHelpCellDelegate) {
@ -140,7 +141,7 @@ public class BotHelpCell extends View {
result = true;
try {
int start = buffer.getSpanStart(pressedLink);
urlPath.setCurrentLayout(textLayout, start);
urlPath.setCurrentLayout(textLayout, start, 0);
textLayout.getSelectionPath(start, buffer.getSpanEnd(pressedLink), urlPath);
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -166,7 +167,7 @@ public class BotHelpCell extends View {
}
} else {
if (pressedLink instanceof URLSpan) {
AndroidUtilities.openUrl(getContext(), ((URLSpan) pressedLink).getURL());
Browser.openUrl(getContext(), ((URLSpan) pressedLink).getURL());
} else {
pressedLink.onClick(this);
}
@ -193,14 +194,16 @@ public class BotHelpCell extends View {
protected void onDraw(Canvas canvas) {
int x = (canvas.getWidth() - width) / 2;
int y = AndroidUtilities.dp(4);
ResourceLoader.backgroundMediaDrawableIn.setBounds(x, y, width + x, height + y);
ResourceLoader.backgroundMediaDrawableIn.draw(canvas);
Theme.backgroundMediaDrawableIn.setBounds(x, y, width + x, height + y);
Theme.backgroundMediaDrawableIn.draw(canvas);
canvas.save();
canvas.translate(textX = AndroidUtilities.dp(2 + 9) + x, textY = AndroidUtilities.dp(2 + 9) + y);
if (pressedLink != null) {
canvas.drawPath(urlPath, urlPaint);
}
textLayout.draw(canvas);
if (textLayout != null) {
textLayout.draw(canvas);
}
canvas.restore();
}
}

View File

@ -0,0 +1,62 @@
/*
* This is the source code of Telegram for Android v. 3.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-2016.
*/
package org.telegram.ui.Cells;
import android.content.Context;
import android.os.Build;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.widget.FrameLayout;
import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.ui.Components.LayoutHelper;
public class BotSwitchCell extends FrameLayout {
private TextView textView;
public BotSwitchCell(Context context) {
super(context);
setBackgroundResource(R.drawable.list_selector);
textView = new TextView(context);
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
textView.setTextColor(0xff4391cc);
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
textView.setSingleLine(true);
textView.setEllipsize(TextUtils.TruncateAt.END);
textView.setMaxLines(1);
textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT));
addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), 14, 0, 14, 0));
}
@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);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(36), MeasureSpec.EXACTLY));
}
public void setText(String text) {
textView.setText(text);
}
}

View File

@ -12,7 +12,7 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.graphics.RectF;
import android.text.Layout;
import android.text.Spannable;
import android.text.StaticLayout;
@ -22,15 +22,15 @@ import android.view.MotionEvent;
import android.view.SoundEffectConstants;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.tgnet.TLRPC;
import org.telegram.messenger.UserConfig;
import org.telegram.ui.Components.ResourceLoader;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.PhotoViewer;
import org.telegram.ui.Components.AvatarDrawable;
@ -43,6 +43,8 @@ public class ChatActionCell extends BaseCell {
}
private static TextPaint textPaint;
private static Paint backPaint;
private static RectF rect;
private URLSpan pressedLink;
@ -69,11 +71,17 @@ public class ChatActionCell extends BaseCell {
textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
textPaint.setColor(0xffffffff);
textPaint.linkColor = 0xffffffff;
textPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
backPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
rect = new RectF();
}
backPaint.setColor(ApplicationLoader.getServiceMessageColor());
imageReceiver = new ImageReceiver(this);
imageReceiver.setRoundRadius(AndroidUtilities.dp(32));
avatarDrawable = new AvatarDrawable();
textPaint.setTextSize(AndroidUtilities.dp(MessagesController.getInstance().fontSize));
textPaint.setTextSize(AndroidUtilities.dp(MessagesController.getInstance().fontSize - 2));
}
public void setDelegate(ChatActionCellDelegate delegate) {
@ -258,26 +266,148 @@ public class ChatActionCell extends BaseCell {
setMeasuredDimension(width, textHeight + AndroidUtilities.dp(14 + (currentMessageObject.type == 11 ? 70 : 0)));
}
private int findMaxWidthAroundLine(int line) {
int width = (int) Math.ceil(textLayout.getLineWidth(line));
int count = textLayout.getLineCount();
for (int a = line + 1; a < count; a++) {
int w = (int) Math.ceil(textLayout.getLineWidth(a));
if (Math.abs(w - width) < AndroidUtilities.dp(12)) {
width = Math.max(w, width);
} else {
break;
}
}
for (int a = line - 1; a >= 0; a--) {
int w = (int) Math.ceil(textLayout.getLineWidth(a));
if (Math.abs(w - width) < AndroidUtilities.dp(12)) {
width = Math.max(w, width);
} else {
break;
}
}
return width;
}
@Override
protected void onDraw(Canvas canvas) {
if (currentMessageObject == null) {
return;
}
Drawable backgroundDrawable;
if (ApplicationLoader.isCustomTheme()) {
backgroundDrawable = ResourceLoader.backgroundBlack;
} else {
backgroundDrawable = ResourceLoader.backgroundBlue;
}
backgroundDrawable.setBounds(textX - AndroidUtilities.dp(5), AndroidUtilities.dp(5), textX + textWidth + AndroidUtilities.dp(5), AndroidUtilities.dp(9) + textHeight);
backgroundDrawable.draw(canvas);
if (currentMessageObject.type == 11) {
imageReceiver.draw(canvas);
}
if (textLayout != null) {
final int count = textLayout.getLineCount();
final int corner = AndroidUtilities.dp(6);
int y = AndroidUtilities.dp(7);
int previousLineBottom = 0;
int dx;
int dy;
for (int a = 0; a < count; a++) {
int width = findMaxWidthAroundLine(a);
int x = (getMeasuredWidth() - width) / 2 - AndroidUtilities.dp(3);
width += AndroidUtilities.dp(6);
int lineBottom = textLayout.getLineBottom(a);
int height = lineBottom - previousLineBottom;
int additionalHeight = 0;
previousLineBottom = lineBottom;
boolean drawBottomCorners = a == count - 1;
boolean drawTopCorners = a == 0;
if (drawTopCorners) {
y -= AndroidUtilities.dp(3);
height += AndroidUtilities.dp(3);
}
if (drawBottomCorners) {
height += AndroidUtilities.dp(3);
}
canvas.drawRect(x, y, x + width, y + height, backPaint);
if (!drawBottomCorners && a + 1 < count) {
int nextLineWidth = findMaxWidthAroundLine(a + 1) + AndroidUtilities.dp(6);
if (nextLineWidth + corner * 2 < width) {
int nextX = (getMeasuredWidth() - nextLineWidth) / 2;
drawBottomCorners = true;
additionalHeight = AndroidUtilities.dp(3);
canvas.drawRect(x, y + height, nextX, y + height + AndroidUtilities.dp(3), backPaint);
canvas.drawRect(nextX + nextLineWidth, y + height, x + width, y + height + AndroidUtilities.dp(3), backPaint);
} else if (width + corner * 2 < nextLineWidth) {
additionalHeight = AndroidUtilities.dp(3);
dy = y + height - AndroidUtilities.dp(9);
dx = x - corner * 2;
Theme.cornerInner[2].setBounds(dx, dy, dx + corner, dy + corner);
Theme.cornerInner[2].draw(canvas);
dx = x + width + corner;
Theme.cornerInner[3].setBounds(dx, dy, dx + corner, dy + corner);
Theme.cornerInner[3].draw(canvas);
} else {
additionalHeight = AndroidUtilities.dp(6);
}
}
if (!drawTopCorners && a > 0) {
int prevLineWidth = findMaxWidthAroundLine(a - 1) + AndroidUtilities.dp(6);
if (prevLineWidth + corner * 2 < width) {
int prevX = (getMeasuredWidth() - prevLineWidth) / 2;
drawTopCorners = true;
y -= AndroidUtilities.dp(3);
height += AndroidUtilities.dp(3);
canvas.drawRect(x, y, prevX, y + AndroidUtilities.dp(3), backPaint);
canvas.drawRect(prevX + prevLineWidth, y, x + width, y + AndroidUtilities.dp(3), backPaint);
} else if (width + corner * 2 < prevLineWidth) {
y -= AndroidUtilities.dp(3);
height += AndroidUtilities.dp(3);
dy = y + corner;
dx = x - corner * 2;
Theme.cornerInner[0].setBounds(dx, dy, dx + corner, dy + corner);
Theme.cornerInner[0].draw(canvas);
dx = x + width + corner;
Theme.cornerInner[1].setBounds(dx, dy, dx + corner, dy + corner);
Theme.cornerInner[1].draw(canvas);
} else {
y -= AndroidUtilities.dp(6);
height += AndroidUtilities.dp(6);
}
}
canvas.drawRect(x - corner, y + corner, x, y + height + additionalHeight - corner, backPaint);
canvas.drawRect(x + width, y + corner, x + width + corner, y + height + additionalHeight - corner, backPaint);
if (drawTopCorners) {
dx = x - corner;
Theme.cornerOuter[0].setBounds(dx, y, dx + corner, y + corner);
Theme.cornerOuter[0].draw(canvas);
dx = x + width;
Theme.cornerOuter[1].setBounds(dx, y, dx + corner, y + corner);
Theme.cornerOuter[1].draw(canvas);
}
if (drawBottomCorners) {
dy = y + height + additionalHeight - corner;
dx = x + width;
Theme.cornerOuter[2].setBounds(dx, dy, dx + corner, dy + corner);
Theme.cornerOuter[2].draw(canvas);
dx = x - corner;
Theme.cornerOuter[3].setBounds(dx, dy, dx + corner, dy + corner);
Theme.cornerOuter[3].draw(canvas);
}
y += height;
}
canvas.save();
canvas.translate(textXLeft, textY);
textLayout.draw(canvas);

View File

@ -1,498 +0,0 @@
/*
* This is the source code of Telegram for Android v. 1.3.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-2016.
*/
package org.telegram.ui.Cells;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.view.MotionEvent;
import android.view.SoundEffectConstants;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ImageLoader;
import org.telegram.messenger.SendMessagesHelper;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.MediaController;
import org.telegram.messenger.MessageObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Components.RadialProgress;
import org.telegram.ui.Components.ResourceLoader;
import org.telegram.ui.Components.SeekBar;
import org.telegram.ui.Components.SeekBarWaveform;
import java.io.File;
public class ChatAudioCell extends ChatBaseCell implements SeekBar.SeekBarDelegate {
public interface ChatAudioCellDelegate {
boolean needPlayAudio(MessageObject messageObject);
}
private static TextPaint timePaint;
private static Paint circlePaint;
private boolean hasWaveform;
private SeekBar seekBar;
private SeekBarWaveform seekBarWaveform;
private int seekBarX;
private int seekBarY;
private RadialProgress radialProgress;
private int buttonState = 0;
private int buttonX;
private int buttonY;
private boolean buttonPressed = false;
private StaticLayout timeLayout;
private int timeX;
private int timeWidth2;
private String lastTimeString = null;
private ChatAudioCellDelegate audioDelegate;
public ChatAudioCell(Context context) {
super(context);
seekBar = new SeekBar(context);
seekBar.setDelegate(this);
seekBarWaveform = new SeekBarWaveform(context);
seekBarWaveform.setDelegate(this);
seekBarWaveform.setParentView(this);
radialProgress = new RadialProgress(this);
drawForwardedName = true;
if (timePaint == null) {
timePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
timePaint.setTextSize(AndroidUtilities.dp(12));
circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
MediaController.getInstance().removeLoadingFileObserver(this);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
updateButtonState(false);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
boolean result = false;
if (delegate.canPerformActions()) {
if (hasWaveform) {
result = seekBarWaveform.onTouch(event.getAction(), event.getX() - seekBarX - AndroidUtilities.dp(13), event.getY() - seekBarY);
} else {
result = seekBar.onTouch(event.getAction(), event.getX() - seekBarX, event.getY() - seekBarY);
}
if (result) {
if (!hasWaveform && event.getAction() == MotionEvent.ACTION_DOWN) {
getParent().requestDisallowInterceptTouchEvent(true);
} else if (hasWaveform && !seekBarWaveform.isStartDraging() && event.getAction() == MotionEvent.ACTION_UP) {
didPressedButton();
}
invalidate();
} else {
int side = AndroidUtilities.dp(36);
boolean area;
if (buttonState == 0 || buttonState == 1) {
area = x >= buttonX - AndroidUtilities.dp(12) && x <= buttonX - AndroidUtilities.dp(12) + backgroundWidth && y >= namesOffset && y <= getMeasuredHeight();
} else {
area = x >= buttonX && x <= buttonX + side && y >= buttonY && y <= buttonY + side;
}
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (area) {
buttonPressed = true;
invalidate();
result = true;
radialProgress.swapBackground(getDrawableForCurrentState());
}
} else if (buttonPressed) {
if (event.getAction() == MotionEvent.ACTION_UP) {
buttonPressed = false;
playSoundEffect(SoundEffectConstants.CLICK);
didPressedButton();
invalidate();
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
buttonPressed = false;
invalidate();
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (!area) {
buttonPressed = false;
invalidate();
}
}
radialProgress.swapBackground(getDrawableForCurrentState());
}
if (result && event.getAction() == MotionEvent.ACTION_DOWN) {
startCheckLongPress();
}
if (event.getAction() != MotionEvent.ACTION_DOWN && event.getAction() != MotionEvent.ACTION_MOVE) {
cancelCheckLongPress();
}
if (!result) {
result = super.onTouchEvent(event);
}
}
}
return result;
}
@Override
protected void onLongPress() {
super.onLongPress();
if (buttonPressed) {
buttonPressed = false;
invalidate();
}
}
public void setAudioDelegate(ChatAudioCellDelegate delegate) {
audioDelegate = delegate;
}
private void didPressedButton() {
if (buttonState == 0) {
if (audioDelegate.needPlayAudio(currentMessageObject)) {
buttonState = 1;
radialProgress.setBackground(getDrawableForCurrentState(), false, false);
invalidate();
}
} else if (buttonState == 1) {
boolean result = MediaController.getInstance().pauseAudio(currentMessageObject);
if (result) {
buttonState = 0;
radialProgress.setBackground(getDrawableForCurrentState(), false, false);
invalidate();
}
} else if (buttonState == 2) {
radialProgress.setProgress(0, false);
FileLoader.getInstance().loadFile(currentMessageObject.messageOwner.media.document, true, false);
buttonState = 3;
radialProgress.setBackground(getDrawableForCurrentState(), true, false);
invalidate();
} else if (buttonState == 3) {
FileLoader.getInstance().cancelLoadFile(currentMessageObject.messageOwner.media.document);
buttonState = 2;
radialProgress.setBackground(getDrawableForCurrentState(), false, false);
invalidate();
} else if (buttonState == 4) {
if (currentMessageObject.isOut() && currentMessageObject.isSending()) {
if (delegate != null) {
delegate.didPressedCancelSendButton(this);
}
}
}
}
public void updateProgress() {
if (currentMessageObject == null) {
return;
}
if (hasWaveform) {
if (!seekBarWaveform.isDragging()) {
seekBarWaveform.setProgress(currentMessageObject.audioProgress);
}
} else {
if (!seekBar.isDragging()) {
seekBar.setProgress(currentMessageObject.audioProgress);
}
}
int duration = 0;
if (!MediaController.getInstance().isPlayingAudio(currentMessageObject)) {
for (int a = 0; a < currentMessageObject.messageOwner.media.document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = currentMessageObject.messageOwner.media.document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeAudio) {
duration = attribute.duration;
break;
}
}
} else {
duration = currentMessageObject.audioProgressSec;
}
String timeString = String.format("%02d:%02d", duration / 60, duration % 60);
if (lastTimeString == null || lastTimeString != null && !lastTimeString.equals(timeString)) {
lastTimeString = timeString;
timeWidth2 = (int)Math.ceil(timePaint.measureText(timeString));
timeLayout = new StaticLayout(timeString, timePaint, timeWidth2, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
}
invalidate();
}
public void downloadAudioIfNeed() {
if (buttonState == 2) {
FileLoader.getInstance().loadFile(currentMessageObject.messageOwner.media.document, true, false);
buttonState = 3;
radialProgress.setBackground(getDrawableForCurrentState(), false, false);
}
}
public void updateButtonState(boolean animated) {
if (currentMessageObject == null) {
return;
}
if (currentMessageObject.isOut() && currentMessageObject.isSending()) {
MediaController.getInstance().addLoadingFileObserver(currentMessageObject.messageOwner.attachPath, this);
buttonState = 4;
radialProgress.setBackground(getDrawableForCurrentState(), true, animated);
Float progress = ImageLoader.getInstance().getFileProgress(currentMessageObject.messageOwner.attachPath);
if (progress == null && SendMessagesHelper.getInstance().isSendingMessage(currentMessageObject.getId())) {
progress = 1.0f;
}
radialProgress.setProgress(progress != null ? progress : 0, false);
} else {
File cacheFile = null;
if (currentMessageObject.messageOwner.attachPath != null && currentMessageObject.messageOwner.attachPath.length() > 0) {
cacheFile = new File(currentMessageObject.messageOwner.attachPath);
if(!cacheFile.exists()) {
cacheFile = null;
}
}
if (cacheFile == null) {
cacheFile = FileLoader.getPathToMessage(currentMessageObject.messageOwner);
}
if (cacheFile.exists()) {
MediaController.getInstance().removeLoadingFileObserver(this);
boolean playing = MediaController.getInstance().isPlayingAudio(currentMessageObject);
if (!playing || playing && MediaController.getInstance().isAudioPaused()) {
buttonState = 0;
} else {
buttonState = 1;
}
radialProgress.setProgress(0, animated);
radialProgress.setBackground(getDrawableForCurrentState(), false, animated);
} else {
String fileName = currentMessageObject.getFileName();
MediaController.getInstance().addLoadingFileObserver(fileName, this);
if (!FileLoader.getInstance().isLoadingFile(fileName)) {
buttonState = 2;
radialProgress.setProgress(0, animated);
radialProgress.setBackground(getDrawableForCurrentState(), false, animated);
} else {
buttonState = 3;
Float progress = ImageLoader.getInstance().getFileProgress(fileName);
if (progress != null) {
radialProgress.setProgress(progress, animated);
} else {
radialProgress.setProgress(0, animated);
}
radialProgress.setBackground(getDrawableForCurrentState(), true, animated);
}
}
}
updateProgress();
}
@Override
public void onFailedDownload(String fileName) {
updateButtonState(true);
}
@Override
public void onSuccessDownload(String fileName) {
updateButtonState(true);
updateWaveform();
}
@Override
public void onProgressDownload(String fileName, float progress) {
radialProgress.setProgress(progress, true);
if (buttonState != 3) {
updateButtonState(false);
}
}
@Override
public void onProgressUpload(String fileName, float progress, boolean isEncrypted) {
radialProgress.setProgress(progress, true);
}
@Override
public void onSeekBarDrag(float progress) {
if (currentMessageObject == null) {
return;
}
currentMessageObject.audioProgress = progress;
MediaController.getInstance().seekToProgress(currentMessageObject, progress);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
setMeasuredDimension(width, AndroidUtilities.dp(66) + namesOffset);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (currentMessageObject.isOutOwner()) {
seekBarX = layoutWidth - backgroundWidth + AndroidUtilities.dp(55);
buttonX = layoutWidth - backgroundWidth + AndroidUtilities.dp(13);
timeX = layoutWidth - backgroundWidth + AndroidUtilities.dp(66);
} else {
if (isChat && currentMessageObject.isFromUser()) {
seekBarX = AndroidUtilities.dp(116);
buttonX = AndroidUtilities.dp(74);
timeX = AndroidUtilities.dp(127);
} else {
seekBarX = AndroidUtilities.dp(64);
buttonX = AndroidUtilities.dp(22);
timeX = AndroidUtilities.dp(75);
}
}
seekBarWaveform.width = seekBar.width = backgroundWidth - AndroidUtilities.dp(70);
seekBarWaveform.height = seekBar.height = AndroidUtilities.dp(30);
seekBarWaveform.width -= AndroidUtilities.dp(20);
seekBarY = AndroidUtilities.dp(11) + namesOffset;
buttonY = AndroidUtilities.dp(13) + namesOffset;
radialProgress.setProgressRect(buttonX, buttonY, buttonX + AndroidUtilities.dp(40), buttonY + AndroidUtilities.dp(40));
updateProgress();
}
@Override
public void setMessageObject(MessageObject messageObject) {
boolean dataChanged = currentMessageObject == messageObject && isUserDataChanged();
if (currentMessageObject != messageObject || dataChanged) {
if (AndroidUtilities.isTablet()) {
backgroundWidth = Math.min(AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(isChat && messageObject.isFromUser() && !messageObject.isOutOwner() ? 102 : 50), AndroidUtilities.dp(300));
} else {
backgroundWidth = Math.min(AndroidUtilities.displaySize.x - AndroidUtilities.dp(isChat && messageObject.isFromUser() && !messageObject.isOutOwner() ? 102 : 50), AndroidUtilities.dp(300));
}
int duration = 0;
for (int a = 0; a < messageObject.messageOwner.media.document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = messageObject.messageOwner.media.document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeAudio) {
duration = attribute.duration;
break;
}
}
availableTimeWidth = backgroundWidth - AndroidUtilities.dp(75 + 14) - (int) Math.ceil(timePaint.measureText("00:00"));
measureTime(messageObject);
int minSize = AndroidUtilities.dp(40 + 14 + 20 + 90 + 10) + timeWidth;
backgroundWidth = Math.min(backgroundWidth, minSize + duration * AndroidUtilities.dp(10));
hasWaveform = false;
if (messageObject.isOutOwner()) {
seekBarWaveform.setColors(0xffc3e3ab, 0xff87bf78, 0xffa9d389);
} else {
seekBarWaveform.setColors(0xffdee5eb, 0xff4195e5, 0xffaed5e2);
}
seekBar.type = messageObject.isOutOwner() ? 0 : 1;
super.setMessageObject(messageObject);
}
updateWaveform();
updateButtonState(dataChanged);
}
@Override
protected int getMaxNameWidth() {
return backgroundWidth - AndroidUtilities.dp(24);
}
@Override
public void setCheckPressed(boolean value, boolean pressed) {
super.setCheckPressed(value, pressed);
if (radialProgress.swapBackground(getDrawableForCurrentState())) {
invalidate();
}
seekBarWaveform.setSelected(isDrawSelectedBackground());
}
@Override
public void setHighlighted(boolean value) {
super.setHighlighted(value);
if (radialProgress.swapBackground(getDrawableForCurrentState())) {
invalidate();
}
seekBarWaveform.setSelected(isDrawSelectedBackground());
}
@Override
public void setPressed(boolean pressed) {
super.setPressed(pressed);
if (radialProgress.swapBackground(getDrawableForCurrentState())) {
invalidate();
}
seekBarWaveform.setSelected(isDrawSelectedBackground());
}
private Drawable getDrawableForCurrentState() {
return ResourceLoader.audioStatesDrawable[currentMessageObject.isOutOwner() ? buttonState : buttonState + 5][isDrawSelectedBackground() ? 2 : (buttonPressed ? 1 : 0)];
}
private void updateWaveform() {
File path = FileLoader.getPathToMessage(currentMessageObject.messageOwner);
for (int a = 0; a < currentMessageObject.messageOwner.media.document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = currentMessageObject.messageOwner.media.document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeAudio) {
if (attribute.waveform == null || attribute.waveform.length == 0) {
MediaController.getInstance().generateWaveform(currentMessageObject);
}
hasWaveform = attribute.waveform != null;
seekBarWaveform.setWaveform(attribute.waveform);
seekBarWaveform.setMessageObject(currentMessageObject);
break;
}
}
}
@Override
protected void onDraw(Canvas canvas) {
if (currentMessageObject == null) {
return;
}
super.onDraw(canvas);
canvas.save();
if (hasWaveform) {
canvas.translate(seekBarX + AndroidUtilities.dp(13), seekBarY);
seekBarWaveform.draw(canvas);
} else {
canvas.translate(seekBarX, seekBarY);
seekBar.draw(canvas);
}
canvas.restore();
radialProgress.setProgressColor(currentMessageObject.isOutOwner() ? 0xff87bf78 : (isDrawSelectedBackground() ? 0xff83b2c2 : 0xffa2b5c7));
timePaint.setColor(currentMessageObject.isOutOwner() ? 0xff70b15c : (isDrawSelectedBackground() ? 0xff89b4c1 : 0xffa1aab3));
circlePaint.setColor(currentMessageObject.isOutOwner() ? 0xff87bf78 : 0xff4195e5);
radialProgress.draw(canvas);
canvas.save();
canvas.translate(timeX, AndroidUtilities.dp(42) + namesOffset);
timeLayout.draw(canvas);
canvas.restore();
if (currentMessageObject.messageOwner.to_id.channel_id == 0 && currentMessageObject.isContentUnread()) {
canvas.drawCircle(timeX + timeWidth2 + AndroidUtilities.dp(8), AndroidUtilities.dp(49.5f) + namesOffset, AndroidUtilities.dp(3), circlePaint);
}
}
}

View File

@ -10,9 +10,9 @@ package org.telegram.ui.Cells;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.text.SpannableStringBuilder;
@ -30,7 +30,6 @@ import org.telegram.messenger.Emoji;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaController;
import org.telegram.messenger.UserObject;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.tgnet.TLRPC;
@ -39,8 +38,7 @@ import org.telegram.messenger.R;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.ImageReceiver;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.ResourceLoader;
import org.telegram.ui.Components.StaticLayoutEx;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.TypefaceSpan;
public class ChatBaseCell extends BaseCell implements MediaController.FileDownloadProgressListener {
@ -53,10 +51,12 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
void didLongPressed(ChatBaseCell cell);
void didPressedReplyMessage(ChatBaseCell cell, int id);
void didPressedUrl(MessageObject messageObject, ClickableSpan url, boolean longPress);
void needOpenWebView(String url, String title, String originalUrl, int w, int h);
void needOpenWebView(String url, String title, String description, String originalUrl, int w, int h);
void didPressedImage(ChatBaseCell cell);
void didPressedShare(ChatBaseCell cell);
void didPressedOther(ChatBaseCell cell);
void didPressedBotButton(ChatBaseCell cell, TLRPC.KeyboardButton button);
boolean needPlayAudio(MessageObject messageObject);
boolean canPerformActions();
}
@ -71,13 +71,15 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
private boolean wasLayout;
protected boolean isAvatarVisible;
protected boolean drawBackground = true;
protected int substractBackgroundHeight;
protected boolean allowAssistant;
protected Drawable currentBackgroundDrawable;
protected MessageObject currentMessageObject;
private int viaWidth;
private int viaNameWidth;
protected int availableTimeWidth;
private static TextPaint timePaint;
protected static TextPaint timePaint;
private static TextPaint namePaint;
private static TextPaint forwardNamePaint;
protected static TextPaint replyNamePaint;
@ -117,14 +119,16 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
protected int nameWidth;
private float nameOffsetX;
private float nameX;
private float nameY;
protected boolean drawName;
protected boolean drawNameLayout;
private StaticLayout forwardedNameLayout;
private StaticLayout[] forwardedNameLayout = new StaticLayout[2];
protected int forwardedNameWidth;
protected boolean drawForwardedName;
private int forwardNameX;
private int forwardNameY;
private float forwardNameOffsetX;
private float forwardNameOffsetX[] = new float[2];
private StaticLayout timeLayout;
protected int timeWidth;
@ -162,7 +166,8 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
timePaint.setTextSize(AndroidUtilities.dp(12));
namePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
namePaint.setTextSize(AndroidUtilities.dp(15));
namePaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
namePaint.setTextSize(AndroidUtilities.dp(14));
forwardNamePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
forwardNamePaint.setTextSize(AndroidUtilities.dp(14));
@ -173,7 +178,7 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
replyTextPaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
replyTextPaint.setTextSize(AndroidUtilities.dp(14));
replyTextPaint.linkColor = 0xff316f9f;
replyTextPaint.linkColor = Theme.MSG_LINK_TEXT_COLOR;
replyLinePaint = new Paint();
}
@ -315,11 +320,11 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
if ((messageObject.messageOwner.flags & TLRPC.MESSAGE_FLAG_HAS_VIEWS) != 0) {
currentViewsString = String.format("%s", LocaleController.formatShortNumber(Math.max(1, messageObject.messageOwner.views), null));
viewsTextWidth = (int) Math.ceil(timePaint.measureText(currentViewsString));
timeWidth += viewsTextWidth + ResourceLoader.viewsCountDrawable[0].getIntrinsicWidth() + AndroidUtilities.dp(10);
timeWidth += viewsTextWidth + Theme.viewsCountDrawable[0].getIntrinsicWidth() + AndroidUtilities.dp(10);
}
if (hasSign) {
if (availableTimeWidth == 0) {
availableTimeWidth = AndroidUtilities.dp(100);
availableTimeWidth = AndroidUtilities.dp(1000);
}
CharSequence name = ContactsController.formatName(signUser.first_name, signUser.last_name).replace('\n', ' ');
int widthForSign = availableTimeWidth - timeWidth;
@ -342,7 +347,7 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
return true;
}
} else if (messageObject.messageOwner.from_id < 0 || messageObject.messageOwner.post) {
if (messageObject.messageOwner.to_id.channel_id != 0 && (messageObject.messageOwner.reply_to_msg_id == 0 || messageObject.type != 13)) {
if (messageObject.messageOwner.to_id.channel_id != 0 && (messageObject.messageOwner.via_bot_id == 0 && messageObject.messageOwner.reply_to_msg_id == 0 || messageObject.type != 13)) {
return true;
}
}
@ -369,6 +374,7 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
currentUser = null;
currentChat = null;
currentViaBotUser = null;
drawNameLayout = false;
if ((messageObject.messageOwner.flags & TLRPC.MESSAGE_FLAG_HAS_VIEWS) != 0) {
if (currentMessageObject.isContentUnread() && !currentMessageObject.isOut()) {
@ -417,25 +423,25 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
namesOffset = 0;
String viaUsername = null;
String viaString = null;
CharSequence viaString = null;
if (messageObject.messageOwner.via_bot_id != 0) {
TLRPC.User botUser = MessagesController.getInstance().getUser(messageObject.messageOwner.via_bot_id);
if (botUser != null && botUser.username != null && botUser.username.length() > 0) {
viaUsername = "@" + botUser.username;
viaString = " via " + viaUsername;
viaWidth = (int) Math.ceil(forwardNamePaint.measureText(viaString));
viaString = AndroidUtilities.replaceTags(String.format(" via <b>%s</b>", viaUsername));
viaWidth = (int) Math.ceil(replyNamePaint.measureText(viaString, 0, viaString.length()));
currentViaBotUser = botUser;
}
} else if (messageObject.messageOwner.via_bot_name != null && messageObject.messageOwner.via_bot_name.length() > 0) {
viaUsername = "@" + messageObject.messageOwner.via_bot_name;
viaString = " via " + messageObject.messageOwner.via_bot_name;
viaWidth = (int) Math.ceil(forwardNamePaint.measureText(viaString));
viaString = AndroidUtilities.replaceTags(String.format(" via <b>%s</b>", viaUsername));
viaWidth = (int) Math.ceil(replyNamePaint.measureText(viaString, 0, viaString.length()));
}
boolean authorName = drawName && isChat && !currentMessageObject.isOutOwner();
boolean viaBot = messageObject.messageOwner.fwd_from == null && viaUsername != null;
boolean viaBot = (messageObject.messageOwner.fwd_from == null || messageObject.type == 14) && viaUsername != null;
if (authorName || viaBot) {
drawName = true;
drawNameLayout = true;
nameWidth = getMaxNameWidth();
if (nameWidth < 0) {
nameWidth = AndroidUtilities.dp(100);
@ -452,30 +458,38 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
} else {
currentNameString = "";
}
CharSequence nameStringFinal = TextUtils.ellipsize(currentNameString.replace("\n", " "), namePaint, nameWidth - AndroidUtilities.dp(12) - (viaBot ? viaWidth : 0), TextUtils.TruncateAt.END);
CharSequence nameStringFinal = TextUtils.ellipsize(currentNameString.replace('\n', ' '), namePaint, nameWidth - (viaBot ? viaWidth : 0), TextUtils.TruncateAt.END);
if (viaBot) {
viaNameWidth = (int) Math.ceil(namePaint.measureText(nameStringFinal, 0, nameStringFinal.length()));
if (viaNameWidth != 0) {
viaNameWidth += AndroidUtilities.dp(4);
}
int color;
if (currentMessageObject.type == 13) {
color = Theme.MSG_STICKER_VIA_BOT_NAME_TEXT_COLOR;
} else {
color = currentMessageObject.isOutOwner() ? Theme.MSG_OUT_VIA_BOT_NAME_TEXT_COLOR : Theme.MSG_IN_VIA_BOT_NAME_TEXT_COLOR;
}
if (currentNameString.length() > 0) {
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(String.format("%s via %s", nameStringFinal, viaUsername));
stringBuilder.setSpan(new TypefaceSpan(null, 0, currentMessageObject.isOutOwner() ? 0xff4a923c : 0xff006fc8), nameStringFinal.length() + 1, nameStringFinal.length() + 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
stringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf"), 0, currentMessageObject.isOutOwner() ? 0xff4a923c : 0xff006fc8), nameStringFinal.length() + 5, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
stringBuilder.setSpan(new TypefaceSpan(Typeface.DEFAULT, 0, color), nameStringFinal.length() + 1, nameStringFinal.length() + 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
stringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf"), 0, color), nameStringFinal.length() + 5, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
nameStringFinal = stringBuilder;
} else {
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(String.format("via %s", viaUsername));
stringBuilder.setSpan(new TypefaceSpan(null, 0, currentMessageObject.isOutOwner() ? 0xff4a923c : 0xff006fc8), 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
stringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf"), 0, currentMessageObject.isOutOwner() ? 0xff4a923c : 0xff006fc8), 4, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
stringBuilder.setSpan(new TypefaceSpan(Typeface.DEFAULT, 0, color), 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
stringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf"), 0, color), 4, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
nameStringFinal = stringBuilder;
}
nameStringFinal = TextUtils.ellipsize(nameStringFinal, namePaint, nameWidth, TextUtils.TruncateAt.END);
}
try {
nameLayout = new StaticLayout(nameStringFinal, namePaint, nameWidth + AndroidUtilities.dp(2), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
if (nameLayout != null && nameLayout.getLineCount() > 0) {
nameWidth = (int)Math.ceil(nameLayout.getLineWidth(0));
namesOffset += AndroidUtilities.dp(19);
nameWidth = (int) Math.ceil(nameLayout.getLineWidth(0));
if (messageObject.type != 13) {
namesOffset += AndroidUtilities.dp(19);
}
nameOffsetX = nameLayout.getLineLeft(0);
} else {
nameWidth = 0;
@ -483,14 +497,21 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
} catch (Exception e) {
FileLog.e("tmessages", e);
}
if (currentNameString.length() == 0) {
currentNameString = null;
}
} else {
currentNameString = null;
nameLayout = null;
nameWidth = 0;
}
currentForwardUser = null;
currentForwardNameString = null;
forwardedNameLayout[0] = null;
forwardedNameLayout[1] = null;
forwardedNameWidth = 0;
if (drawForwardedName && messageObject.isForwarded()) {
currentForwardUser = null;
currentForwardChannel = null;
if (messageObject.messageOwner.fwd_from.channel_id != 0) {
currentForwardChannel = MessagesController.getInstance().getChat(messageObject.messageOwner.fwd_from.channel_id);
@ -511,38 +532,33 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
}
forwardedNameWidth = getMaxNameWidth();
CharSequence str = TextUtils.ellipsize(currentForwardNameString.replace("\n", " "), forwardNamePaint, forwardedNameWidth - AndroidUtilities.dp(40) - viaWidth, TextUtils.TruncateAt.END);
int fromWidth = (int) Math.ceil(forwardNamePaint.measureText(LocaleController.getString("From", R.string.From) + " "));
CharSequence name = TextUtils.ellipsize(currentForwardNameString.replace('\n', ' '), replyNamePaint, forwardedNameWidth - fromWidth - viaWidth, TextUtils.TruncateAt.END);
CharSequence lastLine;
if (viaString != null) {
viaNameWidth = (int) Math.ceil(forwardNamePaint.measureText(LocaleController.getString("From", R.string.From) + " " + str));
str = AndroidUtilities.replaceTags(String.format("%s\n%s <b>%s</b> via <b>%s</b>", LocaleController.getString("ForwardedMessage", R.string.ForwardedMessage), LocaleController.getString("From", R.string.From), str, viaUsername));
viaNameWidth = (int) Math.ceil(forwardNamePaint.measureText(LocaleController.getString("From", R.string.From) + " " + name));
lastLine = AndroidUtilities.replaceTags(String.format("%s <b>%s</b> via <b>%s</b>", LocaleController.getString("From", R.string.From), name, viaUsername));
} else {
str = AndroidUtilities.replaceTags(String.format("%s\n%s <b>%s</b>", LocaleController.getString("ForwardedMessage", R.string.ForwardedMessage), LocaleController.getString("From", R.string.From), str));
lastLine = AndroidUtilities.replaceTags(String.format("%s <b>%s</b>", LocaleController.getString("From", R.string.From), name));
}
forwardedNameLayout = StaticLayoutEx.createStaticLayout(str, forwardNamePaint, forwardedNameWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false, TextUtils.TruncateAt.END, forwardedNameWidth, 2);
if (forwardedNameLayout.getLineCount() > 1) {
forwardedNameWidth = Math.max((int) Math.ceil(forwardedNameLayout.getLineWidth(0)), (int) Math.ceil(forwardedNameLayout.getLineWidth(1)));
lastLine = TextUtils.ellipsize(lastLine, forwardNamePaint, forwardedNameWidth, TextUtils.TruncateAt.END);
try {
forwardedNameLayout[1] = new StaticLayout(lastLine, forwardNamePaint, forwardedNameWidth + AndroidUtilities.dp(2), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
lastLine = TextUtils.ellipsize(AndroidUtilities.replaceTags(LocaleController.getString("ForwardedMessage", R.string.ForwardedMessage)), forwardNamePaint, forwardedNameWidth, TextUtils.TruncateAt.END);
forwardedNameLayout[0] = new StaticLayout(lastLine, forwardNamePaint, forwardedNameWidth + AndroidUtilities.dp(2), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
forwardedNameWidth = Math.max((int) Math.ceil(forwardedNameLayout[0].getLineWidth(0)), (int) Math.ceil(forwardedNameLayout[1].getLineWidth(0)));
forwardNameOffsetX[0] = forwardedNameLayout[0].getLineLeft(0);
forwardNameOffsetX[1] = forwardedNameLayout[1].getLineLeft(0);
namesOffset += AndroidUtilities.dp(36);
forwardNameOffsetX = Math.min(forwardedNameLayout.getLineLeft(0), forwardedNameLayout.getLineLeft(1));
} else {
forwardedNameWidth = 0;
} catch (Exception e) {
FileLog.e("tmessages", e);
}
} else {
currentForwardNameString = null;
forwardedNameLayout = null;
forwardedNameWidth = 0;
}
} else {
currentForwardNameString = null;
forwardedNameLayout = null;
forwardedNameWidth = 0;
}
if (messageObject.isReply()) {
namesOffset += AndroidUtilities.dp(42);
if (messageObject.contentType == 2 || messageObject.contentType == 3) {
namesOffset += AndroidUtilities.dp(4);
} else if (messageObject.type != 0) {
if (messageObject.type != 0) {
if (messageObject.type == 13) {
namesOffset -= AndroidUtilities.dp(42);
} else {
@ -550,33 +566,9 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
}
}
int maxWidth;
if (messageObject.type == 13) {
int width;
if (AndroidUtilities.isTablet()) {
if (AndroidUtilities.isSmallTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
width = AndroidUtilities.displaySize.x;
} else {
int leftWidth = AndroidUtilities.displaySize.x / 100 * 35;
if (leftWidth < AndroidUtilities.dp(320)) {
leftWidth = AndroidUtilities.dp(320);
}
width = AndroidUtilities.displaySize.x - leftWidth;
}
} else {
width = AndroidUtilities.displaySize.x;
}
if (messageObject.isOutOwner()) {
maxWidth = width - backgroundWidth - AndroidUtilities.dp(60);
} else {
maxWidth = width - backgroundWidth - AndroidUtilities.dp(56 + (isChat && messageObject.isFromUser() ? 61 : 0));
}
} else {
maxWidth = getMaxNameWidth() - AndroidUtilities.dp(22);
}
if (!mediaBackground) {
maxWidth -= AndroidUtilities.dp(8);
int maxWidth = getMaxNameWidth();
if (messageObject.type != 13) {
maxWidth -= AndroidUtilities.dp(10);
}
CharSequence stringFinalName = null;
@ -612,23 +604,23 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
}
if (name != null) {
stringFinalName = TextUtils.ellipsize(name.replace("\n", " "), replyNamePaint, maxWidth - AndroidUtilities.dp(8), TextUtils.TruncateAt.END);
stringFinalName = TextUtils.ellipsize(name.replace('\n', ' '), replyNamePaint, maxWidth, TextUtils.TruncateAt.END);
}
if (messageObject.replyMessageObject.messageText != null && messageObject.replyMessageObject.messageText.length() > 0) {
String mess = messageObject.replyMessageObject.messageText.toString();
if (mess.length() > 150) {
mess = mess.substring(0, 150);
}
mess = mess.replace("\n", " ");
mess = mess.replace('\n', ' ');
stringFinalText = Emoji.replaceEmoji(mess, replyTextPaint.getFontMetricsInt(), AndroidUtilities.dp(14), false);
stringFinalText = TextUtils.ellipsize(stringFinalText, replyTextPaint, maxWidth - AndroidUtilities.dp(8), TextUtils.TruncateAt.END);
stringFinalText = TextUtils.ellipsize(stringFinalText, replyTextPaint, maxWidth, TextUtils.TruncateAt.END);
}
}
if (stringFinalName == null) {
stringFinalName = LocaleController.getString("Loading", R.string.Loading);
}
try {
replyNameLayout = new StaticLayout(stringFinalName, replyNamePaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
replyNameLayout = new StaticLayout(stringFinalName, replyNamePaint, maxWidth + AndroidUtilities.dp(6), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
if (replyNameLayout.getLineCount() > 0) {
replyNameWidth = (int)Math.ceil(replyNameLayout.getLineWidth(0)) + AndroidUtilities.dp(12 + (needReplyImage ? 44 : 0));
replyNameOffset = replyNameLayout.getLineLeft(0);
@ -638,7 +630,7 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
}
try {
if (stringFinalText != null) {
replyTextLayout = new StaticLayout(stringFinalText, replyTextPaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
replyTextLayout = new StaticLayout(stringFinalText, replyTextPaint, maxWidth + AndroidUtilities.dp(6), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
if (replyTextLayout.getLineCount() > 0) {
replyTextWidth = (int) Math.ceil(replyTextLayout.getLineWidth(0)) + AndroidUtilities.dp(12 + (needReplyImage ? 44 : 0));
replyTextOffset = replyTextLayout.getLineLeft(0);
@ -657,7 +649,7 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
}
protected int getMaxNameWidth() {
return backgroundWidth - AndroidUtilities.dp(8);
return backgroundWidth - AndroidUtilities.dp(mediaBackground ? 22 : 31);
}
@Override
@ -670,14 +662,14 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
if (isAvatarVisible && avatarImage.isInsideImage(x, y)) {
avatarPressed = true;
result = true;
} else if (drawForwardedName && forwardedNameLayout != null && x >= forwardNameX && x <= forwardNameX + forwardedNameWidth && y >= forwardNameY && y <= forwardNameY + AndroidUtilities.dp(32)) {
} else if (drawForwardedName && forwardedNameLayout[0] != null && x >= forwardNameX && x <= forwardNameX + forwardedNameWidth && y >= forwardNameY && y <= forwardNameY + AndroidUtilities.dp(32)) {
if (viaWidth != 0 && x >= forwardNameX + viaNameWidth + AndroidUtilities.dp(4)) {
forwardBotPressed = true;
} else {
forwardNamePressed = true;
}
result = true;
} else if (drawName && nameLayout != null && viaWidth != 0 && x >= nameX + viaNameWidth && x <= nameX + viaNameWidth + viaWidth && y >= AndroidUtilities.dp(6) && y <= AndroidUtilities.dp(30)) {
} else if (drawNameLayout && nameLayout != null && viaWidth != 0 && x >= nameX + viaNameWidth && x <= nameX + viaNameWidth + viaWidth && y >= nameY - AndroidUtilities.dp(4) && y <= nameY + AndroidUtilities.dp(20)) {
forwardBotPressed = true;
result = true;
} else if (currentMessageObject.isReply() && x >= replyStartX && x <= replyStartX + Math.max(replyNameWidth, replyTextWidth) && y >= replyStartY && y <= replyStartY + AndroidUtilities.dp(35)) {
@ -742,12 +734,12 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
forwardBotPressed = false;
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (drawForwardedName && forwardedNameLayout != null) {
if (drawForwardedName && forwardedNameLayout[0] != null) {
if (!(x >= forwardNameX && x <= forwardNameX + forwardedNameWidth && y >= forwardNameY && y <= forwardNameY + AndroidUtilities.dp(32))) {
forwardBotPressed = false;
}
} else {
if (!(x >= nameX + viaNameWidth && x <= nameX + viaNameWidth + viaWidth && y >= AndroidUtilities.dp(6) && y <= AndroidUtilities.dp(30))) {
if (!(x >= nameX + viaNameWidth && x <= nameX + viaNameWidth + viaWidth && y >= nameY - AndroidUtilities.dp(4) && y <= nameY + AndroidUtilities.dp(20))) {
forwardBotPressed = false;
}
}
@ -796,20 +788,20 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
if (changed || !wasLayout) {
layoutWidth = getMeasuredWidth();
layoutHeight = getMeasuredHeight();
layoutHeight = getMeasuredHeight() - substractBackgroundHeight;
if (timeTextWidth < 0) {
timeTextWidth = AndroidUtilities.dp(10);
}
timeLayout = new StaticLayout(currentTimeString, timePaint, timeTextWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
timeLayout = new StaticLayout(currentTimeString, timePaint, timeTextWidth + AndroidUtilities.dp(6), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
if (!mediaBackground) {
if (!currentMessageObject.isOutOwner()) {
timeX = backgroundWidth - AndroidUtilities.dp(9) - timeWidth + (isChat && currentMessageObject.isFromUser() ? AndroidUtilities.dp(52) : 0);
timeX = backgroundWidth - AndroidUtilities.dp(9) - timeWidth + (isChat && currentMessageObject.isFromUser() ? AndroidUtilities.dp(48) : 0);
} else {
timeX = layoutWidth - timeWidth - AndroidUtilities.dp(38.5f);
}
} else {
if (!currentMessageObject.isOutOwner()) {
timeX = backgroundWidth - AndroidUtilities.dp(4) - timeWidth + (isChat && currentMessageObject.isFromUser() ? AndroidUtilities.dp(52) : 0);
timeX = backgroundWidth - AndroidUtilities.dp(4) - timeWidth + (isChat && currentMessageObject.isFromUser() ? AndroidUtilities.dp(48) : 0);
} else {
timeX = layoutWidth - timeWidth - AndroidUtilities.dp(42.0f);
}
@ -822,14 +814,14 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
}
if (isAvatarVisible) {
avatarImage.setImageCoords(AndroidUtilities.dp(6), layoutHeight - AndroidUtilities.dp(45), AndroidUtilities.dp(42), AndroidUtilities.dp(42));
avatarImage.setImageCoords(AndroidUtilities.dp(6), layoutHeight - AndroidUtilities.dp(44), AndroidUtilities.dp(42), AndroidUtilities.dp(42));
}
wasLayout = true;
}
}
protected void onAfterBackgroundDraw(Canvas canvas) {
protected void drawContent(Canvas canvas) {
}
@ -864,156 +856,170 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
}
if (mediaBackground) {
timePaint.setColor(0xffffffff);
timePaint.setColor(Theme.MSG_MEDIA_TIME_TEXT_COLOR);
} else {
if (currentMessageObject.isOutOwner()) {
timePaint.setColor(0xff70b15c);
timePaint.setColor(isDrawSelectedBackground() ? Theme.MSG_OUT_TIME_SELECTED_TEXT_COLOR : Theme.MSG_OUT_TIME_TEXT_COLOR);
} else {
timePaint.setColor(isDrawSelectedBackground() ? 0xff89b4c1 : 0xffa1aab3);
timePaint.setColor(isDrawSelectedBackground() ? Theme.MSG_IN_TIME_SELECTED_TEXT_COLOR : Theme.MSG_IN_TIME_TEXT_COLOR);
}
}
Drawable currentBackgroundDrawable;
if (currentMessageObject.isOutOwner()) {
if (isDrawSelectedBackground()) {
if (!mediaBackground) {
currentBackgroundDrawable = ResourceLoader.backgroundDrawableOutSelected;
currentBackgroundDrawable = Theme.backgroundDrawableOutSelected;
} else {
currentBackgroundDrawable = ResourceLoader.backgroundMediaDrawableOutSelected;
currentBackgroundDrawable = Theme.backgroundMediaDrawableOutSelected;
}
} else {
if (!mediaBackground) {
currentBackgroundDrawable = ResourceLoader.backgroundDrawableOut;
currentBackgroundDrawable = Theme.backgroundDrawableOut;
} else {
currentBackgroundDrawable = ResourceLoader.backgroundMediaDrawableOut;
currentBackgroundDrawable = Theme.backgroundMediaDrawableOut;
}
}
setDrawableBounds(currentBackgroundDrawable, layoutWidth - backgroundWidth - (!mediaBackground ? 0 : AndroidUtilities.dp(9)), AndroidUtilities.dp(1), backgroundWidth, layoutHeight - AndroidUtilities.dp(2));
setDrawableBounds(currentBackgroundDrawable, layoutWidth - backgroundWidth - (!mediaBackground ? 0 : AndroidUtilities.dp(9)), AndroidUtilities.dp(1), backgroundWidth - (mediaBackground ? 0 : AndroidUtilities.dp(3)), layoutHeight - AndroidUtilities.dp(2));
} else {
if (isDrawSelectedBackground()) {
if (!mediaBackground) {
currentBackgroundDrawable = ResourceLoader.backgroundDrawableInSelected;
currentBackgroundDrawable = Theme.backgroundDrawableInSelected;
} else {
currentBackgroundDrawable = ResourceLoader.backgroundMediaDrawableInSelected;
currentBackgroundDrawable = Theme.backgroundMediaDrawableInSelected;
}
} else {
if (!mediaBackground) {
currentBackgroundDrawable = ResourceLoader.backgroundDrawableIn;
currentBackgroundDrawable = Theme.backgroundDrawableIn;
} else {
currentBackgroundDrawable = ResourceLoader.backgroundMediaDrawableIn;
currentBackgroundDrawable = Theme.backgroundMediaDrawableIn;
}
}
if (isChat && currentMessageObject.isFromUser()) {
setDrawableBounds(currentBackgroundDrawable, AndroidUtilities.dp(52 + (!mediaBackground ? 0 : 9)), AndroidUtilities.dp(1), backgroundWidth, layoutHeight - AndroidUtilities.dp(2));
setDrawableBounds(currentBackgroundDrawable, AndroidUtilities.dp(48 + (!mediaBackground ? 3 : 9)), AndroidUtilities.dp(1), backgroundWidth - (mediaBackground ? 0 : AndroidUtilities.dp(3)), layoutHeight - AndroidUtilities.dp(2));
} else {
setDrawableBounds(currentBackgroundDrawable, (!mediaBackground ? 0 : AndroidUtilities.dp(9)), AndroidUtilities.dp(1), backgroundWidth, layoutHeight - AndroidUtilities.dp(2));
setDrawableBounds(currentBackgroundDrawable, (!mediaBackground ? AndroidUtilities.dp(3) : AndroidUtilities.dp(9)), AndroidUtilities.dp(1), backgroundWidth - (mediaBackground ? 0 : AndroidUtilities.dp(3)), layoutHeight - AndroidUtilities.dp(2));
}
}
if (drawBackground && currentBackgroundDrawable != null) {
currentBackgroundDrawable.draw(canvas);
}
onAfterBackgroundDraw(canvas);
drawContent(canvas);
if (drawShareButton) {
ResourceLoader.shareDrawable[ApplicationLoader.isCustomTheme() ? 1 : 0][sharePressed ? 1 : 0].setBounds(shareStartX = currentBackgroundDrawable.getBounds().right + AndroidUtilities.dp(8), shareStartY = layoutHeight - AndroidUtilities.dp(41), currentBackgroundDrawable.getBounds().right + AndroidUtilities.dp(40), layoutHeight - AndroidUtilities.dp(9));
ResourceLoader.shareDrawable[ApplicationLoader.isCustomTheme() ? 1 : 0][sharePressed ? 1 : 0].draw(canvas);
Theme.shareDrawable.setColorFilter(sharePressed ? Theme.colorPressedFilter : Theme.colorFilter);
setDrawableBounds(Theme.shareDrawable, shareStartX = currentBackgroundDrawable.getBounds().right + AndroidUtilities.dp(8), shareStartY = layoutHeight - AndroidUtilities.dp(41));
Theme.shareDrawable.draw(canvas);
setDrawableBounds(Theme.shareIconDrawable, shareStartX + AndroidUtilities.dp(9), shareStartY + AndroidUtilities.dp(9));
Theme.shareIconDrawable.draw(canvas);
}
if (drawName && nameLayout != null) {
if (drawNameLayout && nameLayout != null) {
canvas.save();
if (mediaBackground || currentMessageObject.isOutOwner()) {
canvas.translate(nameX = currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(10) - nameOffsetX, AndroidUtilities.dp(10));
if (currentMessageObject.type == 13) {
namePaint.setColor(Theme.MSG_STICKER_NAME_TEXT_COLOR);
int backWidth;
if (currentMessageObject.isOutOwner()) {
nameX = AndroidUtilities.dp(28);
} else {
nameX = currentBackgroundDrawable.getBounds().right + AndroidUtilities.dp(22);
}
nameY = layoutHeight - AndroidUtilities.dp(38);
Theme.systemDrawable.setColorFilter(Theme.colorFilter);
Theme.systemDrawable.setBounds((int) nameX - AndroidUtilities.dp(12), (int) nameY - AndroidUtilities.dp(5), (int) nameX + AndroidUtilities.dp(12) + nameWidth, (int) nameY + AndroidUtilities.dp(22));
Theme.systemDrawable.draw(canvas);
} else {
canvas.translate(nameX = currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(19) - nameOffsetX, AndroidUtilities.dp(10));
}
if (currentUser != null) {
namePaint.setColor(AvatarDrawable.getNameColorForId(currentUser.id));
} else if (currentChat != null) {
namePaint.setColor(AvatarDrawable.getNameColorForId(currentChat.id));
} else {
namePaint.setColor(AvatarDrawable.getNameColorForId(0));
if (mediaBackground || currentMessageObject.isOutOwner()) {
nameX = currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(11) - nameOffsetX;
} else {
nameX = currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(17) - nameOffsetX;
}
if (currentUser != null) {
namePaint.setColor(AvatarDrawable.getNameColorForId(currentUser.id));
} else if (currentChat != null) {
namePaint.setColor(AvatarDrawable.getNameColorForId(currentChat.id));
} else {
namePaint.setColor(AvatarDrawable.getNameColorForId(0));
}
nameY = AndroidUtilities.dp(10);
}
canvas.translate(nameX, nameY);
nameLayout.draw(canvas);
canvas.restore();
/*if (forwardedNameLayout == null && viaWidth != 0) {
canvas.drawRect(nameX + viaNameWidth, AndroidUtilities.dp(6), nameX + viaNameWidth + viaWidth, AndroidUtilities.dp(30), namePaint);
}*/
}
if (drawForwardedName && forwardedNameLayout != null) {
forwardNameY = AndroidUtilities.dp(10 + (drawName ? 19 : 0));
if (drawForwardedName && forwardedNameLayout[0] != null && forwardedNameLayout[1] != null) {
forwardNameY = AndroidUtilities.dp(10 + (drawNameLayout ? 19 : 0));
if (currentMessageObject.isOutOwner()) {
forwardNamePaint.setColor(0xff4a923c);
forwardNameX = currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(10);
forwardNamePaint.setColor(Theme.MSG_OUT_FORDWARDED_NAME_TEXT_COLOR);
forwardNameX = currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(11);
} else {
forwardNamePaint.setColor(0xff006fc8);
forwardNamePaint.setColor(Theme.MSG_IN_FORDWARDED_NAME_TEXT_COLOR);
if (mediaBackground) {
forwardNameX = currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(10);
forwardNameX = currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(11);
} else {
forwardNameX = currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(19);
forwardNameX = currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(17);
}
}
canvas.save();
canvas.translate(forwardNameX - forwardNameOffsetX, forwardNameY);
forwardedNameLayout.draw(canvas);
canvas.restore();
for (int a = 0; a < 2; a++) {
canvas.save();
canvas.translate(forwardNameX - forwardNameOffsetX[a], forwardNameY + AndroidUtilities.dp(16) * a);
forwardedNameLayout[a].draw(canvas);
canvas.restore();
}
}
if (currentMessageObject.isReply()) {
if (currentMessageObject.type == 13) {
replyLinePaint.setColor(0xffffffff);
replyNamePaint.setColor(0xffffffff);
replyTextPaint.setColor(0xffffffff);
int backWidth;
replyLinePaint.setColor(Theme.MSG_STICKER_REPLY_LINE_COLOR);
replyNamePaint.setColor(Theme.MSG_STICKER_REPLY_NAME_TEXT_COLOR);
replyTextPaint.setColor(Theme.MSG_STICKER_REPLY_MESSAGE_TEXT_COLOR);
if (currentMessageObject.isOutOwner()) {
backWidth = currentBackgroundDrawable.getBounds().left - AndroidUtilities.dp(32);
replyStartX = currentBackgroundDrawable.getBounds().left - AndroidUtilities.dp(9) - backWidth;
replyStartX = AndroidUtilities.dp(23);
} else {
backWidth = getWidth() - currentBackgroundDrawable.getBounds().right - AndroidUtilities.dp(32);
replyStartX = currentBackgroundDrawable.getBounds().right + AndroidUtilities.dp(23);
}
Drawable back;
if (ApplicationLoader.isCustomTheme()) {
back = ResourceLoader.backgroundBlack;
} else {
back = ResourceLoader.backgroundBlue;
replyStartX = currentBackgroundDrawable.getBounds().right + AndroidUtilities.dp(17);
}
replyStartY = layoutHeight - AndroidUtilities.dp(58);
back.setBounds(replyStartX - AndroidUtilities.dp(7), replyStartY - AndroidUtilities.dp(6), replyStartX - AndroidUtilities.dp(7) + backWidth, replyStartY + AndroidUtilities.dp(41));
back.draw(canvas);
if (nameLayout != null) {
replyStartY -= AndroidUtilities.dp(25 + 6);
}
int backWidth = Math.max(replyNameWidth, replyTextWidth) + AndroidUtilities.dp(14 + (needReplyImage ? 44 : 0));
Theme.systemDrawable.setColorFilter(Theme.colorFilter);
Theme.systemDrawable.setBounds(replyStartX - AndroidUtilities.dp(7), replyStartY - AndroidUtilities.dp(6), replyStartX - AndroidUtilities.dp(7) + backWidth, replyStartY + AndroidUtilities.dp(41));
Theme.systemDrawable.draw(canvas);
} else {
if (currentMessageObject.isOutOwner()) {
replyLinePaint.setColor(0xff8dc97a);
replyNamePaint.setColor(0xff61a349);
replyLinePaint.setColor(Theme.MSG_OUT_REPLY_LINE_COLOR);
replyNamePaint.setColor(Theme.MSG_OUT_REPLY_NAME_TEXT_COLOR);
if (currentMessageObject.replyMessageObject != null && currentMessageObject.replyMessageObject.type == 0) {
replyTextPaint.setColor(0xff000000);
replyTextPaint.setColor(Theme.MSG_OUT_REPLY_MESSAGE_TEXT_COLOR);
} else {
replyTextPaint.setColor(0xff70b15c);
replyTextPaint.setColor(isDrawSelectedBackground() ? Theme.MSG_OUT_REPLY_MEDIA_MESSAGE_SELETED_TEXT_COLOR : Theme.MSG_OUT_REPLY_MEDIA_MESSAGE_TEXT_COLOR);
}
replyStartX = currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(11);
replyStartX = currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(12);
} else {
replyLinePaint.setColor(0xff6c9fd2);
replyNamePaint.setColor(0xff377aae);
replyLinePaint.setColor(Theme.MSG_IN_REPLY_LINE_COLOR);
replyNamePaint.setColor(Theme.MSG_IN_REPLY_NAME_TEXT_COLOR);
if (currentMessageObject.replyMessageObject != null && currentMessageObject.replyMessageObject.type == 0) {
replyTextPaint.setColor(0xff000000);
replyTextPaint.setColor(Theme.MSG_IN_REPLY_MESSAGE_TEXT_COLOR);
} else {
replyTextPaint.setColor(0xff999999);
replyTextPaint.setColor(isDrawSelectedBackground() ? Theme.MSG_IN_REPLY_MEDIA_MESSAGE_SELETED_TEXT_COLOR : Theme.MSG_IN_REPLY_MEDIA_MESSAGE_TEXT_COLOR);
}
if (mediaBackground) {
replyStartX = currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(11);
replyStartX = currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(12);
} else {
replyStartX = currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(20);
replyStartX = currentBackgroundDrawable.getBounds().left + AndroidUtilities.dp(18);
}
}
replyStartY = AndroidUtilities.dp(12 + (drawForwardedName && forwardedNameLayout != null ? 36 : 0) + (drawName && nameLayout != null ? 20 : 0));
replyStartY = AndroidUtilities.dp(12 + (drawForwardedName && forwardedNameLayout[0] != null ? 36 : 0) + (drawNameLayout && nameLayout != null ? 20 : 0));
}
canvas.drawRect(replyStartX, replyStartY, replyStartX + AndroidUtilities.dp(2), replyStartY + AndroidUtilities.dp(35), replyLinePaint);
if (needReplyImage) {
replyImageReceiver.setImageCoords(replyStartX + AndroidUtilities.dp(10), replyStartY, AndroidUtilities.dp(35), AndroidUtilities.dp(35));
replyImageReceiver.draw(canvas);
}
if (replyNameLayout != null) {
canvas.save();
canvas.translate(replyStartX - replyNameOffset + AndroidUtilities.dp(10 + (needReplyImage ? 44 : 0)), replyStartY);
@ -1030,8 +1036,14 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
if (drawTime || !mediaBackground) {
if (mediaBackground) {
setDrawableBounds(ResourceLoader.mediaBackgroundDrawable, timeX - AndroidUtilities.dp(3), layoutHeight - AndroidUtilities.dp(27.5f), timeWidth + AndroidUtilities.dp(6 + (currentMessageObject.isOutOwner() ? 20 : 0)), AndroidUtilities.dp(16.5f));
ResourceLoader.mediaBackgroundDrawable.draw(canvas);
Drawable drawable;
if (currentMessageObject.type == 13) {
drawable = Theme.timeStickerBackgroundDrawable;
} else {
drawable = Theme.timeBackgroundDrawable;
}
setDrawableBounds(drawable, timeX - AndroidUtilities.dp(4), layoutHeight - AndroidUtilities.dp(27), timeWidth + AndroidUtilities.dp(8 + (currentMessageObject.isOutOwner() ? 20 : 0)), AndroidUtilities.dp(17));
drawable.draw(canvas);
int additionalX = 0;
if ((currentMessageObject.messageOwner.flags & TLRPC.MESSAGE_FLAG_HAS_VIEWS) != 0) {
@ -1039,22 +1051,22 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
if (currentMessageObject.isSending()) {
if (!currentMessageObject.isOutOwner()) {
setDrawableBounds(ResourceLoader.clockMediaDrawable, timeX + AndroidUtilities.dp(11), layoutHeight - AndroidUtilities.dp(13.0f) - ResourceLoader.clockMediaDrawable.getIntrinsicHeight());
ResourceLoader.clockMediaDrawable.draw(canvas);
setDrawableBounds(Theme.clockMediaDrawable, timeX + AndroidUtilities.dp(11), layoutHeight - AndroidUtilities.dp(13.0f) - Theme.clockMediaDrawable.getIntrinsicHeight());
Theme.clockMediaDrawable.draw(canvas);
}
} else if (currentMessageObject.isSendError()) {
if (!currentMessageObject.isOutOwner()) {
setDrawableBounds(ResourceLoader.errorDrawable, timeX + AndroidUtilities.dp(11), layoutHeight - AndroidUtilities.dp(12.5f) - ResourceLoader.errorDrawable.getIntrinsicHeight());
ResourceLoader.errorDrawable.draw(canvas);
setDrawableBounds(Theme.errorDrawable, timeX + AndroidUtilities.dp(11), layoutHeight - AndroidUtilities.dp(12.5f) - Theme.errorDrawable.getIntrinsicHeight());
Theme.errorDrawable.draw(canvas);
}
} else {
Drawable countDrawable = ResourceLoader.viewsMediaCountDrawable;
setDrawableBounds(countDrawable, timeX, layoutHeight - AndroidUtilities.dp(10) - timeLayout.getHeight());
Drawable countDrawable = Theme.viewsMediaCountDrawable;
setDrawableBounds(countDrawable, timeX, layoutHeight - AndroidUtilities.dp(9.5f) - timeLayout.getHeight());
countDrawable.draw(canvas);
if (viewsLayout != null) {
canvas.save();
canvas.translate(timeX + countDrawable.getIntrinsicWidth() + AndroidUtilities.dp(3), layoutHeight - AndroidUtilities.dp(12.0f) - timeLayout.getHeight());
canvas.translate(timeX + countDrawable.getIntrinsicWidth() + AndroidUtilities.dp(3), layoutHeight - AndroidUtilities.dp(11.3f) - timeLayout.getHeight());
viewsLayout.draw(canvas);
canvas.restore();
}
@ -1062,7 +1074,7 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
}
canvas.save();
canvas.translate(timeX + additionalX, layoutHeight - AndroidUtilities.dp(12.0f) - timeLayout.getHeight());
canvas.translate(timeX + additionalX, layoutHeight - AndroidUtilities.dp(11.3f) - timeLayout.getHeight());
timeLayout.draw(canvas);
canvas.restore();
} else {
@ -1072,27 +1084,27 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
if (currentMessageObject.isSending()) {
if (!currentMessageObject.isOutOwner()) {
Drawable clockDrawable = ResourceLoader.clockChannelDrawable[isDrawSelectedBackground() ? 1 : 0];
Drawable clockDrawable = Theme.clockChannelDrawable[isDrawSelectedBackground() ? 1 : 0];
setDrawableBounds(clockDrawable, timeX + AndroidUtilities.dp(11), layoutHeight - AndroidUtilities.dp(8.5f) - clockDrawable.getIntrinsicHeight());
clockDrawable.draw(canvas);
}
} else if (currentMessageObject.isSendError()) {
if (!currentMessageObject.isOutOwner()) {
setDrawableBounds(ResourceLoader.errorDrawable, timeX + AndroidUtilities.dp(11), layoutHeight - AndroidUtilities.dp(6.5f) - ResourceLoader.errorDrawable.getIntrinsicHeight());
ResourceLoader.errorDrawable.draw(canvas);
setDrawableBounds(Theme.errorDrawable, timeX + AndroidUtilities.dp(11), layoutHeight - AndroidUtilities.dp(6.5f) - Theme.errorDrawable.getIntrinsicHeight());
Theme.errorDrawable.draw(canvas);
}
} else {
if (!currentMessageObject.isOutOwner()) {
setDrawableBounds(ResourceLoader.viewsCountDrawable[isDrawSelectedBackground() ? 1 : 0], timeX, layoutHeight - AndroidUtilities.dp(4.5f) - timeLayout.getHeight());
ResourceLoader.viewsCountDrawable[isDrawSelectedBackground() ? 1 : 0].draw(canvas);
setDrawableBounds(Theme.viewsCountDrawable[isDrawSelectedBackground() ? 1 : 0], timeX, layoutHeight - AndroidUtilities.dp(4.5f) - timeLayout.getHeight());
Theme.viewsCountDrawable[isDrawSelectedBackground() ? 1 : 0].draw(canvas);
} else {
setDrawableBounds(ResourceLoader.viewsOutCountDrawable, timeX, layoutHeight - AndroidUtilities.dp(4.5f) - timeLayout.getHeight());
ResourceLoader.viewsOutCountDrawable.draw(canvas);
setDrawableBounds(Theme.viewsOutCountDrawable, timeX, layoutHeight - AndroidUtilities.dp(4.5f) - timeLayout.getHeight());
Theme.viewsOutCountDrawable.draw(canvas);
}
if (viewsLayout != null) {
canvas.save();
canvas.translate(timeX + ResourceLoader.viewsOutCountDrawable.getIntrinsicWidth() + AndroidUtilities.dp(3), layoutHeight - AndroidUtilities.dp(6.5f) - timeLayout.getHeight());
canvas.translate(timeX + Theme.viewsOutCountDrawable.getIntrinsicWidth() + AndroidUtilities.dp(3), layoutHeight - AndroidUtilities.dp(6.5f) - timeLayout.getHeight());
viewsLayout.draw(canvas);
canvas.restore();
}
@ -1103,6 +1115,7 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
canvas.translate(timeX + additionalX, layoutHeight - AndroidUtilities.dp(6.5f) - timeLayout.getHeight());
timeLayout.draw(canvas);
canvas.restore();
//canvas.drawRect(timeX, layoutHeight - AndroidUtilities.dp(6.5f) - timeLayout.getHeight(), timeX + availableTimeWidth, layoutHeight - AndroidUtilities.dp(4.5f) - timeLayout.getHeight(), timePaint);
}
if (currentMessageObject.isOutOwner()) {
@ -1136,58 +1149,58 @@ public class ChatBaseCell extends BaseCell implements MediaController.FileDownlo
if (drawClock) {
if (!mediaBackground) {
setDrawableBounds(ResourceLoader.clockDrawable, layoutWidth - AndroidUtilities.dp(18.5f) - ResourceLoader.clockDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.5f) - ResourceLoader.clockDrawable.getIntrinsicHeight());
ResourceLoader.clockDrawable.draw(canvas);
setDrawableBounds(Theme.clockDrawable, layoutWidth - AndroidUtilities.dp(18.5f) - Theme.clockDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.5f) - Theme.clockDrawable.getIntrinsicHeight());
Theme.clockDrawable.draw(canvas);
} else {
setDrawableBounds(ResourceLoader.clockMediaDrawable, layoutWidth - AndroidUtilities.dp(22.0f) - ResourceLoader.clockMediaDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.0f) - ResourceLoader.clockMediaDrawable.getIntrinsicHeight());
ResourceLoader.clockMediaDrawable.draw(canvas);
setDrawableBounds(Theme.clockMediaDrawable, layoutWidth - AndroidUtilities.dp(22.0f) - Theme.clockMediaDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(12.5f) - Theme.clockMediaDrawable.getIntrinsicHeight());
Theme.clockMediaDrawable.draw(canvas);
}
}
if (isBroadcast) {
if (drawCheck1 || drawCheck2) {
if (!mediaBackground) {
setDrawableBounds(ResourceLoader.broadcastDrawable, layoutWidth - AndroidUtilities.dp(20.5f) - ResourceLoader.broadcastDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.0f) - ResourceLoader.broadcastDrawable.getIntrinsicHeight());
ResourceLoader.broadcastDrawable.draw(canvas);
setDrawableBounds(Theme.broadcastDrawable, layoutWidth - AndroidUtilities.dp(20.5f) - Theme.broadcastDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.0f) - Theme.broadcastDrawable.getIntrinsicHeight());
Theme.broadcastDrawable.draw(canvas);
} else {
setDrawableBounds(ResourceLoader.broadcastMediaDrawable, layoutWidth - AndroidUtilities.dp(24.0f) - ResourceLoader.broadcastMediaDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.0f) - ResourceLoader.broadcastMediaDrawable.getIntrinsicHeight());
ResourceLoader.broadcastMediaDrawable.draw(canvas);
setDrawableBounds(Theme.broadcastMediaDrawable, layoutWidth - AndroidUtilities.dp(24.0f) - Theme.broadcastMediaDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.0f) - Theme.broadcastMediaDrawable.getIntrinsicHeight());
Theme.broadcastMediaDrawable.draw(canvas);
}
}
} else {
if (drawCheck2) {
if (!mediaBackground) {
if (drawCheck1) {
setDrawableBounds(ResourceLoader.checkDrawable, layoutWidth - AndroidUtilities.dp(22.5f) - ResourceLoader.checkDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.0f) - ResourceLoader.checkDrawable.getIntrinsicHeight());
setDrawableBounds(Theme.checkDrawable, layoutWidth - AndroidUtilities.dp(22.5f) - Theme.checkDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.0f) - Theme.checkDrawable.getIntrinsicHeight());
} else {
setDrawableBounds(ResourceLoader.checkDrawable, layoutWidth - AndroidUtilities.dp(18.5f) - ResourceLoader.checkDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.0f) - ResourceLoader.checkDrawable.getIntrinsicHeight());
setDrawableBounds(Theme.checkDrawable, layoutWidth - AndroidUtilities.dp(18.5f) - Theme.checkDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.0f) - Theme.checkDrawable.getIntrinsicHeight());
}
ResourceLoader.checkDrawable.draw(canvas);
Theme.checkDrawable.draw(canvas);
} else {
if (drawCheck1) {
setDrawableBounds(ResourceLoader.checkMediaDrawable, layoutWidth - AndroidUtilities.dp(26.0f) - ResourceLoader.checkMediaDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.0f) - ResourceLoader.checkMediaDrawable.getIntrinsicHeight());
setDrawableBounds(Theme.checkMediaDrawable, layoutWidth - AndroidUtilities.dp(26.3f) - Theme.checkMediaDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(12.5f) - Theme.checkMediaDrawable.getIntrinsicHeight());
} else {
setDrawableBounds(ResourceLoader.checkMediaDrawable, layoutWidth - AndroidUtilities.dp(22.0f) - ResourceLoader.checkMediaDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.0f) - ResourceLoader.checkMediaDrawable.getIntrinsicHeight());
setDrawableBounds(Theme.checkMediaDrawable, layoutWidth - AndroidUtilities.dp(21.5f) - Theme.checkMediaDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(12.5f) - Theme.checkMediaDrawable.getIntrinsicHeight());
}
ResourceLoader.checkMediaDrawable.draw(canvas);
Theme.checkMediaDrawable.draw(canvas);
}
}
if (drawCheck1) {
if (!mediaBackground) {
setDrawableBounds(ResourceLoader.halfCheckDrawable, layoutWidth - AndroidUtilities.dp(18) - ResourceLoader.halfCheckDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.0f) - ResourceLoader.halfCheckDrawable.getIntrinsicHeight());
ResourceLoader.halfCheckDrawable.draw(canvas);
setDrawableBounds(Theme.halfCheckDrawable, layoutWidth - AndroidUtilities.dp(18) - Theme.halfCheckDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(8.0f) - Theme.halfCheckDrawable.getIntrinsicHeight());
Theme.halfCheckDrawable.draw(canvas);
} else {
setDrawableBounds(ResourceLoader.halfCheckMediaDrawable, layoutWidth - AndroidUtilities.dp(20.5f) - ResourceLoader.halfCheckMediaDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(13.0f) - ResourceLoader.halfCheckMediaDrawable.getIntrinsicHeight());
ResourceLoader.halfCheckMediaDrawable.draw(canvas);
setDrawableBounds(Theme.halfCheckMediaDrawable, layoutWidth - AndroidUtilities.dp(21.5f) - Theme.halfCheckMediaDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(12.5f) - Theme.halfCheckMediaDrawable.getIntrinsicHeight());
Theme.halfCheckMediaDrawable.draw(canvas);
}
}
}
if (drawError) {
if (!mediaBackground) {
setDrawableBounds(ResourceLoader.errorDrawable, layoutWidth - AndroidUtilities.dp(18) - ResourceLoader.errorDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(6.5f) - ResourceLoader.errorDrawable.getIntrinsicHeight());
ResourceLoader.errorDrawable.draw(canvas);
setDrawableBounds(Theme.errorDrawable, layoutWidth - AndroidUtilities.dp(18) - Theme.errorDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(7) - Theme.errorDrawable.getIntrinsicHeight());
Theme.errorDrawable.draw(canvas);
} else {
setDrawableBounds(ResourceLoader.errorDrawable, layoutWidth - AndroidUtilities.dp(20.5f) - ResourceLoader.errorDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(12.5f) - ResourceLoader.errorDrawable.getIntrinsicHeight());
ResourceLoader.errorDrawable.draw(canvas);
setDrawableBounds(Theme.errorDrawable, layoutWidth - AndroidUtilities.dp(20.5f) - Theme.errorDrawable.getIntrinsicWidth(), layoutHeight - AndroidUtilities.dp(11.5f) - Theme.errorDrawable.getIntrinsicHeight());
Theme.errorDrawable.draw(canvas);
}
}
}

View File

@ -1,306 +0,0 @@
/*
* This is the source code of Telegram for Android v. 3.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-2016.
*/
package org.telegram.ui.Cells;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.SoundEffectConstants;
import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ContactsController;
import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.R;
import org.telegram.tgnet.TLRPC;
import org.telegram.messenger.UserConfig;
import org.telegram.ui.Components.AvatarDrawable;
public class ChatContactCell extends ChatBaseCell {
public interface ChatContactCellDelegate {
void didClickAddButton(ChatContactCell cell, TLRPC.User user);
void didClickPhone(ChatContactCell cell);
}
private static TextPaint namePaint;
private static TextPaint phonePaint;
private static Drawable addContactDrawableIn;
private static Drawable addContactDrawableOut;
private ImageReceiver avatarImage;
private AvatarDrawable avatarDrawable;
private StaticLayout nameLayout;
private StaticLayout phoneLayout;
private TLRPC.User contactUser;
private TLRPC.FileLocation currentPhoto;
private boolean avatarPressed = false;
private boolean buttonPressed = false;
private boolean drawAddButton = false;
private int namesWidth = 0;
private ChatContactCellDelegate contactDelegate = null;
public ChatContactCell(Context context) {
super(context);
if (namePaint == null) {
namePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
namePaint.setTextSize(AndroidUtilities.dp(15));
phonePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
phonePaint.setTextSize(AndroidUtilities.dp(15));
phonePaint.setColor(0xff212121);
addContactDrawableIn = getResources().getDrawable(R.drawable.addcontact_blue);
addContactDrawableOut = getResources().getDrawable(R.drawable.addcontact_green);
}
avatarImage = new ImageReceiver(this);
avatarImage.setRoundRadius(AndroidUtilities.dp(21));
avatarDrawable = new AvatarDrawable();
}
public void setContactDelegate(ChatContactCellDelegate delegate) {
this.contactDelegate = delegate;
}
@Override
protected boolean isUserDataChanged() {
if (currentMessageObject == null) {
return false;
}
int uid = currentMessageObject.messageOwner.media.user_id;
boolean newDrawAdd = contactUser != null && uid != UserConfig.getClientUserId() && ContactsController.getInstance().contactsDict.get(uid) == null;
if (newDrawAdd != drawAddButton) {
return true;
}
contactUser = MessagesController.getInstance().getUser(currentMessageObject.messageOwner.media.user_id);
TLRPC.FileLocation newPhoto = null;
if (contactUser != null && contactUser.photo != null) {
newPhoto = contactUser.photo.photo_small;
}
return currentPhoto == null && newPhoto != null || currentPhoto != null && newPhoto == null || currentPhoto != null && newPhoto != null && (currentPhoto.local_id != newPhoto.local_id || currentPhoto.volume_id != newPhoto.volume_id) || super.isUserDataChanged();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
boolean result = false;
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (x >= avatarImage.getImageX() && x <= avatarImage.getImageX() + namesWidth + AndroidUtilities.dp(42) && y >= avatarImage.getImageY() && y <= avatarImage.getImageY() + avatarImage.getImageHeight()) {
avatarPressed = true;
result = true;
} else if (drawAddButton && x >= avatarImage.getImageX() + namesWidth + AndroidUtilities.dp(52) && y >= AndroidUtilities.dp(13) + namesOffset && x <= avatarImage.getImageX() + namesWidth + AndroidUtilities.dp(92) && y <= AndroidUtilities.dp(52) + namesOffset) {
buttonPressed = true;
result = true;
}
if (result) {
startCheckLongPress();
}
} else {
if (event.getAction() != MotionEvent.ACTION_MOVE) {
cancelCheckLongPress();
}
if (avatarPressed) {
if (event.getAction() == MotionEvent.ACTION_UP) {
avatarPressed = false;
playSoundEffect(SoundEffectConstants.CLICK);
if (contactUser != null) {
if (delegate != null) {
delegate.didPressedUserAvatar(this, contactUser);
}
} else {
if (contactDelegate != null) {
contactDelegate.didClickPhone(this);
}
}
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
avatarPressed = false;
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (!(x >= avatarImage.getImageX() && x <= avatarImage.getImageX() + namesWidth + AndroidUtilities.dp(42) && y >= avatarImage.getImageY() && y <= avatarImage.getImageY() + avatarImage.getImageHeight())) {
avatarPressed = false;
}
}
} else if (buttonPressed) {
if (event.getAction() == MotionEvent.ACTION_UP) {
buttonPressed = false;
playSoundEffect(SoundEffectConstants.CLICK);
if (contactUser != null && contactDelegate != null) {
contactDelegate.didClickAddButton(this, contactUser);
}
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
buttonPressed = false;
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (!(x >= avatarImage.getImageX() + namesWidth + AndroidUtilities.dp(52) && y >= AndroidUtilities.dp(13) + namesOffset && x <= avatarImage.getImageX() + namesWidth + AndroidUtilities.dp(92) && y <= AndroidUtilities.dp(52) + namesOffset)) {
buttonPressed = false;
}
}
}
}
if (!result) {
result = super.onTouchEvent(event);
}
return result;
}
@Override
public void setMessageObject(MessageObject messageObject) {
if (currentMessageObject != messageObject || isUserDataChanged()) {
int uid = messageObject.messageOwner.media.user_id;
contactUser = MessagesController.getInstance().getUser(uid);
drawAddButton = contactUser != null && uid != UserConfig.getClientUserId() && ContactsController.getInstance().contactsDict.get(uid) == null;
int maxWidth;
if (AndroidUtilities.isTablet()) {
maxWidth = (int) (AndroidUtilities.getMinTabletSide() * 0.7f);
} else {
maxWidth = (int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.7f);
}
maxWidth -= AndroidUtilities.dp(58 + (drawAddButton ? 42 : 0));
if (contactUser != null) {
if (contactUser.photo != null) {
currentPhoto = contactUser.photo.photo_small;
} else {
currentPhoto = null;
}
avatarDrawable.setInfo(contactUser);
} else {
currentPhoto = null;
avatarDrawable.setInfo(uid, null, null, false);
}
avatarImage.setImage(currentPhoto, "50_50", avatarDrawable, null, false);
String phone = messageObject.messageOwner.media.phone_number;
if (phone != null && phone.length() != 0) {
if (!phone.startsWith("+")) {
phone = "+" + phone;
}
phone = PhoneFormat.getInstance().format(phone);
} else {
phone = LocaleController.getString("NumberUnknown", R.string.NumberUnknown);
}
String currentNameString = ContactsController.formatName(messageObject.messageOwner.media.first_name, messageObject.messageOwner.media.last_name);
if (currentNameString.length() == 0) {
currentNameString = phone;
}
int nameWidth = Math.min((int) Math.ceil(namePaint.measureText(currentNameString)), maxWidth);
if (maxWidth < 0) {
maxWidth = AndroidUtilities.dp(100);
}
CharSequence stringFinal = TextUtils.ellipsize(currentNameString.replace("\n", " "), namePaint, nameWidth, TextUtils.TruncateAt.END);
nameLayout = new StaticLayout(stringFinal, namePaint, nameWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
if (nameLayout.getLineCount() > 0) {
nameWidth = (int)Math.ceil(nameLayout.getLineWidth(0));
} else {
nameWidth = 0;
}
int phoneWidth = Math.min((int) Math.ceil(phonePaint.measureText(phone)), maxWidth);
stringFinal = TextUtils.ellipsize(phone.replace("\n", " "), phonePaint, phoneWidth, TextUtils.TruncateAt.END);
phoneLayout = new StaticLayout(stringFinal, phonePaint, phoneWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
if (phoneLayout.getLineCount() > 0) {
phoneWidth = (int)Math.ceil(phoneLayout.getLineWidth(0));
} else {
phoneWidth = 0;
}
namesWidth = Math.max(nameWidth, phoneWidth);
backgroundWidth = AndroidUtilities.dp(77 + (drawAddButton ? 42 : 0)) + namesWidth;
availableTimeWidth = backgroundWidth - AndroidUtilities.dp(29);
super.setMessageObject(messageObject);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), AndroidUtilities.dp(75) + namesOffset);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (currentMessageObject == null) {
return;
}
int x;
if (currentMessageObject.isOutOwner()) {
x = layoutWidth - backgroundWidth + AndroidUtilities.dp(8);
} else {
if (isChat && currentMessageObject.isFromUser()) {
x = AndroidUtilities.dp(69);
} else {
x = AndroidUtilities.dp(16);
}
}
avatarImage.setImageCoords(x, AndroidUtilities.dp(9) + namesOffset, AndroidUtilities.dp(42), AndroidUtilities.dp(42));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (currentMessageObject == null) {
return;
}
avatarImage.draw(canvas);
if (nameLayout != null) {
canvas.save();
canvas.translate(avatarImage.getImageX() + avatarImage.getImageWidth() + AndroidUtilities.dp(9), AndroidUtilities.dp(10) + namesOffset);
namePaint.setColor(AvatarDrawable.getColorForId(currentMessageObject.messageOwner.media.user_id));
nameLayout.draw(canvas);
canvas.restore();
}
if (phoneLayout != null) {
canvas.save();
canvas.translate(avatarImage.getImageX() + avatarImage.getImageWidth() + AndroidUtilities.dp(9), AndroidUtilities.dp(31) + namesOffset);
phoneLayout.draw(canvas);
canvas.restore();
}
if (drawAddButton) {
Drawable addContactDrawable;
if (currentMessageObject.isOutOwner()) {
addContactDrawable = addContactDrawableOut;
} else {
addContactDrawable = addContactDrawableIn;
}
setDrawableBounds(addContactDrawable, avatarImage.getImageX() + namesWidth + AndroidUtilities.dp(78), AndroidUtilities.dp(13) + namesOffset);
addContactDrawable.draw(canvas);
}
}
}

View File

@ -14,9 +14,9 @@ import android.widget.FrameLayout;
import android.widget.ProgressBar;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.R;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.ActionBar.Theme;
public class ChatLoadingCell extends FrameLayout {
@ -26,7 +26,8 @@ public class ChatLoadingCell extends FrameLayout {
super(context);
frameLayout = new FrameLayout(context);
frameLayout.setBackgroundResource(ApplicationLoader.isCustomTheme() ? R.drawable.system_loader2 : R.drawable.system_loader1);
frameLayout.setBackgroundResource(R.drawable.system_loader);
frameLayout.getBackground().setColorFilter(Theme.colorFilter);
addView(frameLayout, LayoutHelper.createFrame(36, 36, Gravity.CENTER));
ProgressBar progressBar = new ProgressBar(context);

View File

@ -1,457 +0,0 @@
/*
* This is the source code of Telegram for Android v. 3.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-2016.
*/
package org.telegram.ui.Cells;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.SoundEffectConstants;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ImageLoader;
import org.telegram.messenger.MediaController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.SendMessagesHelper;
import org.telegram.messenger.FileLoader;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Components.RadialProgress;
import org.telegram.ui.Components.ResourceLoader;
import org.telegram.ui.Components.SeekBar;
import java.io.File;
public class ChatMusicCell extends ChatBaseCell implements SeekBar.SeekBarDelegate {
public interface ChatMusicCellDelegate {
boolean needPlayMusic(MessageObject messageObject);
}
private static TextPaint timePaint;
private static TextPaint titlePaint;
private static TextPaint authorPaint;
private SeekBar seekBar;
private int seekBarX;
private int seekBarY;
private RadialProgress radialProgress;
private int buttonState = 0;
private int buttonX;
private int buttonY;
private boolean buttonPressed = false;
private StaticLayout timeLayout;
private int timeX;
private String lastTimeString = null;
private StaticLayout titleLayout;
private int titleX;
private StaticLayout authorLayout;
private int authorX;
private ChatMusicCellDelegate musicDelegate;
public ChatMusicCell(Context context) {
super(context);
seekBar = new SeekBar(context);
seekBar.setDelegate(this);
radialProgress = new RadialProgress(this);
drawForwardedName = false;
if (timePaint == null) {
timePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
timePaint.setTextSize(AndroidUtilities.dp(13));
titlePaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
titlePaint.setTextSize(AndroidUtilities.dp(16));
titlePaint.setColor(0xff212121);
titlePaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
authorPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
authorPaint.setTextSize(AndroidUtilities.dp(15));
authorPaint.setColor(0xff212121);
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
MediaController.getInstance().removeLoadingFileObserver(this);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
updateButtonState(false);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
boolean result = seekBar.onTouch(event.getAction(), event.getX() - seekBarX, event.getY() - seekBarY);
if (result) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
getParent().requestDisallowInterceptTouchEvent(true);
}
invalidate();
} else {
int side = AndroidUtilities.dp(36);
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (x >= buttonX && x <= buttonX + side && y >= buttonY && y <= buttonY + side) {
buttonPressed = true;
invalidate();
result = true;
radialProgress.swapBackground(getDrawableForCurrentState());
}
} else if (buttonPressed) {
if (event.getAction() == MotionEvent.ACTION_UP) {
buttonPressed = false;
playSoundEffect(SoundEffectConstants.CLICK);
didPressedButton();
invalidate();
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
buttonPressed = false;
invalidate();
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (!(x >= buttonX && x <= buttonX + side && y >= buttonY && y <= buttonY + side)) {
buttonPressed = false;
invalidate();
}
}
radialProgress.swapBackground(getDrawableForCurrentState());
}
if (!result) {
result = super.onTouchEvent(event);
}
}
return result;
}
private void didPressedButton() {
if (buttonState == 0) {
if (musicDelegate != null) {
if (musicDelegate.needPlayMusic(currentMessageObject)) {
buttonState = 1;
radialProgress.setBackground(getDrawableForCurrentState(), false, false);
invalidate();
}
}
} else if (buttonState == 1) {
boolean result = MediaController.getInstance().pauseAudio(currentMessageObject);
if (result) {
buttonState = 0;
radialProgress.setBackground(getDrawableForCurrentState(), false, false);
invalidate();
}
} else if (buttonState == 2) {
radialProgress.setProgress(0, false);
FileLoader.getInstance().loadFile(currentMessageObject.messageOwner.media.document, true, false);
buttonState = 3;
radialProgress.setBackground(getDrawableForCurrentState(), true, false);
invalidate();
} else if (buttonState == 3) {
FileLoader.getInstance().cancelLoadFile(currentMessageObject.messageOwner.media.document);
buttonState = 2;
radialProgress.setBackground(getDrawableForCurrentState(), false, false);
invalidate();
} else if (buttonState == 4) {
if (currentMessageObject.isOut() && currentMessageObject.isSending()) {
if (delegate != null) {
delegate.didPressedCancelSendButton(this);
}
}
}
}
public void setMusicDelegate(ChatMusicCellDelegate delegate) {
musicDelegate = delegate;
}
public void updateProgress() {
if (currentMessageObject == null) {
return;
}
if (!seekBar.isDragging()) {
seekBar.setProgress(currentMessageObject.audioProgress);
}
int duration = 0;
int currentProgress = 0;
for (int a = 0; a < currentMessageObject.messageOwner.media.document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = currentMessageObject.messageOwner.media.document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeAudio) {
duration = attribute.duration;
break;
}
}
if (MediaController.getInstance().isPlayingAudio(currentMessageObject)) {
currentProgress = currentMessageObject.audioProgressSec;
}
String timeString = String.format("%d:%02d / %d:%02d", currentProgress / 60, currentProgress % 60, duration / 60, duration % 60);
if (lastTimeString == null || lastTimeString != null && !lastTimeString.equals(timeString)) {
lastTimeString = timeString;
int timeWidth = (int) Math.ceil(timePaint.measureText(timeString));
timeLayout = new StaticLayout(timeString, timePaint, timeWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
}
invalidate();
}
public void downloadAudioIfNeed() {
//if (buttonState == 2) {
//FileLoader.getInstance().loadFile(currentMessageObject.messageOwner.media.document, true, false);
// buttonState = 3;
// invalidate();
//}
}
public void updateButtonState(boolean animated) {
if (currentMessageObject == null) {
return;
}
if (currentMessageObject.isOut() && currentMessageObject.isSending()) {
MediaController.getInstance().addLoadingFileObserver(currentMessageObject.messageOwner.attachPath, this);
buttonState = 4;
radialProgress.setBackground(getDrawableForCurrentState(), true, animated);
Float progress = ImageLoader.getInstance().getFileProgress(currentMessageObject.messageOwner.attachPath);
if (progress == null && SendMessagesHelper.getInstance().isSendingMessage(currentMessageObject.getId())) {
progress = 1.0f;
}
radialProgress.setProgress(progress != null ? progress : 0, false);
} else {
File cacheFile = null;
if (currentMessageObject.messageOwner.attachPath != null && currentMessageObject.messageOwner.attachPath.length() > 0) {
cacheFile = new File(currentMessageObject.messageOwner.attachPath);
if (!cacheFile.exists()) {
cacheFile = null;
}
}
if (cacheFile == null) {
cacheFile = FileLoader.getPathToMessage(currentMessageObject.messageOwner);
}
if (cacheFile.exists()) {
MediaController.getInstance().removeLoadingFileObserver(this);
boolean playing = MediaController.getInstance().isPlayingAudio(currentMessageObject);
if (!playing || playing && MediaController.getInstance().isAudioPaused()) {
buttonState = 0;
} else {
buttonState = 1;
}
radialProgress.setProgress(0, animated);
radialProgress.setBackground(getDrawableForCurrentState(), false, animated);
} else {
String fileName = currentMessageObject.getFileName();
MediaController.getInstance().addLoadingFileObserver(fileName, this);
if (!FileLoader.getInstance().isLoadingFile(fileName)) {
buttonState = 2;
radialProgress.setProgress(0, animated);
radialProgress.setBackground(getDrawableForCurrentState(), false, animated);
} else {
buttonState = 3;
Float progress = ImageLoader.getInstance().getFileProgress(fileName);
if (progress != null) {
radialProgress.setProgress(progress, animated);
} else {
radialProgress.setProgress(0, animated);
}
radialProgress.setBackground(getDrawableForCurrentState(), true, animated);
}
}
}
updateProgress();
}
@Override
public void onFailedDownload(String fileName) {
updateButtonState(true);
}
@Override
public void onSuccessDownload(String fileName) {
updateButtonState(true);
}
@Override
public void onProgressDownload(String fileName, float progress) {
radialProgress.setProgress(progress, true);
if (buttonState != 3) {
updateButtonState(false);
}
}
@Override
public void onProgressUpload(String fileName, float progress, boolean isEncrypted) {
radialProgress.setProgress(progress, true);
}
@Override
public void onSeekBarDrag(float progress) {
if (currentMessageObject == null) {
return;
}
currentMessageObject.audioProgress = progress;
MediaController.getInstance().seekToProgress(currentMessageObject, progress);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
setMeasuredDimension(width, AndroidUtilities.dp(78) + namesOffset);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (currentMessageObject.isOutOwner()) {
seekBarX = layoutWidth - backgroundWidth + AndroidUtilities.dp(52);
buttonX = layoutWidth - backgroundWidth + AndroidUtilities.dp(13);
timeX = layoutWidth - backgroundWidth + AndroidUtilities.dp(63);
} else {
if (isChat && currentMessageObject.isFromUser()) {
seekBarX = AndroidUtilities.dp(113);
buttonX = AndroidUtilities.dp(74);
timeX = AndroidUtilities.dp(124);
} else {
seekBarX = AndroidUtilities.dp(61);
buttonX = AndroidUtilities.dp(22);
timeX = AndroidUtilities.dp(72);
}
}
seekBar.width = backgroundWidth - AndroidUtilities.dp(67);
seekBar.height = AndroidUtilities.dp(30);
seekBarY = AndroidUtilities.dp(26) + namesOffset;
buttonY = AndroidUtilities.dp(13) + namesOffset;
radialProgress.setProgressRect(buttonX, buttonY, buttonX + AndroidUtilities.dp(40), buttonY + AndroidUtilities.dp(40));
updateProgress();
}
@Override
public void setMessageObject(MessageObject messageObject) {
boolean dataChanged = currentMessageObject == messageObject && isUserDataChanged();
if (currentMessageObject != messageObject || dataChanged) {
if (AndroidUtilities.isTablet()) {
backgroundWidth = Math.min(AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(isChat && messageObject.isFromUser() && !messageObject.isOutOwner() ? 102 : 50), AndroidUtilities.dp(300));
} else {
backgroundWidth = Math.min(AndroidUtilities.displaySize.x - AndroidUtilities.dp(isChat && messageObject.isFromUser() && !messageObject.isOutOwner() ? 102 : 50), AndroidUtilities.dp(300));
}
if (messageObject.isOutOwner()) {
seekBar.type = 0;
radialProgress.setProgressColor(0xff87bf78);
} else {
seekBar.type = 1;
radialProgress.setProgressColor(0xffa2b5c7);
}
int maxWidth = backgroundWidth - AndroidUtilities.dp(86);
CharSequence stringFinal = TextUtils.ellipsize(messageObject.getMusicTitle().replace("\n", " "), titlePaint, maxWidth, TextUtils.TruncateAt.END);
titleLayout = new StaticLayout(stringFinal, titlePaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
if (titleLayout.getLineCount() > 0) {
titleX = -(int) Math.ceil(titleLayout.getLineLeft(0));
}
stringFinal = TextUtils.ellipsize(messageObject.getMusicAuthor().replace("\n", " "), authorPaint, maxWidth, TextUtils.TruncateAt.END);
authorLayout = new StaticLayout(stringFinal, authorPaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
if (authorLayout.getLineCount() > 0) {
authorX = -(int) Math.ceil(authorLayout.getLineLeft(0));
}
int duration = 0;
for (int a = 0; a < messageObject.messageOwner.media.document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = messageObject.messageOwner.media.document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeAudio) {
duration = attribute.duration;
break;
}
}
availableTimeWidth = backgroundWidth - AndroidUtilities.dp(72 + 14) - (int) Math.ceil(timePaint.measureText(String.format("%d:%02d / %d:%02d", duration / 60, duration % 60, duration / 60, duration % 60)));
super.setMessageObject(messageObject);
}
updateButtonState(dataChanged);
}
@Override
public void setCheckPressed(boolean value, boolean pressed) {
super.setCheckPressed(value, pressed);
if (radialProgress.swapBackground(getDrawableForCurrentState())) {
invalidate();
}
}
@Override
public void setHighlighted(boolean value) {
super.setHighlighted(value);
if (radialProgress.swapBackground(getDrawableForCurrentState())) {
invalidate();
}
}
@Override
public void setPressed(boolean pressed) {
super.setPressed(pressed);
if (radialProgress.swapBackground(getDrawableForCurrentState())) {
invalidate();
}
}
private Drawable getDrawableForCurrentState() {
return ResourceLoader.audioStatesDrawable[currentMessageObject.isOutOwner() ? buttonState : buttonState + 5][isDrawSelectedBackground() ? 2 : (buttonPressed ? 1 : 0)];
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (currentMessageObject == null) {
return;
}
if (currentMessageObject.isOutOwner()) {
timePaint.setColor(0xff70b15c);
} else {
timePaint.setColor(isDrawSelectedBackground() ? 0xff89b4c1 : 0xffa1aab3);
}
radialProgress.draw(canvas);
canvas.save();
canvas.translate(timeX + titleX, AndroidUtilities.dp(12) + namesOffset);
titleLayout.draw(canvas);
canvas.restore();
canvas.save();
if (MediaController.getInstance().isPlayingAudio(currentMessageObject)) {
canvas.translate(seekBarX, seekBarY);
seekBar.draw(canvas);
} else {
canvas.translate(timeX + authorX, AndroidUtilities.dp(32) + namesOffset);
authorLayout.draw(canvas);
}
canvas.restore();
canvas.save();
canvas.translate(timeX, AndroidUtilities.dp(52) + namesOffset);
timeLayout.draw(canvas);
canvas.restore();
}
}

View File

@ -18,6 +18,7 @@ import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.R;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.ActionBar.Theme;
public class ChatUnreadCell extends FrameLayout {
@ -38,7 +39,8 @@ public class ChatUnreadCell extends FrameLayout {
textView = new TextView(context);
textView.setPadding(0, 0, 0, AndroidUtilities.dp(1));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
textView.setTextColor(0xff4a7297);
textView.setTextColor(Theme.CHAT_UNREAD_TEXT_COLOR);
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER));
}

View File

@ -21,8 +21,10 @@ import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.SoundEffectConstants;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageLoader;
@ -30,11 +32,12 @@ import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.R;
import org.telegram.messenger.Utilities;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Components.LetterDrawable;
import org.telegram.ui.Components.RadialProgress;
import org.telegram.ui.Components.ResourceLoader;
import org.telegram.ui.ActionBar.Theme;
import java.io.File;
import java.util.ArrayList;
@ -42,6 +45,16 @@ import java.util.Locale;
public class ContextLinkCell extends View implements MediaController.FileDownloadProgressListener {
private final static int DOCUMENT_ATTACH_TYPE_NONE = 0;
private final static int DOCUMENT_ATTACH_TYPE_DOCUMENT = 1;
private final static int DOCUMENT_ATTACH_TYPE_GIF = 2;
private final static int DOCUMENT_ATTACH_TYPE_AUDIO = 3;
private final static int DOCUMENT_ATTACH_TYPE_VIDEO = 4;
private final static int DOCUMENT_ATTACH_TYPE_MUSIC = 5;
private final static int DOCUMENT_ATTACH_TYPE_STICKER = 6;
private final static int DOCUMENT_ATTACH_TYPE_PHOTO = 7;
private final static int DOCUMENT_ATTACH_TYPE_GEO = 8;
public interface ContextLinkCellDelegate {
void didPressedImage(ContextLinkCell cell);
}
@ -52,6 +65,7 @@ public class ContextLinkCell extends View implements MediaController.FileDownloa
private boolean needDivider;
private boolean buttonPressed;
private boolean needShadow;
private int linkY;
private StaticLayout linkLayout;
@ -62,18 +76,26 @@ public class ContextLinkCell extends View implements MediaController.FileDownloa
private int descriptionY = AndroidUtilities.dp(27);
private StaticLayout descriptionLayout;
private TLRPC.BotInlineResult result;
private TLRPC.Document gif;
private TLRPC.BotInlineResult inlineResult;
private TLRPC.Document documentAttach;
private int documentAttachType;
private boolean mediaWebpage;
private static TextPaint titleTextPaint;
private static TextPaint descriptionTextPaint;
private static Paint paint;
private static Drawable shadowDrawable;
private int TAG;
private int buttonState;
private RadialProgress radialProgress;
private long lastUpdateTime;
private boolean scaled;
private float scale;
private long time = 0;
private static AccelerateInterpolator interpolator = new AccelerateInterpolator(0.5f);
private ContextLinkCellDelegate delegate;
public ContextLinkCell(Context context) {
@ -93,7 +115,6 @@ public class ContextLinkCell extends View implements MediaController.FileDownloa
paint.setStrokeWidth(1);
}
setWillNotDraw(false);
linkImageView = new ImageReceiver(this);
letterDrawable = new LetterDrawable();
radialProgress = new RadialProgress(this);
@ -107,47 +128,43 @@ public class ContextLinkCell extends View implements MediaController.FileDownloa
descriptionLayout = null;
titleLayout = null;
linkLayout = null;
TLRPC.PhotoSize currentPhotoObject = null;
TLRPC.PhotoSize currentPhotoObjectThumb = null;
ArrayList<TLRPC.PhotoSize> photoThumbs = null;
String url = null;
linkY = AndroidUtilities.dp(27);
if (result == null && gif == null) {
if (inlineResult == null && documentAttach == null) {
setMeasuredDimension(AndroidUtilities.dp(100), AndroidUtilities.dp(100));
return;
}
int maxWidth = MeasureSpec.getSize(widthMeasureSpec) - AndroidUtilities.dp(AndroidUtilities.leftBaseline) - AndroidUtilities.dp(8);
int viewWidth = MeasureSpec.getSize(widthMeasureSpec);
int maxWidth = viewWidth - AndroidUtilities.dp(AndroidUtilities.leftBaseline) - AndroidUtilities.dp(8);
TLRPC.Document document = null;
if (result != null && result.document != null) {
document = result.document;
} else if (gif != null) {
document = gif;
}
if (document != null) {
TLRPC.PhotoSize currentPhotoObject = null;
TLRPC.PhotoSize currentPhotoObjectThumb = null;
ArrayList<TLRPC.PhotoSize> photoThumbs = null;
String url = null;
if (documentAttach != null) {
photoThumbs = new ArrayList<>();
photoThumbs.add(document.thumb);
} else if (result != null && result.photo != null) {
photoThumbs = new ArrayList<>(result.photo.sizes);
photoThumbs.add(documentAttach.thumb);
} else if (inlineResult != null && inlineResult.photo != null) {
photoThumbs = new ArrayList<>(inlineResult.photo.sizes);
}
if (!mediaWebpage && result != null) {
if (result.title != null) {
if (!mediaWebpage && inlineResult != null) {
if (inlineResult.title != null) {
try {
int width = (int) Math.ceil(titleTextPaint.measureText(result.title));
CharSequence titleFinal = TextUtils.ellipsize(result.title.replace("\n", " "), titleTextPaint, Math.min(width, maxWidth), TextUtils.TruncateAt.END);
titleLayout = new StaticLayout(titleFinal, titleTextPaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
int width = (int) Math.ceil(titleTextPaint.measureText(inlineResult.title));
CharSequence titleFinal = TextUtils.ellipsize(Emoji.replaceEmoji(inlineResult.title.replace('\n', ' '), titleTextPaint.getFontMetricsInt(), AndroidUtilities.dp(15), false), titleTextPaint, Math.min(width, maxWidth), TextUtils.TruncateAt.END);
titleLayout = new StaticLayout(titleFinal, titleTextPaint, maxWidth + AndroidUtilities.dp(4), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
letterDrawable.setTitle(result.title);
letterDrawable.setTitle(inlineResult.title);
}
if (result.description != null) {
if (inlineResult.description != null) {
try {
descriptionLayout = ChatMessageCell.generateStaticLayout(result.description, descriptionTextPaint, maxWidth, maxWidth, 0, 3);
descriptionLayout = ChatMessageCell.generateStaticLayout(Emoji.replaceEmoji(inlineResult.description, descriptionTextPaint.getFontMetricsInt(), AndroidUtilities.dp(13), false), descriptionTextPaint, maxWidth, maxWidth, 0, 3);
if (descriptionLayout.getLineCount() > 0) {
linkY = descriptionY + descriptionLayout.getLineBottom(descriptionLayout.getLineCount() - 1) + AndroidUtilities.dp(1);
}
@ -156,10 +173,10 @@ public class ContextLinkCell extends View implements MediaController.FileDownloa
}
}
if (result.url != null) {
if (inlineResult.url != null) {
try {
int width = (int) Math.ceil(descriptionTextPaint.measureText(result.url));
CharSequence linkFinal = TextUtils.ellipsize(result.url.replace("\n", " "), descriptionTextPaint, Math.min(width, maxWidth), TextUtils.TruncateAt.MIDDLE);
int width = (int) Math.ceil(descriptionTextPaint.measureText(inlineResult.url));
CharSequence linkFinal = TextUtils.ellipsize(inlineResult.url.replace('\n', ' '), descriptionTextPaint, Math.min(width, maxWidth), TextUtils.TruncateAt.MIDDLE);
linkLayout = new StaticLayout(linkFinal, descriptionTextPaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -167,32 +184,52 @@ public class ContextLinkCell extends View implements MediaController.FileDownloa
}
}
boolean isGifDocument = false;
if (document != null && MessageObject.isGifDocument(document)) {
currentPhotoObject = document.thumb;
isGifDocument = true;
} else if (result != null && result.photo != null) {
documentAttachType = DOCUMENT_ATTACH_TYPE_NONE;
String ext = null;
if (documentAttach != null) {
if (MessageObject.isGifDocument(documentAttach)) {
documentAttachType = DOCUMENT_ATTACH_TYPE_GIF;
currentPhotoObject = documentAttach.thumb;
} else if (MessageObject.isStickerDocument(documentAttach)) {
documentAttachType = DOCUMENT_ATTACH_TYPE_STICKER;
currentPhotoObject = documentAttach.thumb;
ext = "webp";
} else {
currentPhotoObject = documentAttach.thumb;
}
} else if (inlineResult != null && inlineResult.photo != null) {
documentAttachType = DOCUMENT_ATTACH_TYPE_PHOTO;
currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(photoThumbs, AndroidUtilities.getPhotoSize(), true);
currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(photoThumbs, 80);
if (currentPhotoObjectThumb == currentPhotoObject) {
currentPhotoObjectThumb = null;
}
}
if (result != null) {
if (result.content_url != null) {
if (result.type != null) {
if (result.type.startsWith("gif")) {
if (!isGifDocument) {
url = result.content_url;
isGifDocument = true;
if (inlineResult != null) {
if (inlineResult.content_url != null) {
if (inlineResult.type != null) {
if (inlineResult.type.startsWith("gif")) {
if (documentAttachType != DOCUMENT_ATTACH_TYPE_GIF) {
url = inlineResult.content_url;
documentAttachType = DOCUMENT_ATTACH_TYPE_GIF;
}
} else if (inlineResult.type.equals("photo")) {
url = inlineResult.thumb_url;
if (url == null) {
url = inlineResult.content_url;
}
} else if (result.type.equals("photo")) {
url = result.content_url;
}
}
}
if (url == null && result.thumb_url != null) {
url = result.thumb_url;
if (url == null && inlineResult.thumb_url != null) {
url = inlineResult.thumb_url;
}
}
if (url == null && currentPhotoObject == null && currentPhotoObjectThumb == null) {
if (inlineResult.send_message instanceof TLRPC.TL_botInlineMessageMediaVenue || inlineResult.send_message instanceof TLRPC.TL_botInlineMessageMediaGeo) {
double lat = inlineResult.send_message.geo.lat;
double lon = inlineResult.send_message.geo._long;
url = String.format(Locale.US, "https://maps.googleapis.com/maps/api/staticmap?center=%f,%f&zoom=15&size=72x72&maptype=roadmap&scale=%d&markers=color:red|size:small|%f,%f&sensor=false", lat, lon, Math.min(2, (int) Math.ceil(AndroidUtilities.density)), lat, lon);
}
}
@ -200,9 +237,9 @@ public class ContextLinkCell extends View implements MediaController.FileDownloa
int w = 0;
int h = 0;
if (document != null) {
for (int b = 0; b < document.attributes.size(); b++) {
TLRPC.DocumentAttribute attribute = document.attributes.get(b);
if (documentAttach != null) {
for (int b = 0; b < documentAttach.attributes.size(); b++) {
TLRPC.DocumentAttribute attribute = documentAttach.attributes.get(b);
if (attribute instanceof TLRPC.TL_documentAttributeImageSize || attribute instanceof TLRPC.TL_documentAttributeVideo) {
w = attribute.w;
h = attribute.h;
@ -212,24 +249,26 @@ public class ContextLinkCell extends View implements MediaController.FileDownloa
}
if (w == 0 || h == 0) {
if (currentPhotoObject != null) {
currentPhotoObject.size = -1;
if (currentPhotoObjectThumb != null) {
currentPhotoObjectThumb.size = -1;
}
w = currentPhotoObject.w;
h = currentPhotoObject.h;
} else if (result != null) {
w = result.w;
h = result.h;
} else if (inlineResult != null) {
w = inlineResult.w;
h = inlineResult.h;
}
}
if (document != null || currentPhotoObject != null || url != null) {
if (w == 0 || h == 0) {
w = h = AndroidUtilities.dp(80);
}
if (documentAttach != null || currentPhotoObject != null || url != null) {
String currentPhotoFilter;
String currentPhotoFilterThumb = "52_52_b";
if (mediaWebpage) {
width = (int) (w / (h / (float) AndroidUtilities.dp(80)));
if (Build.VERSION.SDK_INT >= 11 && isGifDocument) {
if (Build.VERSION.SDK_INT >= 11 && documentAttachType == DOCUMENT_ATTACH_TYPE_GIF) {
currentPhotoFilterThumb = currentPhotoFilter = String.format(Locale.US, "%d_%d_b", (int) (width / AndroidUtilities.density), 80);
} else {
currentPhotoFilter = String.format(Locale.US, "%d_%d", (int) (width / AndroidUtilities.density), 80);
@ -239,25 +278,26 @@ public class ContextLinkCell extends View implements MediaController.FileDownloa
currentPhotoFilter = "52_52";
}
if (isGifDocument) {
if (document != null && Build.VERSION.SDK_INT >= 11) {
linkImageView.setImage(document, null, currentPhotoObject != null ? currentPhotoObject.location : null, currentPhotoFilter, document.size, null, false);
if (documentAttachType == DOCUMENT_ATTACH_TYPE_GIF) {
if (documentAttach != null && Build.VERSION.SDK_INT >= 11) {
linkImageView.setImage(documentAttach, null, currentPhotoObject != null ? currentPhotoObject.location : null, currentPhotoFilter, documentAttach.size, ext, false);
} else {
linkImageView.setImage(null, url, null, null, currentPhotoObject != null ? currentPhotoObject.location : null, currentPhotoFilter, -1, null, true);
linkImageView.setImage(null, url, null, null, currentPhotoObject != null ? currentPhotoObject.location : null, currentPhotoFilter, -1, ext, true);
}
} else {
if (currentPhotoObject != null) {
linkImageView.setImage(currentPhotoObject.location, currentPhotoFilter, currentPhotoObjectThumb != null ? currentPhotoObjectThumb.location : null, currentPhotoFilterThumb, 0, null, false);
linkImageView.setImage(currentPhotoObject.location, currentPhotoFilter, currentPhotoObjectThumb != null ? currentPhotoObjectThumb.location : null, currentPhotoFilterThumb, 0, ext, false);
} else {
linkImageView.setImage(null, url, currentPhotoFilter, null, currentPhotoObjectThumb != null ? currentPhotoObjectThumb.location : null, currentPhotoFilterThumb, -1, null, true);
linkImageView.setImage(null, url, currentPhotoFilter, null, currentPhotoObjectThumb != null ? currentPhotoObjectThumb.location : null, currentPhotoFilterThumb, -1, ext, true);
}
}
drawLinkImageView = true;
}
if (mediaWebpage) {
if (gif != null) {
width = MeasureSpec.getSize(widthMeasureSpec);
setBackgroundDrawable(null);
if (inlineResult == null) {
width = viewWidth;
int height = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(width, height);
if (needDivider) {
@ -275,6 +315,7 @@ public class ContextLinkCell extends View implements MediaController.FileDownloa
linkImageView.setImageCoords(AndroidUtilities.dp(5), AndroidUtilities.dp(5), width, AndroidUtilities.dp(80));
}
} else {
setBackgroundResource(R.drawable.list_selector);
int height = 0;
if (titleLayout != null && titleLayout.getLineCount() != 0) {
height += titleLayout.getLineBottom(titleLayout.getLineCount() - 1);
@ -290,14 +331,23 @@ public class ContextLinkCell extends View implements MediaController.FileDownloa
int maxPhotoWidth = AndroidUtilities.dp(52);
int x = LocaleController.isRTL ? MeasureSpec.getSize(widthMeasureSpec) - AndroidUtilities.dp(8) - maxPhotoWidth : AndroidUtilities.dp(8);
letterDrawable.setBounds(x, AndroidUtilities.dp(8), x + maxPhotoWidth, AndroidUtilities.dp(62));
letterDrawable.setBounds(x, AndroidUtilities.dp(8), x + maxPhotoWidth, AndroidUtilities.dp(60));
linkImageView.setImageCoords(x, AndroidUtilities.dp(8), maxPhotoWidth, maxPhotoWidth);
}
}
public void setLink(TLRPC.BotInlineResult contextResult, boolean media, boolean divider) {
public void setLink(TLRPC.BotInlineResult contextResult, boolean media, boolean divider, boolean shadow) {
needDivider = divider;
result = contextResult;
needShadow = shadow;
if (needShadow && shadowDrawable == null) {
shadowDrawable = getContext().getResources().getDrawable(R.drawable.header_shadow);
}
inlineResult = contextResult;
if (inlineResult != null && inlineResult.document != null) {
documentAttach = inlineResult.document;
} else {
documentAttach = null;
}
mediaWebpage = media;
requestLayout();
updateButtonState(false);
@ -305,13 +355,32 @@ public class ContextLinkCell extends View implements MediaController.FileDownloa
public void setGif(TLRPC.Document document, boolean divider) {
needDivider = divider;
result = null;
gif = document;
needShadow = false;
inlineResult = null;
documentAttach = document;
mediaWebpage = true;
requestLayout();
updateButtonState(false);
}
public boolean isSticker() {
return documentAttachType == DOCUMENT_ATTACH_TYPE_STICKER;
}
public boolean showingBitmap() {
return linkImageView.getBitmap() != null;
}
public TLRPC.Document getDocument() {
return documentAttach;
}
public void setScaled(boolean value) {
scaled = value;
lastUpdateTime = System.currentTimeMillis();
invalidate();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
@ -333,7 +402,13 @@ public class ContextLinkCell extends View implements MediaController.FileDownloa
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mediaWebpage || delegate == null || result == null) {
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());
}
}
if (mediaWebpage || delegate == null || inlineResult == null) {
return super.onTouchEvent(event);
}
int x = (int) event.getX();
@ -341,22 +416,24 @@ public class ContextLinkCell extends View implements MediaController.FileDownloa
boolean result = false;
int side = AndroidUtilities.dp(48);
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (letterDrawable.getBounds().contains(x, y)) {
buttonPressed = true;
result = true;
}
} else {
if (buttonPressed) {
if (event.getAction() == MotionEvent.ACTION_UP) {
buttonPressed = false;
playSoundEffect(SoundEffectConstants.CLICK);
delegate.didPressedImage(this);
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
buttonPressed = false;
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (!letterDrawable.getBounds().contains(x, y)) {
if (inlineResult != null && inlineResult.content_url != null && inlineResult.content_url.length() > 0) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (letterDrawable.getBounds().contains(x, y)) {
buttonPressed = true;
result = true;
}
} else {
if (buttonPressed) {
if (event.getAction() == MotionEvent.ACTION_UP) {
buttonPressed = false;
playSoundEffect(SoundEffectConstants.CLICK);
delegate.didPressedImage(this);
} else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
buttonPressed = false;
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (!letterDrawable.getBounds().contains(x, y)) {
buttonPressed = false;
}
}
}
}
@ -386,7 +463,7 @@ public class ContextLinkCell extends View implements MediaController.FileDownloa
}
if (linkLayout != null) {
descriptionTextPaint.setColor(0xff316f9f);
descriptionTextPaint.setColor(Theme.MSG_LINK_TEXT_COLOR);
canvas.save();
canvas.translate(AndroidUtilities.dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline), linkY);
linkLayout.draw(canvas);
@ -394,12 +471,68 @@ public class ContextLinkCell extends View implements MediaController.FileDownloa
}
if (!mediaWebpage) {
letterDrawable.draw(canvas);
if (inlineResult != null && inlineResult.type.equals("file")) {
int w = Theme.inlineDocDrawable.getIntrinsicWidth();
int h = Theme.inlineDocDrawable.getIntrinsicHeight();
int x = linkImageView.getImageX() + (AndroidUtilities.dp(52) - w) / 2;
int y = linkImageView.getImageY() + (AndroidUtilities.dp(52) - h) / 2;
canvas.drawRect(linkImageView.getImageX(), linkImageView.getImageY(), linkImageView.getImageX() + AndroidUtilities.dp(52), linkImageView.getImageY() + AndroidUtilities.dp(52), LetterDrawable.paint);
Theme.inlineDocDrawable.setBounds(x, y, x + w, y + h);
Theme.inlineDocDrawable.draw(canvas);
} else if (inlineResult != null && (inlineResult.type.equals("audio") || inlineResult.type.equals("voice"))) {
int w = Theme.inlineAudioDrawable.getIntrinsicWidth();
int h = Theme.inlineAudioDrawable.getIntrinsicHeight();
int x = linkImageView.getImageX() + (AndroidUtilities.dp(52) - w) / 2;
int y = linkImageView.getImageY() + (AndroidUtilities.dp(52) - h) / 2;
canvas.drawRect(linkImageView.getImageX(), linkImageView.getImageY(), linkImageView.getImageX() + AndroidUtilities.dp(52), linkImageView.getImageY() + AndroidUtilities.dp(52), LetterDrawable.paint);
Theme.inlineAudioDrawable.setBounds(x, y, x + w, y + h);
Theme.inlineAudioDrawable.draw(canvas);
} else if (inlineResult != null && (inlineResult.type.equals("venue") || inlineResult.type.equals("geo"))) {
int w = Theme.inlineLocationDrawable.getIntrinsicWidth();
int h = Theme.inlineLocationDrawable.getIntrinsicHeight();
int x = linkImageView.getImageX() + (AndroidUtilities.dp(52) - w) / 2;
int y = linkImageView.getImageY() + (AndroidUtilities.dp(52) - h) / 2;
canvas.drawRect(linkImageView.getImageX(), linkImageView.getImageY(), linkImageView.getImageX() + AndroidUtilities.dp(52), linkImageView.getImageY() + AndroidUtilities.dp(52), LetterDrawable.paint);
Theme.inlineLocationDrawable.setBounds(x, y, x + w, y + h);
Theme.inlineLocationDrawable.draw(canvas);
} else {
letterDrawable.draw(canvas);
}
} else {
if (inlineResult != null && (inlineResult.send_message instanceof TLRPC.TL_botInlineMessageMediaGeo || inlineResult.send_message instanceof TLRPC.TL_botInlineMessageMediaVenue)) {
int w = Theme.inlineLocationDrawable.getIntrinsicWidth();
int h = Theme.inlineLocationDrawable.getIntrinsicHeight();
int x = linkImageView.getImageX() + (linkImageView.getImageWidth() - w) / 2;
int y = linkImageView.getImageY() + (linkImageView.getImageHeight() - h) / 2;
canvas.drawRect(linkImageView.getImageX(), linkImageView.getImageY(), linkImageView.getImageX() + linkImageView.getImageWidth(), linkImageView.getImageY() + linkImageView.getImageHeight(), LetterDrawable.paint);
Theme.inlineLocationDrawable.setBounds(x, y, x + w, y + h);
Theme.inlineLocationDrawable.draw(canvas);
}
}
if (drawLinkImageView) {
canvas.save();
if (scaled && scale != 0.8f || !scaled && scale != 1.0f) {
long newTime = System.currentTimeMillis();
long dt = (newTime - lastUpdateTime);
lastUpdateTime = newTime;
if (scaled && scale != 0.8f) {
scale -= dt / 400.0f;
if (scale < 0.8f) {
scale = 0.8f;
}
} else {
scale += dt / 400.0f;
if (scale > 1.0f) {
scale = 1.0f;
}
}
invalidate();
}
canvas.scale(scale, scale, getMeasuredWidth() / 2, getMeasuredHeight() / 2);
linkImageView.draw(canvas);
canvas.restore();
}
if (mediaWebpage) {
if (mediaWebpage && (documentAttachType == DOCUMENT_ATTACH_TYPE_PHOTO || documentAttachType == DOCUMENT_ATTACH_TYPE_GIF)) {
radialProgress.draw(canvas);
}
@ -410,10 +543,14 @@ public class ContextLinkCell extends View implements MediaController.FileDownloa
canvas.drawLine(AndroidUtilities.dp(AndroidUtilities.leftBaseline), getMeasuredHeight() - 1, getMeasuredWidth(), getMeasuredHeight() - 1, paint);
}
}
if (needShadow && shadowDrawable != null) {
shadowDrawable.setBounds(0, 0, getMeasuredWidth(), AndroidUtilities.dp(3));
shadowDrawable.draw(canvas);
}
}
private Drawable getDrawableForCurrentState() {
return buttonState == 1 ? ResourceLoader.buttonStatesDrawables[6] : null;
return buttonState == 1 ? Theme.photoStatesDrawables[5][0] : null;
}
public void updateButtonState(boolean animated) {
@ -422,27 +559,24 @@ public class ContextLinkCell extends View implements MediaController.FileDownloa
}
String fileName = null;
File cacheFile = null;
if (result != null) {
if (result.photo instanceof TLRPC.TL_photo) {
TLRPC.PhotoSize currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(result.photo.sizes, AndroidUtilities.getPhotoSize(), true);
if (currentPhotoObject != null) {
currentPhotoObject.size = -1;
}
if (inlineResult != null) {
if (inlineResult.document instanceof TLRPC.TL_document) {
fileName = FileLoader.getAttachFileName(inlineResult.document);
cacheFile = FileLoader.getPathToAttach(inlineResult.document);
} else if (inlineResult.photo instanceof TLRPC.TL_photo) {
TLRPC.PhotoSize currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(inlineResult.photo.sizes, AndroidUtilities.getPhotoSize(), true);
fileName = FileLoader.getAttachFileName(currentPhotoObject);
cacheFile = FileLoader.getPathToAttach(currentPhotoObject);
} else if (result.document instanceof TLRPC.TL_document) {
fileName = FileLoader.getAttachFileName(result.document);
cacheFile = FileLoader.getPathToAttach(result.document);
} else if (result.content_url != null) {
fileName = Utilities.MD5(result.content_url) + "." + ImageLoader.getHttpUrlExtension(result.content_url, "jpg");
} else if (inlineResult.content_url != null) {
fileName = Utilities.MD5(inlineResult.content_url) + "." + ImageLoader.getHttpUrlExtension(inlineResult.content_url, "jpg");
cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName);
} else if (result.thumb_url != null) {
fileName = Utilities.MD5(result.thumb_url) + "." + ImageLoader.getHttpUrlExtension(result.thumb_url, "jpg");
} else if (inlineResult.thumb_url != null) {
fileName = Utilities.MD5(inlineResult.thumb_url) + "." + ImageLoader.getHttpUrlExtension(inlineResult.thumb_url, "jpg");
cacheFile = new File(FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE), fileName);
}
} else if (gif != null) {
fileName = FileLoader.getAttachFileName(gif);
cacheFile = FileLoader.getPathToAttach(gif);
} else if (documentAttach != null) {
fileName = FileLoader.getAttachFileName(documentAttach);
cacheFile = FileLoader.getPathToAttach(documentAttach);
}
if (fileName == null) {
radialProgress.setBackground(null, false, false);
@ -473,7 +607,7 @@ public class ContextLinkCell extends View implements MediaController.FileDownloa
}
public TLRPC.BotInlineResult getResult() {
return result;
return inlineResult;
}
@Override

View File

@ -395,7 +395,7 @@ public class DialogCell extends BaseCell {
if (mess.length() > 150) {
mess = mess.substring(0, 150);
}
mess = mess.replace("\n", " ");
mess = mess.replace('\n', ' ');
messageString = Emoji.replaceEmoji(AndroidUtilities.replaceTags(String.format("<c#ff4d83b3>%s:</c> <c#ff808080>%s</c>", name.replace("\n", ""), mess), AndroidUtilities.FLAG_TAG_COLOR), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20), false);
} else {
if (message.messageOwner.media != null && !message.isMediaEmpty()) {
@ -407,7 +407,7 @@ public class DialogCell extends BaseCell {
if (mess.length() > 150) {
mess = mess.substring(0, 150);
}
mess = mess.replace("\n", " ");
mess = mess.replace('\n', ' ');
messageString = Emoji.replaceEmoji(AndroidUtilities.replaceTags(String.format("<c#ff4d83b3>%s:</c> <c#ff808080>%s</c>", name.replace("\n", ""), mess), AndroidUtilities.FLAG_TAG_COLOR), messagePaint.getFontMetricsInt(), AndroidUtilities.dp(20), false);
}
}
@ -559,7 +559,7 @@ public class DialogCell extends BaseCell {
}
nameWidth = Math.max(AndroidUtilities.dp(12), nameWidth);
CharSequence nameStringFinal = TextUtils.ellipsize(nameString.replace("\n", " "), currentNamePaint, nameWidth - AndroidUtilities.dp(12), TextUtils.TruncateAt.END);
CharSequence nameStringFinal = TextUtils.ellipsize(nameString.replace('\n', ' '), currentNamePaint, nameWidth - AndroidUtilities.dp(12), TextUtils.TruncateAt.END);
try {
nameLayout = new StaticLayout(nameStringFinal, currentNamePaint, nameWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
} catch (Exception e) {
@ -609,7 +609,7 @@ public class DialogCell extends BaseCell {
if (mess.length() > 150) {
mess = mess.substring(0, 150);
}
mess = mess.replace("\n", " ");
mess = mess.replace('\n', ' ');
messageString = Emoji.replaceEmoji(mess, messagePaint.getFontMetricsInt(), AndroidUtilities.dp(17), false);
}
messageWidth = Math.max(AndroidUtilities.dp(12), messageWidth);

View File

@ -12,6 +12,8 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
@ -34,6 +36,7 @@ import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.ActionBar.Theme;
public class DrawerProfileCell extends FrameLayout {
@ -44,10 +47,11 @@ public class DrawerProfileCell extends FrameLayout {
private Rect srcRect = new Rect();
private Rect destRect = new Rect();
private Paint paint = new Paint();
private int currentColor;
public DrawerProfileCell(Context context) {
super(context);
setBackgroundColor(0xff4c84b5);
setBackgroundColor(Theme.ACTION_BAR_PROFILE_COLOR);
shadowView = new ImageView(context);
shadowView.setVisibility(INVISIBLE);
@ -96,6 +100,12 @@ public class DrawerProfileCell extends FrameLayout {
@Override
protected void onDraw(Canvas canvas) {
Drawable backgroundDrawable = ApplicationLoader.getCachedWallpaper();
int color = ApplicationLoader.getServiceMessageColor();
if (currentColor != color) {
currentColor = color;
shadowView.getDrawable().setColorFilter(new PorterDuffColorFilter(color | 0xff000000, PorterDuff.Mode.MULTIPLY));
}
if (ApplicationLoader.isCustomTheme() && backgroundDrawable != null) {
phoneTextView.setTextColor(0xffffffff);
shadowView.setVisibility(VISIBLE);
@ -133,7 +143,7 @@ public class DrawerProfileCell extends FrameLayout {
nameTextView.setText(UserObject.getUserName(user));
phoneTextView.setText(PhoneFormat.getInstance().format("+" + user.phone));
AvatarDrawable avatarDrawable = new AvatarDrawable(user);
avatarDrawable.setColor(0xff5c98cd);
avatarDrawable.setColor(Theme.ACTION_BAR_MAIN_AVATAR_COLOR);
avatarImageView.setImage(photo, "50_50", avatarDrawable);
}
}

View File

@ -9,9 +9,11 @@
package org.telegram.ui.Cells;
import android.content.Context;
import android.os.Build;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.widget.LinearLayout;
import android.widget.TextView;
@ -66,6 +68,16 @@ public class MentionCell extends LinearLayout {
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(36), MeasureSpec.EXACTLY));
}
@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 setUser(TLRPC.User user) {
if (user == null) {
nameTextView.setText("");

View File

@ -52,7 +52,7 @@ public class PhotoPickerPhotoCell extends FrameLayout {
super.onMeasure(MeasureSpec.makeMeasureSpec(itemWidth, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(itemWidth, MeasureSpec.EXACTLY));
}
public void setChecked(final boolean checked, boolean animated) {
public void setChecked(final boolean checked, final boolean animated) {
checkBox.setChecked(checked, animated);
if (animator != null) {
animator.cancel();
@ -69,13 +69,20 @@ public class PhotoPickerPhotoCell extends FrameLayout {
animator.addListener(new AnimatorListenerAdapterProxy() {
@Override
public void onAnimationEnd(Object animation) {
if (animator.equals(animation)) {
if (animator != null && animator.equals(animation)) {
animator = null;
if (!checked) {
setBackgroundColor(0);
}
}
}
@Override
public void onAnimationCancel(Object animation) {
if (animator != null && animator.equals(animation)) {
animator = null;
}
}
});
animator.start();
} else {

View File

@ -32,6 +32,7 @@ import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.messenger.UserConfig;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.ActionBar.Theme;
public class ProfileSearchCell extends BaseCell {
@ -104,7 +105,7 @@ public class ProfileSearchCell extends BaseCell {
onlinePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
onlinePaint.setTextSize(AndroidUtilities.dp(16));
onlinePaint.setColor(0xff316f9f);
onlinePaint.setColor(Theme.MSG_LINK_TEXT_COLOR);
offlinePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG);
offlinePaint.setTextSize(AndroidUtilities.dp(16));
@ -263,7 +264,7 @@ public class ProfileSearchCell extends BaseCell {
} else if (user != null) {
nameString2 = UserObject.getUserName(user);
}
nameString = nameString2.replace("\n", " ");
nameString = nameString2.replace('\n', ' ');
}
if (nameString.length() == 0) {
if (user != null && user.phone != null && user.phone.length() != 0) {

View File

@ -17,7 +17,7 @@ import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.SimpleTextView;
import org.telegram.ui.ActionBar.SimpleTextView;
public class SendLocationCell extends FrameLayout {

View File

@ -9,9 +9,11 @@
package org.telegram.ui.Cells;
import android.content.Context;
import android.os.Build;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.widget.FrameLayout;
import android.widget.TextView;
@ -34,6 +36,7 @@ public class ShareDialogCell extends FrameLayout {
public ShareDialogCell(Context context) {
super(context);
setBackgroundResource(R.drawable.list_selector);
imageView = new BackupImageView(context);
imageView.setRoundRadius(AndroidUtilities.dp(27));
@ -61,6 +64,16 @@ public class ShareDialogCell extends FrameLayout {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(100), MeasureSpec.EXACTLY));
}
@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 setDialog(TLRPC.Dialog dialog, boolean checked, CharSequence name) {
int lower_id = (int) dialog.id;
TLRPC.FileLocation photo = null;

View File

@ -146,7 +146,7 @@ public class SharedDocumentCell extends FrameLayout implements MediaController.F
}
if (color == -1) {
int idx;
String ext = (idx = name.lastIndexOf(".")) == -1 ? "" : name.substring(idx + 1);
String ext = (idx = name.lastIndexOf('.')) == -1 ? "" : name.substring(idx + 1);
if (ext.length() != 0) {
color = ext.charAt(0) % icons.length;
} else {
@ -198,34 +198,49 @@ public class SharedDocumentCell extends FrameLayout implements MediaController.F
checkBox.setChecked(checked, animated);
}
public void setDocument(MessageObject document, boolean divider) {
public void setDocument(MessageObject messageObject, boolean divider) {
needDivider = divider;
message = document;
message = messageObject;
loaded = false;
loading = false;
if (document != null && document.messageOwner.media != null && document.messageOwner.media.document != null) {
if (messageObject != null && messageObject.getDocument() != null) {
int idx;
String name = FileLoader.getDocumentFileName(document.messageOwner.media.document);
if (name.length() == 0) {
if (document.isMusic()) {
name = document.getMusicAuthor() + " - " + document.getMusicTitle();
String name = null;
if (messageObject.isMusic()) {
TLRPC.Document document;
if (messageObject.type == 0) {
document = messageObject.messageOwner.media.webpage.document;
} else {
document = messageObject.messageOwner.media.document;
}
for (int a = 0; a < document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeAudio) {
if (attribute.performer != null && attribute.performer.length() != 0 || attribute.title != null && attribute.title.length() != 0) {
name = messageObject.getMusicAuthor() + " - " + messageObject.getMusicTitle();
}
}
}
}
String fileName = FileLoader.getDocumentFileName(messageObject.getDocument());
if (name == null) {
name = fileName;
}
nameTextView.setText(name);
placeholderImabeView.setVisibility(VISIBLE);
extTextView.setVisibility(VISIBLE);
placeholderImabeView.setImageResource(getThumbForNameOrMime(name, document.messageOwner.media.document.mime_type));
nameTextView.setText(name);
extTextView.setText((idx = name.lastIndexOf(".")) == -1 ? "" : name.substring(idx + 1).toLowerCase());
if (document.messageOwner.media.document.thumb instanceof TLRPC.TL_photoSizeEmpty || document.messageOwner.media.document.thumb == null) {
placeholderImabeView.setImageResource(getThumbForNameOrMime(fileName, messageObject.getDocument().mime_type));
extTextView.setText((idx = fileName.lastIndexOf('.')) == -1 ? "" : fileName.substring(idx + 1).toLowerCase());
if (messageObject.getDocument().thumb instanceof TLRPC.TL_photoSizeEmpty || messageObject.getDocument().thumb == null) {
thumbImageView.setVisibility(INVISIBLE);
thumbImageView.setImageBitmap(null);
} else {
thumbImageView.setVisibility(VISIBLE);
thumbImageView.setImage(document.messageOwner.media.document.thumb.location, "40_40", (Drawable) null);
thumbImageView.setImage(messageObject.getDocument().thumb.location, "40_40", (Drawable) null);
}
long date = (long) document.messageOwner.date * 1000;
dateTextView.setText(String.format("%s, %s", AndroidUtilities.formatFileSize(document.messageOwner.media.document.size), LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, LocaleController.getInstance().formatterYear.format(new Date(date)), LocaleController.getInstance().formatterDay.format(new Date(date)))));
long date = (long) messageObject.messageOwner.date * 1000;
dateTextView.setText(String.format("%s, %s", AndroidUtilities.formatFileSize(messageObject.getDocument().size), LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, LocaleController.getInstance().formatterYear.format(new Date(date)), LocaleController.getInstance().formatterDay.format(new Date(date)))));
} else {
nameTextView.setText("");
extTextView.setText("");
@ -248,7 +263,7 @@ public class SharedDocumentCell extends FrameLayout implements MediaController.F
if (message.messageOwner.attachPath == null || message.messageOwner.attachPath.length() == 0 || !(new File(message.messageOwner.attachPath).exists())) {
cacheFile = FileLoader.getPathToMessage(message.messageOwner);
if (!cacheFile.exists()) {
fileName = FileLoader.getAttachFileName(message.messageOwner.media.document);
fileName = FileLoader.getAttachFileName(message.getDocument());
}
}
loaded = false;
@ -286,7 +301,7 @@ public class SharedDocumentCell extends FrameLayout implements MediaController.F
}
}
public MessageObject getDocument() {
public MessageObject getMessage() {
return message;
}

View File

@ -10,13 +10,11 @@ package org.telegram.ui.Cells;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
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.StaticLayout;
import android.text.TextPaint;
@ -33,11 +31,13 @@ import org.telegram.messenger.MessageObject;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.messenger.browser.Browser;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Components.CheckBox;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.LetterDrawable;
import org.telegram.ui.Components.LinkPath;
import org.telegram.ui.ActionBar.Theme;
import java.io.File;
import java.util.ArrayList;
@ -100,7 +100,7 @@ public class SharedLinkCell extends FrameLayout {
paint.setStrokeWidth(1);
urlPaint = new Paint();
urlPaint.setColor(0x33316f9f);
urlPaint.setColor(Theme.MSG_LINK_SELECT_BACKGROUND_COLOR);
}
setWillNotDraw(false);
@ -216,7 +216,7 @@ public class SharedLinkCell extends FrameLayout {
if (title != null) {
try {
int width = (int) Math.ceil(titleTextPaint.measureText(title));
CharSequence titleFinal = TextUtils.ellipsize(title.replace("\n", " "), titleTextPaint, Math.min(width, maxWidth), TextUtils.TruncateAt.END);
CharSequence titleFinal = TextUtils.ellipsize(title.replace('\n', ' '), titleTextPaint, Math.min(width, maxWidth), TextUtils.TruncateAt.END);
titleLayout = new StaticLayout(titleFinal, titleTextPaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -252,7 +252,7 @@ public class SharedLinkCell extends FrameLayout {
try {
String link = links.get(a);
int width = (int) Math.ceil(descriptionTextPaint.measureText(link));
CharSequence linkFinal = TextUtils.ellipsize(link.replace("\n", " "), descriptionTextPaint, Math.min(width, maxWidth), TextUtils.TruncateAt.MIDDLE);
CharSequence linkFinal = TextUtils.ellipsize(link.replace('\n', ' '), descriptionTextPaint, Math.min(width, maxWidth), TextUtils.TruncateAt.MIDDLE);
StaticLayout layout = new StaticLayout(linkFinal, descriptionTextPaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
linkY = description2Y;
if (descriptionLayout2 != null && descriptionLayout2.getLineCount() != 0) {
@ -378,7 +378,7 @@ public class SharedLinkCell extends FrameLayout {
pressedLink = a;
linkPreviewPressed = true;
try {
urlPath.setCurrentLayout(layout, 0);
urlPath.setCurrentLayout(layout, 0, 0);
layout.getSelectionPath(0, layout.getText().length(), urlPath);
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -390,7 +390,7 @@ public class SharedLinkCell extends FrameLayout {
if (webPage != null && Build.VERSION.SDK_INT >= 16 && webPage.embed_url != null && webPage.embed_url.length() != 0) {
delegate.needOpenWebView(webPage);
} else {
AndroidUtilities.openUrl(getContext(), links.get(pressedLink));
Browser.openUrl(getContext(), links.get(pressedLink));
}
} catch (Exception e) {
FileLog.e("tmessages", e);
@ -461,7 +461,7 @@ public class SharedLinkCell extends FrameLayout {
}
if (!linkLayout.isEmpty()) {
descriptionTextPaint.setColor(0xff316f9f);
descriptionTextPaint.setColor(Theme.MSG_LINK_TEXT_COLOR);
int offset = 0;
for (int a = 0; a < linkLayout.size(); a++) {
StaticLayout layout = linkLayout.get(a);

View File

@ -123,13 +123,20 @@ public class SharedPhotoVideoCell extends FrameLayoutFixed {
animator.addListener(new AnimatorListenerAdapterProxy() {
@Override
public void onAnimationEnd(Object animation) {
if (animator.equals(animation)) {
if (animator != null && animator.equals(animation)) {
animator = null;
if (!checked) {
setBackgroundColor(0);
}
}
}
@Override
public void onAnimationCancel(Object animation) {
if (animator != null && animator.equals(animation)) {
animator = null;
}
}
});
animator.start();
} else {
@ -229,8 +236,8 @@ public class SharedPhotoVideoCell extends FrameLayoutFixed {
if (messageObject.isVideo()) {
photoVideoView.videoInfoContainer.setVisibility(VISIBLE);
int duration = 0;
for (int b = 0; b < messageObject.messageOwner.media.document.attributes.size(); b++) {
TLRPC.DocumentAttribute attribute = messageObject.messageOwner.media.document.attributes.get(b);
for (int b = 0; b < messageObject.getDocument().attributes.size(); b++) {
TLRPC.DocumentAttribute attribute = messageObject.getDocument().attributes.get(b);
if (attribute instanceof TLRPC.TL_documentAttributeVideo) {
duration = attribute.duration;
break;
@ -239,8 +246,8 @@ public class SharedPhotoVideoCell extends FrameLayoutFixed {
int minutes = duration / 60;
int seconds = duration - minutes * 60;
photoVideoView.videoTextView.setText(String.format("%d:%02d", minutes, seconds));
if (messageObject.messageOwner.media.document.thumb != null) {
TLRPC.FileLocation location = messageObject.messageOwner.media.document.thumb.location;
if (messageObject.getDocument().thumb != null) {
TLRPC.FileLocation location = messageObject.getDocument().thumb.location;
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);

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